Monday, July 21, 2014

ndh2k14> [crackme] ChunckNorris.apk - 200 points


Je n'ai pas fait ce challenge pendant la nuit du Hack, c'est @PaulWebSec qui l'a validé lors du wargame. je n'avais jamais regardé un apk de près, je vais donc profiter de ce write up pour présenter tous les outils que j'ai pu utiliser pour valider ce challenge.

Enoncé du challenge:

Chuck Norris 
 
We found a strange application on Chuck Norris' smartphone.
Notice would be something like NDH2K14_XXXXXXXX 
(where XXXXXXXX stands for the mysterious hash inside the application).
 
On télécharge l'apk et c'est parti ! Première étape: Un apk, qu'est ce que c'est ?
 
[tic@Arch ndh]$ file ChuckNorris.apk 
 ChuckNorris.apk: Microsoft OOXML

OOXML pour office open xml, soit grosso modo une archive qu'on peut unzipper.

[tic@Arch ndh]$ unzip ChuckNorris.apk; ls ChuckNorris
AndroidManifest.xml  classes.dex  META-INF  res  resources.arsc

Ce qui nous intéresse ici, c'est le code source de l'application. le fichier classes.dex semble tout indiqué.

[tic@Arch ndh]$ file classes.dex
 classes.dex: Dalvik dex file version 035


Une recherche google plus tard et on apprend qu'il existe un outil nommé dex2jar permettant de transformer un .dex en .jar. Il est de plus livré de base avec Kali / Accessible dans le AUR repository dans Archlinux / téléchargeable en tar.gz.


[tic@Arch ndh]$ dex2jar classes.dex
 dex2jar classes.dex -> classes-dex2jar.jar

On a maintenant un beau .jar prêt à être décompilé. Pour cela jd-gui est l'outil tout indiqué. On le télécharge depuis leur site web ou dans l'AUR. Ensuite, un simple

[tic@Arch ndh]$ jd-gui classes.dex2jar.jar

permet d'obtenir une GUI présentant le code source de l'application. Ce code source est cependant lacunaire. Il permet simplement d'avoir une idée de ce qui se passe mais ne permet pas de patcher un apk.


Pour patcher un apk, il faut utiliser un autre outil: apktool.
Petit piège, il faut utiliser apktool2 pour que tout marche bien, sinon gare aux heures de sommeil perdues en vain devant des pages d'exception java. Donc téléchargez apktool depuis le site de son auteur et pas depuis autre part. apktool doit être situé dans le path, ainsi que apktool.jar et aapt. Tant qu'on y est mettez aussi les dossiers platform-tools et tools du sdk android dans le path.

On peut alors désassembler l'apk pour obtenir un code entre le Java et le Bytecode: le smali. Compréhensible et modifiable.

[tic@Arch ndh]$ apktool d $(pwd)/ChuckNorris.apk
# désassemble l'apk
[tic@Arch ndh]$ apktool b $(pwd)/ChuckNorris.apk
# réassemble l'apk 


Sous windows, on peut aussi utiliser Virtuous 10 qui permet en quelques clics d'obtenir le smali. Je n'ai pas réussi à le faire fonctionner. J'obtiens les mêmes erreurs qu'avec apktool 1.


Une autre façon de voir ce qui se passe dans cet apk est ... de le lancer.

Pour cela on peut soit lancer l'apk sur un vrai smartphone, soit le lancer grâce à l'émulateur fourni par le sdk android.
Pour utiliser l'émulateur, trois étapes nécessaires:

[tic@Arch ndh]$ android
 


[tic@Arch ndh]$ android avd




[tic@Arch ndh]$ emulator -avd <nom_vm>

Puis lorsque l'émulateur est lancé:

[tic@Arch ndh]$ adb install -r ChuckNorris.apk

On obtient un premier aperçu de l'application, il s'agit d'une série de trois questions tournant autour de l'univers de mickey. Lorsqu'on finit cette série, on a le choix entre recommencer le jeu ou quitter. Si on recommence, on obtient le nombre de bonnes réponses obtenues aux questions.




