tp5 mysql 1064_ThinkPHP5.0.10 SQL注入

本文详细分析了ThinkPHP5.0.10版本中的一个SQL注入漏洞,该漏洞源于Mysql类的parseWhereItem方法中未对数据进行充分过滤,结合Request类filterValue方法未过滤NOT LIKE关键字,导致了SQL注入。通过提供payload展示漏洞利用过程,并解释了官方的修复方法是在Request.php的filterValue方法中过滤NOT LIKE。最后,文章还讨论了不同版本中此漏洞的存在情况和原因。
摘要由CSDN通过智能技术生成

0x00

继续看,这个漏洞和上一篇文章审计的依旧有很多共通之处,所以现在审计也是变得越来越轻松了。

0x01漏洞概述

本次漏洞存在于 Mysql 类的 parseWhereItem 方法中。由于程序没有对数据进行很好的过滤,直接将数据拼接进 SQL 语句。再一个, Request 类的 filterValue 方法漏过滤 NOT LIKE 关键字,最终导致 SQL注入漏洞 的产生。漏洞影响版本: ThinkPHP=5.0.10 。

环境准备

composer create-project topthink/think=5.0.10 tp5010

composer.json文件:

"require": {

"php": ">=5.4.0",

"topthink/framework": "5.0.10"

},

更新:执行composer update

接下来设置漏洞点和配置数据库

将 application/index/controller/Index.php 文件代码设置如下:

namespace app\index\controller;

class Index

{

public function index()

{

$username = request()->get('username/a');

$result = db('users')->where(['username' => $username])->select();

var_dump($result);

}

}

创建数据库信息如下:

create database tpdemo;

use tpdemo;

create table users(

id int primary key auto_increment,

username varchar(50) not null

);

insert into users(id,username) values(1,'wtz');

在 config/database.php 文件中配置数据库相关信息

开启 config/app.php 中的 app_debug 和 app_trace

漏洞分析

payload:

http://127.0.0.1:88/tp5010/public/index.php/index/index?username[0]=not%20like&username[1][0]=%%&username[1][1]=233&username[2]=)%20union%20select%201,user()%23

75407aa827422f272bd5aaa059b34769.png

这里就是not like 模糊查询,

eg:

查询user表中姓名中没有“王”字的:

select * from user where name not like '%王%'

not like我们可控,这也是sql注入的直接原因

因为官方有安全更新,我们先去github上找一下对于这个sql注入漏洞的安全更新

3597ed4c0627553fdecf75eb3054b116.png

e7178eb8941238f00a2b5d22b03db7ac.png

可以看到,增加了过滤

NOT LIKE

前面已经提过:所有用户参数都会经过 Request 类的 input 方法处理,该方法会调用 filterValue 方法。

该方法是用来过滤表单中的表达式,但是我们仔细看其代码,会发现少过滤了 NOT LIKE ,而本次漏洞正是利用了这一点。

e71cef32325a8c58fa78fd59f9fdd048.png

c849b57beefe89011559ac4f908a1ac4.png

注意我们payload是NOT LIKE

我们开启debug,开始分析一下

d7fdb26f03a3f97d9c057bf497ff8a09.png

用户输入的数据会原样进入框架的 SQL 查询方法中。首先程序先调用 Query 类的 where 方法,通过其 parseWhereExp 方法分析查询表达式,然后再返回并继续调用 select 方法准备开始构建 select 语句。(这个点得记住,框架的sql查询方法先进入 Query 类)

我们先进入Query类去看看

49328edd89c7298d2222b7fd1cd76989.png

在select方法中

这里$this->builder 为 \think\db\builder\Mysql 类,该类继承于 Builder 类,所以接着会调用 Builder 类的 select 方法。

我们直接去看Builder 类的 select 方法。

5fd1ba36cc1d7b1f59dda881d41bfc02.png

d125d41789e284c133ec05deab0c20d8.png

在 select 方法中,程序会对 SQL 语句模板用变量填充,其中用来填充 %WHERE% 的变量中存在用户输入的数据。

可以看到这里返回的就是我们预期的查询语句,那么他是怎么拼接过来的呢?

我们去看一下parseWhere方法

2d27446485eba5ac852bb39308505b61.png

去看一下buildWhere这个构造select语句的方法

3b22f35f7de04f3315239b86071de5e5.png

f89773a6ad79af54f8f1a5957faa89e4.png

看到这里经由parseWhereIte方法后直接进行拼接

而且经过了parseWhereItem方法

a31c0bdcc8a7fdfef9357cdcfaeeb5b5.png

该函数的返回结果存储在 $str 变量中,并被拼接进 SQL 语句。

,我们往下看看这个方法 在这个方法中

where子单元分析

390411a0afe35e7b7cc26aede623fa95.png

我们可以看到NOT LIKE 可以被我们控制!我们也就控制了mysql的逻辑运算符。利用这一点构造我们的查询语句

500f75d25c9c7aa4fd05570695e272cf.png

3e1d066c8dcc8be20b53b7f60f269c4d.png

最后成功构造我们的sql查询语句,返回了$whereStr

58bd78d23894f9ca53897337e2ce504d.png

漏洞修复

下面是抄的:

在 5.0.10 之后的版本,官方的修复方法是:在 Request.php 文件的 filterValue 方法中,过滤掉 NOT LIKE 关键字。而在 5.0.10 之前的版本中,这个漏洞是不存在的,但是其代码也没有过滤掉 NOT LIKE 关键字,这是为什么呢?经过调试,发现原来在 5.0.10 之前的版本中,其默认允许的表达式中不存在 not like (注意空格),所以即便攻击者可以通过外部控制该操作符号,也无法完成攻击。(会直接进入下入157行,下图是 5.0.9 版本的代码)相反, 5.0.10 版本其默认允许的表达式中,存在 not like ,因而可以触发漏洞。

a991cd080f9c4c923562eed7cb4ce82b.png

攻击总结

七月火师傅的图:

9ac238f36ed3fb11f45f63b7489e1b37.png

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值