【译】实战演练:看我是如何将LFI变为RFI的
字数 1614 2025-08-29 08:31:41

从LFI到RFI:利用文件描述符实现漏洞升级

1. 文件包含漏洞基础

1.1 PHP文件包含漏洞原理

PHP文件包含漏洞产生于通过PHP函数引入文件时,由于文件名未经合理校验,导致意外文件操作。最常见的是本地文件包含(LFI)漏洞。

典型漏洞代码示例

if ($_GET['method']) {
    include $_GET['method'];
} else {
    include 'index.php';
}

1.2 本地文件包含(LFI)利用方式

攻击者可以提交类似https://example.com/search.php?method=upload/1.jpg的URL,其中1.jpg是攻击者上传的包含恶意PHP代码的图片文件,从而执行恶意代码。

2. 从LFI到RFI的突破性发现

2.1 关键发现

  1. JAR包文件利用:Web应用程序在特定配置下可以加载服务器上的JAR包文件并执行其中的Java类
  2. 静态代码块执行:可以在Java类中定义静态代码块,在类加载时自动执行

示例恶意Java类

public class LoadRunner {
    static {
        System.out.println("Load runner'ed");
        // 这里可以放置恶意代码
    }
    public static void main(String[] args) {}
}

2.2 挑战与解决方案

主要挑战

  • 如何让应用程序加载攻击者控制的JAR包文件
  • 如何确定JAR包文件在服务器上的路径

