题目地址: https://pwnable.tw/challenge/#3
程序分析
题目地址: https://pwnable.tw/challenge/#3
这道题是一个计算器的小程序,通过输入表达式进行求值,不支持括号
[email protected]:~/Desktop/ctf/pwnable.tw$ ./calc |
通过简单测试,发现输入+100000
会造成程序崩溃,调试确定问题原因是发生在calc
函数内部
unsigned int calc() |
这里的value_stack
是运算变量栈,用于存放输入的运算符两边的数字,例如输入1+3
,则value_stack的变化是这样的
value_stack 的运算值栈变化 |
但问题来了,当我们尝试输入+2
时变化是这样的
输入+ |
知道通过输入+X
可以泄露打印value_stack[X]的值,那么我们可以尝试泄露stack cookie来造成栈异常,但仔细研究了一下,除了运算符那个栈可溢出,但仅限于”+-*/“,所以实际意义不大,再仔细分析,可以发现,程序还可以造成栈上任意地址写的效果,
发生在eval
的函数中
_DWORD *__cdecl eval(_DWORD *value_stack, char a2) |
通过构造+X+Y
或者+X-Y
,当然*/
也能用,如下
输入+ |
利用
好了原理都知道了,一个栈上任意读,一个任意写,可以很快的pwn掉,但有一个坑在于,这里面在布置int 80利用代码时,需要
eax=11 # sys_execve |
ebx需要在栈上面布置一个binsh的字符串,这就需要用到ebp了,而ebp>0x80000000 !!! 坑的是输入的值是一个int类型,无法写高于0x7FFFFFFF的值(因为你不能输入-进去当数字运算),所以这里用了一个小技巧,通过多次累加让目标值溢出,最终的利用代码如下,
from pwn import * |