Lors de la lecture du code source grâce à jd-gui, on se rend compte que l'application calcule un hash puis l'envoie par sms au 06066060060. (Ou alors on est juste curieux et on veut savoir ce qui est envoyé par sms). Il y a aussi une fonction sendmail, qui ne semble cependant jamais appelée.

Ma première tentative a été de désassembler l'apk avec apktool, de changer le numéro de téléphone en un que je connais puis de réassembler l'apk. Je pense que ça fonctionne, mais mon téléphone est trop vieux, l'apk ne le supporte pas.

Il existe un moyen de simuler l'envoi de sms / mail dans un émulateur. Pour cela on installe droidbox qui permet de monitorer un apk dans un émulateur. (Bien lire les spécs de droidbox, il faut utiliser la bonne version du sdk avec la bonne device sinon rien ne marche.)
On répond aux trois questions et droidbox enregistre (entre autre) l'appel sms et l'affiche sous forme de json.



Le contenu du sms est le flag à valider: NDH2k14_2F6F1126D3DD17DA3A42CBE0C2B0447C





 

Tuesday, July 15, 2014

ndh2k14> [crypto] AussieHackerz - 100 points

 
Énoncé du challenge: 
 
Aussie Hackerz have hide a flag in this cryptic text. 
 
3035C994C99FC9943831327170373337C79DC99FC994C990703238C990343771313137C994323
338C990383735C99FC79DC79D3833E280BE3431CA9E32C9A57075 
 
Quand je vois une chaîne hexadécimale dans un challenge, je fais toujours une petite conversion en ascii / utf8 pour voir si il n'y a pas un message caché.
Pour ça, j'ai un petit snippet qui marche bien. Préparez vous, encore du joli python. Résultat: 05ɔɟɔ812qp737ǝɟɔɐp28ɐ47q117ɔ238ɐ875ɟǝǝ83‾41ʞ2ɥpu

Cette suite de caractère semble n'avoir aucun sens au premier abord. Cependant, on s'aperçoit assez vite que les dernières lettres lues à l'envers donnent ndh2k14 ! C'est un flag !

Si on l'entre tel quel, le challenge ne se valide pas. C'est là que le Aussie de AussieHackerz prend son sens, il va falloir lire ce texte à la façon des australiens, c'est à dire la tête en bas.

 Le flag lu de cette façon devient: ndh2k14_38eef57832c711q74a82dacfe737db218cfc50

Cette fois ci, c'est la bonne.

Wednesday, July 2, 2014

ndh2k14> [Forensic] Special OVH Challenge - 300 points

Énoncé du challenge:
Bonjour,

Je vous écri parce que je pense que g trouver le mot de passe root de votre serveur !
Sa serez trop long à vous expliquez, mais g pu récupérer le trafic réseau dun admin OVH
qui avé accé à la machine nuitduhack.ovh.
Je lai vu se connecté sur la konsole vsphere et tapé le mot de passe root.
Je suis quasi sure que le trafic n&#039;était pas chiffré (g pa vu le cadena dans son brouseur).
Le trafic réseau est la (3Mo) : http://static.wargame.ndh/ovh.pcap
(md5 : f65b0b1e18ede5b0361b1a4473923c3f)
Je pense que récupérez le mot de passe est plu compliquer que de trouvé ce qui sé passé sur lécran. À vous de voir...
Nessayer pas de hacké le serveur vsphere, les preuve se passe hor ligne.
Pouvé vou maidé pour trouvé ce kil sest affiché sur la konsole, et le mdp root du serveur ?
Si vous trouvé, je vous offriré une place à la ndh2k14 (et un bisou) !

Il est précisé qu'une fois le challenge résolu, il faut aller au stand OVH pour récupérer une récompense spéciale.
Le fichier fourni est une trame réseau au format pcap de 3Mo, disponible ici.

Forensic de la trame réseau


Wireshark nous informe qu'elle contient 3662 paquets, étalés sur 91 secondes. Plusieurs protocoles sont utilisés: icmp, tcp, llc, tls et du raw ethernet. La première chose à faire est d'inspecter les différents flux de communication à la recherche de données intéressantes.

