| What Is Pickle? | ||||||||
|
the pickle module can serialize Python objects into a byte stream stream can be written to a file or transmitted over a network can deserialize this byte stream back into a Python object can seem to be incredibly convenient for persisting data, caching, or sending complex objects does have drawbacks |
||||||||
| How To Use Pickle | ||||||||
|
Pickle is fairly straightforward to use can serialize almost any Python object convenient to use because there is no need to build complicated serialization tools import dataclasses
import pickle
@dataclasses.dataclass
class User:
name: str
age: int
data = User(name="Flip", age=71)
pickled_data = pickle.dumps(data)
unpickled_data = pickle.loads(pickled_data)
assert data == unpickled_data
abbreviated output shown below
b'\\x80\\...\\x08__main__\\x94\\x8c\\x04User\\x94...\\x8c\\x04name\\x94...\\x8c\\x03age\\x94K/ub.'can pick out some minor details but output is difficult to read the __main__ and User fragments inform Pickle of the type it should deserialize |
||||||||
| The Dangers | ||||||||
|
||||||||
| Malicious Payloads | ||||||||
simple example of malicious payload
import os
import pickle
class Payload:
def __init__(
self,
init,
*args
):
self.init = init
self.args = args
def __reduce__(self):
return self.init, self.args
payload = pickle.dumps(
Payload(
os.system,
'echo Malicious code executed!'>
))
# writes data as a binary file
with open('payload.bin', 'wb') as f:
f.write(payload)
when payload.bin is read and unpickled the code is run
with open('payload.bin', 'rb') as f:
payload = f.read()
pickle.loads(payload)
normally __reduce__ is used to pickle how to re-instantiate the object which was serializedabove the passed constuctor is os.system and its c'tor argument below shows normal use
@dataclasses.dataclass
class User:
name: str
age: int
def __reduce__(self):
# Reduce returns the callable and args required to rebuild this class
return User, (self.name, self.age)
the malicious file
b'\x80...\x94\x8c\x06system\x94\x93\x94\x8c\x1decho Malicious code executed!\x94\x85\x94R\x94.'the malicious code tricks Pickle into processing os.system as a class which has been serialized |
||||||||
| Safer Alternatives | ||||||||
|