考试太忙啦,我写这篇文章的时候这个惊天大洞已经快凉透了
1 前置知识
1.1 Apache Log4j2
Apache Log4j2 是一款优秀的 Java 日志框架。该工具重写了 Log4j 框架,并且引入了大量丰富的特性。该日志框架被大量用于业务系统开发,用来记录日志信息。大多数情况下,开发者可能会将用户输入导致的错误信息写入日志中。
在Log4j2中,可以使用了lookup来查找、搜索内容,下面的东西它都能搜到,功能很强大
![](https://tzt.cool/wp-content/uploads/2022/10/截屏2022-10-27-13.30.01.png)
1.2 JNDI
JNDI即Java Naming and Directory Interface
(JAVA命名和目录接口),它提供一个目录系统,并将服务名称与对象关联起来,从而使得开发人员在开发过程中可以使用名称来访问对象。
1.3 LDAP
LDAP即Lightweight Directory Access Protocol
(轻量级目录访问协议),目录是一个为查询、浏览和搜索而优化的专业分布式数据库,它呈树状结构组织数据,就好象Linux/Unix系统中的文件目录一样。目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好像它的名字一样。
2 漏洞详情
2.1 影响版本
Apache Log4j 2.x <= 2.14.1
Minecraft 全版本所有系列服务端,除 Mohist 1.18 外
2.2 攻击检测
可以通过检查日志中是否存在”jndi:ldap://
“, “jndi:rmi
“等字符来发现可能的攻击行为。
2.3 安全建议
- 升级 Apache Log4j2 所有相关应用到最新的 log4j-2.15.0-rc1 版本,https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc1
- 升级已知受影响的应用及组件,如 spring-boot-strater-log4j2 / Apache Solr / Apache Flink / Apache Druid
建议同时采用如下临时措施进行漏洞防范:
- 1)添加 jvm 启动参数
-Dlog4j2.formatMsgNoLookups=true
; - 2)在应用 classpath 下添加
log4j2.component.properties
配置文件,文件内容为log4j2.formatMsgNoLookups=true
; - 3)JDK 使用 11.0.1、8u191、7u201、6u211 及以上的高版本;
- 4)部署使用第三方防火墙产品进行安全防护。
- 5)将系统环境变量
FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS
设置为true
- 6)尽快升级Apache Log4j2所有相关应用到最新的
log4j-2.15.0-rc2
版本,地址 https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2
3 漏洞原理——JNDI注入攻击
假如某一个Java程序中,将浏览器的类型记录到了日志中:
String userAgent = request.getHeader("User-Agent");
logger.info(userAgent);
假如有人发来了一个HTTP请求,他的User-Agent
是这样的字符串:
${jndi:ldap://127.0.0.1/exploit}
接下来,log4j2将会对这行要输出的字符串进行解析。
首先,它发现了字符串中有 ${},知道这个里面包裹的内容是要单独处理的。
进一步解析,发现是JNDI扩展内容。
再进一步解析,发现了是LDAP协议,LDAP服务器在127.0.0.1,要查找的key是exploit。
最后,调用具体负责LDAP的模块去请求对应的数据。
如果只是请求普通的数据,那也没什么,但问题就出在还可以请求Java对象!
而JNDI还支持一个叫命名引用(Naming References)的方式,可以通过远程下载一个class文件,然后下载后加载起来构建对象。
![](http://tzt.cool/wp-content/uploads/2021/12/640.webp)
4 漏洞复现
别看了,还没写呢
5 漏洞修复
![](https://tzt.cool/wp-content/uploads/2022/10/截屏2022-10-27-13.30.56-1024x293.png)
修复后的log4j2在JNDI lookup中增加了很多的限制:
1.默认不再支持二次跳转(也就是命名引用)的方式获取对象
2.只有在log4j2.allowedLdapClasses列表中指定的class才能获取。
3.只有远程地址是本地地址或者在log4j2.allowedLdapHosts列表中指定的地址才能获取
彻底封锁了通过打印日志去远程加载class的方式
6 参考资料
- https://github.com/tangxiaofeng7/apache-log4j-poc
- https://github.com/bkfish/Apache-Log4j-Learning
- https://www.veracode.com/blog/research/exploiting-jndi-injections-java
- https://github.com/welk1n/JNDI-Injection-Exploit
- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core/usages?p=1
- https://mp.weixin.qq.com/s/4MnOQGg7LBYCUE7BuuGfEQ
Comments | 2 条评论
tql
我是itian