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了
|
|