Deserialization Attacks
Insecure deserialization converts attacker-supplied data into objects that trigger dangerous code paths. In Java it leads to RCE via gadget chains. In PHP it enables object injection that rides existing application logic. This post covers all major platforms.
Why Deserialization is Dangerous
When an application deserializes data, it reconstructs an object from bytes. If the reconstructed object’s class has methods that execute code during construction, comparison, or garbage collection, an attacker who controls the serialized data controls what code runs.
Java Deserialization
Detection
Java serialized objects start with the magic bytes AC ED 00 05 (hex) or rO0AB (base64).
Look for these in:
- HTTP parameters or cookies containing base64 blobs
- Java RMI endpoints (port 1099)
- JMX (port 9999)
- AMF endpoints
- HTTP request bodies
|
ysoserial — Gadget Chain Generator
|
Common Gadget Chains
| Library | Chain Name | Condition |
|---|---|---|
| Apache Commons Collections 3.1 | CommonsCollections1-6 | Common, widely found |
| Apache Commons Collections 4.0 | CommonsCollections2,4 | CC4 in classpath |
| Spring Framework | Spring1,2 | Spring in classpath |
| Apache Groovy | Groovy1 | Groovy in classpath |
| BeanShell | BeanShell1 | BeanShell in classpath |
| Hibernate | Hibernate1,2 | Hibernate in classpath |
| Clojure | Clojure | Clojure in classpath |
Testing Unknown Classpaths
Use ysoserial URLDNS chain — it only triggers a DNS lookup (no RCE attempt), safe for detection:
|
If you get a DNS callback, the endpoint deserializes. Then test specific gadget chains.
PHP Object Injection
PHP’s unserialize() reconstructs objects from strings. If user input reaches it, you can inject objects whose magic methods execute code.
PHP serialization format
|
O:4:"User"— object of classUserwith name length 42:— 2 propertiess:4:"name";s:5:"Alice"— string “name” = string “Alice”s:8:"isAdmin";b:0;— string “isAdmin” = bool false
Magic methods exploited
|
Example exploit — POP chain
Application has a logging class:
|
Craft malicious serialized object:
|
Send as the cookie or parameter that gets unserialize()d.
Tools
|
Python Pickle
Python’s pickle module can execute arbitrary code during deserialization via __reduce__.
Detection
Pickle data usually starts with \x80\x04 (protocol 4) or \x80\x02 (protocol 2) or just \x80 / (.
Creating a pickle RCE payload
|
Reverse shell via pickle
|
Send as a cookie or parameter that the server pickle.loads().
.NET Deserialization
Detection
.NET serialized data often in XML (<root type="System...), JSON with $type, or binary.
Common vulnerable points:
ViewStatein ASP.NET (base64 + MAC-protected, but exploitable if MAC key leaked)- WCF endpoints
BinaryFormatterin custom code
ysoserial.net
|
ViewState exploitation
|
Node.js — node-serialize
|
Scanning
|
Remediation
- Never deserialize untrusted data.
- For Java: use
SerialKiller,ValidatingObjectInputStream, or switch to JSON/Protobuf. - For PHP: avoid
unserialize()on user input. Use JSON instead. - For Python: never
pickle.loads()user data. Use JSON. - Implement integrity checks (HMAC) on serialized data before deserializing.
- Keep libraries updated — gadget chains are tied to specific library versions.
Discussion
Leave a comment · All fields required · No spam
No comments yet. Be the first.