解决方案

  • 利用Linux的/proc/[PID]/fd/*文件描述符机制访问上传的文件
  • 通过猜测HTTP请求处理程序的PID和文件描述符编号来定位文件

3. 文件描述符利用技术详解

3.1 Linux文件描述符机制

在Linux中,当一个进程打开文件时,会在/proc/[PID]/fd/目录下创建对应的文件描述符链接。这使得我们可以:

  • 不需要猜测随机生成的文件名或路径
  • 只需猜测PID和文件描述符编号即可访问文件

3.2 实际利用步骤

  1. 上传恶意文件:通过文件上传功能将恶意JAR包上传到服务器
  2. 获取PID:确定HTTP请求处理程序的进程ID
  3. 查找文件描述符:在/proc/[PID]/fd/目录下查找对应的文件描述符
  4. 通过LFI包含:利用LFI漏洞包含/proc/[PID]/fd/[编号]路径

3.3 减少搜索空间的技巧

  1. 多文件上传:同时上传多个相同文件,增加命中概率
  2. PID预测:服务器重启后PID分配顺序通常一致,可缩小PID猜测范围

4. 实战演示:Flask框架案例

4.1 测试环境搭建

Flask示例应用代码

from flask import Flask, request
import os

UPLOAD_FOLDER = "/tmp"
app = Flask(__name__)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER

@app.route("/", methods=["GET"])
def show_me_the_money():
    x = request  # 访问request对象会触发文件描述符创建
    import code
    code.interact(local=locals())  # 进入交互式调试环境

if __name__ == "__main__":
    app.run()

4.2 文件上传脚本

import requests

response = requests.get(
    "http://127.0.0.1:5000/",
    files={
        "upload_file": open("/tmp/hullo", "rb"),
        # 可添加多个文件增加命中率
    },
)

4.3 查找文件描述符

  1. 获取Flask进程PID:ps aux | grep flask
  2. 查看文件描述符目录:ls -la /proc/[PID]/fd/
  3. 确认文件内容:cat /proc/[PID]/fd/[编号]

5. 关键注意事项

  1. 文件大小限制:小文件可能被直接读入内存而不创建文件描述符(如Flask中1MB以下文件)

    • 解决方案:在JAR包中添加填充数据使其超过阈值
  2. 框架特性差异

    • Flask和Django等框架是"惰性加载"请求体数据
    • 只有访问请求体数据时才会创建文件描述符
  3. 请求处理程序要求

    • 处理程序必须访问FILES字典或请求体数据
    • 需要定位到会处理上传文件的请求处理程序

6. 攻击利用流程总结

  1. 识别目标系统中的LFI漏洞
  2. 寻找文件上传功能或请求体数据处理点
  3. 上传特制JAR包文件(确保大小超过内存加载阈值)
  4. 确定Web服务器进程PID
  5. 通过LFI包含/proc/[PID]/fd/[编号]路径
  6. 触发JAR包中静态代码块的执行

7. 防御建议

  1. 输入验证:严格校验文件包含路径,禁止包含用户可控的完整路径
  2. 禁用危险函数:如非必要,禁用includerequire等危险函数
  3. 文件上传限制
    • 限制上传文件类型
    • 使用随机不可预测的存储路径
    • 及时关闭文件描述符
  4. 进程隔离:Web服务器进程使用低权限用户运行
  5. 访问控制:限制对/proc目录的访问

通过这种创新的方法,安全研究人员可以将传统的LFI漏洞升级为更危险的RFI漏洞,极大地扩展了攻击面。理解这种技术有助于开发更安全的Web应用程序和更有效的防御措施。

从LFI到RFI:利用文件描述符实现漏洞升级 1. 文件包含漏洞基础 1.1 PHP文件包含漏洞原理 PHP文件包含漏洞产生于通过PHP函数引入文件时,由于文件名未经合理校验,导致意外文件操作。最常见的是本地文件包含(LFI)漏洞。 典型漏洞代码示例 : 1.2 本地文件包含(LFI)利用方式 攻击者可以提交类似 https://example.com/search.php?method=upload/1.jpg 的URL,其中 1.jpg 是攻击者上传的包含恶意PHP代码的图片文件,从而执行恶意代码。 2. 从LFI到RFI的突破性发现 2.1 关键发现 JAR包文件利用 :Web应用程序在特定配置下可以加载服务器上的JAR包文件并执行其中的Java类 静态代码块执行 :可以在Java类中定义静态代码块,在类加载时自动执行 示例恶意Java类 : 2.2 挑战与解决方案 主要挑战 : 如何让应用程序加载攻击者控制的JAR包文件 如何确定JAR包文件在服务器上的路径 解决方案 : 利用Linux的 /proc/[PID]/fd/* 文件描述符机制访问上传的文件 通过猜测HTTP请求处理程序的PID和文件描述符编号来定位文件 3. 文件描述符利用技术详解 3.1 Linux文件描述符机制 在Linux中,当一个进程打开文件时,会在 /proc/[PID]/fd/ 目录下创建对应的文件描述符链接。这使得我们可以: 不需要猜测随机生成的文件名或路径 只需猜测PID和文件描述符编号即可访问文件 3.2 实际利用步骤 上传恶意文件 :通过文件上传功能将恶意JAR包上传到服务器 获取PID :确定HTTP请求处理程序的进程ID 查找文件描述符 :在 /proc/[PID]/fd/ 目录下查找对应的文件描述符 通过LFI包含 :利用LFI漏洞包含 /proc/[PID]/fd/[编号] 路径 3.3 减少搜索空间的技巧 多文件上传 :同时上传多个相同文件,增加命中概率 PID预测 :服务器重启后PID分配顺序通常一致,可缩小PID猜测范围 4. 实战演示:Flask框架案例 4.1 测试环境搭建 Flask示例应用代码 : 4.2 文件上传脚本 4.3 查找文件描述符 获取Flask进程PID: ps aux | grep flask 查看文件描述符目录: ls -la /proc/[PID]/fd/ 确认文件内容: cat /proc/[PID]/fd/[编号] 5. 关键注意事项 文件大小限制 :小文件可能被直接读入内存而不创建文件描述符(如Flask中1MB以下文件) 解决方案:在JAR包中添加填充数据使其超过阈值 框架特性差异 : Flask和Django等框架是"惰性加载"请求体数据 只有访问请求体数据时才会创建文件描述符 请求处理程序要求 : 处理程序必须访问FILES字典或请求体数据 需要定位到会处理上传文件的请求处理程序 6. 攻击利用流程总结 识别目标系统中的LFI漏洞 寻找文件上传功能或请求体数据处理点 上传特制JAR包文件(确保大小超过内存加载阈值) 确定Web服务器进程PID 通过LFI包含 /proc/[PID]/fd/[编号] 路径 触发JAR包中静态代码块的执行 7. 防御建议 输入验证 :严格校验文件包含路径,禁止包含用户可控的完整路径 禁用危险函数 :如非必要,禁用 include 、 require 等危险函数 文件上传限制 : 限制上传文件类型 使用随机不可预测的存储路径 及时关闭文件描述符 进程隔离 :Web服务器进程使用低权限用户运行 访问控制 :限制对 /proc 目录的访问 通过这种创新的方法,安全研究人员可以将传统的LFI漏洞升级为更危险的RFI漏洞,极大地扩展了攻击面。理解这种技术有助于开发更安全的Web应用程序和更有效的防御措施。