一个写笔记的程序,下面是程序的一些功能。
1 | $ ./hacknote |
因为想去弄懂一些细节,所以在GitHub上搜到了源代码。
顺便看看并总结angelboy大神的幻灯片,分享收获。
The workflow of malloc
- 第一次执行 malloc
- 无论一开始 malloc 多少空间 < 128 KB 都会有 kernel 给132 KB 的 heap segment (rw) 这部分为 main arena
- 第二次执行 malloc 时,只要分配的空间大小不超过 128 KB,则不再执行 system call 跟系统要空间,超过大小才会有 brk 从kernel 索要空间存储。
- 即使 free 掉所有 main arena 分配的空间,也不会立即还给 kernel
- 这时存储空间由 glibc 管理
Mechanism of glibc malloc
- Chunk
- glibc 在用作存储管理时的数据结构
- malloc 时分配出去的为一个 chunk
- chunk header(prev_size + size)+ user data
- 如果该 chunk 被 free 则会将 chunk 加入叫做 bin 的链表里
- 分类
- Allocated chunk
- Free chunk
- Top chunk
- heap
- Allocated chunk
- prev_size
- 如果上一个的 chunk 是 freed,则该位置上会存有上一个 chunk 的 size(包括 header)
- 这里指的上一个是在连续存储的上一个
- size
- 该 chunk 大小,其中有三个 flag
- PREV_INUSE (bit 0): 上一个 chunk 是否不是 freed
- IS_MMAPPED (bit 1): 该 chunk 是不是由 mmap 所分配出去的
- NON_MAIN_ARENA (bit 2): 是否不属于 main arena
- 该 chunk 大小,其中有三个 flag
- 图
- prev_size
free chunk
- prev_size
- size
- fd : point to next chunk(包括 bin)
- 这里指的是链表中的 next chunk,而非连续存储的 chunk
- bk : point to last chunk(包括 bin)
- 这里指的是链表中的 last chunk,而非连续存储的 chunk
- fd_nextsize : point to next large chunk(不包含 bin)
- bk_nextsize : point to last large chunk(不包含 bin)
freed chunk
- top chunk
- 第一次 malloc 时就会将 heap 切成两块 chunk,第一个 chunk 就是分配出去的 chunk,剩下的空间被视为 top chunk,之后要是分配空间不足时会有 top chunk 切出去
- prev_size
1 | def l(): |
1 | #!/usr/bin/env python3 |
one_gadget
- strings
1 | -> strings -tx /lib/x86_64-linux-gnu/libc.so.6 | grep /bin/sh |
- 用 objdump 打开 libc.so.6
1 | objdump -d libc.so.6 | grep 18ac40 -A 7 -B 3 |
1 | 45575: call 35a60 <sigprocmask@@GLIBC_2.2.5> |
One Gadget: 0x4557a
execve(“/bin/sh”, rsp+0x30, environ);