Iog4j2漏洞相关技术分析

网友投稿 947 2022-09-16

Iog4j2漏洞相关技术分析

Iog4j2漏洞相关技术分析

背景

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

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

漏洞影响

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

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

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

漏洞复现

利用漏洞攻击过程

复现代码

github地址按照README.md里面的步骤可以完整运行整个流程模块说明

模块

说明

business-app

正常的业务应用

marshalsec

攻击方搭建,用于启动LDAP服务的开源工具

evil-class="table-last-column table-last-row" data-id="t4606665-AXkZH48X" data-transient-attributes="table-cell-selection" style="min-width: auto; overflow-wrap: break-word; margin: 4px 8px; border: 1px solid rgb(217, 217, 217); padding: 4px 8px; cursor: default; vertical-align: top;">

攻击方搭建,启动Http服务,提供恶意代码-

evil-data-id="pd157317-9qIiNYkL">


使用SpringMVC的Controller,data-id="pd157317-e8XGA1Jh">


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


marshalsec

marshalsec是一款开源的工具,可以用于快速启动LDAP服务github地址:data-id="pd157317-z0ZxXhHv">


business-app

business-app代表正常的业务方java应用,为了方便复现,跳过正常data-id="pd157317-FP3WGnyx">


符合漏洞条件的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)攻击。

引文: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地址中去调用方法。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:C#tools(乘风破浪的姐姐第三季)
下一篇:PHP删除数组中特定元素
相关文章

 发表评论

暂时没有评论,来抢沙发吧~