This pwn need to use Unsorted Bin Attack and House Of Orange to exploit. First, I would like to introduce Unsorted Bin Attack, House Of Orange and some relevant technique.
Environment: I use 64 bit to make example.
Condition: Control unsorted chunk’s bk pointer.
Unsorted Bin uses FIFO strategy.
- Set free unsorted chunk’s pointer to target_addr - 0x10, this chunk will be the first free chunk in Unsorted Bin.
- Call malloc, the first free chunk will be put into the corresponding bin.
- Then the operations below will be performed:
victim = unsorted_bin(av)->bk = p;
So, use Unsorted Bin Attack can set target_addr’s value to
FSOP(File-Stream Oriented Programming), like ROP and SROP, but it use FILE struct to construct the exploit chain. One of the use of FSOP is House Of Orange.
FSOP mainly use
_IO_ﬂush_all_lockp function, it flushes all standard I/O stream before process being terminated. It travels all FILE struct by element _chain pointer. The code:
int _IO_flush_all_lockp (int do_lock)
According to the code above,
_IO_flush_all_lockp which called by
abort will call
_IO_OVERFLOW (fp, EOF), and we can hijack 用
_IO_OVERFLOW through FILE struct’s vtable. There are 3 situations that program will call
- glibc abort
- exit function
- main return
When there occurs some errors in
malloc, it will call
malloc_printerr and then
This exploit makes advantage of changing
_IO_list_all and forges
vtable which includes
extern struct _IO_FILE_plus *_IO_list_all;
At the beginning of the program, pwner needs to input the name of author on
bss_0x602060 which behind the chunk_list(
bss_0x6020A0). Pwner can input a string of length 0x40 without \x00, when program output the author’s name, the heap address leaks.
Edit() function, there are two lines of code following, in
InputString() function, it doesn’t end up input string with \x00 which leads to larger string length.
The first part of expolit:
But how to leak libc information while there is no
free() in the program?
When user malloc a chunk whose size is larger than top chunk, the program will call
sysmalloc() and free the top chunk into unsorted bin. Then the top chunk fd and bk will point to the address which is relevant with
# trigger free in sysmalloc, now the top chunk size is 0xfe1
Now, we know the heap and libc address and the next step is to perform unsorted bin attack.
First, construct a chunk of size 0x61. When it comes to
malloc(1), the fake chunk will be put into fastbin. Use unsorted bin attack,
_IO_list_all will be changed to
main_arena+88. After the fake chunk being put into fastbin, the
malloc() will continue to find the next free unsorted chunk. Because next chunk’s size is 0,
malloc() then triggers
printerr(). So the program searches the FILE struct from
_IO_list_all whose value is already
main_arena+88 and calls
The first FILE struct is invalid, and through the
main_arena+216), the program will find the next FILE struct whose address is fastbin’s first chunk which is forged by pwner. So the following code will be triggered:
FILE_OVERFLOW(fp, EOF) => system(fp) => system('/bin/sh')
The last part of exploits:
# Index overflow, the size of chunk will be changed to heap address