format string with stack frame
0x00:写在前面
格式化字符串漏洞出现的时间很早了,偶然在前一段时间学到了一个其他的利用姿势,通过栈桢结构去利用格式化字符串漏洞。
原文链接
0x01:原理
在函数调用的时候,会开辟一段空间去给当前函数使用,做法是通过抬高栈来实现(sub esp,0x**),为了执行函数后能正确的返回,栈基指针ebp是指向上一个函数的ebp的,也就是被调用函数ebp指向调用函数ebp。
大概的样子就如图了,简单的写一个demo就可以发现这个。
对于格式化字符串来说,本质还是任意地址的读写,可以用来修改got、ret_addr
去控制程序流程,还可以 多次利用格式串,把shellcode
一个字节一个字节写到一个w+x
的内存地址去,然后修改got跳过去执行。
但是如果格式化字符串不在栈中呢?如果不在栈中,那么就不能通过 %*$ 这样的方式去定位,增大了利用难度,在看了phrack的文章,了解到了一种姿势:假如要把 sleep@got
修改成 system@got
,可以先利用格
式串把sleep@got先写到当前ebp指向,然后再次利用,把这个改掉,因为都是在 got表中,所以只需要改最后两个字节(x86)。 这样的话就实现了 不在栈中格式串的利用了。
0x02:实例
拿plaidctf-2015的一个pwn来演示。
bin文件的基本信息如图,分别运行和在ida中分析。
明显的FSB在 make_response
函数中。
但是,用户的输入是在 0804A040
这个地址,这个地址是在.bss
段的(栈中看不到,但是好处是不随机) 思路大概就是,把shellcode
放在这个地方,然后修改 make_response
的ret addr
到这个地址去,然后就可以拿到shell了。
1. leak 栈地址 找到ret addr
2. 写到上一个ebp去
3. 修改ret addr 到 0804A040
0x03:exp
1 | #!/usr/bin/python |