fastjson漏洞--以运维角度进行修复

news2024/11/15 23:04:57

文章目录

  • 前言
  • 一、漏洞详情
  • 二、修复过程
    • 1.通过脚本方式修复
      • 1.1.脚本修复原理
      • 1.2.脚本演示
      • 1.3.执行脚本
    • 2. 手动升级包
      • 2.1.修复步骤
      • 2.2.遇到的问题


前言

该漏洞是三个月前由安全团队扫描出来的,主要影响是: FastJSON是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。由于具有执行效率高的特点,应用范围广泛。FastJSON 存在反序列化远程代码执行漏洞,漏洞成因是Fastjson autoType开关的限制可被绕过,然后反序列化有安全风险的类。攻击者利用该漏洞可实现在目标机器上的远程代码执行。本文主要从运维侧修复手段介绍了该漏洞的两种修复方式。


提示:以下是本篇文章正文内容,下面案例如果不放心,先自行在测试环境验证,验证通过后再上生产环境操作

一、漏洞详情

FastJSON是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。由于具有执行效率高的特点,应用范围广泛。 FastJSON 存在反序列化远程代码执行漏洞,漏洞成因是Fastjson autoType开关的限制可被绕过,然后反序列化有安全风险的类。攻击者利用该漏洞可实现在目标机器上的远程代码执行。 主要影响FastJSON<=1.2.80 版本

二、修复过程

修复过程涉及到服务重启,请自行确认重启时间

1.通过脚本方式修复

该版本涉及autotype行为变更,在某些场景会出现不兼容的情况

注意事项:
	1、该脚本适合以 lib 库形式依赖 fastjson-*.jar 包的Java微服务包,如 Springboot 打包的 jar 包。
	2、该脚本不支持直接打包 fastjson class 的 jar 包,即 jar 包中存在 "com/alibaba/fastjson/..." 类似结构,需要从代码升级修复。
	3、该脚本不支持docker 镜像包据说有签名校验,直接改镜像文件可能会导致不可用。由于环境所限,这种情况没有验证过。
	4、脚本适合 fastjson 全部版本。

1.1.脚本修复原理

1、扫描当前服务器所有jar包。
2、查看jar包依赖包中是否包括  fastjson-*.jar 包。
3、如果有,更新该依赖包为fastjson-1.2.83.jar。同时脚本在更新 jar 包之前,会备份该jar包到/export/fastjson_repair_workspace/backup_jars/ 目录下,防止替换后服务启动失败,后续方便回滚。

1.2.脚本演示

#!/bin/bash
# 2024-09-02
WORK_DIR="/root/fastjson_repair_workspace"
BACKUP_DIR="$WORK_DIR/backup_jars"
ALL_JARS="$WORK_DIR/all_jars.txt"
TARGET_JARS="$WORK_DIR/target_jars.txt"
DONE_FILE="$WORK_DIR/DONEFILE"
TARGET_VERSION="fastjson-1.2.81.jar" #修改为当前jar包中对应的fastjson包名,去lib目录下确认即可
FIX_VERSION="fastjson-1.2.83.jar"    #要确认升级的包

#检查脚本执行环境是否具备超管权限
function check_env() {
    mkdir -p $BACKUP_DIR
    if [ $? -eq 1 ];then
        echo "Permission denied, need root user"
        exit
    fi
}

#检查脚本执行用户,必须以服务器管理员root用户执行
function check_user() {
    if [ "$(whoami)" != "root" ];then
        echo "Need root user"
        exit
    fi
}

#检查是否有zip命令
function check_zip() {
    which zip &> /dev/null
    if [ $? -eq 1 ];then
        echo "Install zip first"
        exit
    fi
}
#检查是否有unzip命令
function check_unzip() {
    which unzip &> /dev/null
    if [ $? -eq 1 ];then
        echo "Install unzip first"
        exit
    fi
}
#检查当前服务器环境中是否存在要修复的fastjson包
check_fastjson_jar() {
    if [ ! -f ./$FIX_VERSION ];then
        echo "Fix task need $FIX_VERSION"
        exit
    fi
}

