Overview
Insecure deserialization often leads to remote code execution. Even if deserialization flaws do not result in remote code execution, they can be used to perform attacks, including replay attacks, injection attacks, and privilege escalation attacks.
Common vulnerable coding example
Here listed some risky points for different languages
Java
Assume we have written a vulnerable program like:
1 | import java.io.BufferedReader; |
This program deserializes the input bytes file and executes the command. So it’s possible to write the exploit poc to generate the target payload.
1 | import java.io.ObjectOutputStream; |
Compile and run this poc, the payload will be generated.
1 | root@tester code/java » javac VulAttack.java |
Now compile and run the previous vulnerable program, it will lead to RCE.
1 | root@tester code/java » javac VulnerableTaskHolder.java |
Python
Imagine the following code:
1 | import pickle |
The first serialization is to write object to file and another deserialization is to convert bytes in file to object and return it. The result will be:
1 | root@tester code/python » python3 serialize.py |
Let’s take a look at the generated bytes file:
1 | root@tester code/python » xxd file1 |
If the deserialized data is untrusted and can be changed to malicious data, it will lead to RCE. By comment serialization function and change file1 content to malicious data:
1 | cos |
It will run bash shell after running script to deserialize it, you will see bash shell open.
1 | root@tester code/python » python3 serrialize.py |
Mitigation
The best way to protect your web application from this type of risk is not to accept serialized objects from untrusted sources. If you can’t do this, there are some technical recommendations that you can try to implement:
- Implementing integrity checks such as digital signatures on any serialized objects to prevent hostile object creation or data tampering.
- Enforcing strict type constraints during deserialization before object creation as the code typically expects a definable set of classes. Bypasses to this technique have been demonstrated, so reliance solely on this is not advisable.
- Isolating and running code that deserializes in low privilege environments when possible.
- Logging deserialization exceptions and failures, such as where the incoming type is not the expected type, or the deserialization throws exceptions.
- Restricting or monitoring incoming and outgoing network connectivity from containers or servers that deserialize.
- Monitoring deserialization, alerting if a user deserializes constantly.
Reference
https://owasp.org/www-project-top-ten/2017/Top_10.html
https://sucuri.net/guides/owasp-top-10-security-vulnerabilities-2020/