John the Ripper 与密码加盐

Kali LinuxBeginner
立即练习

引言

在网络安全领域,保护用户凭证至关重要。密码在存储时,很少以明文形式保存。通常,它们会被哈希(hashed),这意味着使用单向加密函数将其转换为固定长度的字符字符串。即使攻击者获得了数据库访问权限,这也能防止他们直接获取密码。然而,简单的哈希是不够的。攻击者可以使用预先计算好的哈希表(彩虹表,rainbow tables)或暴力破解(brute-force attacks)来破解密码。

这时,“加盐”(salting)技术就派上用场了。加盐是一种技术,在哈希密码之前,会向密码添加一个独特的、随机的字符串(即“盐”,salt)。然后,这个盐会与哈希值一起存储。当用户尝试登录时,会检索相同的盐,并将其与输入的密码结合后再进行哈希,然后将生成的哈希值与存储的哈希值进行比较。

在这个实验(lab)中,你将探索密码加盐的概念,理解它在增强安全性方面的重要性,并观察像 John the Ripper 这样强大的密码破解工具如何与加盐哈希进行交互。你将学会识别加盐哈希,了解 John the Ripper 如何处理它们,并掌握加盐技术对密码破解难度的显著影响。最后,你将一窥加盐技术在实际密码存储中的实现方式。

理解加盐(Salting)的概念

在本步骤中,你将学习密码加盐的基本概念,以及它为何对增强密码安全性至关重要。

当密码被“加盐”时,一个独特的、随机的字符串(盐)会在密码被哈希之前添加到密码中。这意味着即使两个用户拥有完全相同的密码,他们的存储哈希值也会不同,因为每个人使用了不同的盐。这有效地对抗了依赖于给定密码的固定哈希的预计算彩虹表。它也使得暴力破解攻击更加困难,因为攻击者必须计算每个可能的密码 每个可能的盐的哈希值,而不仅仅是每个可能的密码。

让我们来看一个加盐哈希的例子。打开在你 ~/project 目录中创建的 salted_passwords.txt 文件。

cat ~/project/salted_passwords.txt

你将看到类似以下的输出:

user1:$6$salt12345$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:user1password
user2:5f4dcc3b5aa765d61d8327deb882cf99
user3:$6$another_salt$zyxwuvtsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA./:anotherpassword
user4:$6$short$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:shortpass

注意 user1user3user4 的行。它们包含一个类似 $6$salt12345$$6$another_salt$ 的部分。$6$ 表示使用的哈希算法(本例中为 SHA-512),而第二个和第三个 $ 符号之间的字符串(salt12345another_salt)就是盐。第三个 $ 之后的部分是密码与盐组合后的实际哈希值。user2 的行是一个未加盐的 MD5 哈希,我们稍后会用它进行比较。

关键要点是,每个加盐哈希都有一个独特的盐,这使得使用相同的预计算表同时破解多个密码更加困难。

识别加盐哈希

在本步骤中,你将学习如何根据常见格式识别加盐哈希。识别这些格式是理解如何进行密码破解或防御的第一步。

不同的哈希算法和系统使用各种格式来存储加盐哈希。然而,许多常见格式,尤其是在 Linux 系统中使用的格式,都遵循一种模式:盐直接嵌入在哈希字符串中,通常由 $ 等特殊字符分隔。

让我们重新检查 salted_passwords.txt 文件,并专门寻找指示加盐的模式。

cat ~/project/salted_passwords.txt

正如你在上一步中观察到的:

  • user1:$6$salt12345$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:user1password
  • user3:$6$another_salt$zyxwuvtsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA./:anotherpassword
  • user4:$6$short$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:shortpass

这些行清楚地显示了 $6$ 前缀(表示 SHA-512 crypt),后面跟着盐字符串(例如 salt12345another_saltshort),然后是实际的哈希。这种结构是加盐哈希的一个有力指示。

相比之下,user2 的行:

  • user2:5f4dcc3b5aa765d61d8327deb882cf99