#环境检查
function check_find_env() {
    check_user
    check_env
    check_zip
}

function check_fix_env() {
    check_user
    check_env
    check_zip
    check_unzip
    check_fastjson_jar
}

#查看服务器所有jar包
function find_all_jars() {
    echo "Finding all jars ..."
    mkdir -p $WORK_DIR
    if [ -f $ALL_JARS ];then
        if [ -f $DONE_FILE ];then
            echo "Jarlist exsit: $ALL_JARS"
        else
            rm -f $ALL_JARS
            echo "Jarlist broken, run again"
            exit
        fi
    else
        find / -path "$BACKUP_DIR" -prune -o -path "/proc" -prune -o -print | grep "\.jar$" > $ALL_JARS
        if [ $? -eq 0 ];then
            touch $DONE_FILE
        fi
    fi
    echo "Find " $(wc -l $ALL_JARS|awk '{print$1}') " jars."
    echo
}


function find_lib_jars() {
    echo $* > /tmp/tmp_jarlist
    while read line;
    do
        fastjson_version=$(echo $line|awk -F'/' '{print$NF}')
        if [[ "$fastjson_version" < "$TARGET_VERSION" ]];then
            return 1
        fi
    done < /tmp/tmp_jarlist
    return 0
}

#检查查找出来的jar包是否包含target_version版本的包
function find_target_jars() {
    echo "Finding target jars ..."
    > $TARGET_JARS
    num=1
    while read jar;
    do
        ret=$(unzip -l $jar 2> /dev/null | grep fastjson.*jar| grep -v "Archive")
        if [ -n "$ret" ];then
            find_lib_jars $ret
            if [ $? -eq 1 ];then
                echo "Find [$num] $jar"
                echo $jar >> $TARGET_JARS
                ((num++))
            fi
        else
            ret=$(unzip -l $jar 2> /dev/null | grep "com/alibaba/fastjson" |grep -v "Archive")
            if [ -n "$ret" ];then
                echo "[NOT support] Find [$num] $jar"
                ((num++))
            fi
        fi
    done < $ALL_JARS
    echo "Find " $(wc -l $TARGET_JARS|awk '{print$1}') " target jars."
    echo
}

