分析
checksec
1 | parallels@ubuntu:~/ctf/qiang/opm$ checksec opm |
程序分析
Add函数
创建一个结构体role,如果没创建过,可以参考这篇文章
1 | 00000000 ; --------------------------------------------------------------------------- |
Show
利用
利用思路
输入name和punch count时。由于没有限制输入大小,造成栈溢出。能覆盖堆指针,堆指针随函数返回保存中bss段。
通过这两次的溢出就能很容易更改堆指针指向其它地址。
atoi
头文件:#include <stdlib.h>
atoi() 函数用来将字符串转换成整数(int),其原型为:
int atoi (const char * str);
【函数说明】atoi() 函数会扫描参数 str 字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过 isspace() 函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(‘\0’)才结束转换,并将结果返回。
【返回值】返回转换后的整型数;如果 str 不能转换成 int 或者 str 为空字符串,那么将返回 0。
leak heap
待补充
正常添加role
1 | pwndbg> x /10gx 0x555555554000+0x2020E0 |
1 | pwndbg> x /10gx 0x0000555555768c20 |
第二次添加role,并进行堆溢出
1 | pwndbg> x /10gx 0x555555554000+0x2020E0 |
可以看到真正的堆指针应该是0x555555768cc0,而因为溢出,\x00\x10覆盖了最后两个字节,堆指针被修改为0x555555760010
此后
1 | pwndbg> x /10gx 0x0000555555760010 |
第三次创建role。
1 | payload = 'C'*0x80 |
首先,第一次栈溢出,可以看到本来v6在0x555555768d80,然后被payload溢出了一个字节,变成了0x555555768d00。
1 | pwndbg> heap |
而这个地址刚好就是第二次的name堆指针所指向的chunk。
于是写入之后,就变成了
1 | pwndbg> x /10gx 0x555555768d00 |
然后再次溢出,使得v6的值修改为0x555555760010,这是第二次的堆指针,这样修改之后,在打印函数里,就会将我们修改过后的第二次的name值,再次打印出来。
这样就leak出了第三次分配的name的堆地址。
1 | pwndbg> x /10gx 0x555555554000+0x2020E0 |
leak got表
有了堆地址就可以泄露存放在堆中的函数指针,从而有了got表的地址。
存放函数指针的地址在p64(heap_addr‐0x30)
1 | pwndbg> x /10gx 0x0000555555768dc0-0x30 |
TODO
leak system
TODO
getshell
TODO