本文最后更新于:2023年10月15日 晚上
[MRCTF2020]套娃 先看页面源代码,发现有代码注释:
1 2 3 4 5 6 7 8 $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 ~" ; }
要传入b_u_p_t
参数,但是不能有_
注意 :
变量名中的点和空格被转换成下划线。例如 <input name="a.b" />
变成了 $_REQUEST["a_b"]
。
所以我们可以传入b u p t
或b.u.p.t
实现绕过。
在正则表达式中^
代表从字符串起始处匹配,$
代表结尾,/^23333$/
要求字符串恰好等于23333
。
所以第二个if
语句意思是b_u_p_t
的值不能等于(强比较)23333
,但要通过正则匹配。
在非多行模式下(即没有/s
),$
会忽略在句尾的%0a
例:
1 2 3 if (preg_match ('/^flag$/' , $_GET ['a' ]) && $_GET ['a' ] !== 'flag' ) { echo $flag ; }
只需传入?a=flag%0a
同理,本题中传入
即可。
提示flag在secrettw.php
访问并查看页面源代码:
有脏东西
这东西很长,在那一行上双击可快速选中该行。
这是Jsfuck
编码,详情见Jsfuck – 一个很有意思的Javascript特性
可以直接使用在线工具解码,比如CTF在线工具-在线JSfuck加密|在线JSfuck解密|JSfuck|JSfuck原理|JSfuck算法 (hiencode.com)
也可以将其复制到浏览器控制台中:
post me Merak
用post方法传入一个名为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 <?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检测 添加报文,据我所知有两种方法
X-Forwarded-For: 127.0.0.1
Client-ip: 127.0.0.1
这里不知道为什么第一个不行,只能使用第二个。
php伪协议 这里可以使用data伪协议,对于data,
例:
1 2 3 <?php echo file_get_contents ('data://text/plain;base64,SSBsb3ZlIFBIUAo=' ); ?>
同理,本题传入:
1 ?2333=data://text/plain;base64,dG9kYXQgaXMgYSBoYXBweSBkYXk= #todat is a happy day
代码逆向 我用python写了个change()
的逆向函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import base64def change (v ): re='' for i in range (len (v)): re += chr (ord (v[i]) - i*2 ); re=base64.b64encode(re.encode()) return re.decode()if __name__ == '__main__' : s="flag.php" print (change(s))
payload
参考(引用) [MRCTF2020]套娃_ctf套娃密码_Sk1y的博客-CSDN博客
preg_match绕过总结 - MustaphaMond - 博客园 (cnblogs.com)
PHP: 来自 PHP 之外的变量 - Manual