#替换jar包
function update_jars() {
    jarpath=$1
    filepath=$2
    jarname=$(basename $jarpath)
    filedir=$(dirname $filepath)
    mkdir -p /export/fastjson_repair_workspace/libjars/
    cp $jarpath /export/fastjson_repair_workspace/libjars/$jarname
    mkdir -p /export/fastjson_repair_workspace/libjars/$filedir
    cp ./$FIX_VERSION /export/fastjson_repair_workspace/libjars/$filedir
    cd /export/fastjson_repair_workspace/libjars/
    zip -d $jarname $filepath
    echo "adding: $filedir/$FIX_VERSION"
    jar -uf0 $jarname $filedir/$FIX_VERSION
    cp -f $jarname $jarpath
    cd - &> /dev/null
    rm -rf /export/fastjson_repair_workspace/libjars/*
}
#修复jar包
function fix_lib_jars() {
    jarpath=$1
    if [ ! -n "$(unzip -l $jarpath 2> /dev/null | grep fastjson.*jar | grep -v "Archive")" ];then
        echo "[WARN] NOT Fixed"
    fi
    unzip -l $jarpath 2> /dev/null | grep fastjson.*jar | grep -v "Archive" > /tmp/tmp_jarlist
    while read line;
    do
        fastjson_version=$(echo $line|awk -F'/' '{print$NF}')
        if [[ "$fastjson_version" < "$TARGET_VERSION" ]];then
            libjar=$(echo $line|awk '{print$NF}')
            update_jars $jarpath $libjar
            echo "Fixed"
        fi
    done < /tmp/tmp_jarlist
}

function fix_target_jars() {
    if [ ! -f $TARGET_JARS ];then
        echo "run check first."
        exit
    fi

    echo "Fix target jars ..."
    echo
    num=1
    while read jar;
    do
        echo "==== $num ===="
        echo "Backup $jar"
        mkdir -p ${BACKUP_DIR}$(dirname $jar)
        cp -f $jar ${BACKUP_DIR}$(dirname $jar)

        echo "Fix $(basename $jar) ..."
        fix_lib_jars $jar
        echo
        ((num++))
    done < $TARGET_JARS
    echo "Fixed " $(wc -l $TARGET_JARS|awk '{print$1}') " target jars."
    mv -f $TARGET_JARS ${TARGET_JARS}.fixed.$(date +%Y%m%d_%H%M%S)
}

function usage() {
    echo "Version 1.0.0"
    echo "Usage: $0 [check|fix]"
}

function check() {
    check_find_env
    find_all_jars
    find_target_jars
}

function fix() {
    check_fix_env
    fix_target_jars
}


if [ "$1" = "check" ];then
    check
elif [ "$1" = "fix" ];then
    fix
else
    usage
fi

1.3.执行脚本

``

[root@prometheus ~]# chmod +x fastjson_repair.sh 
[root@prometheus ~]# sh fastjson_repair.sh 
Version 1.0.0
Usage: fastjson_repair.sh [check|fix] #check是检查包  fix是对fastjson包进行升级处理
[root@prometheus ~]# sh fastjson_repair.sh check
Finding all jars ...
Find  751  jars.

Finding target jars ...
Find [1] /export/server/icity-client/icity-client-system-1.0.0.jar
Find [2] /export/server/icity-server/icity-server-system-1.0.0.jar
Find  2  target jars.  #发现了两个fastjson版本低于1.28.3版本的包

在这里插入图片描述
执行 ./fast_repaire.sh check脚本如下所示
在这里插入图片描述

vim java微服务包 查看jar中包含的fastjson包,果然低于1.28.3版本
在这里插入图片描述
执行fix命令


2. 手动升级包

有时,java微服务包使用上述脚本无法完成修复,而且研发不能快速配合修复,那么从运维角度出发进行修复

2.1.修复步骤

如下图所示

1、拷贝需要修复的jar包至某一个空目录下

2、执行jar -xf   xxxx.jar 对包进行解压

3、将解压后META-INF目录下的MANIFEST.MF文件 移动到跟META-INF目录平级  mv META-INF/MANIFEST.MF  ../

4、cd BOOT-INF/lib/目录下,将低版本的fastjson包移除,将高版本的包移动到该目录下

5、执行打包命令  jar -cfm0 xxx.jar  /xxx/xxx/MANIFEST.MF *

6、将第5步构建好的包移动到对应的服务目录下,重新启动该服务,观察日志,没有报错;且vim  xxxx.jar 发现fastjson包为替换后的版本的包,则修复成功

在这里插入图片描述
在这里插入图片描述
将上述低版本的fastjson jar包从当前lib目录下删除,将fastjson-1.2.83高版本的包拷贝到lib目录下
在这里插入图片描述
重新执行打包命令构建新的java微服务包
在这里插入图片描述
将上述新构建好的jar包拷贝到原来的位置,并重新启动服务,查看服务日志是否报错,如果没报错,则fastjson漏洞修复完成

2.2.遇到的问题

	在执行java微服务包构建时,遇到了下方的错误
	The calling method's class, org.apache.catalina.authenticator.AuthenticatorBase, was loaded from the following location:

    jar:file:/export/system-server-1.0.0.jar!/BOOT-INF/lib/tomcat-embed-core-9.0.60.jar!/org/apache/catalina/authenticator/AuthenticatorBase.class

The called method's class, javax.servlet.ServletContext, is available from the following locations:

    jar:file:/export/system-server-1.0.0.jar!/BOOT-INF/lib/servlet-api-6.0.53.jar!/javax/servlet/ServletContext.class
    jar:file:/export/system-server-1.0.0.jar!/BOOT-INF/lib/tomcat-embed-core-9.0.60.jar!/javax/servlet/ServletContext.class

The called method's class hierarchy was loaded from the following locations:

    javax.servlet.ServletContext: jar:file:/export/system-server-1.0.0.jar!/BOOT-INF/lib/servlet-api-6.0.53.jar!/
解决方法:
	将BOOT-INF/lib/目录下的servlet-api-6.0.53.jar包替换为一个高版本的包,
	例如servlet-api-7.0.0.jar,然后重新执行上述构建即可解决。
	https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-servlet-api/7.0.0   
	在上述地址可以下载这个包,重命名为对应的名字即可使用

至此,fastjson低版本漏洞修复的两种方法介绍完毕


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2126935.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器人--手眼标定算法

教程 知乎1 CSDN博主 什么是手眼标定 eye_to_hand 相机不在机器人上-----相机坐标系相对于机器人基坐标系的转换矩阵不变&#xff1b; eye_in_hand 相机在机器人上-----相机坐标系相对于机器人工具坐标系的转换矩阵不变&#xff1b; 手眼标定的目的 目的&#xff1a;求解出…

模板语法

模板语法 {{.}} 模板语法都包含在 {{ 和 }} 中间&#xff0c;其中{{ . }}中的点表示当前对象。 当传入一个结构体对象时&#xff0c;可以根据 . 来访问结构体的对应字段。 当传入的变量是map时&#xff0c;也可以在模板文件中通过 . 根据key来取值。 main.go package maini…

S3C2440 ARM设备驱动(boot loader,kernel,rootfs)

一、开发板Linux启动需求 1、bootloader 为内核启动准备环境&#xff0c;并引导内核启动 2、kernel&#xff08;linux内核&#xff09; 操作系统的核心&#xff0c;&#xff08;狭义上的操作系统&#xff09; 3、rootfs 一堆有组织的文件 1. bootloader(一个裸机程序) 初始化C…

【MM24】【水下目标分割】Dual_SAM

论文&#xff1a;https://arxiv.org/abs/2404.04996 代码&#xff1a;https://github.com/Drchip61/Dual_SAM 点评 这篇文章介绍的改进SAM,面向海洋生物的分割。但是海洋图像易受噪声影响&#xff0c;论文中仅是通过一个gamma变换减弱了这种影响。双主干网络的参数量并没有提及…

2.队列和队列集

队列的本质就是环形buff,加了互斥操作,加了阻塞-唤醒. 1.介绍一下环形BUFF 2.阻塞和唤醒 在我们队列中是有一个读list 链表 和 一个写list链表 他们就是用来保存 读 或者 写阻塞 的任务 假设我们 就绪链表中有A 和 B两个任务 他们正常情况下都是轮流运行, 这个时候 A 想读队…

IDEA中集成Git及Github

我的博客大纲 我的GIT学习大纲 1、IDEA中集成Git 1.1.设置IDEA忽略一些文件&#xff1a; a.为什么要忽略一些文件 1.在将项目推送之前&#xff0c;有一些文件是可以忽略的&#xff0c;忽略这些文件与实际功能无关&#xff0c;不参与服务器上部署运行&#xff0c;把他们忽略掉…

【DCL】Dual Contrastive Learning for General Face Forgery Detection

文章目录 Dual Contrastive Learning for General Face Forgery Detectionkey points:贡献方法数据视图生成对比学习架构实例间对比学习实例内对比学习总损失函数实验实验细节定量结果跨数据集评估跨操作评估消融实验可视化Dual Contrastive Learning for General Face Forgery…

HarmonyOS开发5.0【封装request泛型方法】axios

一 准备工作 1. 先开启一下虚拟机的权限 src/main/module.json5 打开module.json5在15~19行 进行配置网络权限 2. 在终端下载安装一下 ohpm install ohos/axios 复制 粘贴进去回车就行 3. 这样显示就是安装好了 如果导入不行就关了重新启动 二 创建一个ETS文件&#xff0c;…

后端开发刷题 | 矩阵的最小路径和

描述 给定一个 n * m 的矩阵 a&#xff0c;从左上角开始每次只能向右或者向下走&#xff0c;最后到达右下角的位置&#xff0c;路径上所有的数字累加起来就是路径和&#xff0c;输出所有的路径中最小的路径和。 数据范围: 1≤n,m≤500&#xff0c;矩阵中任意值都满足 0≤ai,j…

Linux系统:cd命令

1、命令详解&#xff1a; cd命令用于改变当前工作目录的命令&#xff0c;切换到指定的路径&#xff0c;全称为change directory&#xff0c;若目录名称省略&#xff0c;则默认变换至使用者的 home 目录。 2、官方参数&#xff1a; 选项&#xff1a;-L 强制遵循符号链接-P 使用…

基于RFID技术的光交箱哑资源智能化管理方案

一、现状 &#xff08;一&#xff09;现状与挑战 在当前通信网络基础设施中&#xff0c;哑资源如光缆接头、跳线等在网络中占据着重要地位。然而&#xff0c;传统的哑资源管理方式存在诸多问题&#xff0c;一方面&#xff0c;管理主要依赖人工记录和定期巡检&#xff0c;效率…

每日OJ_牛客_合唱团(打家劫舍dp)

目录 牛客_合唱团&#xff08;打家劫舍dp&#xff09; 解析代码1 解析代码2 牛客_合唱团&#xff08;打家劫舍dp&#xff09; 合唱团__牛客网 有 n 个学生站成一排&#xff0c;每个学生有一个能力值&#xff0c;牛牛想从这 n 个学生中按照顺序选取 k 名学生&#xff0c;要求…

MongoDB高可用和分片集群知识

一、MongoDB实现高可用 1. MongoDB复制集(Replication Set) 在实际生产中&#xff0c;MongoDB要实现高可用&#xff0c;以免MongoDB单实例挂了&#xff0c;服务不可用。MongoDB实现高可用是以MongoDB复制集的形式实现&#xff0c;和集群部署概念相同&#xff0c;MongoDB复制集…

火柴人跑酷

运行图片&#xff1a; 这里面有三个boss&#xff0c;和各种元素属性列举一下&#xff1a; 元素作用 火 运用火元素将攻击抵消 水 和火元素一致 磁 自动吸取经验…

vscode设置vue标签不换行

1、打开 文件 --> 首选项 --> 设置 2、在设置里搜索 vetur.format&#xff0c;项较多&#xff0c;向下滑动找到 在 setting.json 中编辑 按钮 点进去 3、修改配置文件vetur.format.defaultFormatterOptions {"files.autoSave": "afterDelay","…

全网最适合入门的面向对象编程教程:47 Python函数方法与接口-回调函数Callback

全网最适合入门的面向对象编程教程&#xff1a;47 Python 函数方法与接口-回调函数 Callback 摘要&#xff1a; 回调函数是编程中一种非常常见的模式&#xff0c;用于将函数作为参数传递给其他函数或方法。这种模式在 Python 中广泛应用于事件处理、异步编程、函数式编程等场景…

cadence SPB17.4 - ORCAD - ERROR(ORCAP-1616): Reference is invalid for this part

文章目录 cadence SPB17.4 - ORCAD - ERROR(ORCAP-1616): Reference is invalid for this part概述笔记END cadence SPB17.4 - ORCAD - ERROR(ORCAP-1616): Reference is invalid for this part 概述 在抄GDLink on Board的原理图。 抄完之后进行原理图DRC, 有个元件报错。 …

C语言代码练习(第十八天)

今日练习&#xff1a; 48、猴子吃桃问题。猴子第1天摘下若干个桃子&#xff0c;当即吃了一半&#xff0c;还不过瘾&#xff0c;又多吃了一个。第2天早上又将剩下的桃子吃掉一半&#xff0c;又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时&…

digits Social Login插件 google OAuth 2.0登录 400 redirect_uri_mismatch错误解决

以下是Social Login插件google登录配置&#xff1a; 直接使用这个URI 会在登录时提示错误&#xff1a;400 redirect_uri_mismatch&#xff0c;此时需要点击错误详情把这个重定向URI设置到google中即可

Java:类和对象(2)

一 对象的构建和初始化 1.对象构建 (Object Construction) Student student1new Student("zhangsan",12,"123456"); Student student2new Student("lisi",10,"15236"); 2. 构造函数&#xff08;Constructor&#xff09; 构造函数的…