Angry Guessing Game 200 [Volga CTF 2017]

Hi,

Today i’m sharing  my first write up which concerns Angry Guessing Game challenge of VolgaCTF 2017.

It’s a reverse challenge, so if you don’t like reverse, you can freely avoid the entire post, and continue browsing BBC category on xvideos.

Binary can be found at: guessing_game

So at first let’s make a file to be aware of what we are going to reverse:

Okay, it’s a stripped linux 64 bits binary, I don’t really like Linux, 64 bits, and stripped binaries.
Nevermind.

We run the binary to see what its actually about.

Well, it is a pretty simple program.
Two rounds, of guessing a number.
If you succeed, you get to the third round, and the binary will ask you a license key, that we obviously don’t have but no problem, we are reverser.

Let’s open IDA pro that we bought legally at 1K$.

And here, we are going to search for strings via « search text » option.

We go to the string’s xref
And after few more investigations, we find out two blocks that corresponds to the good and bad license key.

So we know where to search for the key generator.
Few minutes later, we got this.

Yay, we are near from the source, be ready for the battle, it will be hard.
Be prepared to hold the gate my friends. It will be harr… WAIT WHAT…

Publié dans CTF | Laisser un commentaire

[VolgaCTF-2017-Quals] Corps news 300 write-up

Challenge web, contenant :
– Une page home,
– Une page de login,
– Une page profil où on peut changer son mot de passe,
– Une page news où on peut poster des news via un formulaire. Elle contient un lien « read private news ».

Quand on clique sur read private news, le serveur nous renvoie ce message :

On tente donc de set un header et de rejouer la requête :

En vain, on reçoit toujours le même message…

On tente ensuite une XSS dans les news en postant :

On lance un netcat et on poste notre XSS. Résultat : un bot se connecte et il y’a bien une XSS!

On fouille, on fouille, mais rien d’autre, jusqu’à ce qu’on remarque que dans la page des news, on a le nom d’un admin…
On va donc essayer de modifier le mot de passe de notre admin en envoyant ceci :

Ce script récupère le token de protection contre les CSRF, envoie ensuite une requête post contenant le token et le nouveau mot de passe.

On peut désormais se connecter avec le compte de l’admin. Lorsqu’on se connecte, on voit sur la page profile une ligne intéressante :
Your Secret header : asdJHF7dsJF65$FKFJjfjd773ehd5fjsdf7

Mince… Encore cette histoire de header… On envoie donc une nouvelle requête avec comme headers :
Secret : asdJHF7dsJF65$FKFJjfjd773ehd5fjsdf7

Ou encore :
Your Secret : asdJHF7dsJF65$FKFJjfjd773ehd5fjsdf7

Mais rien à faire, on ne récupère toujours rien. Il y’a aussi toujours le problème du « debug header » dont on parlait au début…

On retourne donc sur la page de news, on essaie tout plein de possibilités pour set le fameux debug header. Après avoir passé un bon moment à faire du guessing, on se rend compte qu’il fallait envoyer un json en post data contenant :
{« header »: {« debug »: »true »}}

Voici la requête que j’ai envoyé :

On renvoie la même requête, mais cette fois-ci avec le fameux secret header et c’est gagné :

Publié dans CTF | Laisser un commentaire

[VolgaCTF-2017-Quals] PyCrypto 150 write-up

Il s’agit d’une épreuve de reverse / crypto.

Les sources : pycrypto.tar

On nous donne trois fichiers :
flag.enc : un fichier contenant 2412 caractères, quasi tous non-human readable
pycryptography.so : un module python3
encrypt.py : un script python3, utilisé pour chiffré flag.enc :

Pour commencer, on le lance avec python3 :

Une autre erreur, effectivement, on n’a pas de module secret contenant le flag comme par magie sur notre machine. On commente donc la ligne 4.

On veut comprendre ce que fait la fonction encrypt, qui est appelée avec deux paramètres : le flag et os.urandom(20) qui renvoie 20 bytes random. On lance notre interpréteur python3 et on fait donc quelques tests :

A priori, il s’agit d’un XOR.