Il y a 36 flux tcp différents, on peut les isoler un à un avec le filtre "tcp.stream eq X" (où X est le numéro du stream) dans Wireshark. En parcourant ces flux, on se rend compte qu'il y a beaucoup de junk, preuve que la capture du traffic a sans doute été effectuée sur un vrai réseau. À partir du 7ème flux tcp, le client (192.168.1.28) se connecte au serveur (32.187.228.20) en http:

GET /console/?vmId=vm-155&vmName=nuitduhack.ovh&host=pcc-37-187-228-20.ovh.com [...]
Host: pcc-37-187-228-20.ovh.com:7331
Connection: keep-alive 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1976.2 Safari/537.36 DNT: 1 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: fr,en-US;q=0.8,en;q=0.6 

Les connections suivantes correspondent à la récupération des ressources du serveur: css, favicon, images et le javascript: modernizr-2.0.6.min.js, jquery-1.6.2.js, wmks.js, nsXmlRpcClient.js... Les choses deviennent intéressantes au flux numéro 13:

GET /console/authd?vmId=vm-155&vmName=nuitduhack.ovh&host=pcc-37-187-228-20.ovh.com [...]
Upgrade: websocket 
Connection: Upgrade
Sec-WebSocket-Protocol: binary, uint8utf8, base64 
Sec-WebSocket-Key: 0bYKMnj6Xk8fpl5GPCs8rw== 
Sec-WebSocket-Version: 13 
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame 

HTTP/1.1 101 Switching Protocols 
Set-Cookie: JSESSIONID=3xlo0t8zjjof1ab01h7h21t3v;Path=/console 
Upgrade: WebSocket
Connection: Upgrade 
Sec-WebSocket-Accept: B09kCJ0sOuS8IqXayw9K207Xg2o= 
Sec-WebSocket-Protocol: binary

 Le client demande au serveur un passage au protocole Websocket [rfc6455], qui consiste à établir une connexion directe entre le client et le serveur, et ne plus utiliser http pour communiquer. La suite est une communication binaire...

Extraction des données utiles de la trace


En regardant de plus près on voit passer 80 images au format JFIF (une forme de JPEG) et 11 en PNG, dont celles-ci:








Les images sont altérées mais on arrive à distinguer 3 séquences "login: root, password : ?", les 2 premières sont suivies de "login incorrect" et la dernière des images suivantes:

 

Il y a donc eu 2 tentatives de log infructueuses et la dernière qui a fonctionné, l'idée est donc de regarder dans la trame réseau ce qu'il s'est passé entre l'envoi de ces images, on remarque des messages de cette forme:

