#
# I IO_buf_base 劫持技术,
# 文章写的会比较凌乱,是在一边解题同时记录
# 环境以及保护
1 | giantbranch@ubuntu:~/Desktop/pwnabletw/hijack_io_buf_base$ strings libc.so.6 | grep ubuntu |
ubuntu2.23 下的题目,只有 canary 保护没有开启,没有思路
# 主要代码
1 | int __cdecl __noreturn main(int argc, const char **argv, const char **envp) |
# 分析
# 初步印象
代码很简单,malloc,free 没有多余的操作,但是 malloc 不会清空申请的堆块中的内存,同时我们可以输入空。但是只有一个堆块,紧邻 topchunk, 无法利用 unsortedbin 泄露 main_arena, 铃响其他办法
malloc 的一个机制
当我们在应用层调用 malloc 申请堆的时候,在 glibc 中实际上调用的是_lib_malloc 函数,但是_lib_malloc 函数只是用来简单的封装_int_malloc 函数的,_int_malloc 函数才是申请堆的核心函数。
_int_malloc 会根据应用层用户申请的内存块大小,从而分配相应的 chunk 给用户使用。
函数的分配堆内存的主要执行流程
①请求大小在 fastbin 的范围内:在 fastbins 中找是否有对应的 chunk 可以使用。
②请求大小在 smallbin 的范围内:在 smallbin 中找是否有对应的 chunk 可以使用。
③请求大小在 largebin 的范围内:先调用 malloc_consolidate 对 fastbins 进行整理加入 unsortedbins。然后在 unsortedbin 中查看是否有满足要求的 chunk 可以使用。
④在 largebin 中寻找可用的 chunk 来使用。
⑤寻找较大的 bin 链中是否有可用的 chunk 来使用。
⑥切割 topchunk 来使用。
⑦topchunk 也不够了,再次调用 malloc_consolidate 整理 fastbins。
⑧topchunk 不够用,再次 malloc_consolidate 之后还没有可以用的,最终调用 sysmalloc(系统调用)申请内存。
1 | pwndbg> p *(struct _IO_FILE_plus *)stdin |
这是正常的 stdin 的 IO_FILE_plus 结构体,_IO_buf_base 是输入缓冲区开始的地方(其实应该是 read_base 是开始的地方,但是这里肯可能是说 read_base = buf_base),记得程序代码那个末尾写 0 吗。在这里将 _IO_buf_base 最低位改为 0. 这个地址其实是_IO_write_base, 这里就可以实现_IO_FILE_plus 的覆盖
1 | pwndbg> p *(struct _IO_FILE_plus *)stdin |