43980-7hjp9oraw53.png
破解密码Bruteforcing可能需要很长时间,大多数用户通常使用常用的英文单词或名称,以及数字作为密码。因此,字典攻击对于破解密码非常有用。

字典是一个简单的txt文件,可能包含几千到几百万个常用单词或短语(也包括数字)。

如果您有一个被盗的用户凭证数据库,您可以通过将所有字典单词与hashed passwords!

哈希通常是一种单向函数,可从输入字符串创建唯一摘要。例如,如果您的密码是hello_there,则输出哈希摘要将如下所示
算法 输出哈希
MD5 290e1c9cc54995453b810dfb15b853a1
SHA-1 f976f0ad02501f0a95bfcf3c1081e0759b508d47
SHA-256 299d2e40d6b7026b6029b8ff4cff0ad0fbfe14b20d704a609a2631cada32fb

在这里,MD5、SHA-1和SHA-256被广泛使用的散列算法将字符串转换为单向输出。

该术语one-way意味着您无法从散列输出中检索字符串。对密码进行哈希处理很重要,因为我们不想让密码公开。

如果您正在登录您的社交媒体帐户(例如 Facebook/Instagram)或您的笔记本电脑,则必须输入您的用户名和密码。但是,系统会维护一个包含您的姓名和散列密码的用户数据库。例如,

用户名 密码哈希
先生 678cfd979de6de0ec70d08b0b7a4b6aad645802abe2504aed9c4d1ca3da101c5
来宾_用户 3809f08dc16f01a7c9393eab3146e38e7ffd7d19b0aa5a3754aa2f7780fc4b77
其他 b712430498d0b31595b86c34a939b4dcdde5050a4e8a143e99037a6e6984a68f
现在,假设您已经窃取/找到了这样的用户凭证数据库。但是,由于无法计算字符串,因此需要在哈希后匹配不同的猜测字符串。

要求
被盗用户凭证数据库(两列:用户名、密码哈希)
一个字典文件(每行包含一个字典单词)
攻击者应该知道正在使用哪种算法。虽然这不是什么大问题。攻击者可以一个接一个地尝试所有算法。在这篇文章中,我们将使用SHA-256

创建一个简单的 Python 程序

首先,让我们导入必要的模块

import pandas as pd
from hashlib import sha256

现在,我们需要编写一个函数,如果哈希字典单词与数据库密码匹配,则返回 True

def dictionary_attack(dictionary_word,target_hash):
    pass_bytes = dictionary_word.encode('utf-8')
    pass_hash = sha256(pass_bytes)
    digest = pass_hash.hexdigest()
    if digest == target_hash:
        return True

假设,我们要检查是否可以破解第一个用户的密码。因此,我们需要password_hash从用户数据库中获取第一个,并依次传递所有字典单词。

if __name__ == "__main__":
    # read user DB and the dictionary using pandas.read_csv
    dictionary = pd.read_csv("password_dictionary", names=['passwords'])
    users = pd.read_csv("users")
    
    # match all words from the dictionary until it matches/ends
    for test_word in dictionary["passwords"]:
        if dictionary_attack(test_word,users["password_hash"][0]) == True:
            print("Matched Password: ", test_word)
            break
        else:
            continue

现在,在几秒钟内,我们从字典中得到了一个匹配的单词:2midrash.

好吧,如果你想破解所有用户的密码,你可以添加一个新的 for 循环来迭代所有用户的索引。或者对于任何范围的用户,您都可以创建这样的函数并在主函数中调用它。

# inputs an string and returns the sha256 digest
def create_hash(word):
    pass_bytes = word.encode('utf-8')
    pass_hash = sha256(pass_bytes)
    digest = pass_hash.hexdigest()
    return digest

# inputs the number of users and returns nothing
# intended for finding passwords for multiple users
def find_multiple_users(num_user):
    for i in range(num_user):
        check_pass = users["password_hash"][i]
        for test_word in dictionary["passwords"]:
            if create_hash(test_word) == check_pass:
                print("Found Matched Password:", test_word, "for user", users["username"][i])
                break

但是,我们上面使用的代码在为多个用户计算时效率很高。你能猜到,为什么?

因为我们每次匹配用户数据库密码时都会创建哈希。因此,如果我们对 20 个用户密码尝试 20000 个字典单词,则哈希计算的次数将是 20000*20。

为了避免额外的计算,我们可以预先计算哈希并将这些值保存在字典中。新字典将具有字典单词 askeys并且散列输出将是值。因此,我们可以在代码中添加一个额外的函数,如下所示

# Returns the dictionary of password and corresponding digests
def hash_dictionary():
    global hash_dict
    hash_dict = {}
    for test_word in dictionary["passwords"]:
        hash_dict[test_word] = create_hash(test_word)
    return hash_dict

您可以检查代码和文件并了解不同的实验设置。四个实验如下:

实验 1:为第一个用户匹配字典单词所需的时间
实验 2:近似平均。所有用户的时间
实验 3:如果使用哈希字典(预先计算的哈希),大约需要时间
实验 4:在用户密码中添加 Salt 以避免重复
这就是今天的全部内容,加油!