解决反序列化的信息泄露问题java_java反序列化漏洞修复方案

2022-08-03 08:17:34 浏览数 (1)

大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说解决反序列化的信息泄露问题java_java反序列化漏洞修复方案,希望能够帮助大家进步!!!

威胁说明

如果Java应用对用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在产生过程中就有可能带来任意代码执行。

问题原因

类ObjectInputStream在反序列化时,没有对生成的对象的输入做限制,使攻击者利用反射调用函数进行任意命令执行。

CommonsCollections组件中对于集合的操作存在可以进行反射调用的方法

问题根源

Apache Commons Collections允许链式的任意的类函数反射调用。

问题函数

org.apache.commons.collections.Transformer接口

问题版本

3.2.2之前所有版本

快速排查

目前打包有apache commons collections库并且应用比较广泛的主要中间件有Jenkins、WebLogic、Jboss、WebSphere、OpenNMS等。

如果使用了以上中间件,需检测中间件安装目录是否包含apache commons collections库及其版本。特别是项目中发现使用了readObject函数。如:

ls -R 安装目录 | grep commons-collections.jar

ls -R 安装目录 | grep *.commons-collections.jar

ls -R 安装目录 | grep apache.commons.collections.jar

ls -R 安装目录 | grep *.commons-collections.*.jar

如果包含,且版本低于3.2.2,请参考修复建议。

修复建议

  1. 通用修复方案

方法:更新Apache Commons Collections库至3.2.2及以上版本。

警告:此方法为中间件上游修复方案,如果使用了中间件,请查看对应中间件的修复方案。

  1. spring-boot-starter-actuator

仅开放需要的接口:

endpoints.enabled = false

endpoints.metrics.enabled = true

开启账户密码认证:

引入spring-boot-starter-security依赖

org.springframework.boot

spring-boot-starter-security

在application.properties中指定actuator的端口以及开启security功能,配置访问权限验证:

management.port=8099

management.security.enabled=true

security.user.name=xxxxx

security.user.password=xxxxxx

  1. Jboss

影响版本:

Platform

Package

State

Red Hat Subscription Asset Manager 1

jasperreports-server-pro

受攻击

Red Hat OpenStack Platform 8.0 (Liberty)

opendaylight

无影响

Red Hat JBoss Portal 5

jbossas

受攻击

Red Hat JBoss Fuse Service Works 6

jbossas

受攻击

Red Hat JBoss Enterprise SOA Platform 5

JBossAS

受攻击

Red Hat JBoss Enterprise SOA Platform 5

jbossas

受攻击

Red Hat JBoss Enterprise SOA Platform 4

JBossAS

受攻击

Red Hat JBoss EWS 2

tomcat

无影响

RHEV Manager 3

jasperreports-server-pro

受攻击

  1. WebLogic

影响版本:10.3.6.0、12.1.2.0、12.1.3.0、12.2.1.0

  1. jenkins

影响版本:

所有低于1.637的Jenkins主线版本,包括1.637。

所有低于1.625.1的Jenkins LTS版本,包括1.625.1。

Jenkins主线版本用户应该升级至1.638或以上。

Jenkins LTS版本用户应该升级至1.625.2或以上。

在Groovy脚本控制台(/script)运行下面的代码,这将关闭正在运行的Jenkins的CLI子系统,而无需重新启动。

将下面的代码放到$JENKINS_HOME/init.groovy.d/cli-shutdown.groovy,保证确保在主机重启后保护保持不变。

import jenkins.*;

import jenkins.model.*;

import hudson.model.*;

// disabled CLI access over TCP listener (separate port)

def p = AgentProtocol.all()

p.each { x ->

if (x.name.contains("CLI")) p.remove(x)

}

// disable CLI access over /cli URL

def removal = { lst ->

lst.each { x -> if (x.getClass().name.contains("CLIAction")) lst.remove(x) }

}

def j = Jenkins.instance;

removal(j.getExtensionList(RootAction.class))

removal(j.actions)

  1. websphere

影响版本:

WebSphere Application Server ND Version V9.0.0.0 – V9.0.0.11

WebSphere Application Server ND Version V8.5.0.0 – V8.5.5.15

WebSphere Virtual Enterprise Version 7.0(官方已停止维护)

官方补丁:

提示:以上IBM提供的补丁连接,需输入登录账号后才能下载。

注意:在打补丁之前请先关闭WebSphere服务,安装完成后再将服务开启。

  1. 临时方案

如果无法打补丁,以下为各中间件官方推荐的临时方案:

方式1:使用SerialKiller替换进行序列化操作的ObjectInputStream类。

方式2:在不影响业务的情况下,删除所有commons-collections包中的InvokerTransformer.class、InstantiateFactory.class、InstantiateTransformer.class,例如:

zip -d commons-collections-3.2.1.redhat-3.jar org/apache/commons/collections/functors/InvokerTransformer.class

警告:临时方案中任何变动都需手动验证业务可用性。

  1. 强制封禁方案

严格意义说起来,Java相对来说安全性问题比较少,出现的一些问题大部分是利用反射,最终用Runtime.exec(String cmd)函数来执行外部命令的。

如果可以禁止JVM执行外部命令,未知漏洞的危害性会大大降低,可以大大提高JVM的安全性。

如下,只要在Java代码里简单加一段程序,就可以禁止执行外部程序了。

SecurityManager originalSecurityManager = System.getSecurityManager();

if (originalSecurityManager == null) {

// 创建自己的SecurityManager

SecurityManager sm = new SecurityManager() {

private void check(Permission perm) {

// 禁止exec

if (perm instanceof java.io.FilePermission) {

String actions = perm.getActions();

if (actions != null && actions.contains("execute")) {

throw new SecurityException("execute denied!");

}

}

// 禁止设置新的SecurityManager

if (perm instanceof java.lang.RuntimePermission) {

String name = perm.getName();

if (name != null && name.contains("setSecurityManager")) {

throw new SecurityException(

"System.setSecurityManager denied!");

}

}

}

@Override

public void checkPermission(Permission perm) {

check(perm);

}

@Override

public void checkPermission(Permission perm, Object context) {

check(perm);

}

};

System.setSecurityManager(sm);

}

0 人点赞