jeudi 29 janvier 2015

FIC Challenge Writeup, EPITA edition

Les solutions du challenge EPITA – réalisé par des élèves pour le FIC 2015 – sont désormais en ligne, mais uniquement sous forme de vidéos. Je vais donc vous proposer une solution pour la catégorie "Virus", plus old school car sous la forme d’un billet de blog.

La question posée

Tout commence par un dump mémoire de 1 Go, qu'on identifie assez facilement comme étant issu d'un système Windows 32 bits:
$ file MEMORY.DMP
MEMORY.DMP: MS Windows 32bit crash dump, PAE, full dump, 262014 pages

Ce fichier est accompagné d'une signature au format ".nbd" (utilisé par ClamAV):
virus=60400001000000EB9490909090565383EC14C7042430604000E8B70700008B1D4860400083EC0485DB742D66908B03890424E8A607000083EC0489C6E8

On imagine assez bien qu'il va falloir retrouver cette signature dans le dump mémoire. Deux outils s'offrent à nous: WinDbg ou Volatility. Je choisis Volatility, qui est quand même plus adapté au forensics.

Identifions plus précisément le "profil" du système à l'aide de la commande imageinfo:

Determining profile based on KDBG search...
Suggested Profile(s) : Win7SP0x86, Win7SP1x86 AS Layer1 : IA32PagedMemoryPae (Kernel AS) AS Layer2 : WindowsCrashDumpSpace32 (Unnamed AS) AS Layer3 : FileAddressSpace (MEMORY.DMP) PAE type : PAE DTB : 0x3ecd8680L KDBG : 0x82938be8 Number of Processors : 1 Image Type (Service Pack) : 0 KPCR for CPU 0 : 0x82939c00 KUSER_SHARED_DATA : 0xffdf0000 Image date and time : 2014-11-17 13:25:46 UTC+0000 Image local date and time : 2014-11-17 14:25:46 +0100

Une fois le bon profil identifié, il est possible de lister tous les processus en cours d'exécution avec la commande pslist ou pstree. La commande psscan permet de retrouver également les processus récemment exécutés dont le jeton persiste en mémoire, mais dans le cas présent seul consent.exe est concerné (qui présente la fameuse boite de dialogue "Cancel or Allow").