Si le flag est dans le fichier, alors celui-ci devrait contenir : VolgaCTF{ (chaque flag commençant par ceci).

On tente donc une attaque : on génère les 11 possibilités de clefs de 20 bytes contenant la string « VolgaCTF ».

On utilise chacune des clef obtenue pour XOR une partie du fichier flag.enc afin d’obtenir une nouvelle clef, censée se rapprocher de la clef utilisée pour XOR flag.enc à l’origine.

Avec nos clefs, on XOR flag.enc et on cherche la string « VolgaCTF » dans chacun des textes générés, si elle y est, on va donc récupérer une partie du fichier en clair.

Voici mon script :

On récupère un flag.enc partiellement déchiffré :

On a une URL partiellement « déchiffrée » à la fin du texte. Pour la récupérer, on utilise… google ! 😀

On lance cette recherche : inurl:2015/08/12 inurl:pad-attack et on récupère un seul résultat :
http://whitehatjourney.wordpress.com/2015/08/12/many-time-pad-attack/

On va donc se servir de cette URL pour récupérer la clef du XOR et déchiffrer notre message. L’idée est de XOR L’URL récupérée en clair avec L’URL dans le texte chiffré. Comme cette URL est plus grande que la clef utilisée pour le XOR, on va donc récupérer entièrement la clef et pouvoir récupérer le texte en clair.

On exécute notre script et on récupère le flag :

Publié dans CTF | Laisser un commentaire

[VolgaCTF-2017-Quals] Time_Is 150 write-up

The Time_Is challenge was the first one in ‘exploit’ category.

Part 1: WTF sha1 Puzzle ?!

First and foremost I didn’t understood the goal, because after downloading the binary, it looked different than online version to be pwned:

After some tests, we can see that every connection leads to a different prefix (‘8a7ce272dfac9e6b8b89445f’), while the rest of the phrase remains exactly the same, so I resolved to write a dirty python function that finds ‘x’:

When we send the correct answer to online service, it finally executes the ./time_is ELF64 executable. So this part was some kind of advanced captcha, designed to prevent lazy people (juste as me) trying to exploit directly online, because captcha break most of time needs severall minutes to be broken.

Part 2: Time Is to ROP !

A checksec tells us that stack protector, fortified source, NX and relro (partial) are all enabled. So we’ll probably need to do ROP. Now let’s take a look into available functions on GOT:

Only sucking functions, no system(), no read(), so wee probably can’t rely on « Return to PLT ». Therefore, there is a secure version of printf __printf_chk which prevents buffer overflows and position specifiers (« %42$lx »), but is still interesting …

Let’s take a look into what the binary does:

So, we are prompted to enter some « time zones » in a loop.
These is a buffer overflow vulnerability on this loop:

As ./time_is is stripped, i used radare2 to automatically detect functions so I can browse into x86_64 easily, the core dump is caused by stack canary override as expected.

Therefore, while user_input is displayed back, followed by current time, __printf_chk() is used, so we can leak stack canary and some interesting addresses:

NOTE: Here i couldn’t use printf position specifiers because of __printf_chl() protections, so i just send (a lot of) %p. juste enough to leak the stack canary 0x6cba956fa3e1c000 and a libc address 0x7ffff7a56511 (<__libc_start_main+241>)

Since we got canary, we can write it back on next user input, in order to bypass the stack protector. The libc address will be used to calculate offsets of « /bin/sh » and system() in the glibc.

The only missing information is the remotely used version of glibc, to be able to calculate the right offsets. And as the captcha puzzle is very slow to crack, we can’t simply try all offsets from common glibc versions.

Fortunately, the binary has debug symbols, and we know exactly the version of the gcc and distribution used at compile time: GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 and as this is a CTF and not real life, the running glibc is probably the one available in last version of this distribution:

Then i wrote the sploit with pwnlib, and go to bed !

 

Publié dans CTF | Laisser un commentaire

[NULLCON-CTF] Exploit400 (fr)

Voici un petit write-up du challenge exploit400, du CTF Nullcon Hackim 2014.

Vous pouvez trouver le binaire ici : exploit400
Et la source ici : exploit400.c

Le fait que nous avions accés au code source du programme nous a bien facilité la tâche.

Le programme est on ne peut plus simple :
– Il ouvre et lit le flag de validation, et le stock dans le heap.
– Il demande ensuite une saisie, qui abouti facilement à un stack based overflow.

Il n’y a pas beaucoup de protection, et j’ai programmé mon exploit en prenant en compte l’ASLR probable :

Comment lire le flag stocké en mémoire ? J’ai choisi de faire du ROP afin de bypass l’ASLR et NX.

La première chose que j’ai fais, c’est mettre à zéro 4 bytes du segment DATA. Pour se faire, j’ai utilisé la fonction read, présente dans la @PLT, afin d’envoyer 0x00000000.

Ensuite, j’exécute un malloc, d’avoir une adresse du heap, et connaître ainsi l’emplacement du flag.

L’adresse du flag est alors à : EAX – OFFSET. Avec quelques gadgets, je stocke cette valeur en mémoire. (dans la zone initialisé grâce à la fonction read)

Je m’envois alors cette valeur via la fonction write

J’ai choisi d’utiliser une technique de fake-stack-frame + stack-pivot afin d’avoir un code « dynamique » (je calcule comme ça les offsets du heap dans l’exploit, et je peux créer la fake-stack-frame en conséquence). Je reçois ma stack via read(), que je stock dans le segment DATA.
J’exécute ensuite une instruction du type pop ebp; leave; ret; afin de changer de stack-frame.

Envois du payload

Mise à zéro d’une variable en mémoire (premier read)

Lecture de l’adresse du HEAP envoyée

Création + envoi de la fake-stack-frame. Il s’agit s’implement d’un write() envoyant le flag.

Réception du flag et validation du challenge !!!

Un challenge simple, mais plutôt marrant.

Voici l’exploit entier :

Publié dans CTF | Marqué avec , , , | Laisser un commentaire