对不起,如果这是一个奇怪的问题。
我其实对定时攻击很好奇,所以我做了一些研究并理解了这个概念。我明白了,代码如下:
if token == password:
print('Welcome')
else:
print('Wrong password')
相当于:
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 - 我正在使用 python 3.9.2
所以我制作了一个易受攻击的代码,如下所示:-
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()
这个简单的程序会将用户给定的密码(通过upass
参数)与存储在同一目录中的文件pass.txt中的密码进行比较。如果密码匹配,那么它会用欢迎消息问候用户,否则,它会提醒用户登录失败。
假设:-
- 密码长度为 4 个字符。
- 它只是大写字母(没有数值或特殊字符)。
我可以使用以下方法利用密码:-
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)
我得到了TEST
正确的输出。但是,您可以清楚地看到我没有使用==
字符串比较,实际上我使用的是它的等效方法。所以我决定切换回==
并检查我的漏洞利用是否有效。所以我将equal()
方法修改为:-
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
所以使用这段代码,当我调用该attack
方法时,令我惊讶的是它给了我非常奇怪的结果。当我多次运行它时,我得到了以下输出:AOAD
, BVCB
& LGAZ
。这显然不是pass.txt文件中存储的密码。
所以我的问题是,是==
不是容易受到定时攻击?