FCSC 2023 - Salty Auth
Enonce
Le lien nous redirige directement ici:
On va devoir vérifier les 2 conditions afin de pouvoir afficher le flag.
Conditions
Nous devons:
- Trouver la longueur du mot de passe
- Générer une collision entre fnv164(password) == fn16v4(hostname+salt)
Longueur du password
Si l’on fournit en GET
un parametre ?password=test
les comparaisons échouent et le même code source est affiché.
Voici un petit script pour trouver la longueur:
|
|
Nous trouvons une longueur de 36
.
Bien, toutefois le salt
inconnu est bien embêtant …
On pourrait bruteforcer pendant des heures avec ce genre de script mais c’est interdit:
|
|
Leak du hostname via phpinfo() ?
Le principal souci pour vérifier la 2nde condition est que nous ne connaissons ni hostname, ni salt.
Nous allons trouver hostname
, vous verrez l’utilité dans la partie suivante.
En me repenchant dessus j’ai trouvé une vulnérabilité: on peut appeler une certaine fonction log_attack
lors de l’exit():
|
|
Et récupérer le hostname:
Réinitialisation du salt via extract()
Une fonction saute au yeux dans ce code, à quoi sert-elle?
|
|
Ici réside ce qui nous permettra d’outrepasser la 2nde condition. On trouve rapidement quelques ressources sur extract:
- https://github.com/HackThisSite/CTF-Writeups/blob/master/2016/SCTF/Ducks/README.md
- https://davidnoren.com/post/php-extract-vulnerability/
PHP has a function named extract() to take all provided GET and POST requests and assign them to internal variables. Developers will, at times, use this function instead of manually assigning $_POST[var1] to $var1. This function will overwrite any previously defined variables, including server variables.
Ici nous allons par la register global $SERVER.
En échouant la vérification nous allons pouvoir écraser le variable salt
.
Grâce à extract on peut:
- préciser notre password
- écraser le salt afin de contrôler la loose comparison.
On remarque tout de suite la 2nde condition if (hash('fnv164', $password) == hash('fnv164', $secret))
:
Voici un script permettant de trouver un password de 36 caractères pour forcer une Loose comparison
|
|
Résumons:
|
|
Tada!!