login
刚开始看这题的时候有点不知所云,完全不知道是要leak canary还是爆破来做,第二天想到,succ()中sprintf()函数的格式化字符串参数是在栈上的,
尝试下用s1修改他,果然成功修改输出s2的格式(第一天的时候就有这个现象了,当时还以为printf()有bug…)
然后就是用格式化字符串修改stack_chk_fail@got,原本是想找个ret的gadget,但是很奇怪的是没办法用格式化字符串精确修改,好像每多输出一个字符修改的结果会多2,
后来发现只修改一个字节刚好可以把stack_chk_fail@got修改成malloc@plt + 6这样即使修改了canary函数也可以正常返回,然后就可以愉快的做ROP了
然后做ROP执行system('/bin/sh')的时候老是失败,感觉是因为前面的格式化字符串修改了太多栈的内容影响到了system(),
于是转而用syscall执行execve('/bin/sh', 0, 0)这里要把ecx,edx都设置为0,然而sprintf()遇到\x00就断了,
调试的时候发现执行ROP的时候edx已经为0了,然后在题目给的libc里面找到了这么一个gadget
0x000282d3 : xor ecx, ecx ; pop ebx ; mov eax, ecx ; pop esi ; pop edi ; pop ebp ; ret
然后就可以愉快的getshell了
|
|
dragon
程序漏洞在申请堆块存放content的时候是根据输入字符串大小申请堆块的,然是edit()函数固定修改32个字节,这样就存在溢出了
利用House of Force这个技巧,溢出修改Top Chunk的大小,而且程序申请堆块存放name的时候,也只是检查长度是否小于32,并没有检查是否为负数,
这样就可以申请大小为负的堆块,然后分配到一个指向bss段中的list,然后就可以任意读写了
|
|
note
note结构体中有Title和content,特别没良心的不给Show功能,
漏洞点在EditContent功能一次只能修改48个字节的content,但是允许从content后部开始修改,
程序使用的是talloc,网上搜索了一波发现貌似还有点复杂,不过调试发现talloc的chunk只是拓展了ptmalloc的堆块结构,
而且释放内存实际上最终还是要执行ptmalloc的free(),所以完全可以当作老式的linux exploit来搞
利用溢出来做unlink attack,然后我们就的到了一个指向在bss段的note list的指针,修改_talloc_free@got为puts@plt + 6,这样就把Delete()变成了Show
但这样并不能leak libc,因为在程序释放内存之前会对堆块做检查,这样就无法直接读got,只能leak堆上的main_arena指针了
在这之前要先得到堆地址,note结构体中,Title紧跟着content_ptr,把Title填满就可以leak heap了,
但是程序的ChangeTitle()函数读取输入的时候会在输入的末尾补\x00,而且非常诡异的是只要把Title填满,下一次atoi()函数的结果一定会为0,程序直接退出
后来发现EditContent()是不会在输入末尾补\x00的,然后利用之前unlink的到的指针修改note list,将其作为一个note结构体,
这样就可以用EditContent()的方法修改某个note的Title,然后打印出来就可以的到堆的地址,
之后要打印出堆上的main_arena指针,但是main_arena指针的位置在堆块的头部,并不在Title的位置,无法通过Delete()函数的检查,
所以在这之前,利用之前指向note list的指针,多次修改堆内容,将main_arena指针前面的内容修改成一个talloc的chunk头部,然后就可以通过检查,将main_arena的指针打印出来
然后就可以修改atoi@got为system(),输入/bin/sh就可以getshell了
|
|