Offset Name Pid PPid Thds Hnds Time
> 0x84138b78 System 4 0 90 532 2014-11-15 12:49:59 UTC+0000
> 0x85359d40 smss.exe 260 4 2 29 2014-11-15 12:49:59 UTC+0000
> 0x85ad2d40 csrss.exe 348 332 9 549 2014-11-15 12:50:00 UTC+0000
> 0x85a7cc88 wininit.exe 400 332 3 74 2014-11-15 12:50:00 UTC+0000
> 0x85cd6030 services.exe 500 400 9 213 2014-11-15 12:50:00 UTC+0000
> 0x85e8aad0 msdtc.exe 436 500 12 143 2014-11-15 12:50:06 UTC+0000
> 0x85d17658 svchost.exe 632 500 11 365 2014-11-15 12:50:01 UTC+0000
> 0x8434fb30 dllhost.exe 2660 632 6 80 2014-11-17 13:25:36 UTC+0000
> 0x85d4a138 svchost.exe 712 500 8 292 2014-11-15 12:50:01 UTC+0000
> 0x85d6aa30 svchost.exe 800 500 19 507 2014-11-15 12:50:01 UTC+0000
> 0x8433fc88 audiodg.exe 1280 800 7 150 2014-11-15 13:05:54 UTC+0000
> 0x85da6030 svchost.exe 884 500 14 341 2014-11-15 12:50:01 UTC+0000
> 0x85ebed40 dwm.exe 1160 884 6 199 2014-11-15 12:50:06 UTC+0000
> 0x85db3530 svchost.exe 916 500 34 1067 2014-11-15 12:50:01 UTC+0000
> 0x85e1f530 svchost.exe 1036 500 14 387 2014-11-15 12:50:01 UTC+0000
> 0x85e7b030 svchost.exe 1148 500 19 509 2014-11-15 12:50:01 UTC+0000
> 0x85f00880 spoolsv.exe 1364 500 14 340 2014-11-15 12:50:02 UTC+0000
> 0x85f15760 taskhost.exe 1396 500 10 221 2014-11-15 12:50:02 UTC+0000
> 0x85f2f1f8 svchost.exe 1432 500 18 297 2014-11-15 12:50:02 UTC+0000
> 0x8542a030 vmtoolsd.exe 1596 500 11 391 2014-11-15 12:50:02 UTC+0000
> 0x85df2a58 TPAutoConnSvc. 1784 500 10 141 2014-11-15 12:50:02 UTC+0000
> 0x85e35d40 TPAutoConnect. 200 1784 4 131 2014-11-15 12:50:03 UTC+0000
> 0x85e0c968 sppsvc.exe 1820 500 4 149 2014-11-15 12:50:02 UTC+0000
> 0x85f85d40 svchost.exe 1892 500 6 92 2014-11-15 12:50:03 UTC+0000
> 0x843fb5d8 svchost.exe 2588 500 5 42 2014-11-17 13:24:45 UTC+0000
> 0x842c8988 svchost.exe 3100 500 12 245 2014-11-15 12:52:58 UTC+0000
> 0x84ba5030 WmiApSrv.exe 3176 500 5 113 2014-11-15 12:50:35 UTC+0000
> 0x86130b40 SearchIndexer. 3280 500 14 691 2014-11-15 12:50:44 UTC+0000
> 0x85d01b40 svchost.exe 3940 500 15 358 2014-11-15 12:52:04 UTC+0000
> 0x85cdd030 lsass.exe 520 400 7 601 2014-11-15 12:50:00 UTC+0000
> 0x85ce0030 lsm.exe 528 400 10 164 2014-11-15 12:50:00 UTC+0000
> 0x85c9fd40 csrss.exe 408 392 9 521 2014-11-15 12:50:00 UTC+0000
> 0x855cdd40 conhost.exe 292 408 1 32 2014-11-15 12:50:03 UTC+0000
> 0x84c16030 conhost.exe 3156 408 2 51 2014-11-15 12:50:35 UTC+0000
> 0x85cb8d40 winlogon.exe 456 392 3 113 2014-11-15 12:50:00 UTC+0000
> 0x843e8318 Utilman.exe 2176 456 5 126 2014-11-17 13:25:39 UTC+0000
> 0x84598d40 Magnify.exe 2980 2176 5 112 2014-11-17 13:25:43 UTC+0000
> 0x8531c140 explorer.exe 812 1188 52 1244 2014-11-15 12:50:06 UTC+0000
> 0x8473e030 taskmgr.exe 160 812 6 118 2014-11-17 13:23:45 UTC+0000
> 0x84ce5030 iexplore.exe 352 812 14 370 2014-11-17 13:24:14 UTC+0000
> 0x843c1378 iexplore.exe 1132 352 25 631 2014-11-17 13:24:16 UTC+0000
> 0x8607e030 HN_Hex-Ed.exe 576 812 1 5 2014-11-17 13:23:42 UTC+0000
> 0x85ddb030 wmplayer.exe 1372 812 22 519 2014-11-17 13:23:48 UTC+0000
> 0x843af0c0 7zFM.exee 2080 812 1 74 2014-11-17 13:24:06 UTC+0000
> 0x860b6d40 vmtoolsd.exe 2200 812 7 209 2014-11-15 12:50:08 UTC+0000
> 0x84276d40 CFF Explorer.e 2280 812 2 66 2014-11-17 13:23:54 UTC+0000
> 0x842ff3f8 calc.exe 2304 812 6 94 2014-11-17 13:24:59 UTC+0000
> 0x846c0030 Solitaire.exe 2692 812 9 206 2014-11-17 13:24:23 UTC+0000
> 0x842c6d40 regedit.exe 2812 812 1 65 2014-11-15 16:09:40 UTC+0000
> 0x842ac030 firefox.exe 2844 812 44 689 2014-11-15 12:52:57 UTC+0000
> 0x84520628 Signature Expl 2928 812 5 136 2014-11-17 13:25:25 UTC+0000
> 0x8517f728 Task Explorer. 3136 812 6 151 2014-11-17 13:25:15 UTC+0000
> 0x861bb030 cmd.exe 3148 812 1 21 2014-11-15 12:50:35 UTC+0000
> 0x843fbac0 Hearts.exe 3420 812 10 212 2014-11-17 13:24:51 UTC+0000
> 0x85193a20 notepad.exe 3764 812 2 73 2014-11-17 13:24:01 UTC+0000
> 0x8449e2b8 osk.exe 3792 1880 15 175 2014-11-17 13:24:43 UTC+0000

