作为一名刚入行的网络安全爱好者,第一次接触RCE漏洞时那种既兴奋又困惑的感觉我至今记忆犹新。RCE(Remote Code/Command Execution)作为Web安全领域的核心漏洞类型,是每个安全研究员必须掌握的技能。今天我就以RCE-labs-level0这个经典靶场为例,带大家从零开始拆解命令注入的奥秘。
RCE漏洞本质上分为两种形式:远程代码执行(Remote Code Execution)和远程命令执行(Remote Command Execution)。虽然缩写都是RCE,但两者存在微妙差异。代码执行通常发生在应用层,比如PHP的eval()函数执行恶意代码;而命令执行则是直接操作系统shell,比如通过system()函数执行系统命令。在CTF比赛中,我们最终目标往往是获取服务器上的flag文件,这就需要我们灵活运用这两种技术。
首先我们需要从GitHub获取靶场源码:
bash复制git clone https://github.com/ProbiusOfficial/RCE-labs
cd RCE-labs
这个靶场使用PHP编写,建议使用Docker快速搭建测试环境:
bash复制docker run -d -p 8080:80 -v $(pwd):/var/www/html php:apache
访问http://localhost:8080/level0即可进入第一关。靶场设计非常友好,所有关卡都有明确提示,特别适合新手循序渐进地学习。
打开level0页面,我们会看到一个简单的输入框,提示我们尝试执行代码。查看页面源码可以发现关键部分:
php复制<?php
if(isset($_GET['a'])){
$code = $_GET['a'];
eval($code);
}
?>
这段代码直接将GET参数a的值传递给eval()函数执行,这就是典型的代码注入漏洞。eval()会将其中的字符串作为PHP代码执行,这给了我们操作空间。
eval()是PHP中一个危险但强大的函数,它能够将传入的字符串作为PHP代码执行。当开发者未经严格过滤就直接使用用户输入作为eval参数时,就会形成安全漏洞。例如:
php复制// 危险示例
eval("echo 'Hello, '.$_GET['name'];");
攻击者可以通过构造特殊的name参数注入任意代码:
code复制?name=';phpinfo();//
这会导致服务器执行echo 'Hello, ';phpinfo();//';,从而暴露服务器信息。
虽然都能实现攻击效果,但代码执行和命令执行在实现层面有所不同:
| 类型 | 执行环境 | 典型函数 | 影响范围 |
|---|---|---|---|
| 代码执行 | 应用运行时 | eval(), assert() | 限于当前应用 |
| 命令执行 | 操作系统 | system(), exec() | 整个服务器 |
在CTF中,我们通常需要根据场景选择合适的方式。比如当需要读取系统文件时,命令执行往往更直接有效。
观察靶场结构可以发现flag存储在flag.php中,通常这类文件会定义$flag变量。我们可以构造如下payload:
code复制?a=include('flag.php');var_dump($flag);
这个payload做了三件事:
注意:在实际测试中,可能需要尝试多种变量名,如$FLAG、$flag_content等,这取决于靶场的具体实现。
当我们需要更大操作空间时,可以尝试执行系统命令:
code复制?a=system("cat /flag");
这个payload使用system函数执行系统命令cat来直接读取flag文件。相比代码执行,这种方法更加直接,但需要注意:
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 代码执行 | 无需知道flag路径 | 依赖变量名已知 | 简单CTF题目 |
| 命令执行 | 操作更灵活 | 需要路径信息 | 复杂渗透测试 |
对于初学者,建议先从代码执行入手,逐步过渡到命令执行技术。
最根本的解决方案是避免使用eval等危险函数。如果必须使用,应该实施严格过滤:
php复制// 安全示例:限制允许的函数
$allowed = ['date', 'strtotime'];
if(in_array($_GET['func'], $allowed)){
eval($_GET['func'].'();');
}
大多数情况下,eval的功能可以通过其他安全方式实现。比如动态调用函数可以使用call_user_func:
php复制// 更安全的替代方案
if(function_exists($_GET['func'])){
call_user_func($_GET['func']);
}
除了代码层面的防护,服务器配置也很重要:
disable_functions = "eval, system, exec"可能原因及解决方案:
<?=代替<?php echo几个简单的测试方法:
?a=echo 1+1;看是否输出2?a=phpinfo();在复杂场景下,可能需要执行多条语句:
code复制?a=$f=file_get_contents('/flag');echo $f;
或者使用注释避免语法错误:
code复制?a=/*abc*/system("whoami")//
掌握了level0的基础后,建议按照以下路线深入学习:
优质学习资源:
记住,在真实渗透测试中,未经授权的RCE测试是违法行为。所有技术学习都应在授权靶场或自己搭建的环境中进行。保持好奇心,但更要遵守法律和道德规范。