ThinkPHP6.0 任意文件操作
字数 938 2025-08-26 22:11:56

ThinkPHP6.0 任意文件操作漏洞分析与复现

漏洞概述

ThinkPHP6.0 中存在一个任意文件操作漏洞,攻击者可以通过精心构造的Session ID来在服务器上创建或覆盖任意文件。该漏洞源于Session ID验证不足,导致攻击者可以控制文件路径和内容。

漏洞分析

漏洞原理

  1. Session ID验证不足:ThinkPHP6.0 在设置Session ID时仅检查长度是否为32,未对字符类型进行严格验证
  2. 文件路径构造:Session数据会被存储在文件中,文件名由sess_前缀加上Session ID构成
  3. 目录遍历:攻击者可以通过构造包含路径遍历字符(../)的Session ID来控制文件存储位置

关键代码分析

漏洞修复补丁:官方补丁

补丁主要修改:

  • 从仅检测Session ID长度为32
  • 增加了ctype_alnum检查,确保Session ID只包含字母和数字

环境搭建

  1. 启用.env配置文件:

    cp .example.env .env
    
  2. 启用Session功能:
    修改app/middleware.php,取消Session初始化的注释:

    return [
        // 全局请求缓存
        // \think\middleware\CheckRequestCache::class,
        // 多语言加载
        // \think\middleware\LoadLangPack::class,
        // Session初始化
        \think\middleware\SessionInit::class
    ];
    
  3. 创建测试控制器:
    app/controller/Index.php中添加测试方法:

    public function test(){
        session('demo', $_GET['c']);
    }
    

漏洞复现

  1. 构造恶意请求:

    http://target.com/index/test?c=malicious_content&PHPSESSID=../../../path/to/target/file
    
  2. 注意Session ID长度必须为32字符,否则会重新设置Session

漏洞利用流程

  1. 攻击者发送带有恶意Session ID的请求
  2. 服务器处理Session时调用setId方法
    • 第一次调用:读取Session
    • 第二次调用:在请求结束时通过SessionInit->end() -> Session->save()
  3. think\Session\Store->save()方法:
    • 拼接sess_前缀和Session ID得到文件名
    • 创建目录(如果不存在)
  4. 最终通过writeFile将Session数据写入文件

防御措施

  1. 升级到已修复版本
  2. 严格验证Session ID,确保只包含字母数字字符
  3. 对文件路径进行规范化处理,防止目录遍历

总结

该漏洞由于Session ID验证不足,导致攻击者可以控制文件存储路径和内容,可能造成任意文件写入甚至远程代码执行。开发者应及时应用补丁或升级框架版本。

ThinkPHP6.0 任意文件操作漏洞分析与复现 漏洞概述 ThinkPHP6.0 中存在一个任意文件操作漏洞,攻击者可以通过精心构造的Session ID来在服务器上创建或覆盖任意文件。该漏洞源于Session ID验证不足,导致攻击者可以控制文件路径和内容。 漏洞分析 漏洞原理 Session ID验证不足 :ThinkPHP6.0 在设置Session ID时仅检查长度是否为32,未对字符类型进行严格验证 文件路径构造 :Session数据会被存储在文件中,文件名由 sess_ 前缀加上Session ID构成 目录遍历 :攻击者可以通过构造包含路径遍历字符( ../ )的Session ID来控制文件存储位置 关键代码分析 漏洞修复补丁: 官方补丁 补丁主要修改: 从仅检测Session ID长度为32 增加了 ctype_alnum 检查,确保Session ID只包含字母和数字 环境搭建 启用 .env 配置文件: 启用Session功能: 修改 app/middleware.php ,取消Session初始化的注释: 创建测试控制器: 在 app/controller/Index.php 中添加测试方法: 漏洞复现 构造恶意请求: 注意Session ID长度必须为32字符,否则会重新设置Session 漏洞利用流程 攻击者发送带有恶意Session ID的请求 服务器处理Session时调用 setId 方法 第一次调用:读取Session 第二次调用:在请求结束时通过 SessionInit->end() -> Session->save() think\Session\Store->save() 方法: 拼接 sess_ 前缀和Session ID得到文件名 创建目录(如果不存在) 最终通过 writeFile 将Session数据写入文件 防御措施 升级到已修复版本 严格验证Session ID,确保只包含字母数字字符 对文件路径进行规范化处理,防止目录遍历 总结 该漏洞由于Session ID验证不足,导致攻击者可以控制文件存储路径和内容,可能造成任意文件写入甚至远程代码执行。开发者应及时应用补丁或升级框架版本。