La commande procdump permet de reconstruire les fichiers EXE correspondant à ces processus. Un simple scan ClamAV nous donne ensuite le processus recherché (PID 576):

$ clamscan -d ../signature.nbd *
executable.576.exe: virus.UNOFFICIAL FOUND

Compte-tenu de l'ordre de lancement des processus, on peut dire que l'utilisateur a pris grand soin de brouiller les pistes en ouvrant de nombreuses applications inutiles a posteriori. La commande screenshot permet même de reconstruire l'état de son écran au moment du dump mémoire.
image
Maintenant intéressons-nous à la manière dont a été conçu ce challenge :)

Vers l'infini … et au-delà

Pour la blague, la commande hashdump permet de voir que tous les comptes Windows locaux disposent d'un mot de passe vide. C'est plutôt une bonne chose de ne pas avoir réutilisé un mot de passe sensible dans la VM du challenge.

Administrateur:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: Invité:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: Florian:1000:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::

La commande consoles permet d'afficher l'historique de toutes les commandes issues d'une application console. On peut voir que l'utilisateur a testé son challenge directement dans la VM:

CommandHistory: 0x111458
Application: cmd.exe
Flags: Allocated, Reset
CommandCount: 14
LastAdded: 13
LastDisplayed: 13
FirstCommand: 0
CommandCountMax: 50
ProcessHandle: 0x58
Cmd #0 at 0x116970: volatility-2.4.standalone.exe -f MEMORY.DMP --profile=Win7SP0x86 pslist
Cmd #1 at 0x1159d8: volatility-2.4.standalone.exe -f MEMORY.DMP --profile=Win7SP0x86 procdump -p 736
Cmd #2 at 0x115a88: volatility-2.4.standalone.exe -f MEMORY.DMP --profile=Win7SP0x86 procdump -p 736 -D test
Cmd #4 at 0x116e70: clamscan.exe -d Downloads
Cmd #5 at 0x1163d0: clamscan.exe -d Downloads\simple_virus
Cmd #6 at 0x116cc0: clamscan.exe -d signature.nbd Downloads
Cmd #7 at 0x116d18: clamscan.exe -d signature.nbd Downloads\simple_virus
Cmd #9 at 0x116d90: SysinternalsSuite\strings.exe virusexo2.exe.safe
Cmd #10 at 0x1043c8: SysinternalsSuite\strings.exe virusexo2.exe.safe > res.txt
Cmd #12 at 0x1155d0: SysinternalsSuite\strings.exe Virus\Virus.exe
Cmd #13 at 0x115638: SysinternalsSuite\strings.exe Virus\Virus.exe > res.txt

La commande iehistory ne donne pas beaucoup d'information non plus, car l'utilisateur démarre sa machine le 15 novembre 2014 vers 12:49, puis télécharge et installe FireFox trois minutes plus tard depuis l'emplacement suivant:

https://download-installer.cdn.mozilla.net/pub/firefox/releases/32.0/win32/fr/Firefox%20Setup%20Stub%2032.0.exe

