Log4j2是log4j 1.x和logback的改进版,提供了比其前身Log4j1.x更多的功能和性能改进。
漏洞描述
日志在打印时当遇到”${“后,以”:”号作为分割,将表达式内容分割成两部分,前面一部分prefix,后面部分作为key,然后通过prefix去找对应的lookup,通过对应的lookup实例调用lookup方法,最后将key作为参数带入执行,引发远程代码执行漏洞。
环境搭建
导入以下依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId >
<artifactId> log4j-api</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId >
<artifactId> log4j-core</artifactId>
<version>2.8.1</version>
</dependency>
使用网上的payload尝试一下,DNSlog收到请求
漏洞分析
在JndiManager#lookup打一个断点,可以在堆栈看到他的调用过程。
MessagePatternConverter#format
判断workingBuilder的当前位置是不是${开头
现在满足条件,下面调用了replace()方法,
跟进substitute方法,prefixMatcher和suffixMatcher提取${...}类型的表达式
然后赋值到varName
调用了resolveVariable
StrSubstitutor.resolveVariable()调用了resolver.lookup方法
跟到这个lookup里面,获取了前缀和变量名,然后获取对应的查找器,这里是jndi
跟进去lookup.lookup(event, name);
跟一下jndiManager的lookup,跳到了JndiManager#lookup方法,
再往下一步就到了javax.naming.InitialContext#lookup(java.lang.String),造成了JNDI注入
漏洞复现
使用JNDI-Injection-Exploit-1.0-SNAPSHOT-all工具,命令如下:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A 127.0.0.1
替换payload运行
/image-1720440180758.png)
/image-20240704202326991.png)
/image-1720440194575.png)
/image-20240704223510369.png)
/image-1720440241835.png)
/image-1720440249850.png)
/image-1720440259837.png)
/image-1720440277396.png)
/image-1720440289409.png)
/image-1720440304099.png)
/image-1720440314042.png)
/image-1720440323497.png)
/image-1720440331285.png)
/image-1720440337785.png)
/image-1720440360773.png)