LFI to RCE
字数 1112 2025-08-29 08:32:01

LFI to RCE 漏洞利用技术详解

一、漏洞背景

本文基于[HITCON CTF 2018]One Line PHP Challenge题目环境,分析如何从本地文件包含(LFI)漏洞实现远程代码执行(RCE)。题目环境为Ubuntu 18.04 + PHP 7.2 + Apache。

二、漏洞代码分析

题目源码极为简洁:

<?php
($_ = @$_GET['orange']) && @substr(file($_)[0], 0, 6) === '@<?php' ? include($_) : highlight_file(__FILE__);

代码逻辑:

  1. 检查是否存在orange参数
  2. 读取该参数指定的文件内容
  3. 检查文件前6个字符是否为@<?php
  4. 如果满足条件则包含该文件,否则显示源码

三、漏洞利用思路

1. 文件上传机制

PHP处理文件上传时:

  • 文件流会被保存到临时目录
  • 文件名格式:php[0-9A-Za-z]{3,6}
  • 文件存活周期:
    • PHP正常结束且文件未被移动/重命名:请求结束后删除
    • PHP非正常结束(如崩溃):文件永久保留
    • 正常情况下临时文件存活时间约30秒

2. 利用方法

方法一:暴力破解

在30秒内猜测临时文件名,但概率极低(1/2176782336)

方法二:使PHP崩溃

通过特定POC使PHP崩溃,使临时文件永久保留,从而有足够时间爆破

四、技术细节分析

1. 崩溃POC

php://filter/convert.quoted-printable-encode/resource=data://,%bfAAAAAAAAAAAAAAAAAAAAAAA%ff%ff%ff%ff%ff%ff%ff%ffAAAAAAAAAAAAAAAAAAAAAAAA

2. PHP底层漏洞分析

漏洞位于php-src/ext/standard/filters.c中的PHP_CONV_ERR_TOO_BIG错误处理:

case PHP_CONV_ERR_TOO_BIG: {
    char *new_out_buf;
    size_t new_out_buf_size;
    new_out_buf_size = out_buf_size << 1;
    
    if (new_out_buf_size < out_buf_size) {
        // 处理逻辑
    } else {
        new_out_buf = perealloc(out_buf, new_out_buf_size, persistent);
        // 内存分配会倍增,导致过大
    }
    break;
}

关键问题:

  1. 当输入字符串包含ASCII>126的字符时进入特定分支
  2. lbchars_len变量未初始化
  3. 通过控制lbchars_len值可导致整数溢出
  4. 最终导致段错误(segfault)使PHP崩溃

3. 相关CVE

CVE-2016-7125

  • 影响版本:
    • PHP 5.x < 5.6.25
    • PHP 7.x < 7.0.10
  • 漏洞描述:ext/session/session.c中错误解析会话名称,允许通过控制会话注入任意会话数据

五、漏洞利用步骤

  1. 上传恶意文件
  2. 使用POC使PHP崩溃:
    file(urldecode('php://filter/convert.quoted-printable-encode/resource=data://,%bfAAAAAAAAFAAAAAAAAAAAAAA%ff%ff%ff%ff%ff%ff%ff%ffAAAAAAAAAAAAAAAAAAAAAAAA'));
    
  3. 临时文件被永久保留
  4. 爆破临时文件名
  5. 通过LFI包含临时文件实现RCE

六、防御措施

  1. 升级PHP版本
  2. 禁用危险函数和协议
  3. 对文件包含操作进行严格校验
  4. 设置open_basedir限制文件访问范围
  5. 避免使用用户输入直接作为文件路径

七、影响版本测试

经测试,以下版本受影响:

  • PHP 7.1.3
  • PHP 5.6.28

PHP 7.4及以上版本不受此漏洞影响。

八、总结

该漏洞利用链结合了:

  1. PHP文件上传机制
  2. 过滤器内存处理缺陷
  3. 临时文件保留特性
  4. 本地文件包含漏洞

通过精心构造的输入触发PHP崩溃,绕过临时文件删除机制,最终实现从LFI到RCE的转换。

LFI to RCE 漏洞利用技术详解 一、漏洞背景 本文基于[ HITCON CTF 2018 ]One Line PHP Challenge题目环境,分析如何从本地文件包含(LFI)漏洞实现远程代码执行(RCE)。题目环境为Ubuntu 18.04 + PHP 7.2 + Apache。 二、漏洞代码分析 题目源码极为简洁: 代码逻辑: 检查是否存在 orange 参数 读取该参数指定的文件内容 检查文件前6个字符是否为 @<?php 如果满足条件则包含该文件,否则显示源码 三、漏洞利用思路 1. 文件上传机制 PHP处理文件上传时: 文件流会被保存到临时目录 文件名格式: php[0-9A-Za-z]{3,6} 文件存活周期: PHP正常结束且文件未被移动/重命名:请求结束后删除 PHP非正常结束(如崩溃):文件永久保留 正常情况下临时文件存活时间约30秒 2. 利用方法 方法一:暴力破解 在30秒内猜测临时文件名,但概率极低(1/2176782336) 方法二:使PHP崩溃 通过特定POC使PHP崩溃,使临时文件永久保留,从而有足够时间爆破 四、技术细节分析 1. 崩溃POC 2. PHP底层漏洞分析 漏洞位于 php-src/ext/standard/filters.c 中的 PHP_CONV_ERR_TOO_BIG 错误处理: 关键问题: 当输入字符串包含ASCII>126的字符时进入特定分支 lbchars_len 变量未初始化 通过控制 lbchars_len 值可导致整数溢出 最终导致段错误(segfault)使PHP崩溃 3. 相关CVE CVE-2016-7125 : 影响版本: PHP 5.x < 5.6.25 PHP 7.x < 7.0.10 漏洞描述: ext/session/session.c 中错误解析会话名称,允许通过控制会话注入任意会话数据 五、漏洞利用步骤 上传恶意文件 使用POC使PHP崩溃: 临时文件被永久保留 爆破临时文件名 通过LFI包含临时文件实现RCE 六、防御措施 升级PHP版本 禁用危险函数和协议 对文件包含操作进行严格校验 设置 open_basedir 限制文件访问范围 避免使用用户输入直接作为文件路径 七、影响版本测试 经测试,以下版本受影响: PHP 7.1.3 PHP 5.6.28 PHP 7.4及以上版本不受此漏洞影响。 八、总结 该漏洞利用链结合了: PHP文件上传机制 过滤器内存处理缺陷 临时文件保留特性 本地文件包含漏洞 通过精心构造的输入触发PHP崩溃,绕过临时文件删除机制,最终实现从LFI到RCE的转换。