J'a découvert un peu par hasard un nouveau challenge de RE: Désamorcer une bombe logique.
Le concept est simple et intéressant. Vous avez un programme qui attend des entrées utilisateur. Si les réponses fournit ne sont pas correctes: BOOM c'est perdu, sinon vous passer à la phase suivante. Il y a en tout 6 phases à désamorcer dans ce challenge, plus une 7ème, cachée ;).

Le challenge original se trouve ici.

Init

Avant de se lancer dans le reverse il est utile de lire le manuel de ce challenge. On y apprend que l'on peut passer les inputs via un fichier texte, histoire de ne pas tout réécrire à la main à chaque fois.

Inputs phase 1
Inputs phase 2
...
Inputs phase 6
inputs.txt

Commençons par les vérifications d'usage.

|_$ rabin2 -I bomb

arch     x86
baddr    0x8048000
binsz    26943
bintype  elf
bits     32
canary   false
class    ELF32
compiler GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
crypto   false
endian   little
havecode true
intrp    /lib/ld-linux.so.2
laddr    0x0
lang     c
linenum  true
lsyms    true
machine  Intel 80386
maxopsz  16
minopsz  1
nx       false
os       linux
pcalign  0
pic      false
relocs   true
relro    no
rpath    NONE
sanitiz  false
static   false
stripped false
subsys   linux
va       true
file bomb

bomb: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.0.0, with debug_info, not stripped
rabin2 -zz bomb

[Strings]
nth paddr      vaddr      len size section         type  string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
53  0x00001660 0x08049660 59  60   .rodata         ascii Welcome to my fiendish little bomb. You have 6 phases with\n
54  0x000016a0 0x080496a0 44  45   .rodata         ascii which to blow yourself up. Have a nice day!\n
55  0x000016e0 0x080496e0 41  42   .rodata         ascii Phase 1 defused. How about the next one?\n
56  0x00001720 0x08049720 30  31   .rodata         ascii That's number 2.  Keep going!\n
57  0x0000173f 0x0804973f 15  16   .rodata         ascii Halfway there!\n
58  0x00001760 0x08049760 36  37   .rodata         ascii So you got that one.  Try this one.\n
59  0x000017a0 0x080497a0 30  31   .rodata         ascii Good work!  On to the next...\n
60  0x000017c0 0x080497c0 29  30   .rodata         ascii Public speaking is very easy.
63  0x00001820 0x08049820 38  39   .rodata         ascii Wow! You've defused the secret stage!\n
89  0x00001ac0 0x08049ac0 56  57   .rodata         ascii So you think you can stop the bomb with ctrl-c, do you?\n
90  0x00001af9 0x08049af9 7   8    .rodata         ascii Well...
99  0x00001b8a 0x08049b8a 27  28   .rodata         ascii Error: Input line too long\n
103 0x00001be5 0x08049be5 27  28   .rodata         ascii Subject: Bomb notification\n
110 0x00001c58 0x08049c58 22  23   .rodata         ascii /usr/sbin/sendmail -bm
116 0x00001ce1 0x08049ce1 9   10   .rodata         ascii \nBOOM!!!\n
117 0x00001ceb 0x08049ceb 23  24   .rodata         ascii The bomb has blown up.\n
120 0x00001d20 0x08049d20 39  40   .rodata         ascii Curses, you've found the secret phase!\n
121 0x00001d60 0x08049d60 53  54   .rodata         ascii But finding it and solving it are quite different...\n
122 0x00001da0 0x08049da0 42  43   .rodata         ascii Congratulations! You've defused the bomb!\n
123 0x00001e20 0x0804ae20 7   8    .data           ascii generic
124 0x00002220 0x0804b220 16  17   .data           ascii isrveawhobpnutfg
268 0x000042a6 0x0000000c 6   7    .debug_info     ascii bomb.c
Comme toujours j'ai fait le tri dans la sortie de cette commande

Exécutons le programme une première fois histoire de voir ce que ca donne.

Phase 1

Si on analyse le main on découvre l'appelle aux différentes fonctions.

Concentrons nous sur la fonction sym.initialize_bomb.

On remarque la mise en place d'un signal handler. En cherchant dans la documentation de signal, on découvre que c'est le signal d'interruption (nb: 2) qui sera intercepté. Vérifions cela:

La première fonction est directement écrite en version compilé dans le main.

Explorons cette fonction.

La lecture de notre première input est lue et stockée dans la pile. Il est ensuite utilisé dans la première fonction à désamorcer. Si l'input que l'on fournit est la même que celle en mémoire alors le registre EAX est mis à zéro. Si ce registre est à zéro alors on évite l'appelle à sym.explode_bomb.
Bien entendu la string en mémoire est celle qui est poussée sur la stack donc: "Public speaking is very easy."

Vérifions ça...

Bingo !

Et voilà qui conclu la première partie de ce challenge.

Social et Media

Comme toujours je suis disponible sur Twitter et cie, si vous avez des questions, des remarques, des suggestions etc. N’hésitez pas !

Twitter: @GhostAgs

Discord: hackraw