CTF-All-In-One/doc/1.5.8_glibc_malloc.md

120 lines
3.3 KiB
Markdown
Raw Normal View History

2017-10-11 17:22:24 +07:00
# 1.5.8 glibc malloc
2018-01-10 16:35:17 +07:00
- [glibc](#glibc)
- [malloc](#malloc)
- [参考资料](#参考资料)
2018-04-29 21:21:55 +07:00
[下载文件](../src/others/1.5.8_glibc_malloc)
2018-01-10 16:35:17 +07:00
## glibc
2018-08-05 16:43:10 +07:00
2018-01-10 16:35:17 +07:00
glibc 即 GNU C Library是为 GNU 操作系统开发的一个 C 标准库。glibc 主要由两部分组成,一部分是头文件,位于 `/usr/include`;另一部分是库的二进制文件。二进制文件部分主要是 C 语言标准库,有动态和静态两个版本,动态版本位于 `/lib/libc.so.6`,静态版本位于 `/usr/lib/libc.a`
这一章中,我们将阅读分析 glibc 的源码,下面先把它下载下来,并切换到我们需要的版本:
2018-08-05 16:43:10 +07:00
```text
2018-01-10 16:35:17 +07:00
$ git clone git://sourceware.org/git/glibc.git
$ cd glibc
$ git checkout --track -b local_glibc-2.23 origin/release/2.23/master
```
2018-08-05 16:43:10 +07:00
2018-05-24 15:33:36 +07:00
下面来编译它,首先修改配置文件 Makeconfig`-Werror` 注释掉,这样可以避免高版本 GCCv8.1.0 将警告当做错误处理:
2018-08-05 16:43:10 +07:00
```text
2018-05-24 15:33:36 +07:00
$ cat Makeconfig | grep -i werror | grep warn
+gccwarn += #-Werror
```
2018-08-05 16:43:10 +07:00
2018-05-24 15:33:36 +07:00
接下来需要打上一个 patch
2018-08-05 16:43:10 +07:00
```diff
2018-05-24 15:33:36 +07:00
$ cat regexp.patch
diff --git a/misc/regexp.c b/misc/regexp.c
index 19d76c0..9017bc1 100644
--- a/misc/regexp.c
+++ b/misc/regexp.c
2018-08-05 16:43:10 +07:00
@@ -29,14 +29,17 @@
2018-05-24 15:33:36 +07:00
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_23)
2018-08-05 16:43:10 +07:00
2018-05-24 15:33:36 +07:00
-/* Define the variables used for the interface. */
-char *loc1;
-char *loc2;
2018-08-05 16:43:10 +07:00
+#include <stdlib.h> /* Get NULL. */
2018-05-24 15:33:36 +07:00
+
+/* Define the variables used for the interface. Avoid .symver on common
+ symbol, which just creates a new common symbol, not an alias. */
+char *loc1 = NULL;
+char *loc2 = NULL;
compat_symbol (libc, loc1, loc1, GLIBC_2_0);
compat_symbol (libc, loc2, loc2, GLIBC_2_0);
2018-08-05 16:43:10 +07:00
2018-05-24 15:33:36 +07:00
/* Although we do not support the use we define this variable as well. */
-char *locs;
+char *locs = NULL;
compat_symbol (libc, locs, locs, GLIBC_2_0);
$ patch misc/regexp.c regexp.patch
```
2018-08-05 16:43:10 +07:00
2018-05-24 15:33:36 +07:00
然后就可以编译了:
2018-08-05 16:43:10 +07:00
```text
2018-05-24 15:33:36 +07:00
$ mkdir build && cd build
$ ../configure --prefix=/usr/local/glibc-2.23
$ make -j4 && sudo make install
```
如果我们想要在编译程序时指定 libc可以像这样
2018-08-05 16:43:10 +07:00
```text
2018-06-02 13:52:30 +07:00
$ gcc -L/usr/local/glibc-2.23/lib -Wl,--rpath=/usr/local/glibc-2.23/lib -Wl,-I/usr/local/glibc-2.23/lib/ld-2.23.so test.c
2018-05-24 15:33:36 +07:00
$ ldd a.out
linux-vdso.so.1 (0x00007ffcc76b0000)
libc.so.6 => /usr/local/glibc-2.23/lib/libc.so.6 (0x00007f6abd578000)
/usr/local/glibc-2.23/lib/ld-2.23.so => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f6abdb1c000)
```
2018-01-10 16:35:17 +07:00
2018-06-08 19:46:05 +07:00
然后如果希望在调试时指定 libc 的源文件,可以使用 gdb 命令 `directory`,但是这种方法的缺点是不能解析子目录,所以推荐使用下面的命令在启动时加载:
2018-08-05 16:43:10 +07:00
```text
gdb `find ~/path/to/glibc/source -type d -printf '-d %p '` ./a.out
```
2018-01-10 16:35:17 +07:00
2018-03-25 21:48:54 +07:00
## malloc.c
2018-08-05 16:43:10 +07:00
2018-01-10 16:35:17 +07:00
下面我们先分析 glibc 2.23 版本的源码,它是 Ubuntu16.04 的默认版本,在 pwn 中也最常见。然后,我们再探讨新版本的 glibc 中所加入的漏洞缓解机制。
2018-03-25 21:48:54 +07:00
## 相关结构
2018-08-05 16:43:10 +07:00
### 堆块结构
2018-03-25 21:48:54 +07:00
- Allocated Chunk
- Free Chunk
- Top Chunk
2018-08-05 16:43:10 +07:00
### Bins 结构
2018-03-25 21:48:54 +07:00
- Fast Bins
- Small Bins
- Large Bins
- Unsorted Bins
2018-08-05 16:43:10 +07:00
### Arena 结构
2018-03-25 21:48:54 +07:00
## 分配函数
2018-08-05 16:43:10 +07:00
2018-03-25 21:48:54 +07:00
`_int_malloc()`
## 释放函数
2018-08-05 16:43:10 +07:00
2018-03-25 21:48:54 +07:00
`_int_free()`
## 重分配函数
2018-08-05 16:43:10 +07:00
`_int_realloc()`
2018-01-10 16:35:17 +07:00
## 参考资料
2018-08-05 16:43:10 +07:00
2018-01-10 16:35:17 +07:00
- [The GNU C Library (glibc)](https://www.gnu.org/software/libc/)
- [glibc manual](https://www.gnu.org/software/libc/manual/)