ThinkPHP5.0.x SQL注⼊
Posted H3rmesk1t
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThinkPHP5.0.x SQL注⼊相关的知识,希望对你有一定的参考价值。
Thinkphp5.0.x SQL注⼊
初始配置
- 这里利用
ThinkPHP5.0.14
做示例,戳此进行下载- 下载后的源码中,需要对
Application\\index\\controller\\Index.php
内容进行修改
<?php
namespace app\\index\\controller;
use think\\Db;
class Index
{
public function index()
{
$name = input("get.name/a");
Db::table("users")->where(["id"=>1])->insert(["username"=>$name]);
return '<style type="text/css">*{ padding: 0; margin: 0; } .think_default_text{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:)</h1><p> ThinkPHP V5<br/><span style="font-size:30px">十年磨一剑 - 为API开发设计的高性能框架</span></p><span style="font-size:22px;">[ V5.0 版本由 <a href="http://www.qiniu.com" target="qiniu">七牛云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="http://tajs.qq.com/stats?sId=9347272" charset="UTF-8"></script><script type="text/javascript" src="http://ad.topthink.com/Public/static/client.js"></script><thinkad id="ad_bd568ce7058a1091"></thinkad>';
}
}
配置数据库相关文件,并开启thinkphp的调试功能
漏洞利用
Payload:
http://127.0.0.1/cms/public/index.php/index/index/index?name[0]=inc&name[1]=updatexml(1,concat(0x7,user(),0x7e),1)&name[2]=1
或者
http://127.0.0.1/cms/public/index.php/index/index/index?name[0]=dec&name[1]=updatexml(1,concat(0x7,user(),0x7e),1)&name[2]=1
漏洞分析
漏洞描述
尽管
ThinkPHP 5.0.x框架
采用了参数化查询方式来操作数据库,但是在insert
和update
方法中,传入的参数可控,且无严格过滤,最终导致SQL注入漏洞发生
ThinkPHP5.0.x目录结构
thinkphp 应用部署目录
├─application 应用目录(可设置)
│ ├─common 公共模块目录(可更改)
│ ├─index 模块目录(可更改)
│ │ ├─config.php 模块配置文件
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录
│ │ ├─model 模型目录
│ │ ├─view 视图目录
│ │ └─ ... 更多类库目录
│ ├─command.php 命令行工具配置文件
│ ├─common.php 应用公共(函数)文件
│ ├─config.php 应用(公共)配置文件
│ ├─database.php 数据库配置文件
│ ├─tags.php 应用行为扩展定义文件
│ └─route.php 路由配置文件
├─extend 扩展类库目录(可定义)
├─public WEB 部署目录(对外访问目录)
│ ├─static 静态资源存放目录(css,js,image)
│ ├─index.php 应用入口文件
│ ├─router.php 快速测试文件
│ └─.htaccess 用于 apache 的重写
├─runtime 应用的运行时目录(可写,可设置)
├─vendor 第三方类库目录(Composer)
├─thinkphp 框架系统目录
│ ├─lang 语言包目录
│ ├─library 框架核心类库目录
│ │ ├─think Think 类库包目录
│ │ └─traits 系统 Traits 目录
│ ├─tpl 系统模板目录
│ ├─.htaccess 用于 apache 的重写
│ ├─.travis.yml CI 定义文件
│ ├─base.php 基础定义文件
│ ├─composer.json composer 定义文件
│ ├─console.php 控制台入口文件
│ ├─convention.php 惯例配置文件
│ ├─helper.php 助手函数文件(可选)
│ ├─LICENSE.txt 授权说明文件
│ ├─phpunit.xml 单元测试配置文件
│ ├─README.md README 文件
│ └─start.php 框架引导文件
├─build.php 自动生成定义文件(参考)
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件
Payload说明
Payload:
http://127.0.0.1/cms/public/index.php/index/index/index?name[0]=inc&name[1]=updatexml(1,concat(0x7,user(),0x7e),1)&name[2]=1
http://localhost/thinkphp/ public/ index.php/ index/ index/ index
域名 网站目录 对外访问目录 入口文件 前台 控制器 方法名
Application\\index\\controller\\Index.php补充代码说明
$name = input("get.name/a");
input()为TP框架的助手函数,get.name/a 表示获取get传入的name变量,并将其强制转换为数组类型
Db::table("users")->where(["id"=>1])->insert(["username"=>$name]);
TP框架采用的是PDO方式对数据库进行查询
本地代码审计
首先通过TP框架的助手函数
input
获取到参数,name变量情况如下
跟进
thinkphp/library/think/db/Query.php
中的where
方法,再跟进insert
方法,找到$sql = $this->builder->insert($data, $options, $replace);
,跟进去
跟进到
thinkphp/library/think/db/Builder.php
,找到$data = $this->parseData($data, $options);
,跟进去
跟进
parseData
方法,可以看出$val
是数组,且根据$val[0]
值为inc,通过switch语句进入parseKey
方法
跟进
thinkphp/library/think/db/builder/mysql.php
的parseKey
方法,此处并未对传入的$key
进行更多的过滤与检查,最后返回的仍然是1 and (updatexml(1,concat(0x7,user(),0x7e),1))
回到
parseData
方法,floatval($val[2])
返回1
,这也正是Payload传入username[2]=1
的原因,将其与前面经过parseKey
方法的结果进行拼接后返回给result
回到
thinkphp/library/think/db/Builder.php
的insert
方法中,可以看到返回的$sql
成功造成了sql注入
漏洞修复
- 参考官方commit:https://github.com/top-think/framework/commit/363fd4d90312f2cfa427535b7ea01a097ca8db1b
- 在进行dec和inc操作之前对
$val[1]
的值进行了再次确认
以上是关于ThinkPHP5.0.x SQL注⼊的主要内容,如果未能解决你的问题,请参考以下文章