[MRCTF2020] 套娃

发布于 2021-08-06  67 次阅读


知识点

​ - PHP在解析查询字符串时会将所有参数转换为有效地变量名,此时

  1. 它会删除空白符
  2. 将某些字符转化为下划线(包括空格)
    • 字符串换行符 可以表示字符串的结尾

解题

image-20210111173533621
$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 ~";
}

打开题目查看源代码,发现一处注释,获取到源码一份

第一个if不能出现_,可以根据字符串解析特性绕过

第二个if要求 不能出现23333,但是正则要能匹配的到,而且第二个if中正则^$代表的是行的开头和结尾,所以可以使用换行来绕过

构造paylaod

?b%20u%20p%20t=23333%0a
image-20210111175528130

提示FLAG在secrettw.php访问

image-20210111175715584

提示本地ip访问

image-20210111175909212

写入XFF头没有效果,但是发现有一串JS代码放到控制台看看

image-20210111180259056

看来是提示post传参

image-20210111180611506
<?php 
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'])); }
?>

随便传入一个Merak的值,获得了当前页面的源码

change函数,相当于对于传入的值进行了 一次加密

想要获得FLAG,要满足以下几点要求:

  1. IP等于127.0.0.1,这里XFF不能用,可以使用client-ip
  2. 2333的值等于todat is a happy day,而且要绕过file_get_contents函数,可以使用伪协议绕过
  3. 经过change函数加密后,仍然可以读取flag.php

构造change的解密EXP

image-20210111181831278

因此,传参改ip即可

image-20210111182612431