写点什么

Iog4j2 漏洞相关技术分析

作者:极光开发者
  • 2021 年 12 月 31 日
  • 本文字数:3064 字

    阅读完需:约 10 分钟

Iog4j2漏洞相关技术分析

背景

2021 年 12 月初,极光安全团队通过安全威胁舆情发现 Apache Log4j2 存在远程代码执行漏洞,迅速对该漏洞危害性评估和涉及面漏斗分析,制定了应急响应方案,对涉及到的代码组件类和主机资产类快速整理,外部安全扫描对该漏洞进行优先级扫描,避免威胁进一步扩大和阻断,对内推动该漏洞版本组件的修复进度,持续关注该漏洞组件的后续发展。

本文通过构造环境复现漏洞,了解这个漏洞产生的原因,分析修复漏洞方法,研究学习背后的相关技术。

漏洞影响

Log4j2 作为 java 代码项目中广泛使用的开源日志组件,漏洞影响范围极广,堪称史诗级、核弹级漏洞。

直接和间接依赖 Log4j2 的开源组件总计有 17 万个,也就是说有至少 17 万个开源组件是受 Log4j2 漏洞影响 GitHub 作为全球最大的开源代码托管平台,抽样分析发现至少 5.8%的 java 开源项目受该漏洞影响

在 java 语言的开源组件流行度排行中,Log4j2 列第 13 位

漏洞复现

利用漏洞攻击过程



复现代码

github 地址https://github.com/zheng93775/log4j2-attack 按照 README.md 里面的步骤可以完整运行整个流程模块说明

 


evil-http-server

首先我们准备一个含有恶意执行代码的类,恶意代码执行时会在 Windows 下启动计算器


使用 SpringMVC 的 Controller,http 请求返回的相应是恶意类的二进制字节码




编译后,启动服务,监听 9090 端口




marshalsec


marshalsec 是一款开源的工具,可以用于快速启动 LDAP 服务 github 地址:https://github.com/mbechler/marshalsec

首先编译项目,然后运行 jar 启动 LDAP 服务



business-app

business-app 代表正常的业务方 java 应用,为了方便复现,跳过正常 http 服务请求过程,启动后直接记录日志




符合漏洞条件的 Windows 系统环境下运行 Main.java,就会成功打开计算器

相关技术

JNDI

什么是 JNDI

JNDI 全称为 Java Naming and Directory Interface,即 Java 名称与目录服务接口。是 SUN 公司提供的一种标准的 Java 命名系统接口,在 J2EE 规范中是重要的规范之一。JNDI 提供统一的客户端 API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口。

JNDI 中的命名(Naming),就是将 Java 对象以某个名称的形式绑定(binding)到一个容器环境(Context) 中,以后调用容器环境(Context)的查找(lookup)方法就可以查找出某个名称所绑定的 Java 对象。

JNDI 架构

JNDI 架构上主要包含两个部分,Java 的应用层接口 和 SPI。



SPI 全称为 Service Provider Interface,即服务供应接口,主要作用是为底层的具体目录服务提供统一接口, 从而实现目录服务的可插拔式安装。在 JDK 中包含了 RMI、LDAP、CORBA 等内置的目录服务

为什么要用 JNDI

JNDI 是 java 语言产生漏洞的一个比较大的因素,我们平时在业务开发中基本没有使用到,那么为什么 log4j2 的代码要支持 jndi 呢?

 

1. JNDI 提出的目的是为了解耦,是为了开发更加容易维护,容易扩展,容易部署的应用。

2. JNDI 是一个 Sun 提出的一个规范(类似于 JDBC),具体的实现是各个厂商实现的,可以看出,老外还是非常认可这个规范,很多地方做了很多解耦的设计,包括 Log4J。

3. JNDI 在 J2EE 系统中的角色是“交换机”,是 J2EE 组件在运行时间接地查找其他组件、资源或服务的通用机制。

4. JNDI 是通过资源的名字来查找的,资源的名字在整个 J2EE 应用中是唯一的。

除了 Log4j,还有很多组件用了 JNDI,比如:Hibernate、JTA、Tomcat、WebLogic、WebSphere

LDAP

全称为 Lightweight Directory Access Protocol,即轻量级目录访问协议。

LDAP 是开放的 Internet 标准,支持跨平台的 Internet 协议,在业界中得到广泛认可的,并且市场上或者开源社区上的大多产品都加入了对 LDAP 的支持,因此对于这类系统,不需单独定制,只需要通过 LDAP 做简单的配置就可以与服务器做认证交互。

修复漏洞方法分析

升级 log4j2

log4j 漏洞受影响的版本为 2.0 至 2.15.0.rc1,建议升级至 2.17.0 及以上正式版本

2.15.0.rc1

