无参 RCE 技巧汇总
无参 RCE(Remote Code Execution)是指在无法直接向目标函数传递参数的情况下,利用 PHP 内置函数链式调用来间接实现代码执行或敏感文件读取的技术。这类技巧常见于 CTF 竞赛和渗透测试中,通常出现在 Web 应用存在 eval() / assert() / call_user_func() 等可执行代码的函数,但参数被硬编码或过滤,无法直接传入自定义字符串的场景。
一、利用 getallheaders() — HTTP 请求头注入
1.1 原理
getallheaders() 是 PHP 内置函数,用于获取当前 HTTP 请求的所有请求头信息,并以关联数组的形式返回。该函数不需要任何参数,直接调用即可获得完整的请求头数据。
结合数组指针操作函数:
current($array)— 返回数组当前指针指向的元素(默认指向第一个元素)end($array)— 将数组内部指针移动到最后一个元素并返回其值next($array)— 将数组内部指针向前移动一位并返回该元素的值
攻击者可以在自定义的 HTTP 请求头中注入恶意命令,利用上述函数提取该请求头的值并传递给 system() 执行,从而实现对无参数限制的绕过。
1.2 代码示例
方法一:使用 current() 取首元素
system(current(getallheaders()));在 HTTP 请求头第一行添加自定义头:
x: cat /flag方法二:使用 end() 取末元素
system(end(getallheaders()));在 HTTP 请求头最后一行添加自定义头:
x: cat /flag方法三:使用 next() 取第二个元素(绕过 current/end 禁用)
system(next(getallheaders()));修改 User-Agent 请求头的值为命令:
User-Agent: cat /flag1.3 适用场景
getallheaders()未被禁用目标环境中
$_GET/$_POST/$_SERVER等超全局变量被屏蔽或不可控只需要执行单条命令
需配合 Burp Suite 或 cURL 等工具修改请求头
二、利用 get_defined_vars() — 变量回溯执行
2.1 原理
get_defined_vars() 返回一个包含所有已定义变量列表的多维数组,涵盖超全局变量($_GET、$_POST、$_SERVER、$_COOKIE、$_FILES 等)以及用户自定义变量。
利用链式调用逐层提取这些变量中的内容,最终将攻击者传入的 POST/GET 参数值作为 PHP 代码字符串交由 eval() 执行。核心在于通过 get_defined_vars() 获取到 $_POST 或 $_GET,进而提取内部键值。
2.2 方法一:回溯 POST/GET 变量 → eval() 执行
步骤 1:信息收集 — 打印所有已定义变量
print_r(get_defined_vars());目的:打印当前运行环境中所有已定义变量,用于发现潜在的可控输入点。
步骤 2:定位第二个数组元素(通常是 $_POST 或 $_GET)
print_r(next(get_defined_vars()));目的:next() 将 get_defined_vars() 返回数组的指针移向第二个元素(常见是 $_POST),缩小排查范围。
步骤 3:提取最后一个键值对的值
print_r(array_pop(next(get_defined_vars())));目的:array_pop() 弹出并返回数组的最后一个元素。若 $_POST 的最后一个元素是攻击者传入的参数值(例如 WX=system('ls')),则可以直接获取该值。
步骤 4:最终执行 — 替换 print_r 为 eval
eval(array_pop(next(get_defined_vars())));无参RCE技巧汇总:PHP函数链式调用与绕过技术
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法