[WARGAME NDH 2016] Write-Up – Web: Sticky! Sticky!

04
juil.
2016
  • Google Plus
  • LinkedIn
  • Viadeo
Posted by: Yann C.  /   Category: CTF / Events / NDH / NDH2k16 / OS / Vulnérabilités, exploits et PoC / Wargame   /   Un commentaire

Présentation d’un write-up de résolution du challenge « Web – Sticky! Sticky! » du WARGAME de la Nuit du Hack 2016.

Le weekend du 02-03 juillet 2016 se déroulait le WARGAME de la Nuit du Hack 2016 sous forme d’un CTF Jeopardy. Ayant eu l’occasion et le temps d’y participer avec quelques collègues et amis, voici un write-up de résolution d’un des challenges auquel nous avons pu participer.

  • Catégorie : Web
  • Nom : Sticky! Sticky!
  • Description : HEY! Welcome back!
    • Hint 1 : check all the cookies!!!
    • Hint 2 : resolution is in base32
  • URL : http://sticky.wargame.ndh
  • Points : 250

Vu le nom du challenge, « sticky », on se doute qu’une notion de cookie et de « persistance » va entrer en jeu…

En se rendant à l’URL du challenge, nous étions invités à renseigner un nom d’utilisateur :

Sticky-Sticky login page

Sticky-Sticky login page

Dès lors qu’un login était indiqué, une simple page « Welcome back » était affichée avec une réflexion du login :

Sticky-Sticky connected

Sticky-Sticky connected

En observant plus en détail les requêtes, nous avons un cookie de défini :

GET /index.php HTTP/1.1
Host: sticky.wargame.ndh
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Cookie: user_id=553241; validator=validator.wargame.ndh; resolution="YCUAACI="
Connection: close
  • user_id : l’identifiant de l’utilisateur qui s’incrémente (généré côté serveur)
  • validator : un nom d’hôte privée de « validation »
  • resolution : une valeur encodée, en Base64 ? (l’obtention du second « hint » du challenge indiqua qu’elle était en Base32 finalement…).

En testant divers encodage / décodage en Base64 de la valeur « resolution », aucune information pertinente n’est révélée, mis à part des erreurs intéressantes (également visible après de multiples exécution de la requête) :

DNS resolution error

DNS resolution error

Dans le cas où l’on modifie la valeur du cookie « validator », on obtient une erreur de tentative d’hijack :

Hijack validator

Hijack validator

On poursuit les tests en tentant d’injecter un payload au travers du login. Mis à part une petite XSS persistante, rien d’exploitable :

XSS in Sticky! Sticky!

XSS in Sticky! Sticky!

La présence de cette XSS, stockée côté serveur (bien que les réponses paraissaient derrières un load-balancer), a permis à un malicieux troll d’injecter un faux-flag qui en a dérouté plus d’un ^^ ! Bien joué 😉 !

D’après les erreurs précédentes et les hints, on en déduit plusieurs choses :

  • Le frontend est une simple application web de connexion et de réflexion d’un login
  • Le login (et ses privilèges) semblent vérifiés auprès d’un domaine tiers inaccessible « validator.wargame.ndh », dont nous avons la main au travers des cookies
  • Nous avons également la main sur le « user_id » via les cookies, valeur qui, positionnée à « 1 », permet d’afficher un « Welcome admin! »
  • L’hôte de validation « validator.wargame.ndh » semble en écoute sur le port « 8888 » comme indiqué dans le précédent message d’erreur
  • Lorsqu’on altère la valeur encodée « resolution » au travers des cookies, on a un message d’erreur lié à la résolution DNS de l’hôte « validator.wargame.com ». Serait-ce l’adresse arbitraire du « name server » de résolution DNS ?

Tentons d’intérroger le serveur « sticky.wargame.ndh » sur le port 8888 lui-même :

GET / HTTP/1.1
Host: sticky.wargame.ndh:8888
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Cookie: user_id=553241; validator=validator.wargame.ndh; resolution="YCUAACI="
Connection: close

Réponse :

HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Sun, 03 Jul 2016 01:32:06 GMT
Content-Type: text/plain; charset=utf-8
Connection: close
Content-Length: 25

{"admin": 0, "name": "0"}

La résolution du challenge nécessite très certainement de forcer cette réponse avec un « admin:1 » !

Intéressons nous d’avantage à la valeur du cookie « resolution », qui, suite à la délivrance du second « hint », s’avère être en Base32 :

  • Valeur par défaut : YCUAACI=
  • Base32 to Hex : C0A80009
  • ASCII : [192][168][0][9]

C’est donc une IP qui est encodée dans le champ « resolution » du cookie ! Tout devient censé :

Une requête émise vers l’application avec le cookie engendre les actions suivantes :

  • Le serveur web interroge le serveur de nom (NS) dont l’IP est encodée en Base32, transmis dans le cookie « resolution ». Valeur par défaut : 192.168.0.9.
  • Le serveur demande au NS l’IP correspondant au domaine indiqué dans le cookie « validator » : « Quelle est l’IP correspondante au domaine validator.wargame.ndh ? »
  • Le serveur d’IP correspondante est interrogé sur le port 8888 pour valider le nom d’utilisateur. Ce serveur web retourne du JSON de type :
{"admin": 0, "name": "admin"}
Sticky! Stycky normal behavior

Sticky! Stycky normal behavior

Côté client, nous avons la main pour se faire passer pour ce serveur de noms, ce serveur de validation, et forcer une validation JSON avec :

{"admin": 1, "name": "admin"}

Mon poste, connecté au réseau du Wargame de la NDH, avait pour IP : 172.16.16.250, soit en hexadécimal : AC1010FA et donc en Base32 : VQIBB6Q= (convertisseur disponible ici).

La nouvelle valeur du cookie « resolution » sera donc VQIBB6Q=. Le serveur web cherchera à résoudre le nom d’hôte indiqué dans « validator » sur le NS qui sera finalement ma machine 172.16.16.250.

Il me faut donc transformer mon poste en tant que serveur DNS. Pour cela :

apt-get install dnsmasq
echo validator.wargame.ndh 172.16.16.250 >> /etc/hosts
/etc/init.d/dnsmasq start

C’est chose faite !

Maintenant que la résolution DNS de l’hôte « validator.wargame.ndh » est faites par mon poste, et qu’elle pointe sur mon poste, il ne reste plus qu’à monter un petit serveur web sur le port 8888 qui renverra le JSON « admin:1 » :

mkdir sticky
cd sticky
vi 1 # {"admin":1,"name":"admin"}
python -m SimpleHTTPServer 8888

Notre serveur web est lancé sur le port 8888, et un fichier « 1 » délivre le JSON adéquat pour devenir admin.

Il ne reste plus qu’à réaliser la dernière requête vers « sticky.wargame.ndh », avec comme cookie :

  • user_id=1 : l’admin
  • validator=validator.wargame.ndh : qui sera résolu part notre propre serveur de nom
  • resolution=VQIBB6Q= : l’IP en Base32 de notre serveur de nom
Stikcy flag

Stikcy flag

Bingo ! Flag : ndh2k16_e5f3eb90c4438c1a062125e3f74c2b41

Sticky! Sticky! PWN !

Sticky! Sticky! PWN !

Merci à toute l’équipe de la NDH2K16 pour cet événement et pour toute l’organisation !

Salutations à nj8, St0rn, Emiya, Mido, downgrade, Ryuk@n et tout ceux dont je n’ai hélas pas le pseudo :), on remet ça quand vous voulez 😉 // Gr3etZ

Sources & ressources :

  • Google Plus
  • LinkedIn
  • Viadeo
Yann C.

About the Author : Yann C.

Consultant en sécurité informatique et s’exerçant dans ce domaine depuis le début des années 2000 en autodidacte par passion, plaisir et perspectives, il maintient le portail ASafety pour présenter des articles, des projets personnels, des recherches et développements, ainsi que des « advisory » de vulnérabilités décelées notamment au cours de pentest.