Deserialization can be exploited blackbox, but better not do on production server. It could cause unforeseen consequences like DOS, mass privesc, etc. Just don’t

Serialization is the process of taking an object from memory and converting it into a series of bytes so that it can be stored or transmitted over a network and then reconstructed later on. Deserialization is the reverse action: taking serialized data and reconstructing the original object

Identifying Serialization#

White-Box#

When we have access to the source code, we want to look for specific function calls to identify possible deserialization vulnerabilities quickly. These functions include (but are certainly not limited to):

  • unserialize() - PHP
  • pickle.loads() - Python Pickle
  • jsonpickle.decode() - Python JSONPickle
  • yaml.load() - Python PyYAML / ruamel.yaml
  • readObject() - Java
  • Deserialize() - C# / .NET
  • Marshal.load() - Ruby

And a whole lot more in .NET

Serializer Example Reference
BinaryFormatter .Deserialize(...) Microsoft
fastJSON JSON.ToObject(...) GitHub
JavaScriptSerializer .Deserialize(...) Microsoft
Json.NET JsonConvert.DeserializeObject(...) Newtonsoft
LosFormatter .Deserialize(...) Microsoft
NetDataContractSerializer .ReadObject(...) Microsoft
ObjectStateFormatter .Deserialize(...) Microsoft
SoapFormatter .Deserialize(...) Microsoft
XmlSerializer .Deserialize(...) Microsoft
YamlDotNet .Deserialize<...>(...) GitHub

Black-Box#

If we do not have access to the source code, it is still easy to identify serialized data due to the distinct characteristics in serialized data:

  • If it looks like: a:4:{i:0;s:4:"Test";i:1;s:4:"Data";i:2;a:1:{i:0;i:4;}i:3;s:7:"ACADEMY";} - PHP
  • If it looks like: (lp0\nS'Test'\np1\naS'Data'\np2\na(lp3\nI4\naaS'ACADEMY'\np4\na. - Pickle Protocol 0, default for Python 2.x
  • Bytes starting with 80 01 (Hex) and ending with . - Pickle Protocol 1, Python 2.x
  • Bytes starting with 80 02 (Hex) and ending with . - Pickle Protocol 2, Python 2.3+
  • Bytes starting with 80 03 (Hex) and ending with . - Pickle Protocol 3, default for Python 3.0-3.7
  • Bytes starting with 80 04 95 (Hex) and ending with . - Pickle Protocol 4, default for Python 3.8+
  • Bytes starting with 80 05 95 (Hex) and ending with . - Pickle Protocol 5, Python 3.x
  • ["Test", "Data", [4], "ACADEMY"] - JSONPickle, Python 2.7 / 3.6+
  • - Test\n- Data\n- - 4\n- ACADEMY\n - PyYAML / ruamel.yaml, Python 3.6+
  • Bytes starting with AC ED 00 05 73 72 (Hex) or rO0ABXNy (Base64) - Java
  • Bytes starting with 00 01 00 00 00 ff ff ff ff (Hex) or AAEAAAD///// (Base64) - C# / .NET
  • Bytes starting with 04 08 (Hex) - Ruby

For .NET Framework applications, we can keep an eye out for the following:

  • Base64-encoded strings beginning with AAEAAAD/////
  • Strings containing $type
  • Strings containing __type
  • Strings containing TypeObject