ThinkPHP3.2.x框架SQL注入

暗月博客 2019年11月21日22:30:41评论455 views字数 3106阅读10分21秒阅读模式
摘要

尽管ThinkPHP 3.2.x使用了 I 方法来过滤参数,但是还是过滤不严谨,导致SQL注入发生。

漏洞简述

尽管ThinkPHP 3.2.x使用了 I 方法来过滤参数,但是还是过滤不严谨,导致SQL注入发生。

ThinkPHP基础知识

在进行漏洞分析之前,我们需要了解一下ThinkPHP3.2基础知识,这里仅介绍对本次漏洞分析有帮助的部分。

ThinkPHP3.2的 目录结构

├─ThinkPHP 框架系统目录(可以部署在非web目录下面)
│  ├─Common       核心公共函数目录
│  ├─Conf         核心配置目录
│  ├─Lang         核心语言包目录
│  ├─Library      框架类库目录
│  │  ├─Think     核心Think类库包目录
│  │  ├─Behavior  行为类库目录
│  │  ├─Org       Org类库包目录
│  │  ├─Vendor    第三方类库目录
│  │  ├─ ...      更多类库目录
│  ├─Mode         框架应用模式目录
│  ├─Tpl          系统模板目录
│  ├─LICENSE.txt  框架授权协议文件
│  ├─logo.png     框架LOGO文件
│  ├─README.txt   框架README文件
│  └─ThinkPHP.php 框架入口文件

我们本次的 payload 为:http://localhost/thinkphp32/index.php?username[0]=bind&username[1]=0 and updatexml(1,concat(0x7,user(),0x7e),1)

环境搭建

这里我们使用ThinkPHP3.2.3完整版来进行实验,下载地址:http://www.thinkphp.cn/donate/download/id/610.html

我们先安装好phpstudy,然后将下载好的ThinkPHP3.2.3完整版解压,将里面的thinkphp拷贝至phpstudy的网站根目录下的thinkphp32文件夹下,php版本这里用5.6。在thinkphp32目录下新建一个index.php文件,内容如下:

<?php define("APP_PATH","./Application/"); define('APP_DEBUG',True);  include "ThinkPHP/ThinkPHP.php";

浏览器访问http://localhost/thinkphp32/index.php ,会在thinkphp32目录下生成一个Application文件夹,目录结构如下:

Application
├─Common         应用公共模块
│  ├─Common      应用公共函数目录
│  └─Conf        应用公共配置文件目录
├─Home           默认生成的Home模块
│  ├─Conf        模块配置文件目录
│  ├─Common      模块函数公共目录
│  ├─Controller  模块控制器目录
│  ├─Model       模块模型目录
│  └─View        模块视图文件目录
├─Runtime        运行时目录
│  ├─Cache       模版缓存目录
│  ├─Data        数据目录
│  ├─Logs        日志目录
│  └─Temp        缓存目录

修改 thinkphp32/Application/Home/Controller/IndexController.class.php 文件代码,内容如下:

<?php namespace Home/Controller; use Think/Controller; class IndexController extends Controller {     public function index(){         $condition["name"] = I("name");         $data["pass"] = "1998";         $result = M("users")->where($condition)->save($data);     } }

配置连接数据库的文件 Application/Common/Conf/config.php ,内容如下:

<?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, // 数据库调试模式 开启后可以记录SQL日志 3.2.3新增 );



漏洞分析

这次,我们还是根据payload,使用正向审计的方式来进行本次审计工作。首先我们来看一下我们创建的 thinkphp32/Application/Home/Controller/IndexController.class.php 文件代码,程序使用 I 方法来安全获取 username 变量,如下图:

ThinkPHP3.2.x框架SQL注入

我们跟进 I 方法看看, I 方法位于 thinkphp32/ThinkPHP/Common/functions.php 文件中,可以看到 $input 变量的值等于超全局数据 $_GET 的值。如下图:

ThinkPHP3.2.x框架SQL注入

接着主要是对获取到的变量,使用 htmlspecialchars() 进行过滤,如下图:

ThinkPHP3.2.x框架SQL注入

可以看到函数尾部使用了thinkphp自定义的过滤该方法 think_filter ,如下图:

ThinkPHP3.2.x框架SQL注入

该方法也在这个文件中定义,代码如下。可以清楚的看到并没有过滤 bind ,如下图:

function think_filter(&$value){  // TODO 其他安全过滤  // 过滤查询特殊字符     if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){         $value .= ' ';     } }

再回到 thinkphp32/Application/Home/Controller/IndexController.class.php 文件,看语句 $result = M("users")->where($condition)->save($data);我们跟进 M 方法, M 方法的话就是新建了一个 Think/Model类,如下图:

ThinkPHP3.2.x框架SQL注入

我们继续看 save 方法,在程序末尾有个 update 操作,继续跟进

ThinkPHP3.2.x框架SQL注入

update 方法位于 thinkphp32/ThinkPHP/Library/Think/Db/Driver.class.php 文件中, parseSet 方法主要做了set[0] =password=:0 ,我们主要关注 parseWhere 方法。

ThinkPHP3.2.x框架SQL注入

ThinkPHP3.2.x框架SQL注入

我们跟进 parseWhere 方法,发现其中拼接了经过 parseWhereItem 方法处理的语句,如下图:

ThinkPHP3.2.x框架SQL注入

我们跟进 parseWhereItem 方法,会发现当 $val[0] 等于 bind 的时候,直接将参数进行拼接,如下图:

ThinkPHP3.2.x框架SQL注入

最终,执行攻击者构造的 SQL 语句,效果如下:

ThinkPHP3.2.x框架SQL注入

ThinkPHP3.2.x框架SQL注入

总结

笔者也是第一次审计Thinkphp3.2框架,在审计这套框架前还找了网络上的视频快速入门了下,再结合Thinkphp3.2手册,完成此次漏洞的审计。当然,文章有不当之处,还希望大家斧正。

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
暗月博客
  • 本文由 发表于 2019年11月21日22:30:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   ThinkPHP3.2.x框架SQL注入http://cn-sec.com/archives/73598.html

发表评论

匿名网友 填写信息