00001173  82 88 4d 2e ca 2b 32 2a  ca 23 b0 2e ca 35       ..M..+2* .#...5
00001181  82 88 d1 0c 88 5d ae 0c  88 55 d1 26 89 5d       .....].. .U.&.]
0000118F  82 88 9f 26 5c fd e0 26  5c f5 9f 16 5d fd       ...&\..& \...].
0000119D  82 88 6a 5d f0 13 15 5d  f0 1b 6a 77 f0 13       ..j]...] ..jw..
000011AB  82 88 77 b4 f7 8c 08 b4  f7 84 77 84 f7 8c       ..w..... ..w...
000011B9  82 88 95 38 b3 f0 ea 38  b3 f8 95 2a b2 f0       ...8...8 ...*..
000011C7  82 88 a8 70 40 96 d7 70  40 9e a8 62 40 96       ...p@..p @..b@.
000011D5  82 88 0a a0 74 ba 75 a0  74 b2 0a 8c 75 ba       ....t.u. t...u.
000011E3  82 88 a5 b4 af fa da b4  af f2 a5 98 af fa       ........ ......
000011F1  82 88 55 e4 3f dc 2a e4  3f d4 55 f4 3e dc       ..U.?.*. ?.U.>.
000011FF  82 88 1f 3f 6a 43 60 3f  6a 4b 1f 2f 6a 43       ...?jC`? jK./jC
0000120D  82 88 c4 7f 81 f8 bb 7f  81 f0 c4 6c 80 f8       ........ ...l..
0000121B  82 88 3f c6 f4 36 40 c6  f4 3e 3f d4 f5 36       ..?..6@. .>?..6
00001229  82 88 01 45 66 16 7e 45  66 1e 01 56 66 16       ...Ef.~E f..Vf.
00001237  82 88 e4 78 b0 99 9b 78  b0 91 e4 6a b0 99       ...x...x ...j..
00001245  82 88 df ac ec 89 a0 ac  ec 81 df 86 ed 89       ........ ......
00001253  82 88 e3 bf a5 65 9c bf  a5 6d e3 95 a4 65       .....e.. .m...e
00001261  82 88 87 da d0 4c f8 da  d0 44 87 f0 d1 4c       .....L.. .D...L
0000126F  82 88 75 d2 b2 e4 0a d2  b2 ec 75 f8 b3 e4       ..u..... ..u...
0000127D  82 88 28 b3 49 cd 57 b3  49 c5 28 99 48 cd       ..(.I.W. I.(.H.
0000128B  82 88 bb 48 d1 d8 c4 48  d1 d0 bb 62 d0 d8       ...H...H ...b..
00001299  82 88 ab ed 0f 67 d4 ed  0f 6f ab c7 0e 67       .....g.. .o...g
000012A7  82 88 51 a0 ee b5 2e a0  ee bd 51 8a ef b5       ..Q..... ..Q...

[...]

Leur structure est commune, les octets 0x82 0x88 sont présents en début de chaque ligne. A ce moment là, la lecture de la rfc du protocole Websocket s'impose:

      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     | |1|2|3|       |K|             |                               |
     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
     |     Extended payload length continued, if payload len == 127  |
     + - - - - - - - - - - - - - - - +-------------------------------+
     |                               |Masking-key, if MASK set to 1  |
     +-------------------------------+-------------------------------+
     | Masking-key (continued)       |          Payload Data         |
     +-------------------------------- - - - - - - - - - - - - - - - +
     :                     Payload Data continued ...                :
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
     |                     Payload Data continued ...                |
     +---------------------------------------------------------------+

En résumé, les octets 0x82 et 0x88 indiquent que ce sont des trames de 8 octets et avec une charge utile masquée. Ce masque est indiqué par les 4 octets qui suivent 0x82 0x88. Par exemple pour la première ligne, le masque vaut 4d 2e ca 2b et le payload 32 2a  ca 23 b0 2e ca 35. Pour décoder, on xor chaque octet du payload avec l'octet correspondant dans le masque. On retrouve alors les données envoyées par le client au serveur:
127 4 0 8 253 0 0 20 
127 0 0 8 0 42 1 0 
127 0 0 8 0 42 1 0 
127 0 0 8 0 42 1 0 
127 0 0 8 0 48 1 0 
127 0 0 8 0 42 0 0 
127 0 0 8 0 48 0 0 
127 0 0 8 0 18 1 0 
127 0 0 8 0 18 0 0 
127 0 0 8 0 17 1 0 
127 0 0 8 0 17 0 0 
127 0 0 8 0 30 1 0 
127 0 0 8 0 30 0 0 
127 0 0 8 0 19 1 0 
127 0 0 8 0 18 1 0 
127 0 0 8 0 19 0 0 
[...]
La structure de ces données est assez curieuse, il y a peu des variations entre les lignes et même après plusieurs tentatives de conversion en ascii et autres, ces données ne parlent pas.

Faire parler les chiffres


D'après les images, on sait que ces données correspondent à une transformation près, aux touches clavier que l'utilisateur a pressées au moment de taper son mot de passe. Il faut maintenant comprendre comment ces touches sont interprétées, c'est à dire quel est le protocole de communication entre le client et le serveur. On jette alors un oeil aux javascripts que le client avait téléchargé précédemment à la recherche du mot "keyboard", le fichier nsXmlRpcClient.js correspond. En recherchant la constante 127, on tombe là dessus:

   /*
    * Server->Client message IDs.
    */

   msgFramebufferUpdate: 0,
   msgSetColorMapEntries: 1,
   msgRingBell: 2,
   msgServerCutText: 3,
   msgVMWSrvMessage: 127,

   /*
    * Client->Server message IDs.
    */

   msgClientEncodings: 2,
   msgFBUpdateRequest: 3,
   msgKeyEvent: 4,
   msgPointerEvent: 5,
   msgVMWClientMessage: 127,

Puis en cherchant la constante msgVMWClientMessage, on arrive sur la fonction chargée d'envoyer les messages:

      arr.push8(this.msgVMWClientMessage);
      arr.push8(4);           // ACK message sub-type
      arr.push16(8);          // Length
      arr.push8(updateReqId); // update id
      arr.push8(0);           // padding
      arr.push16(time);       // render time in tenths of millis
      this._sendBytes(arr);

On comprend maintenant quelle est la signification des données envoyées par le client. En continuant notre lecture du code, on trouve ces tables qui associent un octet à chaque touche clavier:

   // Space, enter
   32 : 0x39,
   13 : 0x1c,
   // Keys a-z
   97  : 0x1e,
   98  : 0x30,
   99  : 0x2e,
   100 : 0x20,
  ...
   // Symbol keys ; = , - . / ` [ \ ] '
   59 : 0x27, // ;
   61 : 0x0d, // =
   44 : 0x33, // ,
   45 : 0x0c, // -
   46 : 0x34, // .
   47 : 0x35, // /
   96 : 0x29, // `

