内网不出网环境下Fastjson反序列化漏洞攻击的应急响应与流量特征分析 1. 项目概述一次典型的内部网络安全事件前几天我处理了一起让我印象深刻的内部安全事件。一个核心业务系统突然出现CPU占用率飙升、响应缓慢的情况但网络监控显示一切正常系统并未对外暴露任何端口。这属于典型的“不出网”环境下的安全事件排查起来比常规的互联网攻击要棘手得多。经过一系列分析最终定位到问题根源是应用内部一个老版本的Fastjson组件存在反序列化漏洞被内部某个已被攻陷的跳板机利用植入了内存Webshell。这种场景在金融、政务、大型企业的内网中并不少见。系统看似安全地运行在内网但一旦边界被突破攻击者在内网横向移动时这类漏洞就是绝佳的跳板。整个应急响应的过程就像一次侦探破案而“流量特征”就是现场留下的最关键的指纹。这次复盘我就重点聊聊在无法直接看到外联行为不出网的情况下我是如何从海量的内部应用流量中抽丝剥茧锁定Fastjson攻击特征的。这对于从事安全运维、应急响应的朋友来说是一个非常有价值的实战案例。2. 应急响应的核心思路与前期研判当接到系统异常告警时我的第一反应不是直奔服务器去查日志而是先建立一个清晰的排查框架。在不出网的环境中攻击者的目标通常不是直接窃取数据外传因为出不去而是进行权限维持、横向移动或作为下一步攻击的跳板。因此我的核心思路围绕以下几点展开2.1 建立“由果溯因”的排查模型异常现象是CPU高、服务慢。这可能是资源耗尽型攻击如内存马循环执行消耗CPU也可能是漏洞利用过程中执行了高负载命令如编译、文件遍历。我首先排除了业务高峰和硬件故障将焦点锁定在应用层。进程与线程分析通过top -Hp [pid]或arthas工具的thread命令查看是哪个Java线程占用了大量CPU。当时发现是几个名为“http-nio-8080-exec-xxx”的线程池线程持续高占用这提示问题很可能出在处理HTTP请求的业务逻辑上而非GC或系统线程。内存快照初步筛查使用jmap -histo:live [pid]快速查看存活对象实例。我特别注意是否有大量不常见的、与反序列化或动态类加载相关的类实例比如TemplatesImpl、Transformer数组等。虽然这次没直接发现但这步能为后续分析提供方向。网络连接确认用netstat -antp | grep [pid]仔细检查了该Java进程的所有网络连接。确认只有预期的内部服务调用如数据库、Redis和负载均衡器的健康检查连接没有陌生的、尤其是向非业务地址的TCP连接。这再次印证了“不出网”的判断。注意所谓“不出网”严格来说是指没有主动向互联网或非授权内网地址发起连接的能力。但攻击者可能使用DNS、ICMP、HTTP代理隧道等更隐蔽的方式外联。在初期我们基于常规TCP连接判断可以快速缩小范围。2.2 锁定关键数据源应用日志与网络流量在不出网环境下攻击痕迹主要留存在两个地方应用日志和内部网络流量。很多运维会优先看日志这没错但高明的攻击者会清理或绕过日志记录。因此网络流量镜像分析成为了不可或缺甚至更可靠的手段。我立即协调网络团队在核心交换机上对异常服务器的业务网卡进行了流量镜像将流量导到我的安全分析平台。同时我开始收集应用日志如Tomcat的localhost_access_log、应用自身的业务日志。我的策略是流量分析为主日志验证为辅。因为流量是原始通信的复现难以被彻底抹除。3. 核心流量特征解析如何识别Fastjson攻击流量抓取下来后面对的是海量的HTTP数据包。如何快速定位恶意流量这就需要我们对Fastjson反序列化漏洞的利用流量特征有深刻的理解。根据公开的漏洞利用方式和实战经验我总结了以下几个关键特征点进行筛查3.1 特征一HTTP POST请求体中的“type”标志这是Fastjson反序列化漏洞最直接、最核心的特征。Fastjson在解析JSON时如果启用了AutoType功能早期版本默认开启攻击者可以通过在JSON对象中设置type属性指定一个任意的、应用ClassPath中存在的类名Fastjson会尝试实例化这个类。在流量中如何识别请求方法通常是POST请求因为攻击PayloadJSON数据放在请求体Body中。Content-Type一般为application/json这是标准JSON API的格式本身无异常。请求体内容你需要仔细查看POST数据。恶意Payload的JSON结构里根对象或嵌套较深的对象中会有一个键名为type其值是一个完整的Java类名。例如{ type: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl, _bytecodes: [yv66vgAAADQA...base64编码的恶意字节码], _name: a.b, _tfactory: {}, _outputProperties: {} }或者利用Tomcat DBCP的{ type: org.apache.tomcat.dbcp.dbcp2.BasicDataSource, driverClassName: com.mysql.jdbc.Driver, driverClassLoader: {type: com.sun.org.apache.bcel.internal.util.ClassLoader}, connectionProperties: userxxx;passwordxxx;... }实操心得在Wireshark或流量分析系统里你可以直接过滤HTTP POST请求 (http.request.method POST)然后追踪TCP流查看HTTP请求体。用搜索功能在整个抓包文件中搜索type这个关键字效率极高。但要注意正常的业务请求也可能包含type字段如果业务设计如此所以需要结合类名进行判断。3.2 特征二异常的Java类名与依赖利用链光有type不够关键看它指向什么类。攻击者利用的类通常具有以下特点非常用业务类如com.sun.*,org.apache.xalan.*,org.apache.tomcat.dbcp.*等。这些是JDK或中间件自带的类正常业务逻辑极少会直接通过JSON反序列化来构造它们。涉及类加载或代码执行如TemplatesImpl用于加载字节码、BasicDataSource用于触发类加载器加载恶意驱动。在流量中你会看到这些类名后面跟着一大串经过Base64编码的_bytecodes字段或者包含driverClassLoader等用于指向恶意类加载器的属性。排查技巧我整理了一个“黑名单类名”列表在流量分析工具中设置告警规则。一旦发现POST数据中出现这些类名立即高亮标记。例如com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImplorg.apache.tomcat.dbcp.dbcp2.BasicDataSourceorg.apache.tomcat.dbcp.dbcp.BasicDataSource(Tomcat 8.0以下)com.sun.rowset.JdbcRowSetImpl(JNDI注入利用链但在不出网环境可能失效)3.3 特征三Payload的编码与结构特征攻击Payload为了绕过WAF或隐藏意图经常进行编码处理。Base64编码_bytecodes字段的值通常是很长的一段Base64字符串这是Java字节码.class文件编码后的结果。在流量中表现为一串由A-Z, a-z, 0-9, , /, 组成的密集字符段非常醒目。Hex编码有时也会使用16进制编码。嵌套结构利用链往往需要多个对象嵌套。例如BasicDataSource利用方式中driverClassLoader本身又是一个包含type的JSON对象。在流量中你会看到多层嵌套的大括号{}结构。分析方法在Wireshark中你可以使用json显示过滤器它会尝试将TCP流解析为JSON并格式化显示这样嵌套结构一目了然。对于Base64部分可以右键选择“导出分组字节流”到一个文件然后用base64 -d命令解码再用file命令查看是否是Java类文件通常显示为“compiled Java class data”。3.4 特征四关联的Webshell流量特征Fastjson漏洞利用成功后攻击者通常会植入一个Webshell以便持久化控制。在不出网环境下这个Webshell的通信流量也混杂在内部HTTP流量中。需要结合已知的Webshell工具流量特征进行关联分析。冰蝎Behinder特征静态路径可变参数请求URL路径通常固定如/upload/test.jsp但每次请求的参数密码、命令不同。Content-Type异常POST请求的Content-Type常为application/octet-stream或application/x-www-form-urlencoded但请求体是加密的二进制数据或乱码。Accept头等长冰蝎客户端的Accept、Accept-Language等头部信息长度固定而浏览器请求的这些头部长度会因环境略有变化。连接保持Connection: keep-alive且会话时间较长。哥斯拉Godzilla特征Cookie尾部有分号早期版本在Cookie值的末尾会多一个分号;这是一个比较独特的特征。三次响应哥斯拉的服务端响应包有时会连续收到多个如3个TCP包这与普通HTTP请求的响应模式不同。Payload加密流量全程加密无明文但加密后的数据块大小可能呈现规律性。关联分析实战在本次事件中我首先通过type特征锁定了攻击注入的时间点例如某日10:05:23。然后我以这个时间点为起点向后分析同一源IP攻击者内网跳板机对同一目标服务器的后续请求。很快我就发现了一个固定的URL路径如/api/v1/health这是一个原本就存在的健康检查接口被当作了Webshell的隐藏路径在频繁被访问且其POST请求的流量特征如固定的Content-Type: application/octet-stream与冰蝎高度吻合。这就形成了完整的攻击证据链利用Fastjson漏洞注入内存马 - 通过内存马访问特定路径实现Webshell功能。4. 完整的应急响应与取证操作流程基于以上的特征分析我梳理出了一套针对此类不出网Fastjson攻击的标准化应急流程。这套流程不仅用于本次事件的处理也成为了我们团队后续的响应手册。4.1 第一步紧急抑制与隔离发现确凿攻击流量后首要任务是止损。网络隔离立即在防火墙或交换机上添加策略阻断攻击源IP那个内网跳板机对受害服务器的所有访问。如果暂时无法精确定位可以考虑将受害服务器从业务集群中临时下线或限制其只接受来自管理网段的访问。进程保留切勿立即重启服务重启会清空内存导致内存Webshell等驻留内存的证据丢失。应该先保存现场。使用jmap -dump:live,formatb,fileheap.bin [pid]导出完整的堆内存快照。使用jstack -l [pid] thread.txt导出线程栈信息。使用arthas的jad、sc、sm命令动态反编译和查看已加载的类寻找可疑的内存马类。4.2 第二步深度取证与漏洞确认隔离后进行深入分析确定漏洞点和影响范围。分析内存快照使用MAT或JProfiler加载heap.bin文件。重点搜索可疑的类名如包含shell、memshell、filter、agent等关键词的类。查找javax.servlet.Filter或javax.servlet.Servlet的实现类实例检查其filterChain或servlet字段是否被替换成了恶意类。查看TemplatesImpl或动态生成的类加载器实例。检查应用依赖进入服务器查看应用部署目录下的WEB-INF/lib/或检查项目的pom.xml确认Fastjson的版本。版本号 1.2.80的都存在已知的高危反序列化漏洞。使用shaded打包方式可能会重命名包路径需要仔细核对。日志回溯结合攻击时间点翻看应用日志、Tomcat访问日志寻找是否有相关的错误堆栈信息。有时漏洞利用不成功也会留下ClassNotFoundException或NoClassDefFoundError的日志这同样是重要的攻击证据。Webshell文件排查虽然攻击者可能只用了内存马但仍需检查Web目录下是否有新增的、可疑的JSP、JSPX或静态文件如图片、文本文件可能用于存放加密的Payload。使用find命令结合文件修改时间-mtime和特征字符串-exec grep -l进行查找。4.3 第三步漏洞根除与系统恢复取证完成后开始清理和修复。清除内存马最彻底的方法是重启应用服务器。重启前确保已备份所有取证数据。如果条件不允许立即重启可以考虑使用Java Agent工具如Java-Memshell-Scanner进行动态检测和清除但这需要较高的技术门槛且可能不彻底。升级/修复Fastjson首选方案将Fastjson升级到最新安全版本如1.2.83及以上。新版本默认关闭了AutoType并提供了安全的白名单机制。临时加固如果无法立即升级可以在启动JVM时添加以下参数来全局关闭AutoType-Dfastjson.parser.autoTypeSupportfalse。同时在代码中明确指定ParserConfig.getGlobalInstance().addAccept(你的包名.)来设置严格的白名单。修复被利用的跳板机通知相关团队对攻击源IP内网跳板机进行彻查清除其上的后门修复其自身的安全漏洞防止攻击再次发生。恢复服务在完成漏洞修复、安全加固如增加WAF规则、配置RASP防护后将服务器重新上线并持续监控一段时间。4.4 第四步复盘与加固建议事件处理完毕必须进行复盘提升整体安全水位。规则沉淀将本次发现的攻击流量特征如特定的type类名、Webshell的HTTP头特征固化到IDS/IPS、WAF或流量审计系统中形成检测规则。资产梳理在全公司范围内扫描所有Java应用建立Fastjson组件使用清单强制要求升级或制定迁移计划。安全开发规范推动研发团队在反序列化操作中使用更安全的Jackson配置ObjectMapper禁用危险特性或Gson。如果必须使用Fastjson强制要求开启SafeMode或配置精确的白名单。纵深防御在不出网环境中同样需要部署主机安全HIDS、RASP等产品。RASP能在应用运行时深度检测反序列化等危险行为即使流量加密也能有效防护。5. 常见问题排查与实战技巧实录在实际操作中总会遇到一些预料之外的情况。这里记录几个我踩过的坑和总结的技巧。5.1 问题一流量太大如何快速定位可疑数据包场景全流量镜像一天可能产生TB级数据逐包分析不现实。技巧时间范围聚焦根据系统异常开始的时间点前后截取15-30分钟的流量包进行分析。协议与端口过滤先过滤出目标服务器业务端口如80、8080、8443的HTTP/HTTPS流量。tcp.port 8080 http。请求方法过滤重点关注POST请求特别是请求体较大的POST请求。http.request.method POST http.content_length 500阈值可根据业务调整。关键字搜索在过滤后的数据包中直接搜索关键词如type、TemplatesImpl、BasicDataSource、_bytecodes、记住我针对Shiro等。Wireshark支持在分组字节流中搜索。使用专业工具Suricata、Zeek等NIDS工具可以实时解析流量并应用规则。你可以编写自定义规则来匹配Fastjson特征。例如一个简单的Suricata规则思路alert http any any - any any (msg:Potential Fastjson Exploit; http.method; content:POST; http.header; content:application/json; pcre:/type\\s*:/; sid:1000001;)。5.2 问题二攻击Payload被GZIP压缩了怎么办场景请求头显示Content-Encoding: gzip导致请求体是乱码无法直接看到type。解决Wireshark自动解码Wireshark通常能自动解码GZIP压缩的HTTP Body。确保在Preferences - Protocols - HTTP中启用了“解压GZIP内容”的选项。解码后就可以像查看明文一样查看JSON内容了。手动解压如果工具没有自动解压你可以将HTTP请求体的原始字节从Content-Length后开始到TCP流结束复制出来保存为.gz文件然后用gzip -d命令解压或者使用Python的gzip模块解压查看。5.3 问题三如何区分恶意的type和业务正常的type场景有些基于JSON-RPC或自定义协议的系统也会使用type字段来标识对象类型。鉴别方法类名白名单与业务研发确认系统合法的type值有哪些。通常只允许如com.company.project.dto.User这样的业务DTO类。任何超出此名单的特别是JDK、第三方库的类都应视为高危。上下文分析观察包含type的请求发生的频率、来源IP、时间。一次性的、来自非常规IP的、在非业务时间发生的请求恶意可能性极高。参数分析恶意Payload的type对象后面通常会跟随着_bytecodes、driverClassLoader等与类加载、代码执行强相关的属性。而业务对象的属性都是业务字段如username、orderId等。5.4 问题四内存马排查有哪些高级技巧场景重启服务器后所有内存证据消失但担心攻击者留有后门文件或计划任务。高级排查计划任务与服务检查系统的crontab (crontab -l)、systemd服务 (systemctl list-units --typeservice)、以及/etc/init.d/等目录看是否有新增的、可疑的定时任务或服务。进程文件映射使用lsof -p [pid]或pmap [pid]查看Java进程打开的文件和内存映射。关注是否有从/tmp、/dev/shm等临时目录加载的JAR或Class文件。Java Agent检测使用jcmd [pid] VM.command_line查看JVM启动参数检查是否有未知的-javaagent参数。也可以检查$JAVA_HOME/lib和$JAVA_HOME/jre/lib目录下的instrument相关JAR包是否被篡改。网络连接深度检查使用ss -antp或netstat结合lsof不仅看ESTABLISHED状态的连接还要看LISTEN和CLOSE_WAIT状态的连接。有些后门会绑定一个本地端口等待连接。处理这次不出网的Fastjson漏洞攻击让我深刻体会到在纵深防御体系中流量分析能力就像安全人员的“火眼金睛”。尤其是在内网环境中攻击者以为隐藏在网络边界之后就可以为所欲为殊不知其攻击动作在流量层面会留下难以磨灭的痕迹。掌握这些漏洞和工具的流量特征构建基于流量的实时检测与回溯能力是从被动响应转向主动防御的关键一步。这件事之后我们团队花了大力气优化了内部的流量审计平台将Fastjson、Log4j2、Shiro等常见漏洞的利用特征都做成了自动化的检测规则现在再有类似的情况告警会在几分钟内就发出来响应效率提升了不止一个量级。