The main vulnerability for getting the admin password is that if you send in a maximum length username (32 bytes) and password (64 bytes) then no string terminating null character was written. Also, usernames and passwords were checked with memcpy and exact length instead of strcpy.
As the program prints out the logged in username this leads to leaking out the next value in the stack: the memcmp result of the admin password.
So the attack was basically:
- try to login with admin and the password you leaked so far (empty at first) plus “~” (0x7e)
- although this will lead to failed login, the memcpy result won’t be cleared
- I am using 0x7e because it is the last readable ASCII character and comparison with password will give smaller results
- try to login with username “guest” + “A”(32-5) and password “guest” + “A”(64-5)
- read the leaked value, this will be the positive difference between “~” and the next character from the password
- logout and try again, until you found the password and can login as admin :)
The admin password (=flag):