pesp-heap_overflow-struct
1.第三种方法,通过堆溢出直接改struct,然后更改结构体chunklist[0].chunk中保存的chunk地址,使其指向free_got_addr,再通过程序中的show函数就可以泄露出free_got_addr中保存的free真实地址,从而获得libc的基地址。当然,这得要求先有一个free来让free的延迟绑定发生。
2.由于这里的chunk地址已经变成free_got_addr,所以当我们修改该chunk的内容时,就相当于修改got表中值,也就修改了真实函数地址的值。这里就可以通过修改该chunk内容来劫持free的got表为system函数真实地址,从而free一个内容为binsh的chunk来getshell。
3.编写exp,增删改查函数就不多说了。
(1)申请三个chunk,先将chunk1释放,之后chunk0用来堆溢出,修改chunk1的fd,进行fastbins攻击,将fakechunk放在struct前面某个位置。这里用到字节错位,原理一样,利用0x7f来攻击fastbins。再连续申请两个chunk,chunk1和chunk3就回来,这里的chunk3就是fakechunk了。现在就可以修改fakechunk从而修改掉chunklist[0].chunk的值,使其指向free_got_addr。从而调用show函数泄露free的真实地址。
1 | #注释头 |
(2)再修改chunk0的内容为system真实地址,这样就相当于劫持free的got表,之后释放掉chunk2即可getshell。
1 | #注释头 |
▲需要注意的一点就是,由于read函数读取,所以我们发送数据时一定会有一个\x0a加入进去,这里如果不考虑进入,free函数后面就是put函数,那么就会造成put函数的Got表被更改,从而无法成功调用put函数。而程序在循环体中的菜单部分又一定会调用put函数,那么这样就会造成程序崩溃。所以需要将put函数也加入进去,但是这样又会造成put函数下一个函数被覆盖\x0a。不过不要紧,gdb调试可以看到put函数下一个函数是stack_chk_fail函数,也就是检查canary出错时才会调用。我们有没有栈溢出修改canary,这个函数当然不会被调用,程序就不会崩溃。