ECW Quals 2018 - MyWishesYourGoal (Guessing - 100)

Comme chaque année le PEC, le Pôle Excellence Cyber à ne pas confondre avec le PAIC ( de toute façon ça revient à la même chose, si tu regardes de trop près ça pique les yeux), organise un CTF réservé aux étudiant.e.s. 

 

Ce qu'on pourra retenir en général de ce CTF : guessing, guessing et ban. Mais bon je souhaitais absolument obtenir une place pour la final j'ai donc fait le vide dans ma tête et me suis préparé à guesser les trucs les plus farfelus. 

 

Résultat : classé 9ème avec 870 pts !

 

 

 Franchement je sais plus mais c'était pas utile.

Un PE

 

Extraction !

La technique utilisée par le "malware" est nommée RunPE, je ne connais pas cette technique en détails cependant, elle est pour moi semblable à l'injection de DLL et au process hollowing.

 

Le fait est que le dropper du malware va écrire en mémoire via des appels successifs à WriteProcessMemory un second PE, puis à l'aide de la fonction ResumeThread va le sortir de son mode dit suspended pour que celui s'exécute en mémoire. Il est ainsi difficilement débuggable.

 

 

On voit très bien ici, les écritures successives en RAM puis l'appel ce nouveau PE. Nous pouvons vérifier ça via x32dbg, ce tool est juste incroyable, c'est un des seul débugger windows que je connaisse ayant une interface plus que potable, un vrai petit bonheur contrairement à ce challenge ..

 

(N'hésitez pas à cliquer sur l'image pour l'agrandir).

 

Ici j'ai mis un breakpoint juste avant l'appel à WriteProcessMemory. On peut facilement naviguer via ctrl + G puis en rentrant le nom de la fonction que l'on veut accèder.

 

En regardant le troisième argument on voit un pointeur sur le buffer contenant la data a être écrite. Clique droit dessus > Follow DWORD in dump et on remarque bien qu'a cette adresse est présent le header d'un PE. Le 4ème argument quand à lui correspond à la taille de la data qui va être écrite, ici 0x400.

 

Ma technique, je suis totalement d'accord pour dire qu'elle est dégueulasse mais pas grave, a été de copier le contenu de chaque buffer grâce au tool HxD qui permet d'ouvrir la ram d'un process. Pour cela, il suffit de sélectionner le process parent car le nouveau est déjà présent mais dans l'état suspendu.

 

 

Egalement en faisant un ctrl + G et en renseignant l'adresse du buffer contenant notre data nous obtenons la partie de la mémoire qui nous intéresse :

 

 

Copions-collons tout cela et répétons la chose 6 fois en faisant bien attention de récupérer le bon nombre de byte spécifié par le 4ème du nom (argument) et nous obtenons un nouveau PE tout beau tout propre pouvant être débugger indépendament de son père !

 

Bruteforce time ! 

Le code intéressant du nouveau PE se trouve ici

 

 

La fonction CreateToolhelp32Snapshot permet avec les argument 0x2 et 0x0 de prendre un snapshot des processus en cours et de les parcourir un par un via la fonction Process32FirstW.

 

La suite n'est pas très complexe, dans la variable v4 est contenu le nom du processus puis la fonction sub_401070 se charge de faire un md5 de cette valeur qui sera comparé au hash ci-dessus en vert.

 

Si l'un des process dont le nom hashé correspond à cette valeur alors l'execution continue sinon le process se termine. Il faut donc trouver le nom du process qui doit être lancé lorsque le fils s'exécute, pour cela une seule façon ...

 

Le bruteforce ... Youpi .... wouh ... Ainsi après 30 secondes interminable le nom tombe : frp.exe.

 

Et voilà notre premier flag ... On continue ?

 

 

More bruteforce and some guessing 

 

La suite du code va récupérer les modules (DLL) de ce nouveau process à la recherche d'une DLL possédant un nom qui une fois haché devra être équivalent à 44f235fee... 

 

 

 

 

C'est la où commence le guessing, premièrement j'ai fait un script qui récupérait le md5 du nom de toutes les DLL de mon windows (avec ou sans majuscules), puis j'ai essayé pleins d'autre nom de DLL ou de processus en vain.

 

Dans un ultime bruteforce d'honneur on trouve que ce hash correspond à C:\rennes.dll.

 

WTF ? Sérieusement, une DLL qui n'existe pas ? Dans un chemin improbable ? Passons ... 

 

More bruteforce and more guessing 

Le troisième flag correspond à la valeur retournée par la fonction faabbccdd présente dans d'une librairie. Double WTF la DLL n'existe pas et cette fonction encore moins ... Il faut alors bruteforcé ce hash md5 sans aucune autre indication ...

 

Bien sûr j'ai google le hash, fait un tour sur crackstation mais rien à l'horizon, après un peu de guessing orienté il s'avère que le hash correspond à : ECW2018 ...

 

La gorge sèche, les yeux qui pleurent, on valide ce 3ème flag

 

The end

Une fois ces 3 flags devinés ou bruteforcés un joli message nous indique comment trouver le dernier flag, je vous laisse l'admirer sans commentaire de ma part :

 

You did it -> Go Flag SHA1(ECW2018{step1step2step3})