La traduction du message avec cette correspondance nous donne:
left_shift  left_shift  left_shift  b  left_shift  b  e  e  w  w  a  a  r  e  r  e  left_shift  a  left_shift  a  g  g  a  a  i  i  n  s  n  s  t  t  left_shift  left_shift  left_shift  left_shift  left_shift  left_shift  left_shift  left_shift  left_shift  left_shift  left_shift  left_shift  left_shift  left_shift  w  w  left_shift  s  s  enter

En reconstituant les touches tapées, sachant que le 7ème octet de chaque ligne indique si la touche est enfoncée ou relâchée, le flag apparait: BewareAgainstWs.

Merci OVH pour les goodies et le raspberryPi !

Monday, June 30, 2014

ndh2014> [forensic] Hold Up - 200 points

by @steveo068
Il semble que quelques personnes ont décidé de confier leurs HackerZCoins à MtGox.
On a trouvé un étrange fichier dans les backups de MtGox, peut-être que des HackerZCoins se sont perdus dans la nature.

Le challenge nous donne accès à un unique fichier HoldUp.img et le flag est le nombre de HackerZCoins perdus.

Une fois le fichier récupéré, on demande à file de nous aider :
steveo@steveo:~/ndh$ file HoldUp.img 
HoldUp.img: Linux rev 1.0 ext3 filesystem data, UUID=44a63bd3-5dab-46d1-8f75-2249c3ef6158, volume name "Data" 
 
On tente de le monter :
steveo@steveo:~/ndh$ mount HoldUp.img /mnt; cd /mnt; ls
HoldUp.zip

On décompresse l'archive et on obtient un répertoire coins rempli de fichier avec l'extension .tc ainsi qu'un fichier splitter.py.

