Nous utilisons Cutter pour ce challenge.
Une fois dans GDB, il faut ajouter un breakpoint sur la fonction main :
(gdb) b main
Breakpoint 1 at 0x1169
puis on lance le programme :
(gdb) run
Starting program: /app/password-manager
Breakpoint 1, 0x000055f840ab1169 in main ()
Ensuite, on désassemble la fonction main :
(gdb) disassemble main
Dump of assembler code for function main:
0x000055f840ab1165 <+0>: push %rbp
0x000055f840ab1166 <+1>: mov %rsp,%rbp
=> 0x000055f840ab1169 <+4>: sub $0x4b0,%rsp
0x000055f840ab1170 <+11>: movabs $0x491e1e4f4f194b1f,%rax # Séquence 0x491e1e4f4f194b1f
0x000055f840ab117a <+21>: movabs $0x4e481c1d4e191c1d,%rdx # Séquence 0x4e481c1d4e191c1d
0x000055f840ab1184 <+31>: mov %rax,-0x460(%rbp)
0x000055f840ab118b <+38>: mov %rdx,-0x458(%rbp)
0x000055f840ab1192 <+45>: movabs $0x4e12484f1818181a,%rax # Séquence 0x4e12484f1818181a
0x000055f840ab119c <+55>: movabs $0x4b1f491f1c181348,%rdx # Séquence 0x4b1f491f1c181348
0x000055f840ab11a6 <+65>: mov %rax,-0x450(%rbp)
0x000055f840ab11ad <+72>: mov %rdx,-0x448(%rbp)
0x000055f840ab11b4 <+79>: movabs $0x184c18131f1a1b1a,%rax # Séquence 0x184c18131f1a1b1a
0x000055f840ab11be <+89>: movabs $0x1b1b194b4b1e4e1e,%rdx # Séquence 0x1b1b194b4b1e4e1e
0x000055f840ab11c8 <+99>: mov %rax,-0x440(%rbp)
0x000055f840ab11cf <+106>: mov %rdx,-0x438(%rbp)
0x000055f840ab11d6 <+113>: movabs $0x4c1f49181d4b1f48,%rax # Séquence 0x4c1f49181d4b1f48
0x000055f840ab11e0 <+123>: movabs $0x131f4819131c4e1f,%rdx # Séquence 0x131f4819131c4e1f
0x000055f840ab11ea <+133>: mov %rax,-0x430(%rbp)
0x000055f840ab11f1 <+140>: mov %rdx,-0x428(%rbp)
0x000055f840ab11f8 <+147>: movl $0x5e525e04,-0x420(%rbp) # Séquence 0x5e525e04
0x000055f840ab1202 <+157>: movq $0x0,-0x4b0(%rbp)
0x000055f840ab120d <+168>: movq $0x0,-0x4a8(%rbp)
0x000055f840ab1218 <+179>: movq $0x0,-0x4a0(%rbp)
0x000055f840ab1223 <+190>: movq $0x0,-0x498(%rbp)
0x000055f840ab122e <+201>: movq $0x0,-0x490(%rbp)
0x000055f840ab1239 <+212>: movq $0x0,-0x488(%rbp)
0x000055f840ab1244 <+223>: movq $0x0,-0x480(%rbp)
0x000055f840ab124f <+234>: movq $0x0,-0x478(%rbp)
0x000055f840ab125a <+245>: movl $0x0,-0x470(%rbp)
0x000055f840ab1264 <+255>: movb $0x0,-0x46c(%rbp)
0x000055f840ab126b <+262>: lea 0xd96(%rip),%rdi # 0x55f840ab2008
0x000055f840ab1272 <+269>: call 0x55f840ab1030 <puts@plt> # affichage d'un message
0x000055f840ab1277 <+274>: mov 0x2dca(%rip),%rax # 0x55f840ab4048 <stdout@GLIBC_2.2.5>
0x000055f840ab127e <+281>: mov %rax,%rdi
0x000055f840ab1281 <+284>: call 0x55f840ab1050 <fflush@plt>
0x000055f840ab1286 <+289>: movl $0x0,-0x4(%rbp)
0x000055f840ab128d <+296>: jmp 0x55f840ab12b1 <main+332>
0x000055f840ab128f <+298>: mov -0x4(%rbp),%eax
0x000055f840ab1292 <+301>: cltq
0x000055f840ab1294 <+303>: movzbl -0x460(%rbp,%rax,1),%eax
0x000055f840ab129c <+311>: xor $0x2a,%eax # décode via XOR 0x2a sur chaque octet
0x000055f840ab129f <+314>: mov %eax,%edx
0x000055f840ab12a1 <+316>: mov -0x4(%rbp),%eax
0x000055f840ab12a4 <+319>: cltq
0x000055f840ab12a6 <+321>: mov %dl,-0x4b0(%rbp,%rax,1)
0x000055f840ab12ad <+328>: addl $0x1,-0x4(%rbp)
0x000055f840ab12b1 <+332>: cmpl $0x43,-0x4(%rbp) # taille
0x000055f840ab12b5 <+336>: jle 0x55f840ab128f <main+298> # tant qu'on n'est pas arrivé à la fin
0x000055f840ab12b7 <+338>: lea -0x4b0(%rbp),%rax # récupère la chaîne décodéé en rbp-0x4b0
0x000055f840ab12be <+345>: mov $0x0,%esi
0x000055f840ab12c3 <+350>: mov %rax,%rdi
0x000055f840ab12c6 <+353>: mov $0x0,%eax
0x000055f840ab12cb <+358>: call 0x55f840ab1060 <open@plt> # ouverture du fichier
0x000055f840ab12d0 <+363>: mov %eax,-0x8(%rbp)
0x000055f840ab12d3 <+366>: cmpl $0x0,-0x8(%rbp)
0x000055f840ab12d7 <+370>: jns 0x55f840ab12e5 <main+384>
0x000055f840ab12d9 <+372>: lea 0xd58(%rip),%rdi # 0x55f840ab2038
0x000055f840ab12e0 <+379>: call 0x55f840ab1030 <puts@plt> # affichage d'un message erreur si pbm
0x000055f840ab12e5 <+384>: lea -0x410(%rbp),%rcx
0x000055f840ab12ec <+391>: mov -0x8(%rbp),%eax
0x000055f840ab12ef <+394>: mov $0x80,%edx
0x000055f840ab12f4 <+399>: mov %rcx,%rsi
0x000055f840ab12f7 <+402>: mov %eax,%edi
0x000055f840ab12f9 <+404>: call 0x55f840ab1040 <read@plt> # lecture du fichier
0x000055f840ab12fe <+409>: mov %eax,-0xc(%rbp)
0x000055f840ab1301 <+412>: mov -0xc(%rbp),%eax
0x000055f840ab1304 <+415>: cltq
0x000055f840ab1306 <+417>: movq $0x0,-0x410(%rbp,%rax,8)
0x000055f840ab1312 <+429>: mov $0x0,%eax
0x000055f840ab1317 <+434>: leave
0x000055f840ab1318 <+435>: ret
End of assembler dump.
Donc, les séquences représentent un nom de fichier codé. Le nom est décodé octet par octet via une opération XOR 0x2a. Le nom de fichier est stocké en rbp - 0x4b0.
Pour avoir le nom du fichier décodé, on doit mettre un breakpoint à 0x000055f840ab12b7 :
(gdb) b *0x000055f840ab12b7
Breakpoint 2 at 0x55f840ab12b7
Puis on continue l’exécution du programme jusqu’à atteindre le 2ème breakpoint :
(gdb) continue
Continuing.
Welcome to my super secure password manager!
Breakpoint 2, 0x000055f840ab12b7 in main ()
Maintenant, pour avoir le nom du fichier, il faut afficher la mémoire en rbp - 0x4b0 :
(gdb) x/s ($rbp-0x4b0)
0x7ffe5b0af550: "5a3ee44c763d76bd0222eb8db9265c5a010592f24d4aa311b5a72c5f5d693b59.txt"
Nous avons maintenant le nom du fichier. Pour l’afficher :
(gdb) shell cat "5a3ee44c763d76bd0222eb8db9265c5a010592f24d4aa311b5a72c5f5d693b59.txt"
FCSC{da8ae129af8512620bc6c9a711392395fba426edc6713819c1baffe004024ff2}
Nous obtenons le flag.