[MRCTF2020]套娃

发布于:2025-08-13 ⋅ 阅读:(21) ⋅ 点赞:(0)
<!--
//1st
$query = $_SERVER['QUERY_STRING'];

 if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){
    die('Y0u are So cutE!');
}
 if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){
    echo "you are going to the next ~";
}
!-->

过滤了param中下划线及其url编码。

绕过方法:用大写的url编码%5F同样可以解码为下划线。

接下来是对传参的一个过滤,要求不等于'23333'但是又能preg_match匹配到。这边漏洞在于正则表达式/^23333$/,^和$分别匹配字符串开头和结尾,但是不匹配换行符,因此我们只需要用'23333%0a'绕过就可以。一开始我想的是用数字绕过,因为这边用的是强等于嘛,但是后来发现不可以,原因在于$_GET['b_u_p_t']已经限定了字符串类型,无法改变。

这里我还遇到了一个疑惑,为什么url里面的%5F到服务端不会自动url解码成下划线呢?这样的话就没法绕过preg_match了呀。原因在于这里取参数用的是$_SERVER['QUERY_STRING'],该变量直接从原始url截取,不像REQUEST是获取解码后的。

第二关,在源代码中可以看到[][(![]+[])[+[]]+([![]]+[][[]])......,很多这种运算,是利用JS的某些特性进行运算得到字符串。例如使用不合法运算得到False,然后+''变成'False',再利用中括号取第一个字符就能得到'F'。就像自增绕过的方法一样。如何解码呢?只需要将他们复制到浏览器控制台中(是JS运行环境)回车运行,就能得到结果。

然后根据提示就能得到源码。

error_reporting(0); 
include 'takeip.php';
ini_set('open_basedir','.'); 
include 'flag.php';

if(isset($_POST['Merak'])){ 
    highlight_file(__FILE__); 
    die(); 
} 


function change($v){ 
    $v = base64_decode($v); 
    $re = ''; 
    for($i=0;$i<strlen($v);$i++){ 
        $re .= chr ( ord ($v[$i]) + $i*2 ); 
    } 
    return $re; 
}
echo 'Local access only!'."<br/>";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission!  Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); }
?>  

$ip = getIp();
if($ip!='127.0.0.1')

利用抓包伪造IP,但是这里用X-Forwarded-For发现并不可以。需要利用Client-ip:127.0.0.1,第一次见,得记一下。

file_get_contents($_GET['2333']) === 'todat is a happy day'

利用data协议就可以。

function change($v){ 
    $v = base64_decode($v); 
    $re = ''; 
    for($i=0;$i<strlen($v);$i++){ 
        $re .= chr ( ord ($v[$i]) + $i*2 ); 
    } 
    return $re; 
}

file_get_contents(change($_GET['file']))

发现change函数就是进行一些简单的运算,不用一个个算,只需要写个逆向代码就行。

function rev-change($v){ 
    $re = ''; 
    for($i=0;$i<strlen($v);$i++){ 
        $re .= chr ( ord ($v[$i]) - $i*2 ); 
    } 
    $v = base64_encode($v); 
    return $re; 
}
echo rev-change('flag.php');

总结一下:这道题考的知识点还是挺多的,有url编码绕过、正则匹配绕过、JS运算编码、伪协议、IP伪造、代码审计。补充了几个知识盲点:浏览器控制台能直接运行这中JS编码,IP伪造有时候XFF没用可以尝试Client-ip。


网站公告

今日签到

点亮在社区的每一天
去签到