Le reste des accès Web s'effectue avec FireFox, pour lequel Volatility ne dispose pas de plugin adapté (EDIT: il existe un plugin tiers dédié à l’analyse du processus FireFox).

La commande timeliner est assez verbeuse, mais donne un bon aperçu de la vie de la machine, car elle agrège dans une seule timeline toutes les sources d'information disponibles (processus, clé UserAssist, connexion réseau, etc.)

L'information la plus pertinente est probablement la réponse à cette question: comment le binaire du challenge s'est-il retrouvé dans la VM ? La réponse est assez folle: l'utilisateur s'est connecté à sa boite email ********@epita.fr avec FireFox (notons au passage que l'EPITA est client du Cloud Microsoft pour sa messagerie), et a téléchargé le binaire sous forme de pièce jointe.

Un simple grep permet de récupérer une bonne partie du carnet d'adresses et des emails chargés dans la page Web, comme par exemple:
Objet : [TCOM]Cours SWRAD avec STERCKMAN
Objet : Re: FIC2015 – challenges
Subject: FIC - binaire exo 2
Sujet : Diffusion offres de stage Sogeti ESEC R&D
Sujet [Ml-srs2015] Fwd: FIC2015 – challenges
Sujet [STAGE] Orange Business Services - Offres en S
Sujet ALERTE sur vos ABSENCES au cours de IBM Z-Series
Sujet Combien gagnent les stagiaires en France ? AJstage m
Sujet Convocation entretiens minist
Sujet Cours de forensics
Sujet Evenement EPITA "Filles et Maths, equation lumineurse"
Sujet Inscription Challenge Airbus
...

Le meilleur pour la fin: la requête de login complète est encore présente en mémoire, ce qui permet de récupérer le mot de passe de l'utilisateur ! Mais je vous rassure: j'ai présenté ces résultats dès la fin du challenge, et le mot de passe a été changé :)

vendredi 23 janvier 2015

FIC Challenge Writeup

Pour le troisième challenge du FIC 2015, Sogeti nous promettait un challenge résolument orienté hacking. Voici un essai de solution.

clip_image001

Le challenge se déroule de la manière suivante: chaque participant vient avec son propre matériel, et doit configurer une adresse IP statique associée à son emplacement physique dans l'Espace Challenge (le sous-réseau privé 192.168.0.0/24 est utilisé). A 11h00 le challenge démarre avec comme indication une simple adresse IP: http://192.168.0.35/

Un serveur Web est disponible à cette adresse. Il sert une image statique avec la musique de NyanCat en arrière-plan.

clip_image003

On imagine assez facilement que ceci n'est qu'un leurre et qu'il nous revient la charge de découvrir l'étape suivante. Deux hypothèses sont envisageables: soit le challenge se trouve sur le serveur Web (un scan "à la Nikto" devrait révéler une page cachée) ; soit le challenge se trouve sur un autre service.

Pour l'instant difficile de conclure car les deux pistes fonctionnent. Un scan Nmap révèle une configuration bien connue des pentesters, dite "arbre de Noël":

Port

Service

80/tcp

Apache 2.0.54 (Win32)

135/tcp

MS-RPC Endpoint Locator

139/tcp

MS-SMB

445/tcp

MS-CIFS

902/tcp

VMWare client

912/tcp

VMWare client

1025/tcp

MS-RPC (port dynamique)

1026/tcp

MS-RPC (port dynamique)

1027/tcp

MS-RPC (port dynamique)

1030/tcp

MS-RPC (port dynamique)

1031/tcp

MS-RPC (port dynamique)

1032/tcp

MS-RPC (port dynamique)

2048/tcp

?

2701/tcp

MS-SCCM

3306/tcp

MySQL

3389/tcp

MS-RDP

5357/tcp

?

6129/tcp

DameWare

8081/tcp

?