这是一个简单的 MD5 哈希。它没有任何分隔符或嵌入的盐,因此很容易被识别为未加盐的哈希。

能够快速区分加盐和未加盐哈希对于安全专业人员和渗透测试人员至关重要,因为它决定了可以采用的破解策略。

观察 John the Ripper 如何处理加盐哈希

在本步骤中,你将使用流行的密码破解工具 John the Ripper 来观察它如何处理加盐和未加盐的哈希。这将展示加盐的实际影响。

首先,让我们尝试使用一个简单的单词列表来破解 salted_passwords.txt 中的密码。我们将为此演示使用一个小型自定义单词列表。

在你的 ~/project 目录中创建一个名为 wordlist.txt 的单词列表文件,其中包含一些常用密码:

echo "password" > ~/project/wordlist.txt
echo "user1password" >> ~/project/wordlist.txt
echo "anotherpassword" >> ~/project/wordlist.txt
echo "shortpass" >> ~/project/wordlist.txt
echo "123456" >> ~/project/wordlist.txt

现在,使用此单词列表针对你的 salted_passwords.txt 文件运行 John the Ripper:

john --wordlist=~/project/wordlist.txt ~/project/salted_passwords.txt

John the Ripper 将会分析哈希。你应该会看到输出表明它正在尝试破解密码。它可能会很快找到 user2 的密码,因为这是一个未加盐的 MD5 哈希,并且“password”在单词列表中。如果相应的明文在单词列表中,它也会找到加盐的密码。

示例输出可能如下所示:

Using default input encoding: UTF-8
Loaded 4 password hashes with no different salts to crack (crypt, generic crypt(3) [MD5/Blowfish/SHA1/SHA256/SHA512/XSHAa/XSHAab/bcrypt/scrypt])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
password         (user2)
user1password    (user1)
anotherpassword  (user3)
shortpass        (user4)
4g 0:00:00:00 DONE (2023-10-27 10:30) ...
Session completed.

John 运行完成后,你可以使用 --show 选项查看已破解的密码:

john --show ~/project/salted_passwords.txt

此命令将显示 John 成功破解的任何密码。

user2:password (user2)
user1:user1password (user1)
user3:anotherpassword (user3)
user4:shortpass (user4)

4 password hashes cracked, 0 left

John the Ripper 被设计用来处理各种哈希格式,包括带有嵌入式盐的格式。它会自动提取盐并在破解过程中使用它。然而,每个密码都存在唯一的盐,这显著增加了破解所需的计算量,尤其是在大规模攻击中。

理解加盐对破解的影响

在本步骤中,你将巩固对加盐为何能显著增加密码破解难度的理解,尤其是在大规模攻击中。

考虑我们 salted_passwords.txt 文件中的 user2 条目:user2:5f4dcc3b5aa765d61d8327deb882cf99。这是密码“password”的未加盐 MD5 哈希。如果攻击者获取了一个未加盐 MD5 哈希数据库,他们可以:

  1. 使用彩虹表 (Rainbow Tables):预先计算好的常用密码哈希表。如果“password”在表中,那么它的哈希 5f4dcc3b5aa765d61d8327deb882cf99 也会在那里,并且可以立即检索到明文。
  2. 同时破解多个密码:如果许多用户拥有相同的弱密码(例如,“123456”),他们的未加盐哈希将是相同的。攻击者只需要破解该哈希的一个实例,就能知道所有共享该密码的用户的密码。

现在,让我们看看加盐的哈希:

  • user1:$6$salt12345$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:user1password
  • user3:$6$another_salt$zyxwuvtsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA./:anotherpassword

