The 2016 SANS Holiday Hack Challenge write-up

Comme chaque année, le SANS proposait son CTF pendant les fêtes de Noël. Pour cette édition, la finalité du SANS Holiday Hack était de déterminer qui avait enlevé le Père Noël, pourquoi avait-il été kidnappé, et où avait-il été retenu prisonnier.

Pour réussir cette mission, nous devions commencer par récupérer des indices sur le compte twitter (https://twitter.com/SantaWClaus) et instagram (https://www.instagram.com/santawclaus/) du Père Noël, qui nous permettaient de récupérer une application Android nommée SantaGram. Il nous fallait également rassembler les composants d’un Cranberry PI (référence au Raspberry PI), pour nous permettre d’accéder à des challenges qui permettaient de progresser dans le jeu.

Les challenges les plus intéressant cependant concernaient l’application Android SantaGram. Outre le fait de récupérer des crédentiaux dans le code source, l’objectif final était de cracker les systèmes annexes utilisés par l’application afin de récupérer les fameux « flags ». Ces flags étaient sous la forme d’enregistrements audio découpés, que l’on devait réunir pour avoir accès aux réponses du challenge.

Le premier fichier audio se situait dans l’application Android. Une fois le fichier APK décompressé, il nous a été possible de faire une recherche par type de fichier, qui nous donnait directement accès au premier flag (1/7) : discombobulatedaudio1.mp3

Comme mentionné précédemment, les autres flags étaient répartis entre les serveurs web utilisés par l’application. Une autre recherche par mot clé, nous a permis de d’identifier rapidement ces serveurs externes :

Les 5 services externes à exploiter que l’on récupérait dans le code source de l’application étaient les suivant :

.tg {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg .tg-5mgg{font-weight:bold;background-color:#c0c0c0;vertical-align:top}
.tg .tg-yw4l{vertical-align:top}

Serveur URL Adresse IP
Mobile Analytics server analytics.northpolewonderland.com 104.198.252.157
Dungeon game dungeon.northpolewonderland.com 35.184.47.139
Debug Server dev.northpolewonderland.com 35.184.63.245
Banner Ad server ads.northpolewonderland.com 104.198.221.240
Uncaught Exception Handler server ex.northpolewonderland.com 104.154.196.33

Serveur 1 : Mobile Analytics server – analytics.northpolewonderland.com

1ère partie:

Dans un premier temps, avec les crédentiaux que l’on avait récupéré en analysant l’application Android (guest :busyreindeer78), il nous était possible de se connecter au serveur Analytics. Une fois connecté, le menu possédait un bouton MP3 pour télécharger le deuxième fichier audio (2/7): discombobulatedaudio2.mp3

2ème partie:

Pour cette deuxième partie, trouver le flag demandait un peu plus de réflexion. Lors de la phase de reconnaissance, nous avons pu identifier qu’un répertoire Git est accessible sur le serveur web via le port 445 :

Le but étant de télécharger le répertoire Git afin de pouvoir analyser ses différentes versions en local :

Une analyse du statut, nous permet de voir que de nombreux fichiers web ont été supprimés :

Grâce à la commande git checkout — . , il nous a alors été possible de récupérer ces fichiers supprimés :

Maintenant que nous avons accès au code source de l’application web, nous pouvons analyser les sources à la recherche de vulnérabilités ou d’éléments cachés nous permettant d’avancer dans le challenge.

Notre premier réflexe a été d’aller analyser le fichier Sprusage.sql à la recherche d’informations concernant la structure de la base de données. Les commentaires des différentes révisions du fichier nous indique qu’il y a eu ajout d’une authentification à un moment donné. Lorsque l’on analyse les modifications effectuées, on se rend compte que les crédentiaux d’un utilisateur « administrator » ont été «hardcodé » : administrator / KeepWatchingTheSkies

Ces crédentiaux nous ont permis d’accéder à l’interface admin de la plateforme. Un nouvel onglet « edit » est maintenant disponible :

Lorsque l’on affiche le code source de cette page, le commentaire « Don’t allow anybody to access this page (yet !) » nous indique que cette page n’est potentiellement pas terminée et pourrait contenir des failles à exploiter.

Plus bas dans ce même fichier, on peut apercevoir que le paramètre de la requête SQL est filtré par la fonction mysqli_reql_escape_string qui n’échappe que certains caractères.

En effectuant une recherche sur le mot clé « mp3 » dans le fichier de la base de données, on connait la structure de la table « audio » qui correspond très probablement à la table où est stocké notre flag.

Lorsque l’on joue avec la page « edit », le serveur nous renvoie la requête effectuée par le serveur web.

Grâce à l’analyse du code source et du fichier SQL, on peut injecter une commande dans l’URL :

Qui nous retournera le résultat suivant :

Le téléchargement direct du second fichier audio ne fonctionne pas. On a vu précédemment que le fichier mp3 était stocké en « MEDIUMBLOB », qui peut être extrait en base64 (Merci Google !).

Après modification de l’injection, l’application nous retourne le fichier audio encodé en base64.

Il ne nous reste plus qu’à décoder ce résultat pour obtenir le fichier audio (3/7) discombobulatedaudio7.mp3 .

Serveur 2 : Dungeon game – dungeon.northpolewonderland.com

Ce serveur affichait un page statique du manuel d’utilisation pour jouer au jeu Dungeon :

Après une analyse du scan NMAP sur le serveur web on pouvait voir que le port 11111 était également ouvert :

Etant donné que ce n’est pas un port standard, nous avons tenté de nous y connecter avec netcat :

Nous avons donc identifié une version online du jeu Dungeon tournant sur le port 11111. Précédemment, un Elf nous avait donné la version binaire du jeu Dungeon. Après analyse du binaire avec ltrace :

On remarque que notre première chaîne de caractères est comparée avec la chaîne « GDT » pour Game Debugging Tool.

On entre dans un mode « debug » où il est possible de modifier certaines valeurs. La commande DT permet d’afficher toutes les commentaires retournés par le jeu. Le script ci-dessous nous a permis d’afficher tous les commentaires présents dans le jeu de la version offline :

Il ne nous restait plus qu’à filtrer le résultat avec un mot clé attendu tel que « elf » pour retrouver l’indice suivant qui nous indiquait de répéter ce processus avec la version online :

Une fois cette même procédure appliquée avec la version online, on récupérait l’indice suivant :

Qui était d’envoyer un email à l’adresse peppermint@northpolewonderland.com pour récupérer le fichier audio (4/7) numéro 3 : discombobulateadio3.mp3

Serveur 3 : Debug server – debug.northpolewonderland.com

Un message d’erreur apparaît lorsque nous essayons de naviguer sur la page web:

Après analyse du code source présent dans l’application SantaGram avec Jadx, on remarque que le mode debug doit être actif pour pouvoir accéder à cette page :

Après verification dans le fichier de configuration:

On change manuellement la valeur de ce paramètre à true:

Puis on reconstruit l’application avec ce changement:

Une fois l’application générée, il nous faut également la signer. Pour cela nous avons utilise l’outil keytool pour créer notre clé, et Jarsigner pour la signer.
Maintenant nous pouvons lancer l’application avec un émulateur Android:

Une fois un nouveau compte créé (les crédentiaux récupérés précédemment ne fonctionnaient pas), nous avons analysé les requêtes échangées entre l’application et le serveur web. En capturant les paramètres de la requête avec Burp jouant le rôle de proxy, nous étions en mesure de reproduire et de modifier ces échanges à notre convenance:

Le flag verbose n’étant pas actif, nous avons rejoué la requête en forçant cette valeur à vrai qui nous a permis de récupérer d’avantage d’informations, dont le nom du fichier audio (5/7): debug-20161224235959-0.mp3 qui était accessible depuis l’adresse: dev.northpolewonderland.com/debug-20161224235959-0.mp3

Serveur 4 : Banner Ads server – ads.northpolewonderland.com

L’URL ads.northpolewonderland.com nous redirigeait sur la page web suivante:

En analysant le code source, on s’apercevait vite que le site utilisait le framework meteor. Un Elf nous avait conseillé précédemment d’utiliser le script MeteorMiner avec TamperMonkey pour analyser ce framework dans le but d’extraire toutes les informations utilisées par l’application. Après avoir navigué quelques secondes dans l’arborescence, nous sommes tombés sur le fichier audio que nous recherchions:

Nous avons donc récupéré ici notre 6ème fichier audio : discombobulatedaudio5.mp3

Serveur 5 : Uncaught Exception Handler server – ex.northpolewonderland.com

Concernant ce dernier challenge, les informations à fournir étaient retournées par le serveur web. Dans un premier temps, le serveur n’acceptait que des requêtes POST :

Dans un premier temps, le serveur web acceptait uniquement du JSON. Défini par une variable « operation » ayant pour valeur soit « WriteCrashDump » ou « ReadCrashDump », ainsi qu’une variable « data » de valeur aléatoire. Une fois la requête bien formée, le serveur nous renvoyait la valeur définie précédemment par la variable « data »:

Concernant l’opération « ReadCrashDump », le serveur retournait la valeur du crash que l’on avait initié précédemment une fois les paramètres bien établis. L’idée étant d’aller lire les informations présentes dans le fichier execption.php. Pour cela, un Elf dans le jeu nous avait donné un indice concernant la vulnérabilité PHP Local File Include qui pouvait nous être utile dans ce cas bien précis. Cette vulnérabilité permet d’exfiltrer le code source php au lieu de le parser et de l’exécuter.

Une fois le code source de la page exception.php récupéré encodé en base64, il ne nous restait plus qu’à le décoder pour obtenir le nom du dernier fichier audio présent dans un commentaire du fichier :

Le dernier fichier audio (7/7) se nommait : discombobulated-audio-6-XyzE3N9YqKNH.mp3 et était accessible à l’adresse suivante : ex.northpolewonderland.com/discombobulated-audio-6-XyzE3N9YqKNH.mp3

Une fois les 7 fichiers audio récupérés, il ne restait plus qu’à les combiner et de modifier la vitesse de lecture pour rendre le contenu audible.

Le contenu du message secret était : « Father Christmas. Santa Claus. Or, as I’ve always known him, Jeff. » tiré de « Doctor Who » A Christmas Carol.
Ce message était aussi le mot de passe de la dernière porte présente dans le jeu qui nous donnait accès à la personne qui avait kidnappé le père Noël.

Cette personne n’était autre que Dr Who en personne qui nous révélait qu’il avait enlevé le père Nöel car il avait besoin de ses pouvoirs magiques pour empêcher la sortie de « Star Wars Holiday Special ».

Pour conclure après de nombreuses heures de jeu, la diversité des challenges (application Android, application web, exploitation de binaire…) proposés par l’équipe du SANS fait de ce CTF un énième succès. Impatient de découvrir ce que leur équipe nous réserve pour l’année prochaine…

Bertrand Stivalet