deserialization-insecure

Insecure deserialization playbook. Use when Java, PHP, or Python applications deserialize untrusted data via ObjectInputStream, unserialize, pickle, or similar mechanisms that may lead to RCE, file access, or privilege escalation.

By yaklang · 3,012 installs

npx skills add yaklang/hack-skills --skill deserialization-insecure

Source repository · Upstream listing

SKILL: Insecure Deserialization — Expert Attack Playbook AI LOAD INSTRUCTION : Expert deserialization techniques across Java, PHP, and Python. Covers gadget chain selection, traffic fingerprinting, tool usage (ysoserial, PHPGGC), Shiro/WebLogic/Commons Collections specifics, Phar deserialization, and Python pickle abuse. Base models often miss the distinction between finding the sink and finding a usable gadget chain. 0. RELATED ROUTING [jndi injection](../jndi injection/SKILL.md) when deserialization leads to JNDI lookup (e.g., post JDK 8u191 bypass via LDAP → deserialization) [unauthorized access common services](../unauthorized access common services/SKILL.md) when the deserialization endpoint is an exposed management service (RMI Registry, T3, AJP) [ghost bits cast attack](../ghost bits cast attack/SKILL.md) when a WAF blocks your BCEL ClassLoader or Fastjson @type payload — Ghost Bits wraps each bytecode byte in a Unicode char whose low 8 bits match, yielding a payload the WAF cannot fingerprint Advanced Reference Also load [JAVA GADGET CHAINS.md](./JAVA GADGET CHAINS.md) when you need: Java gadget chain version compatibility matrix (CommonsCollections 1–7, CommonsBeanutils, Spring, JDK only, Groovy, Hibernate, ROME, C3P0, etc.) SnakeYAML gadget (ScriptEngineManager/URLClassLoader) with exploit JAR structure Hessian/Kryo/Avro/XStream deserialization patterns and traffic fingerprints .NET ViewState deserialization (machineKey requirement, ViewState forgery with ysoserial.net, Blacklist3r) Ruby YAML.load vs YAML.safe load exploitation with version specific chains Detection fingerprints: magic bytes table by format (Java AC ED , .NET AAEAAD , Python pickle 80 0N , PHP O: , Ruby 04 08 ) 1. TRAFFIC FINGERPRINTING — IS IT DESERIALIZATION? Java Serialized Objects Indicator Where to Look Hex ac ed 00 05 Raw binary in request/response body, cookies, POST params Base64 rO0AB Cookies ( rememberMe ), hidden form fields, JWT claims Content Type: application/x java serialized object HTTP headers T3/IIOP protocol traffic WebLogic ports (7001, 7002) PHP Serialized Objects Indicator Where to Look O:NUMBER:"ClassName" pattern POST body, cookies, session files a:NUMBER:{ (array) Same locations phar:// URI usage File operations accepting user controlled paths Python Pickle Indicator Where to Look Hex 80 03 or 80 04 (protocol 3/4) Binary data in requests, message queues Base64 encoded binary blob API params, cookies, Redis values pickle.loads / pickle.load in source Code review / whitebox 2. JAVA — GADGET CHAINS AND TOOLS ysoserial — Primary Tool URLDNS — Safe Confirmation Probe URLDNS triggers a DNS lookup without RCE — safe for confirming deserialization without damage: DNS hit on collaborator = confirmed deserialization. Then escalate to RCE chains. Commons Collections — The Classic Chain The vulnerability exists when org.apache.commons.collections (3.x) is on the classpath and the application calls readObject() on untrusted data. Key classes in the chain: InvokerTransformer → ChainedTransformer → TransformedMap → triggers Runtime.exec() during deserialization. Apache Shiro — rememberMe Deserialization Shiro uses AES CBC to encrypt serialized Java objects in the rememberMe cookie. Attack flow : 1. Detect: response sets rememberMe=deleteMe cookie on invalid session 2. Generate ysoserial payload (CommonsCollections6 recommended for broad compat) 3. AES CBC encrypt with known key + random IV 4. Base64 encode → set as rememberMe cookie value 5. Send request → server decrypts → deserializes → RCE DNSLog confirmation (before full RCE): use URLDNS chain → java jar ysoserial.jar URLDNS "http://xxx.dnslog.cn" → encrypt → set cookie → check DNSLog for hit. Post fix (random key) : Key may still leak via padding oracle, or another CVE (SHIRO 721). WebLogic Deserialization Multiple vectors: T3 protocol (port 7001): direct serialized object injection XMLDecoder (CVE 2017 10271): XML based deserialization via /wls wsat/CoordinatorPortType IIOP protocol : alternative to T3 Java RMI Registry RMI Registry (port 1099) accepts serialized objects by design: JDK Version Constraints JDK Version Impact < 8u121 RMI/LDAP remote class loading works 8u121 8u190 trustURLCodebase=false for RMI; LDAP still works = 8u191 Both RMI and LDAP remote class loading blocked = 8u191 bypass Use LDAP → return serialized gadget object (not remote class) 3. PHP — unserialize AND PHAR Magic Method Chain PHP deserialization triggers magic methods in order: Attack : craft a serialized object whose destruct() or wakeup() triggers dangerous operations (file write, SQL query, command execution, SSRF). Serialized Object Format phpMyAdmin Configuration Injection (Real World Case) phpMyAdmin PMA Config class reads arbitrary files via source property: PHPGGC — PHP Gadget Chain Generator Phar Deserialization Phar archives contain serialized metadata. Any file operation on a phar:// URI triggers deserialization — even when unserialize() is never directly called. Triggering functions (partial list): Attack flow : 1. Upload a valid file (e.g., JPEG with phar polyglot) 2. Trigger file operation: file exists("phar://uploads/avatar.jpg") 3. PHP deserializes phar metadata → gadget chain executes 4. PYTHON — PICKLE reduce Method Python's pickle.loads() calls reduce () on objects during deserialization, which can return a callable + args: Analyzing Pickle Opcodes Common Python Deserialization Sinks Defensive Bypass: RestrictedUnpickler Even when RestrictedUnpickler.find class is used, check if the whitelist is too broad: If safe builtins includes eval , exec , or import → still exploitable. 5. DETECTION METHODOLOGY 6. DEFENSE AWARENESS Language Mitigation Java JEP 290 deserialization filters; whitelist allowed classes; avoid ObjectInputStream on untrusted data; use JSON/Protobuf instead PHP Avoid unserialize() on user input; use json decode() instead; block phar:// in file operations Python Use pickle only for trusted data; use json for external input; PyYAML: always use yaml.safe load() 7. QUICK REFERENCE — KEY PAYLOADS 8. RUBY DESERIALIZATION Ruby Marshal Marshal.load on untrusted data → RCE Fingerprint: binary data, no common text header Gadget chains exist for various Ruby versions Docker verification: hex payload via [hex string].pack("H ") Ruby YAML (YAML.load) YAML.load (not YAML.safe load ) executes arbitrary Ruby objects Pre Ruby 2.7.2 : Gem::Requirement chain → git set: id / git set: sleep 600 Ruby 2.x 3.x : Gem::Installer → TarReader → Kernel system chain (longer, multi step) Always test: YAML.load(" !ruby/object:Gem::Installer\ni: x") for class instantiation check Payload template: Note: YAML.safe load is safe (Ruby 2.1+); Psych.safe load also safe 9. .NET DESERIALIZATION Traffic fingerprint : BinaryFormatter: hex AAEAAD (base64 AAEAAAD///// ) ViewState: hex FF01 or /w prefix JSON.NET: $type property in JSON BinaryFormatter (most dangerous, deprecated in .NET 5+): arbitrary type instantiation XmlSerializer : ObjectDataProvider + XamlReader chain for command execution NetDataContractSerializer : similar to BinaryFormatter, full type info in XML LosFormatter : used in ViewState, deserializes to ObjectStateFormatter JSON.NET : $type property enables type control → ObjectDataProvider + ExpandedWrapper chains Tool : ysoserial.net — generate payloads for all .NET formatters POP gadgets : ObjectDataProvider , ExpandedWrapper , AssemblyInstaller.set Path 10. NODE.JS DESERIALIZATION node serialize : unserialize() with IIFE (Immediately Invoked Function Expression) Payload marker: $$ND FUNC$$ Add () at end to auto execute: funcster : js function property → constructor.constructor to access process cryo : similar to funcster, serializes JS objects with function support RUBY DESERIALIZATION Marshal (Binary Format) YAML.load (Critical — Most Common Ruby Deser Sink) Tools elttam/ruby deserialization — Ruby gadget chain generator frohoff/ysoserial inspiration → check Ruby specific forks .NET DESERIALIZATION Traffic Fingerprinting Indicator Serializer Hex 00 01 00 00 00 / Base64 AAEAAD BinaryFormatter Hex FF 01 / Base64 /w DataContractSerializer ViewState starts with VIEWSTATE LosFormatter / ObjectStateFormatter JSON with $type property JSON.NET (Newtonsoft) TypeNameHandling XML with <ObjectDataProvider XmlSerializer / NetDataContractSerializer BinaryFormatter / LosFormatter XmlSerializer + ObjectDataProvider JSON.NET with TypeNameHandling Vulnerable when TypeNameHandling is set to Auto , Objects , Arrays , or All . Tools pwntester/ysoserial.net — primary .NET deserialization payload generator Gadget chains: TypeConfuseDelegate, TextFormattingRunProperties, PSObject, ActivitySurrogateSelectorFromFile NODE.JS DESERIALIZATION node serialize (IIFE Pattern) funcster PHP create function + Deserialization Combo 11. RUBY DESERIALIZATION Marshal YAML (CVE rich surface) Tools : elttam/ruby deserialization , mbechler/ysoserial (Ruby variant) 12. .NET DESERIALIZATION Fingerprinting Magic Bytes Format AAEAAD (base64) / 00 01 00 00 00 (hex) BinaryFormatter FF 01 or /w (base64) ViewState (ObjectStateFormatter) < (XML opening) XmlSerializer / DataContractSerializer JSON with $type key JSON.NET (TypeNameHandling enabled) BinaryFormatter (most dangerous) ViewState (ASP.NET) XmlSerializer + ObjectDataProvider JSON.NET ($type abuse) Vulnerable when TypeNameHandling != None in JSON deserialization settings. Tools pwntester/ysoserial.net — primary .NET gadget chain generator NotSoSecure/Blacklist3r — decrypt/forge ViewState with known machineKey 13. NODE.JS DESERIALIZATION node serialize (IIFE injection) funcster PHP create function + Deserialization Combo