即使 user1user3 拥有完全相同的密码,他们的哈希也会不同,因为他们的盐(salt12345another_salt)是不同的。这对攻击者有几个关键影响:

  • 彩虹表无效:由于每个哈希都因其盐而变得独一无二,预先计算的彩虹表变得无效。攻击者需要为每种可能的盐准备一个彩虹表,这在计算上是不可行的。
  • 逐个哈希破解:攻击者必须单独破解每个加盐哈希。如果 100 个用户拥有相同的密码,但每个用户都有一个唯一的盐,攻击者必须执行 100 次单独的破解操作,每次针对一个唯一的哈希 - 盐对。这极大地增加了成功攻击所需的时间和资源。
  • 暴力破解的难度增加:对于暴力破解攻击,攻击者必须将每个可能的密码与其特定的盐结合起来,然后再进行哈希和比较。这增加了一个复杂层,并与未加盐哈希相比,显著减慢了破解过程。

本质上,加盐将一个破解问题转化为许多独立的破解问题,使得大规模密码泄露对攻击者来说更加困难和耗时。

实现加盐密码存储

在本步骤中,你将对加盐在实际密码存储系统中如何实现有一个概念性的理解。虽然我们不会构建一个完整的系统,但你将看到核心组件。

当用户设置或更改密码时,一个安全的系统通常会执行以下步骤:

  1. 生成随机盐 (Random Salt):生成一个加密安全的随机盐。此盐对于每个用户和每次密码更改都应该是唯一的。
  2. 组合密码和盐:用户的明文密码与生成的盐连接起来。
  3. 哈希组合字符串:然后将组合后的密码和盐字符串通过一个强大且慢速的哈希算法(例如,bcrypt、scrypt、Argon2 或我们在示例中看到的 SHA-512 crypt)进行哈希。选择慢速哈希算法是因为它们能使暴力破解攻击更加耗时。
  4. 存储哈希和盐:生成的哈希和盐一起存储在数据库中。盐不需要保密;它的目的是确保哈希的唯一性。

当用户尝试登录时:

  1. 检索存储的盐:系统从数据库中检索与用户账户关联的盐。
  2. 组合输入的密码和存储的盐:用户输入的密码与检索到的盐组合在一起。
  3. 哈希组合字符串:然后使用注册期间使用的相同哈希算法对该组合字符串进行哈希。
  4. 比较哈希:将新计算出的哈希与存储的哈希进行比较。如果匹配,则密码是正确的。

让我们使用 mkpasswd 命令来模拟生成一个加盐哈希,该命令是 whois 包的一部分,可以生成 crypt(3) 风格的哈希。

首先,确保已安装 whois

sudo apt install -y whois

现在,为密码“mysecretpassword”生成一个 SHA-512 加盐哈希,并使用自定义盐“mysalt”:

mkpasswd -m sha-512 "mysecretpassword" -s "mysalt"

你将看到类似以下的输出:

$6$mysalt$some_long_hash_string_here

输出 $6$mysalt$some_long_hash_string_here 是加盐哈希。$6$ 表示 SHA-512,mysalt 是你提供的盐,其余部分是实际的哈希。在实际系统中,盐会是随机生成的,而不是手动提供的。

这演示了基本过程。现代应用程序使用库和框架来抽象这些细节,但生成唯一盐、将其与密码组合、哈希并存储两者这一基本原理仍然是安全密码存储的基石。

总结

在本实验中,你对密码加盐及其在增强密码安全性方面的重要作用有了全面的理解。你了解到加盐涉及在密码哈希之前添加一个独特的随机字符串(盐),从而使即使是相同的密码,每个哈希也都是唯一的。

你通过其特征格式成功识别了加盐哈希,这些格式通常包含像 $ 这样的分隔符和一个嵌入的盐字符串。通过使用 John the Ripper 进行实际观察,你看到了这个强大的工具如何处理加盐和未加盐哈希,以及至关重要的是,加盐如何迫使破解过程必须针对每个哈希进行,从而显著增加了攻击者的计算工作量。

最后,你探索了密码存储系统中加盐的概念性实现,理解了生成、组合、哈希和存储盐与密码所涉及的步骤。这些知识对于任何从事网络安全的人来说都是基础,无论是为了防御系统还是理解攻击方法。

通过使每个密码哈希都独一无二,加盐有效地缓解了彩虹表攻击的威胁,并极大地减缓了暴力破解的尝试速度,使其成为健壮密码安全不可或缺的技术。