log4j2远程执行漏洞原理以及解决方案
Posted 猿码优创
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了log4j2远程执行漏洞原理以及解决方案相关的知识,希望对你有一定的参考价值。
好久没更新博客了,因为最近实在是超级忙,最近Log4j2核弹级别漏洞被疯狂刷屏。
2021年12月9日,国内多家机构监测到Apache Log4j2存在任意代码执行漏洞,并紧急通报相关情况。由于Apache Log4j存在递归解析功能,未取得身份认证的用户,可以从远程发送数据请求输入数据日志,轻松触发漏洞,最终在目标上执行任意代码。鉴于Apache Log4j本身涉及多种应用组件,猿码优创将此漏洞威胁等级调整为:严重。
目前经过不懈努力,猿码优创已经给复现了。
还给大家画了一个流程图:
产生原因:存在JNDI注入漏洞,当程序将用户输入的数据被日志记录时,即可触发此漏洞,成功利用此漏洞可以在目标服务器上执行任意远端代码。
我们来看一个简单的业务场景:
下面是一个登录页面:
后端我们把用户谁登录了进行打印。
public void login(string name)
logger.info(",刚刚登录了猿码优创系统", name); //日志框架为:log4j2
输出结果为:yuanmayouchuang刚刚登录了猿码优创系统,这个就忽略演示了。
很简单的一个业务场景,但是如果在这个地方输入:java:os会发生什么呢?
执行:logger.info("$java:os"); //logger为log4j
输出结果:Windows 10 10.0, architecture: amd64-64
有没有感觉特别像SQL注入。
为什么会发生这样的事呢?
log4j2的强大之处在于,除了可以输出程序中的变量,它还提供了一个叫Lookup的东西,可以用来输出更多内容:
lookup 翻译过来就是查找、搜索的意思。那么log4j2中,就是在输出日志的时候,通过方法去查找要输出的内容。相当于一个接口,具体去哪里找,怎么找找,就需要编写具体的代码去实现,就相当于java中的多态差不多意思。
log4j2提供了很多查找方法:
我们主要看一下本次漏洞的罪魁祸首:JNDI 什么是JNDI?它是干嘛的??我们问一下百度百科。
以上看的是不是超级懵,看看上面咱们做的那个实验,传参为:$java:os 输出计算机系统名称,相当于类似于一个字典的数据源,通过传参,然后找字典然后输出相应的信息。
这个时候小伙伴就有想了,跟我有什么关系,输出系统变量,不会引起很大的事故吧。最多欺骗日志输出,能引起什么腥风血浪。
别急,听猿码优创给你慢慢道来。JNDI 既然相当于一个字典,那里面有很多数据源。
其中有一个数据源就是本次漏洞的受害者,那就是LDAP
什么是LDAP?我们先问问百度百科。
what????怎么看了一脸懵逼。
有没有在一些开源系统中看到过这个单词LDAP登录。
LDAP是开放的Internet标准,支持跨平台的Internet协议,在业界中得到广泛认可的,并且市场上或者开源社区上的大多产品都加入了对LDAP的支持,因此对于这类系统,不需单独定制,只需要通过LDAP做简单的配置就可以与服务器做认证交互。“简单粗暴”,可以大大降低重复开发和对接的成本。
这样说能明白了不?再举个例子,比如你们公司购买了一个OA系统,但是呢你们原来有自己的域账户,这个时候OA系统厂家不会为你们单独改造一套系统出来,这样成本太大,这个时候LDAP就派上了用场,通过简单配置,就可以用域账户登录购买的OA系统。但是简单配置相当于是远端加载了一些信息。
来上面两个 lookup和LDAP大家有没有一个简单的了解。好我们来说这次的漏洞原理。
这个时候我们还是用代码举例子。
@GetMapping(value = "/test")
public String test(String info)
//执行远程代码
logger.error("----------------log4j漏洞演示--------------------");
logger.info(info); //logger为log4j
return "success";
这个时候我们info传递:$jndi:ldap://127.0.0.1:3001/
这个时候log4j一发现$ 这个时候里面的信息就是要单独处理的。
发现是JDNI扩展内容:$jndi:ldap://127.0.0.1:3001/yuanmayouchuang ldap服务器在127.0.0.1 直接查找key是:yuanmayouchuang 然后查找完毕去返回相应的数据。
如果是普通的数据那就没什么?问题就是出现在可以请求java对象!启动完项目 Java对象一般只存在于内存中,但也可以通过序列化的方式将其存储到文件中,或者通过网络传输。但更危险的在于:JNDI还支持一个叫命名引用(Naming References)的方式,可以通过远程下载一个class文件,然后下载后加载起来构建对象。
注意:这里就是核弹级别漏洞问题了:JNDI可以远程下载class文件来构建对象!!!
就是下载的class(java编译后的代码)如果里面有恶意代码这不完蛋了吗?
一句话总结漏洞:就是该输出日志的地方执行了远端服务器恶意Class代码
互联网流传一句话:永远不要相信用户的输入的内容。
修复方案:Log4j2修复方案官方地址https://logging.apache.org/log4j/2.x/security.html
版本号 | 解决方案 |
---|---|
2.10-2.14版本 | 系统属性 log4j2.formatMsgNoLookups 或环境变量 LOG4J_FORMAT_MSG_NO_LOOKUPS 设置为 true |
2.7-2.14.1之间的版本 | 设置log4j2.xml的%m为 %mnolookups |
2.10以下版本 | 删除org/apache/logging/log4j/core/lookup/JndiLookup.class这个类 |
哎呀,大家很幸运,然后今天我打开log4j官方发现昨天的翻译就是我上面发的给推翻了。。。
这是最新的解决方案:升级到最新2.0.16版本
log4j2.0.16 core版本 pom文件: https://mvnrepository.com/artifact/org.apache.logging.log4j
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.16.0</version>
</dependency>
log4j2.0.16 api版本 pom文件: https://mvnrepository.com/artifact/org.apache.logging.log4j
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.16.0</version>
</dependency>
到此本文就介绍完毕了。
稍后我会把LDAP模拟攻击源码发出来了,需要大家遵守以下协议。
源码是针对Log4j2超高危RCE漏洞`CVE-2021-4428`的复现DEMO,目的是认识该漏洞的危害性并根据您系统的情况做出针对性的防御。 警告---重要 本DEMO只是针对技术层面的研究,不涉及恶意远程计算机侵入方面的相关脚本。请勿利用漏洞进行非法侵入他人计算机的违法活动。否则您将可能承担以下侵权责任: 1. 根据《中华人民共和国治安管理处罚法》第二十九条 对违反国家规定,侵入计算机信息系统,造成危害的,处五日以下拘留;情节较重的,处五日以上十日以下拘留。 2. 根据《中华人民共和国刑法》第二百八十五条第一款的规定,犯本罪的,处三年以下有期徒刑或者拘役。单位犯本罪的,对单位判处罚金,并对其直接负责的主管人员和其他直接责任人员,依照上述规定处罚。 请勿用于非法用途,否则将承担相应的法律责任。
以上是关于log4j2远程执行漏洞原理以及解决方案的主要内容,如果未能解决你的问题,请参考以下文章