SuperAPI AI 工具集

exploiting-deserialization

安全与审计

查看项目

更新于 10-16 03:24

技能介绍

用途

反序列化会把攻击者可控的字节转换为带有攻击者指定类型的活对象。该技能的目标是识别不安全反序列化的存在,并在获得授权的前提下验证其可被利用。文档强调,漏洞并不在于解析动作本身,而在于构造这些对象时会执行开发者从未预期的代码路径;因此工作需要先识别格式,再在目标类路径中寻找 gadget chain。

何时使用与不使用

适用迹象包括:Cookie、参数、头部或消息体中出现序列化对象;流量或存储中出现文档列出的魔术值;源码审查发现 readObject、unserialize、pickle.loads、Marshal.load、BinaryFormatter、yaml.load 或 ObjectInputStream;消息队列、缓存或会话存储保存序列化对象;需要确认疑似盲反序列化。

不适用场景:仅做 JSON/XML 解析而不实例化对象;以源码审查为主要任务;在证明影响之外构建武器化 payload;分析使用反序列化的恶意软件。

文档明确要求仅针对获得授权测试的系统。

格式识别

魔术字节可判断运行时,而运行时的不同决定整个思路:Java 序列化 Base64 前缀 rO0AB、原始字节 AC ED 00 05;.NET BinaryFormatter 前缀 AAEAAAD/////、字节 00 01 00 00 00 FF FF FF FF;.NET LosFormatter/ViewState 常为 /wEP;PHP serialize() 为 Tzo、YTo(O:、a:);Python pickle 为 gAJ、gASV、KGRw(80 04、80 02、(dp);Ruby Marshal 为 BAh(04 08);Java Hessian/Burlap 为 Yw(63/48);带标签的 YAML 则为 !!python/object、!ruby/object。Java 序列化流中包含明文类名,可用于确认是否为反序列化以及涉及哪些库。

Java 利用

使用 ysoserial 针对目标类路径上存在的链生成 payload,例如 CommonsCollections6、CommonsBeanutils1。文档强调总是先使用 URLDNS:它只依赖 JDK 类,只要发生反序列化就能工作;DNS 命中确认漏洞存在后,才值得去猜测 gadget chain。确定类路径的方法包括:错误消息与堆栈中的库类名、gadgetprobe(Burp)通过错误行为差异探测类是否存在、以及从应用其他响应做版本指纹。常见链及其依赖:CommonsCollections1–7(commons-collections 3.x/4.x)、CommonsBeanutils1、Spring1/2、Groovy1、Hibernate1、Jdk7u21(无需额外库但 JDK 范围窄)、ROME、C3P0。此外,Java 反序列化还可经 JNDI 触达远程类加载(Log4Shell 机制),较新 JDK 对此有限制,需先确认版本。

.NET 利用

ysoserial.net 中 formatter 与 gadget 同等重要。易受影响的 formatter 包括:BinaryFormatter、LosFormatter、NetDataContractSerializer、ObjectStateFormatter、SoapFormatter,以及 TypeNameHandling 不为 None 时的 Json.NET/XmlSerializer。其中最后一种在现代代码中最常见:TypeNameHandling.All 或 .Objects 允许 JSON 自带 $type。ViewState 是 ASP.NET 的经典情况,当 MAC 密钥已知(web.config 泄露、已知默认值,或旧版本 enableViewStateMac="false")时可利用,需先提取 validationKey 与 decryptionKey。

PHP、Python、Ruby

PHP:反序列化期间及之后会触发的魔术方法包括 __wakeup()、__destruct()、__toString()、__call()、__get()。可用 PHPGGC 覆盖常见框架链,如 Laravel/RCE9、Monolog/RCE2(-b 输出 base64)。Phar 反序列化是容易被低估的向量:任何作用于 phar:// 路径的文件系统函数(file_exists、filesize、is_dir 等)都会触发对 phar 元数据的 unserialize,代码中无需出现明显的 unserialize()。

Python:pickle 按设计即可执行任意代码,并非解析器缺陷;可通过 reduce 构造 RCE payload。还需检查未使用 SafeLoader 的 yaml.load()、jsonpickle、dill、shelve、allow_pickle=True 的 numpy.load,以及任何以 pickle 为底层的 ML 模型格式。

Ruby:Marshal.load 处理不可信输入;Rails 与常见 gem 存在 gadget chain;另外还需注意 YAML.load(Psych-4 之前的默认行为)以及 secret_key_base 泄露的 Rails cookie store。

盲测与带外确认

多数真实场景没有回显,因此应先确认再投入构建链。主要确认手段包括:DNS/HTTP 回调(Java URLDNS、PHP 中会访问 URL 的链、Python os.system 调用 curl);时间侧信道(出口被封时用 sleep 类 payload 证明执行);错误差异(畸形对象与类型错误但结构完整的对象产生不同异常,可确认解析但未执行)。文档指出,一次带外交互即可证明反序列化发生,这本身就是发现;升级到完整 shell 往往并非必要且会增加风险。

序列化数据藏匿位置

除明显的请求参数外,还包括:会话 Cookie 与 remember-me 令牌;被 worker 消费的消息队列(RabbitMQ、Kafka、SQS);缓存(Redis、Memcached、Ehcache);由后台任务处理的文件上传;服务间 RPC(RMI、JMX、JNDI、T3(WebLogic)、IIOP);保存序列化 blob 的数据库列;被日志处理器重新读取的日志。队列与缓存场景价值最高,因为消费方通常比 Web 层权限更高,且通常没有代理。

应拒绝的常见理由

文档列举了若干需要驳回的认知,例如“反序列化前会校验输入”(校验序列化 blob 几乎不可能,类型在 blob 内部)、“没有 unserialize() 调用”(PHP 查 Phar,Java 查 RMI/JMX/JNDI,.NET 查 TypeNameHandling)、“没有可用链所以不脆弱”(URLDNS 可独立于类路径确认反序列化)、“是签名 Cookie 所以无法篡改”(仅当密钥保密;需查泄露或默认密钥)、“库已打补丁”(补丁只移除特定 gadget,sink 仍在且新链持续出现)、“是内网只有我们的服务发送”(队列与缓存可达面更广)、“只有 DNS 命中没有 shell 所以低危”(已确认的反序列化 sink 属高危,应按此上报)。

适用场景与限制

该技能面向安全测试、漏洞赏金与红队工作,用于在获得授权的前提下识别并证明不安全反序列化。文档要求仅在授权系统上使用,强调先确认后利用。目前资料未提供关于收费、价格或平台支持范围的信息。