sorry if this is a weird question.
I was actually curious about timing attacks, so I have done a little research and understood the concept. I understood that, code like:
if token == password:
print('Welcome')
else:
print('Wrong password')
is equivalent to:
def equal(s1, s2):
if len(s1) != len(s2):
return False
for i in range(len(s1)):
if s1[i] != s2[i]:
return False
return True
PS - I am using python 3.9.2
So I have crafted a vulnerable code which looks like this:-
f = open('pass.txt', 'r')
password = f.read()
f.close()
def equal(s1, s2):
if len(s1) != len(s2):
return False
for i in range(len(s1)):
if s1[i] != s2[i]:
return False
return True
def login(upass):
if equal(upass, password):
print('Login successful')
else:
print('Login failed')
login()
This simple program will compare the user's given password (via the upass
parameter) with the password stored in the file pass.txt in the same directory. If the password matches then it will greet the user with a welcome message, otherwise, it will alert the user that the login has failed.
Assumptions:-
- Password is 4 characters long.
- It is ONLY uppercase alphabets (no numeric values or special characters).
I was able to exploit the password by using the below method:-
def attack():
leaked = ''
for i in range(4):
result = { letter : 0 for letter in ascii_uppercase }
for _ in range(50000):
for letter in ascii_uppercase:
string = leaked + letter + '.' * ( 4 - len(leaked) - len(letter) )
start = time_ns()
login(string)
end = time_ns()
result[letter] += end - start
leaked += sorted(result.items(), key = lambda item : item[1], reverse=True)[0][0]
print(leaked)
I got the output as TEST
which is correct. However, you can clearly see that I am not using ==
for string comparasion, in fact I am using its equivalent method. So I decided to switch back to ==
and check if my exploit is working. So I modified the equal()
method to this:-
def equal(s1, s2):
# if len(s1) != len(s2):
# return False
# for i in range(len(s1)):
# if s1[i] != s2[i]:
# return False
# return True
if s1 == s2:
return True
else:
return False
So using this code, when I called the attack
method, to my surprise it gave me pretty weird results. I was given the following output when I ran it multiple times: AOAD
, BVCB
& LGAZ
. This is clearly NOT the password stored in the pass.txt file.
So my question is, is ==
not vulnerable to timing attacks?