Text Adventure API
Challenge
A text-adventure API that lets you save and load your session. The load endpoint takes a file upload and the only validation is the extension:
| |
After that it runs pickle.loads on the contents. Unpickling untrusted data is remote code execution.
Approach
pickle calls __reduce__ during deserialization to decide how to rebuild an object. A class that returns (eval, (some_string,)) from __reduce__ runs eval(some_string) the moment the file is loaded. The save endpoint hands the pickled session back, so the plan is to make the loaded object carry the flag in a field, then read it out of the saved response.
Solution
| |
Loading the pickle evaluates the dict expression, setting current_location to the contents of flag.txt. Calling /save returns that session, and the flag comes back in current_location.