日志库logback的攻击路径

来源:香依香偎@闻道解惑

logo

logback

logbacklog4j 创始人设计的另一个开源日志组件。相比 log4j,重构了内核的 logback 的优势在于性能更高(关键路径性能提升十倍)、内存占用更小、文档更完善、功能更全面等等。Github 上的数据显示,logback 被八千多个项目所使用,包括 springboot 在内的多个框架已经使用 logback 作为默认的日志组件。

github

初步分析了一下 logback 库,有一些有趣的发现。

XXE

logback 查找配置文件的函数在ContextInitializer.findURLOfDefaultConfigurationFile(),首先读取启动参数 logback.configurationFile 来获取配置文件的地址(支持远端 URL地址)。如果找不到,再去 classpath 下依次查找如下三个文件作为配置文件:

  • a) logback-test.xml

  • b) logback.groovy(最新版本似乎不再支持)

  • c) logback.xml

configfile

获取配置文件之后,通过 JoranConfigurator.doConfigure() (实现在父类的GenericConfigurator.doConfigure()中) 读取 xml 配置文件,其中调用 SaxEventRecorder.recordEvents() 解析 xml 配置文件时存在 XXE 漏洞。

xxe-01

xxe-02

动态加载

通常情况下,配置文件的这一类 XXE 漏洞并不是大问题,毕竟配置文件只会在初始化的时候加载一次,攻击者没机会触发漏洞。但是 logback 库不一样。只要配置文件中配置了 scan 属性,它就会启动一个 scan task 监控配置文件的变动,支持配置文件变更时的自动加载。

scan-task

scan-doc

也就是说,我们有机会通过上传覆盖 logbackxml 配置文件来触发 XXE 漏洞。触发条件是:

  • a) logback 配置文件中配置了 scan 属性

  • b) logback 配置文件是以文件形式保存。

第二个条件是因为代码 convertToFile() 中的一个限制:配置文件 URL 必须以 file:// 开始。如果像 springboot 那样,把配置文件保存在 jar 包中,配置文件的 URLjar:// 开始,就不会启动实时监控的 scan task

convert

JNDI

除了自动更新之外,logback 的配置文件还有一个更强大的功能:利用 JNDIRPC 功能从远端来读取内容,只要在配置文件中配置 <insertFromJNDI> 标签就行了,JNDI的远端路径就配置在这个标签的 env-entry-name 属性中。

env-entry-name

jndi-lookup

梳理一下,如果一个 web 应用满足如下三个条件:

  • a) logback 配置文件以文件形式保存
  • b) logback 配置文件中配置了 scan 属性
  • c) 有上传接口可以覆盖 logback 配置文件

我们就可以通过覆盖 logback 配置文件,来实现 XXE 攻击,以及 JNDI 的远程 RCE

实战

验证一下。

  • a) 从 github 上拉取 spring-mvc-showcase 项目,将 pom.xmllog4jdependency 修改为 logback,增加 logback.xml 配置文件,并配置 scan 属性。

pom

showcase

  • b) 通过tomcat运行war包。写一个上传接口,其中存在跨目录文件上传漏洞

upload

  • c) 通过上传接口覆盖 logback.xml文件,增加标签,指定恶意的jndi服务。

replace

  • c) 等待一个扫描周期(配置文件中配置的 30 秒)之后,恶意 JNDI 地址收到了访问请求,恶意程序成功执行。

rce

JMX

不仅如此,logback 还实现了 jmxMBeans 接口。只要在配置文件中配置 <jmxConfigurator /> 的空标签,web 应用就会开放 jmx 端口,供 jconsole 进行连接和调用。

jmx-configurator

mbean-interface

在JMXConfigurator这个MBean中,公开给jconsole调用的接口如下。

mbean

验证一下。

  • a) 在之前的环境上,我们重新上传一个 logback.xml,配置上 <jmxConfigurator/> 标签。

upload

  • b) 等待一个周期查看tomcat进程,发现多了一个39327端口。

org-port

new-port

  • c) 使用 jconsole 连接,无需认证即可登录。可以直接查看 tomcat 的管理属性,以及调用 tomcatlogback 提供的 MBeans 操作接口。

jconsole

小结

logback 通过 scan 参数提供了配置文件的动态更新功能。如果可以覆盖这个配置文件,就可以实现XXE、JNDI、jmx等多种攻击方式了。