漏洞爆出的当天,2.15.0.rc1 修复版本就出来了。JndiManager.lookup 方法进行了修改,增加了白名单校验, 但是代码有个问题,catch 住异常后代码仍然可以往下执行,攻击者在 ${jndi}的地址中增加一个空格就可以触发 URISyntaxException,绕过白名单校验。

 

2.15.0.rc2



这个版本解决了 rc1 的问题




 

虽然也有爆出漏洞,但是条件比较苛刻,能利用的可能性很小,还是比较安全的。如果已经升到 2.15.0,应用本身不直接对外网提供服务,也可以选择不升级到更新版本。

在某些非默认配置中,发现 Apache Log4j 2.15.0 中解决 CVE-2021-44228 的修复是不完整的。这可能允许攻击者控制线程上下文映射(MDC)输入数据,当日志记录配置使用非默认的模式布局,使用上下文查找(例

如,${ctx:loginId})或线程上下文映射模式(%X, % MDC,或 %MDC),使用 JNDI 查找模式生成恶意的输入数据,从而导致拒绝服务(DOS)攻击。

引文:https://github.com/cckuailong/Log4j_CVE-2021-45046

2.16.0

更新内容如下

默认禁用 JNDI 的访问,用户需要通过配置 log4j2.enableJndi 参数开启

默认允许协议限制为:java、ldap、ldaps,并将 ldap 协议限制为仅可访问 Java 原始对象 Message Lookups 被完全移除,加固漏洞的防御

JNDI 远程执行漏洞被彻底封死了,但是还有拒绝服务漏洞

Apache 官方发布了 Apache Log4j 拒绝服务攻击漏洞(CVE-2021-45105),此漏洞需要在非默认配置下才能触发。当系统日志配置使用带有 Context Lookups 的非默认 Pattern Layout(例如 ${ctx:loginId})时,攻击者可构造包含递归查找的恶意输入数据,成功利用此漏洞将触发无限循环,导致系统崩溃。

这个漏洞首要前提条件比较苛刻,已经升级到 2.16.0 的可以选择不升级到更新版本

升级 JDK 小版本

升级 jdk 版本至 6u211 / 7u201 / 8u191 / 11.0.1 以上,可以在一定程度上限制 JNDI 等漏洞利用方式。JDK 高版本有什么不同呢

高版本增加了一个变量 com.sun.jndi.ldap.object.trustURLCodebase,这个变量的值默认为 false。除非我们加入如下代码手动复制为 true,才可以在高版本复现漏洞。



JDK 高版本也存在漏洞

绕过方式:LDAP 服务 Codebase 不返回地址,而是返回一个本地已有的 Factory 类,通过 Factory 类创建指定参数的实例实现攻击。比如 Tomcat 中存在的 org.apache.naming.factory.BeanFactory。LDAP 返回示例如下




通过配置关闭 log4j 的 jndi 查找功能

有以下几种方式


设置 jvm 参数 “-Dlog4j2.formatMsgNoLookups=true


在项目 classpath 目录下添加 log4j2.component.properties 配置文件,设置 log4j2. formatMsgNoLookups=true


设置系统环境变量:“LOG4J_FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS” 设置为 “true” 注意,由于这个配置项的判断逻辑是 2.10 版本才加上的,这种方式对于 2.0 <= log4j 版本 < 2.10 无效



删除 log4j-core-2.x.jar 中的 JndiLookup 类

在以前的版本(<2.16.0)中,可以通过从类路径中删除 JndiLookup 类来缓解这个问题。不建议使用这种方式, 某些特殊项目不便升级 log4j 的情况下可以考虑。




 

fastjson 漏洞分析

2019 年 fastjson 被爆出远程代码执行漏洞,当时国内使用了 fastjson 的项目非常多,影响面也非常广,并且漏洞的修复持续了 N 个版本。那么,fastjson 具体是存在什么漏洞呢?

漏洞和 fastjson 中的一个 AutoType 特性,我们先来看看 AutoType 是什么。

AutoType

来看一个示例




序列化



反序列化




执行结果



为了解决这个问题,fastjson 引入了 AutoType




序列化后的字符串多了 @type 字段,反序列化时就可以定位到具体的类型了



利用漏洞攻击过程

思路是指定 @type 的值为某个特殊的类,比如




Java 应用使用 fastjson 反序列化这个字符串,创建 JdbcRowSetImpl 类对象,这个类的 dataSourceName 支持传入一个 rmi 的源,当解析这个 uri 的时候,就会支持 rmi 远程调用,去指定的 rmi 地址中去调用方法。

用户头像

还未添加个人签名 2021.04.23 加入

还未添加个人简介

评论

发布
暂无评论
Iog4j2漏洞相关技术分析