Fastjson 反序列化漏洞实战排查:3 种检测方法与 2 种应急缓解脚本
Fastjson 反序列化漏洞实战排查3 种检测方法与 2 种应急缓解脚本当安全团队收到 Fastjson 漏洞预警时时间就是防御的生命线。本文将从实战角度出发提供一套完整的应急响应流程帮助安全运维工程师和开发负责人快速定位受影响系统并实施临时防护措施。我们将重点介绍三种高效的检测方法和两种无需立即升级的应急缓解方案确保在修复窗口期内有效降低风险。1. 漏洞影响评估与快速定位Fastjson 反序列化漏洞的本质在于攻击者通过精心构造的 JSON 数据利用type参数指定恶意类触发 JNDI 注入或远程代码执行。根据历史漏洞分析受影响版本主要集中在 1.2.80 及以下版本但不同版本存在不同的绕过方式。1.1 受影响组件识别系统级检测Linux 环境# 查找正在运行的Java进程使用的fastjson版本 lsof | grep fastjson | grep -E \.jar | awk {print $9} | xargs -I {} sh -c echo -n {}: ; unzip -p {} META-INF/MANIFEST.MF | grep Implementation-Version || echo 无法确定版本 # 查找项目依赖中的fastjson find /path/to/project -name *.jar -exec sh -c unzip -p {} META-INF/MANIFEST.MF | grep -q fastjson echo 发现fastjson: {} \;依赖分析Maven 项目mvn dependency:tree -Dincludescom.alibaba:fastjson版本风险矩阵版本范围已知漏洞数量最高风险等级≤1.2.245严重1.2.25-1.2.473高危1.2.48-1.2.682高危1.2.69-1.2.801高危≥1.2.830无1.2 流量特征检测攻击流量通常具有以下特征Content-Type: application/jsonPOST 请求体包含type参数可能包含JdbcRowSetImpl、TemplatesImpl等关键词实时流量监控脚本Pythonimport pyshark def detect_fastjson_attack(pkt): if hasattr(pkt, http) and pkt.http.content_type application/json: payload pkt.http.file_data.lower() if btype in payload and (bjndi: in payload or bjdbcrowsetimpl in payload): print(f[!] 疑似Fastjson攻击: {pkt.ip.src} - {pkt.ip.dst}) print(f 路径: {pkt.http.request_uri}) print(f 载荷片段: {payload[:200]}...) capture pyshark.LiveCapture(interfaceeth0, display_filterhttp) capture.apply_on_packets(detect_fastjson_attack)2. 三种高效检测方法2.1 进程级检测lsof 方案增强版检测脚本#!/bin/bash # fastjson_detect_lsof.sh HIGH_RISK_VERSIONS(1.2.24 1.2.47 1.2.68 1.2.80) echo [*] 扫描Java进程使用的fastjson版本... lsof -nP -i4TCP | grep -E java|jdk|jre | awk {print $2} | sort -u | while read pid; do jars$(lsof -p $pid | grep -E \.jar$ | awk {print $9}) for jar in $jars; do if [[ $jar *fastjson* ]]; then version$(unzip -p $jar META-INF/MANIFEST.MF 2/dev/null | grep Bundle-Version\|Implementation-Version | awk {print $2} | tr -d \r) if [[ -z $version ]]; then version$(basename $jar | grep -oP \d\.\d\.\d) fi if [[ -n $version ]]; then risk低风险 for v in ${HIGH_RISK_VERSIONS[]}; do if [[ $version $v || $(printf %s\n $v $version | sort -V | head -n1) $version ]]; then risk高风险 break fi done echo [!] 进程ID: $pid, 路径: $jar, 版本: ${version:-未知}, 风险等级: $risk echo 关联服务: $(ps -p $pid -o command) fi fi done done2.2 依赖树分析全量扫描Maven 项目深度扫描#!/bin/bash # fastjson_detect_maven.sh echo [*] 扫描Maven项目中的fastjson依赖... find / -name pom.xml 2/dev/null | while read pom; do project_dir$(dirname $pom) echo [] 检查项目: $project_dir # 检查直接依赖 if grep -q artifactIdfastjson/artifactId $pom; then version$(grep -A1 artifactIdfastjson/artifactId $pom | grep version | sed -E s/.*version(.*)\/version.*/\1/) echo [!] 发现直接依赖: fastjson $version fi # 完整依赖树分析 if [ -f $project_dir/mvnw ]; then mvn_cmd./mvnw else mvn_cmdmvn fi cd $project_dir $mvn_cmd dependency:tree -Dincludescom.alibaba:fastjson 2/dev/null | grep fastjson cd - /dev/null done2.3 字节码特征检测对于无法直接获取版本号的情况可以通过类文件特征检测# fastjson_bytecode_check.py import os import zipfile import re FASTJSON_CLASSES { com/alibaba/fastjson/JSON.class: { 1.2.24: b\xca\xfe\xba\xbe\x00\x00\x00\x33, 1.2.47: b\xca\xfe\xba\xbe\x00\x00\x00\x34, 1.2.68: b\xca\xfe\xba\xbe\x00\x00\x00\x35 } } def scan_jar_files(path): for root, _, files in os.walk(path): for file in files: if file.endswith(.jar): jar_path os.path.join(root, file) try: with zipfile.ZipFile(jar_path) as z: for class_file in FASTJSON_CLASSES: if class_file in z.namelist(): with z.open(class_file) as f: magic f.read(8) for ver, sig in FASTJSON_CLASSES[class_file].items(): if magic.startswith(sig): print(f[] 发现 {jar_path}: fastjson {ver}) except: continue scan_jar_files(/path/to/scan)3. 两种应急缓解方案当无法立即升级时可采用以下临时防护措施3.1 JVM 参数强制 SafeMode实施步骤定位所有Java应用的启动脚本如 catalina.sh、startup.sh 等添加JVM参数JAVA_OPTS$JAVA_OPTS -Dfastjson.parser.safeModetrue批量修改脚本示例find / -name *.sh -exec grep -l java.*jar {} \; | while read script; do if ! grep -q fastjson.parser.safeMode $script; then sed -i /java.*jar/ s/^/JAVA_OPTS$JAVA_OPTS -Dfastjson.parser.safeModetrue\n/ $script echo [] 已修改: $script fi done验证方法// SafeMode验证测试类 public class FastjsonSafeModeCheck { public static void main(String[] args) { try { String json {\type\:\com.sun.rowset.JdbcRowSetImpl\,\dataSourceName\:\ldap://malicious\,\autoCommit\:true}; Object obj com.alibaba.fastjson.JSON.parse(json); System.err.println([!] SafeMode未生效仍可解析恶意JSON); } catch (Exception e) { System.out.println([] SafeMode已生效拦截恶意请求: e.getMessage()); } } }3.2 代码级 Hook 防护对于无法修改JVM参数的环境可通过Java Agent实现运行时防护// FastjsonProtectAgent.java import java.lang.instrument.Instrumentation; import java.security.ProtectionDomain; public class FastjsonProtectAgent { public static void premain(String args, Instrumentation inst) { inst.addTransformer((loader, className, classBeingRedefined, protectionDomain, classfileBuffer) - { if (com/alibaba/fastjson/parser/ParserConfig.replace(., /).equals(className)) { System.out.println([] 拦截ParserConfig类加载); String safeModeCode package com.alibaba.fastjson.parser;\n public class ParserConfig {\n public static boolean isSafeMode() { return true; }\n // 其他原有方法...\n }; return safeModeCode.getBytes(); } return null; }); } }部署方法编译Agent并打包为JAR在所有Java应用启动参数中添加-javaagent:/path/to/FastjsonProtectAgent.jar4. 漏洞修复与长期防护4.1 升级路径选择当前版本推荐升级路径注意事项≤1.2.24直接升级到1.2.83或v2需要全面测试业务兼容性1.2.25-47先升级到1.2.68开启安全模式再升级到1.2.83注意中间版本的autoType变更1.2.48-80直接升级到1.2.83检查是否有自定义白名单配置4.2 安全配置检查表版本验证find / -name fastjson-*.jar -exec sh -c echo -n {}: ; unzip -p {} META-INF/MANIFEST.MF | grep -E Bundle-Version|Implementation-Version \;安全模式验证// 创建安全检查脚本SecurityCheck.java public class SecurityCheck { public static void main(String[] args) { System.out.println(Fastjson安全模式状态: com.alibaba.fastjson.parser.ParserConfig.getGlobalInstance().isSafeMode()); } }网络防护策略出口防火墙禁止非常规端口如LDAP默认389/636、RMI默认1099入口WAF添加规则拦截包含type和JdbcRowSetImpl的请求5. 应急响应流程优化建立标准化的响应checklist初步评估15分钟内确定受影响系统范围评估漏洞利用可能性临时防护1小时内部署安全模式实施网络层防护彻底修复24-72小时制定升级计划业务兼容性测试持续监控# 持续监控日志中的可疑请求 tail -f /var/log/nginx/access.log | grep -E type|JdbcRowSetImpl|TemplatesImpl在实际应急过程中我们曾遇到一个典型案例某金融系统因历史原因无法立即升级通过组合使用安全模式和网络ACL规则成功阻断了攻击尝试为系统升级争取了72小时时间窗口。关键是要根据业务特点选择最适合的缓解方案同时建立多层防御体系。