Le système lui-même est un Windows 7 x64 SP1 ; un grand classique compatible avec les outils de type Metasploit. On peut supposer que les organisateurs ne veulent pas nous faire perdre de temps à ajuster des offsets exotiques dans nos payloads.

Il est temps de lancer un scan Nessus. Malheureusement nous sommes confrontés à la crise du riche:

· La machine n'est pas à jour de MS14-066 (et donc probablement de MS14-068).

· D'après la bannière du serveur Web, Apache (2.0.54) et PHP (5.2.3) sont vulnérables à des dizaines de failles connues et non corrigées, puisque ces versions ne sont plus maintenues.

· La version de MySQL (4.1.22) est elle-même antédiluvienne.

clip_image005

A ce stade, on peut noter une propriété intéressante (et rare) de ce challenge: chacun peut y trouver son compte. Les fans de stack overflow peuvent tenter d'exploiter les failles de PHP, tandis que les pentesters expérimentés vont exploiter l'injection de commandes dans PHP-CGI (CVE-2012-1823) par exemple.

Le scan Nessus lancé en mode "no limit" (unsafe checks, probe all services on all ports, Web scan, etc.) va révéler également un fichier /phpinfo et un répertoire /phpmyadmin (version 2.11.0) sur le serveur Web. Ce dernier autorise le login root avec un mot de passe vide !

(Pour en avoir discuté avec les autres équipes à la fin du challenge, il semblerait que ce n'était pas la configuration par défaut mais qu'une équipe plus rapide que nous ait supprimé le mot de passe).

La combinaison de phpinfo + MySQL 4 + phpmyadmin sans mot de passe est une solution simple et élégante pour permettre aux étudiants de ne pas rester bloqués dans le challenge. En effet:

· phpinfo permet de récupérer le chemin absolu d'installation du serveur Web: W:\var\www (et W:\home\phpinfo pour le répertoire /phpinfo).

· Connaissant le chemin absolu, il est désormais possible d'utiliser la commande SQL "SELECT INTO DUMPFILE / OUTFILE" pour créer des fichiers lisibles au travers du serveur Web.

· MySQL 4 autorise également la création de bibliothèques binaires qui pourront être chargées en tant qu'UDF (User-Defined Functions) dans MySQL – cette option est disponible avec SQLMap ou Metasploit.

En ce qui nous concerne, nous avons opté pour une solution simple (donc fiable): créer un fichier "fuu.php" qui n'est qu'un Webshell minimaliste: <?php system($_GET[cmd]); ?>

En effet, la configuration PHP obtenue au travers de phpinfo révèle que la commande system() n'a pas été désactivée. Et ça marche !

clip_image007

Il reste à trouver la suite du challenge. Essayons le disque C:

clip_image009

Plusieurs emplacements s'annoncent intéressants: "Private", "Security" et "Sogeti".

Mais avant tout, essayons de voir sous quelle identité tourne le serveur Web. Il serait loisible de récupérer un shell complet au travers de PsExec par exemple, mais ceci nécessite d'être administrateur local. Une élévation locale de privilèges sera peut-être nécessaire.

clip_image011

On sent que la suite du challenge va être tout aussi intéressante, car la machine appartient à un domaine Active Directory. Il faudra peut-être rebondir dans le domaine, effectuer un mouvement latéral, passer par un VPN ou un OWA …

Avoir appelé le domaine "SOGLU" c'est quand même pousser le réalisme assez loin. C'est peut-être à ce moment qu'un participant a demandé aux organisateurs s'il était sur la bonne piste. Malheureusement, non: le challenge de hacking consistait à identifier de la stéganographie dans l'image publiée initialement sur le serveur Web. Du coup personne n'a eû le temps de finir le challenge malgré les indices distribués en abondance par l'organisation, et les gagnants ont été désignés en fonction de l'avancement des équipes. Je pense que la plupart des participants ont été déçus par la fin de cette histoire. Mais on essaiera de faire mieux la prochaine fois !