log4j2.x 漏洞影响产品系列之Apache Solr内存马注入技术研究

Qu3een 2021-12-27 14:01:00

0x00 背景

近日,Apache Log4j2 远程代码执行漏洞(CVE-2021-44228)被揭露,在整个安全圈都引起轰动。对于该漏洞的触发原理、各种绕过、以及后续的拒绝服务攻击漏洞等,均有大量文章分析的头头是道,这里不再对该漏洞进行阐述。在受到Log4j2影响的众多产品中,选择Apache Solr产品进行漏洞复现及利用,在内存马注入环节中遇到一些问题,相信有其他同学或许也遇到同样的问题,本文将针对Apache Solr内存马注入技术进行分析,希望与大家一起探讨。

版本: Apache solr 8.9.0

漏洞触发:Apache Log4j2 远程代码执行漏洞(CVE-2021-44228)

在复现漏洞过程中,发现众多路径,如"/solr/admin/info",“solr/admin/cores”等均存在该漏洞,可通过控制任意参数进行Log4j2的利用,如下图所示:
1.png

内存马注入以及回显

命令执行、反弹shell这些基本操作相信坊间已有很多好用的JNDI工具可以实现,但是通过jndi进行内存马注入或回显过程中,有很多坑点,这也是本篇探讨的重点。

Apache Solr内置服务器是Jetty,在本次Solr环境中,Jetty版本为9.4.x。

0x01 Jetty容器Filter型内存马注入思路:

找到该webapp的上下文context,一般通过该context上下文可获取注入内存马相关的各种对象。在Jetty容器中,web相关的context类为org.eclipse.jetty.webapp.WebAppContext,可通过org.eclipse.jetty.webapp.WebAppClassLoader获取,WebAppClassLoader的_context属性即为WebAppContext,WebAppContext包含的属性中,_servletHandler是注入Filter的关键属性。_servletHandler是org.eclipse.jetty.servlet.ServletHandler类的实例,通过org.eclipse.jetty.servlet.ServletHandler的addFilterWithMapping()方法即可实现注入自定义Filter。
image.png
3.png
整个注入Filter型内存马的流程简单描述为:

org.eclipse.jetty.webapp.WebAppClassLoader webAppClassLoader=(org.eclipse.jetty.webapp.WebAppClassLoader)Thread.currentThread().getContextClassLoader();
org.eclipse.jetty.webapp.WebAppContext webAppContext=(org.eclipse.jetty.webapp.WebAppContext)webAppClassLoader._context;
org.eclipse.jetty.servlet.ServletHandler servletHandler=(org.eclipse.jetty.servlet.ServletHandler)webAppContext._servletHandler;
servletHandler.addFilterWithMapping("FilterClassName","/*", EnumSet.of(DispatcherType.REQUEST));

但在Apache Solr 利用Log4j2漏洞注入内存马却失败了,调试发现,通过Thread.currentThread().getContextClassLoader()获取的ClassLoader并不是以为的org.eclipse.jetty.webapp.WebAppClassLoader,如图所示:
4.png
后翻阅网上关于Jetty内存马的文章,发现有一种获取org.eclipse.jetty.webapp.WebAppClassLoader的方式是通过JmxMBeanServer查找与webapp相关的mbean对象,从而通过该mbean对象间接获得注入Filter需要的属性。

但在调试Solr后发现又错了,该方法仍然不适用于Solr,因为Solr中不存在与webapp相关的任何Mbean。如图:
image.png
不过通过MbeanServer进行处理的方法让我联想到JNDI的其他利用方式——利用Mlet远程加载Mbean从而实现任意代码执行,这里留到后文再进行详细讲解。

继续回到注入Filter内存马的主题。既然通过JNDI获取的currentThread的ContextClassLoader不是WebAppClassLoader,但是在Solr所有的Threads线程中,一定存在跟webapp相关的线程,继而可通过该web线程得到相应的WebAppClassLoader。经测试,这种方法确实可行。
5.png
找到WebAppClassLoader后,后续注入Filter的方式正如上文所讲的一样。核心代码如下:
image.png
成功注入内存马后如下:
6.png
这种通过在所有Threads获取web相关Thread的方法通用性很强,针对各种类型的中间件或容器的内存马注入、回显等均有一定参考价值。

0x02 利用MbeanSever实现回显

另:前文提到可通过MbeanServer远程注册恶意Mbean的方式执行任意命令,这里做个简单说明,可以作为另外一种利用思路。

MBean服务器是一种管理系统MBean的服务,熟悉JMX攻击利用的朋友们可能知道,可通过创建javax.management.loading.MLet MBean,使用它通过远程URL在Mbean服务器中注册恶意Mbean,然后攻击者可调用Mbean中的任意方法,从而实现任意命令执行。

在本环境中,在远程创建一个执行命令的Mbean,然后MBeanSever通过Mlet远程请求该Mbean并注册到MBeanSever中,即可通过MBeanSever执行该恶意Mbean中的任意方法。这里设置的Mbean可通过runCmd()方法执行任意命令,然后将命令执行的结果写入到外部可访问的web路径中,在solr中,可通过相对路径写入solr-webapp/webapp/res.txt中。这也是从侧面进行回显的一种思路,甚至可以作为不依赖中间件或容器特性而实现回显的一种方式。
7.png

0x03 总结

在本次利用Log4j2漏洞对Solr进行内存马注入过程中,对内存马注入技术有了新的认识和思路,以上方法是在常规方式注入失败的情况下进行的,tomcat、Apache Druid等也可能会出现同样注入失败的问题。是因为场景以及Context上下文不同。但只要认真思考注入失败原因,以及跳出常规思维冷静分析,不要放弃,一定可以找到解决方案甚至找到更好的思路,如本文中的mbean的相关利用,后续可能会有更多好的利用,欢迎大家一起探讨。

评论

W

WtHSBG 2022-01-13 00:09:29

0x01 中提到的办法看起来只能在低版本jdk的情况下有用啊,请问第二种思路能不能用来绕过高版本jdk的com.sun.jndi.ldap.object.trustURLCodebase限制

W

WtHSBG 2022-01-13 00:12:53

好吧。。仔细想了下应该不行

Qu3een

这个人很懒,没有留下任何介绍

twitter weibo github wechat

随机分类

软件安全 文章:17 篇
数据分析与机器学习 文章:12 篇
Windows安全 文章:88 篇
IoT安全 文章:29 篇
浏览器安全 文章:36 篇

扫码关注公众号

WeChat Offical Account QRCode

最新评论

Yukong

🐮皮

H

HHHeey

好的,谢谢师傅的解答

Article_kelp

a类中的变量secret_class_var = "secret"是在merge

H

HHHeey

secret_var = 1 def test(): pass

H

hgsmonkey

tql!!!

目录