===== Clark Kent (Reverse150) ===== lien pour télécharger l'archive : [[http://repo.zenk-security.com/ctfs/ndh2k15/clark.tar.gz]] Après extraction de l'archive de l'épreuve, on a un fichier texte "Clark.txt" contenant une citation de Clark Ken et un binaire linux 32-bit. On commence par l'exécuter : $ ./clark Welcome to NDH2k15 Need supercow power!!! Bye! okay... Quand on essaie de débugger le binaire avec gdb, on a une erreur : "./clark": not in executable format: File truncated gdb-peda$ En effet, le header elf est corrompu : angel_killah@mybox:[~/VMShared/hzv/reverse]: readelf -h clark ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x0 Entry point address: 0x80483e0 Start of program headers: 52 (bytes into file) Start of section headers: 123 (bytes into file) Flags: 0x0 Size of this header: 0 (bytes) Size of program headers: 32 (bytes) Number of program headers: 9 Size of section headers: 0 (bytes) Number of section headers: 0 Section header string table index: 0 readelf: Warning: possibly corrupt ELF file header - it has a non-zero section header offset, but no section headers on hexedit le binaire en remplaçant 0x7B qui se trouve à l'offset 0x20 (qui correspond à l'offset de la section header en hexa) par 0. En regardant le code en statique via IDA, on remarque plusieurs choses : * Il y a un appel à la fonction ptrace() pour vérifier que le processus n'est pas attaché à un debugger * Il y a un calcul de checksum sur le code entre 0x80484E6 et 0x80485E1 * Après ces différents tricks anti-debugs, on a un call eax On va débugger pour voir rapidement sur quelle adresse pointe le call eax. Pour bypass le ptrace, pas de problème, on utilise la commande "unptrace" de peda ([[https://github.com/longld/peda]] qui va s'occuper de désactiver le ptrace. Ensuite, on veut breaker au "call eax" mais pour cela il va falloir poser un hardware breakpoint pour bypass le calcul du checksum. En effet, si on pose un breakpoint classique sur call eax, l'instruction va être temporairement remplacé par l'opcode 0xCC correspondant à int 3, ce qui va du coup modifier l'intégrité du code et donc modifier le checksum. Du coup, on va poser un hardware breakpoint, car il a le même effet que le breakpoint classique sauf qu'il ne modifie pas le code mais seulement un registre. Pour poser un hardware breakpoint, il faut déjà que le binaire soit en cours d'exécution. Pas de problème, on va poser un breakpoint sur le main (à 0x8084DD), cette adresse n'étant pas incluse dans le calcul du checksum, on n'aura pas de problème. Ensuite on pose un hardware breakpoint sur le call eax (à 0x80485DF) les commandes à taper sous gdb/peda : unptrace b *0x80484DD r hb *0x80485DF De là, on voit qu'au moment du call eax, eax vaut : 0x804b008. Cette section correspond au heap du binaire (on peut le voir via la commande vmmap sous gdb/peda) On va dumper cette section pour avoir une vision globale du code sous ida, pour cela on va utiliser dumpmem : gdb-peda$ dumpmem out 0x0804b000 Dumped 4096 bytes to 'out' En analysant ce nouveau bout de code sous IDA, on voit plusieurs choses intéressantes : * il y a un appel au syscall sys_getuid pour vérifier qu'on est en root, sinon il y a un msg d'erreur + exit() * à la fin du code, il y a une comparaison, puis une branche avec un appel à sys_write qui doit écrire le message de félicitation (qu'on appelera goodboy) sur le terminal et l'autre branche avec le message d'insulte (qu'on appelera badboy) Et là en faite on a rien besoin de reverser, on remarque que l'adresse de ces chaines sont dans la même zone mémoire : ([esi+149h] pour le badboy, [esi+155h] pour le goodboy gdb-peda$ x/40s $esi+0x135 0x804b13d: "OMG! Why you root?\n" 0x804b151: "Try again!\n" 0x804b15d: "Congratz!\n" 0x804b168: "WhyN0P4tch?" => flag lol