thinkphp防止mysql注入_代码审计 | ThinkPHP5漏洞分析之SQL注入(四)

本文深入探讨了ThinkPHP5中的SQL注入漏洞,源于Request类的filterValue方法未过滤NOT LIKE关键字,导致在5.0.10版本中的安全问题。通过分析代码,展示了如何通过构造恶意payload利用此漏洞。官方在5.0.11版本中修复了这个问题,增加了对NOT LIKE的过滤。了解漏洞原理有助于提升应用的安全防护。
摘要由CSDN通过智能技术生成

原标题:代码审计 | ThinkPHP5漏洞分析之SQL注入(四)

ThinkPHPThinkPHP 漏洞分析,也将更新于 ThinkPHP-Vuln(https://github.com/Mochazz/ThinkPHP-Vuln) 项目上。本篇文章,将分析 ThinkPHPSQL注入漏洞 ( select

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

composer create-project --prefer-dist topthink/think=5.0.10 tpdemo

"require": {

"php": ">=5.4.0",

"topthink/framework": "5.0.10"

},

namespaceappindexcontroller;

classIndex

{

publicfunctionindex()

{

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

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

var_dump($result);

}

}

在 config/database.phpconfig/app.php 中的 app_debug 和 app_trace

createdatabasetpdemo;

usetpdemo;

createtableusers(

idintprimary keyauto_increment,

username varchar( 50) notnull

);

insertintousers( id,username) values( 1, 'mochazz');

访问 http://localhost:8000/index/index/index?username[0]=not like&username[1][0]=%%&username[1][1]=233&username[2]=) union select 1,user()#SQL注入漏洞 。(没开启 app_debugSQL

66d559d30d445fadf571c5cd7c12676b.png

首先在官方发布的 5.0.11 版本更新说明中,发现其中提到该版本包含了一个安全更新,我们可以查阅其 commit 记录,发现其修改的 Request.php 文件代码比较可疑。

eb077e7bd6bf0b4d3f214f63af75d34f.png

接着我们直接跟着上面的攻击 payload 来看看漏洞原理。首先,不管以哪种方式传递数据给服务器,这些数据在 ThinkPHP 中都会经过 Request 类的 input 方法。数据不仅会被强制类型转换,还都会经过 filterValue 方法的处理。该方法是用来过滤表单中的表达式,但是我们仔细看其代码,会发现少过滤了 NOT LIKE ,而本次漏洞正是利用了这一点。

524e348b061cedde8b003af79d278f3d.png

我们回到处理 SQL 语句的方法上。首先程序先调用 Query 类的 where 方法,通过其 parseWhereExp 方法分析查询表达式,然后再返回并继续调用 select 方法准备开始构建 select 语句。

a859835ac307e73b0bb4dd7dd5621a2f.png

上面的 $this->builder 为 thinkdbbuilderMysql 类,该类继承于 Builder 类,所以接着会调用 Builder 类的 select 方法。在 select 方法中,程序会对 SQL 语句模板用变量填充,其中用来填充 %WHERE% 的变量中存在用户输入的数据。我们跟进这个 where 分析函数,会发现其会调用生成查询条件 SQL 语句的 buildWhere 函数。

c9758b1d76759826951eb7fb87abf74f.png

继续跟进 buildWhere 函数,发现用户可控数据又被传入了 parseWhereItem where子单元分析函数,该函数的返回结果存储在 $str 变量中,并被拼接进 SQL 语句。(下图 第16、20行)

4a341fa0ff21e52724b71bf86fc27c81.png

我们跟进 parseWhereItem 方法,发现当操作符等于 NOT LIKE 时,程序所使用的 MYSQL 逻辑操作符竟然可由用户传来的变量控制(下图 第23行 ),这样也就直接导致了 SQL注入漏洞 的发生。

9f9ca25557943884a9a3f32f5974f668.png

正是由于 ThinkPHP 官方的 filterValue 方法漏过滤了 NOT LIKE ,同时 MYSQL 逻辑操作由用户变量控制,使得这一漏洞可以被利用。

在 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 ,因而可以触发漏洞。

5a3c598b351f34dce90a4337908a3f93.png

责任编辑:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值