Contenu du fichier splitter.py
Le script découpe le fichier d'origine dans plein de fichiers de 512 octets. Pour tenter de reconstruire le fichier, il faut concaténer les petits fichiers dans l'ordre. Le nom des fichiers ne nous aide pas du tout mais il s'avère que les fichiers possèdent une date de modification qui semble correcte et qui quand on les trie sont séparées de 2s. Donc il suffit de les trier dans l'ordre croissant des dates de modifications et de les concaténer. Une petite commande bash pour nous aider :
steveo@steveo:~/ndh$ ls -tr coins/*.tc | xargs cat > CoinSteal.tc

Maintenant un coup de file sur CoinSteal.tc:
steveo@steveo:~/ndh$ file CoinSteal.tc
CoinSteal.tc: data

Bon file ne nous aide pas trop pour le coup. On se rabat sur l'extension du fichier : c'est une extension courante pour les containers du défunt TrueCrypt. Le problème maintenant c'est qu'il faut un mot de passe pour monter ces containers.
On décide d'essayer de le bruteforcer avec TrueCrack. Au lieu de faire du simple bruteforce, un dictionnaire est utilisé. Le premier dictionnaire choisi est le darkc0de. Après une heure de calculs, ça ne donne rien. Un autre dictionnaire est tenté : le Rockyou. Celui-ci nous donne immédiatement un mot de passe.

steveo@steveo:~/ndh$ truecrack/src/truecrack -w rockyou.txt -t CoinSteal.tc
TrueCrack v3.5
Website: http://code.google.com/p/truecrack
Contact us:         infotruecrack@gmail.com
Found password:     "iloveyou"
Password length:    "9"
Total computations: "5"


Dans le container, on trouve une feuille de calcul Coins.ods avec la somme d'HackerZCoins dérobés.


ndh2k14> [crypto] MyNameIs.png - 100 points

by @_Frky

Premier challenge crypto de cette NDH2K14, présenté sous la forme d'une image. Le titre (MyNameIs) laisse supposer que la première étape est de trouver qui est le monsieur dont le portait nous est fourni. 
Si l'on fait une recherche d'image google par comparaison avec son portrait, on se rend compte qu'il s'agit de Giambattista della Porta

En cherchant un peu, on apprend que cet homme a en effet contribué à l'évolution de la cryptographie, et qu'il est notamment l'auteur du "premier système littéral à double clef" (voir ici). Il semblerait donc que le texte soit chiffré par une substitution polyalphabétique reposant sur une clef et les treize alphabets de Giambattista. Reste à trouver la clef.

À ce stade, regardons d'un peu plus près le chiffré. Notons qu'il fut également fourni sous forme de fichier texte, ce qui a son importance car on remarque des caractères qui n'apparaissent pas sur l'image (en fait, les tirets):


SQFZIKTWUOIYLYSUOIWQDBZDIYWYMHSADVOYXVSMGGMZPCDT'TGJOIDZJKPKKBZXPQHAIKIYYOQYLIYFXQQYDANVWSTPZ,O'OAD-V-OPFOQUHGYYSWBXSPRPMUHDAFVWAMPSCDUXVCNQN'SOHSUNOBQXSUEKWOZIMFO.UUKALHORUHDSMXQMPYVQJNAMPYHXNDZMMFORUUPGHHJRMHMQFJEJW'YDELEZ,YMQVKLQCMEKWRZYAOECMXDGGSVUJPGHFJBLYWCWRUTP"IQHWTZWUOHGMLDNFXKXQPTCNWBFP".GPR2P14_VTYNKXASJAIHOVRDEHFJSBMWYACH.

C'est très intéressant de voir que les caractères de ponctuation ne semblent pas chiffrés (ce qui est logique, puisqu'il semble s'agir d'une substitution alphabétique). On remarque notamment deux points d'intérêt grâce à la ponctuation:
  • O'OAD-V-OPFOQUHGY... : si le texte chiffré est en français (comme c'est probablement le cas), ce passage suggère assez fortement la syntaxe d'un "C'EST-A-DIRE...". 
  • GPR2P14_VTYNK ... : Ça ressemble fort au format des flags de la ndh: NDH2K14_...
À partir de ces deux correspondances, nous allons chercher à retrouver la clef, en utilisant les tables fournies ici. Si le chiffré correspondant à C est O par exemple, la clef utilisée ici est la lettre C (lettre qui correspond à l'alphabet qui chiffre le C en O). Voici ce que ça donne sur l'ensemble des lettres composant les deux zones citées précédemment:


clair       C'EST-A-DIRE ... NDH2K14_
chiffré       O'OAD-V-OPFO ... GPR2P14_
clef       C'GQU*K*EMCG ... MCG*Q**_

On voit apparaître un cycle dans le premier cas, dont on retrouve une partie dans le second! La clef semble donc être une permutation circulaire de CGQUKEM. Si on compte les lettres alphabétiques avant le début du chiffré correspondant au "C'EST-A-DIRE" (donc le O'OAD), on en compte 92. Modulo la taille de la clef (qui est 7), ça fait 1, donc la seconde lettre de la clef doit être C. La clef est donc MCGQUKE. Si l'on déchiffre avec cette clef, on obtient bien un texte en français, suivi du flag:

LEPHYSICIENITALIENGIOVANNIBATTISTADELLAPORTAFUTL'INVENTEURDUPREMIERSYSTEMELITTERALADOUBLECLEF,C'EST-A-DIRELEPREMIERCHIFFREPOURLEQUEL'ONCHANGEDALPHABETACHAQUELETTRE.CESYSTEMEPOLYALPHABETIQUEETAITEXTREMEMENTROBUSTEPOURL'EPOQUE,ATELPOINTQUEBEAUCOUPCONSIDERENTPORTACOMMELE"PEREDELACRYPTOGRAPHIEMODERNE".NDH2K14_FLAGWASCRYPTEDBYPORTARULEZZZ.

Sunday, June 29, 2014

ndh2k14> [stegano] HZcoin.png - 100 points

Le challenge consiste en une simple image png. Pour le temps d'une nuit à disneyland, Hackerzvoice se lance dans la création de monnaie virtuelle.


L'image est jolie, mais ce qui nous intéresse est dans son code source. 

Voyons d'abord à quoi on a affaire:

tic_@kali:~/ndh$ file HZcoin.png
HZCoin.png: PNG image data285 295 8-bit/color RGBA, non-interlaced

C'est bien une image png ! La surprise passée, je regarde la taille du fichier, au cas où. 69K semble un peu grand pour ce que c'est, mais ça ne saute pas aux yeux.


tic_@kali:~/ndh$ ls -lh HZCoin.png
-rw-r--r-- 1 tic_ users 69K 30 juin  15:35 HZCoin.png


Une manière classique de cacher des informations dans une png est d'utiliser les metadatas. un petit strings permet de voir qu'aucune metadata ne contient de texte. Un coup pour rien.

Une chose à savoir lorsque on travaille avec du png est que les parsers s'arrête au premier IEND qu'ils trouvent. Ainsi toutes les données stockées à la suite ne serons pas parsées et ne seront donc pas affichées. Un petit vim permet de voir que des données binaires suivent le premier IEND trouvé ! Si on regarde bien, il s'agit d'une autre image png.

Pour confirmer nos soupçons on peut également lancer une commande telle que:

tic_@kali:~/ndh$ strings HZcoin.png | grep IEND
IEND
IEND 

qui achève de nous convaincre.


Ici une autre image png est cachée dans la première. La deuxième image contient le flag.

ndh2k14> [web] Awkward - 200 points

Dans un futur plus ou moins lointain, Internet sera remplacé par awkward, un service tcp pour le moins obscur. En tout cas c'est ainsi que le challenge nous est présenté. Ce challenge est un service tcp, on peut donc communiquer avec lui en utilisant telnet.

tic_@kali:~/ndh$ telnet awkward.wargame.ndh 1337
A chaque appel, on reçoit 16 caractères ascii aléatoires et on nous demande une réponse.
Ca donne un truc du genre:
Client (nous) : Init connection
Awkward Server: PççV²b!­|Ó¬
Client : Réponse
Awkward Server: Authentication failed, blabla, use the id (16 lettres en minuscules ou majuscules) blabla

Je teste une petite dizaine de fois de communiquer avec le serveur et j'en déduis que:
  • le premier message fait toujours 16 caractères de long
  • l'id communiqué par la suite par le serveur fait également toujours 16 caractères de long et est composé uniquement de lettres en minuscule ou majuscule
Le fait que l'id et le premier message fassent 16 caractères de long me donne la direction à suivre. Le serveur nous propose un challenge: le premier message et nous demande d'y répondre par un id. Si l'id communiqué est faux, le serveur nous communique gentiment celui qu'il attendait.

Je lance le service et je me rends compte au bout de quelques essais que "6" dans le challenge devient "M" dans l'id s'il est situé en première place. En fait quelque soit l'index de "6", il se transforme en "M", situé au mếme index dans l'id.

On a donc affaire à une substitution. Pour former l'id qui nous permettra de récupérer le flag, il faut créer un dictionnaire décrivant le passage d'un caractère du challenge à un caractère de l'id.