3 perc
AlphaASCII testing
Forrás
A feladathoz egy zip fájl és egy socket van megadva.
A zip-ben csupán egy server.py
fájl van:
from hashlib import md5
import json
'''
Data format:
{
username: [md5(username).hexdigest(), password],
.
.
.
}
'''
users = {
'HTBUser132' : [md5(b'HTBUser132').hexdigest(), 'secure123!'],
'JohnMarcus' : [md5(b'JohnMarcus').hexdigest(), '0123456789']
}
def get_option():
return input('''
Welcome to my login application scaredy cat ! I am using MD5 to save the passwords in the database.
I am more than certain that this is secure.
You can't prove me wrong!
[1] Login
[2] Register
[3] Exit
Option (json format) :: ''')
def main():
while True:
option = json.loads(get_option())
if 'option' not in option:
print('[-] please, enter a valid option!')
continue
option = option['option']
if option == 'login':
creds = json.loads(input('enter credentials (json format) :: '))
usr, pwd = creds['username'], creds['password']
usr_hash = md5(usr.encode()).hexdigest()
for db_user, v in users.items():
if [usr_hash, pwd] == v:
if usr == db_user:
print(f'[+] welcome, {usr} 🤖!')
else:
print(f"[+] what?! this was unexpected. shutting down the system :: {open('flag.txt').read()} 👽")
exit()
break
else:
print('[-] invalid username and/or password!')
elif option == 'register':
creds = json.loads(input('enter credentials (json format) :: '))
usr, pwd = creds['username'], creds['password']
if usr.isalnum() and pwd.isalnum():
usr_hash = md5(usr.encode()).hexdigest()
if usr not in users.keys():
users[usr] = [md5(usr.encode()).hexdigest(), pwd]
else:
print('[-] this user already exists!')
else:
print('[-] your credentials must contain only ascii letters and digits.')
elif option == 'exit':
print('byeee.')
break
if __name__ == '__main__':
main()
Magyarázat
A socket túloldalán ez a program fut (netcat-el elérhető).
A program egy szótárban tárol (users) felhasználókat és azok jelszavait, ahol a kulcs a felhasználónév, az érték pedig egy 2 hosszú tömb a név MD5 hashével és a felhasználó (cleartext) jelszavával.
Kettő dolgot tudunk csinálni az alkalmazással: regisztrálni és belépni. Regisztrálásnál ({"option": "register"}
) egy felhasználónevet és jelszót kell megadni ({"username": "...", "password": "..."}
). A bejelentkezés ({"option": "login"}
) ugyan így működik.
Cél
A cél az, hogy az 50. sorban lévő print utasítás lefusson, ami kiírja a flag.txt tartalmát. Ez úgy érhető el, ha van 2 felhasználó akiknek megegyező a user hash értéke és a jelszava, azonban eltérő névvel rendelkeznek. Röviden hash ütközést kell elérni, ami MD5 esetén nem egy nehéz dolog.
Megoldás
Kereshetnénk a már regisztrált felhasználók neveivel ütköző hasheket is, de mivel mi is be tudunk regisztrálni, így egyszerűbb már ismert ütközésekkel megoldani. Egy kis kutatás után tatáltam egy X bejegyzést, ahol megemlítenek 2 egyező MD5 hasht. Regisztrálunk két felhasználót a két különböző, ám azonos MD5 hashű felhasználónévvel. A jeszló értéke lényegtelen, de egyezniük kell. Ezután bejelentkezünk a másodjára regisztrált felhasználóval, ezzel a kívánt útra terelve a végrehajtást.
{"option": "register"}
{"username": "TEXTCOLLBYfGiJUETHQ4hEcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak", "password": "pws"}
{"option": "register"}
{"username": "TEXTCOLLBYfGiJUETHQ4hAcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak", "password": "pws"}
{"option": "login"}
{"username": "TEXTCOLLBYfGiJUETHQ4hAcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak", "password": "pws"}