使用 John the Ripper 破解 SHA1 哈希

Kali LinuxBeginner
立即练习

引言

在本实验中,你将使用强大的开源密码破解工具 John the Ripper 来探索破解 SHA1 哈希的过程。理解哈希是如何被破解的,对于理解密码安全漏洞和实施更强的安全措施至关重要。你将学习如何从明文密码生成 SHA1 哈希,为 John the Ripper 准备这些哈希,然后使用该工具恢复原始密码。这种实践经验将让你深入了解哈希算法的有效性以及强壮、唯一的密码的重要性。

从密码生成 SHA1 哈希

在此步骤中,你将从几个示例密码生成 SHA1 哈希。SHA1 (Secure Hash Algorithm 1) 是一种加密哈希函数,它接收一个输入并生成一个 160 位(20 字节)的哈希值,通常表示为 40 位十六进制数字。虽然由于存在漏洞,SHA1 在某些应用中被认为在加密上已不安全,但它对于演示哈希破解原理仍然很有用。

首先,让我们创建一个名为 passwords.txt 的文件,其中包含一些简单的密码。

echo -e "password123\nlabexuser\nsecretpass" > passwords.txt

现在,我们将使用 sha1sum 命令为 passwords.txt 文件中的每个密码生成 SHA1 哈希。-t 选项告诉 sha1sum 以文本模式读取,-b 选项告诉它以二进制模式读取。我们将使用 xargs 将文件的每一行作为参数传递给 sha1sum

cat passwords.txt | xargs -I {} sh -c 'echo -n "{}" | sha1sum' > hashes.txt

此命令从 passwords.txt 读取每个密码,将其通过管道传递给 sha1sum(使用 echo -n 防止添加换行符,这会改变哈希值),然后将输出(哈希值和原始密码)重定向到一个名为 hashes.txt 的新文件中。

让我们查看 hashes.txt 的内容:

cat hashes.txt

你应该会看到类似以下的输出,其中每一行都包含一个 SHA1 哈希值,后面跟着原始密码:

5d41402abc4b2a76b9719d911017c592070b4783  password123
1234567890abcdef1234567890abcdef12345678  labexuser
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8  secretpass

注意: 第二列(原始密码)是 sha1sum 默认包含的。在破解时,John the Ripper 通常只需要哈希值本身。我们将在下一步为 John 准备文件。

为 SHA1 准备哈希文件

在此步骤中,你将准备 hashes.txt 文件,使其仅包含 SHA1 哈希值,这是 John the Ripper 进行破解时期望的格式。当前的 hashes.txt 文件同时包含哈希值和原始密码,这不适合作为 John 的输入。

我们将从 hashes.txt 中提取哈希值,并将它们保存到一个名为 sha1_hashes_for_john.txt 的新文件中。我们可以使用 awk 命令来实现这一点,因为它允许我们轻松地从文件中选择特定的列。

awk '{print $1}' hashes.txt > sha1_hashes_for_john.txt

此命令指示 awk 打印 hashes.txt 中每一行的第一个字段($1),并将输出重定向到 sha1_hashes_for_john.txt

现在,让我们检查新文件的内容,确保它只包含哈希值:

cat sha1_hashes_for_john.txt

你应该会看到类似以下的输出,只列出了 SHA1 哈希值:

5d41402abc4b2a76b9719d911017c592070b4783
1234567890abcdef1234567890abcdef12345678
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8

现在该文件已准备好用作 John the Ripper 的输入。

使用 John the Ripper 破解 SHA1 哈希

在此步骤中,你将使用 John the Ripper 来破解存储在 sha1_hashes_for_john.txt 中的 SHA1 哈希。John the Ripper 是一个快速的密码破解工具,支持多种操作系统。它的主要目的是检测弱 Unix 密码。它支持多种哈希类型,包括 SHA1。

我们将使用 John the Ripper 的“字典模式”(wordlist mode)来尝试破解哈希。此模式会尝试使用预定义的列表(“字典”)中的密码。在本实验中,我们将创建一个包含原始密码的简单字典文件。在实际场景中,你将使用一个更大、更全面的字典。

首先,创建一个名为 wordlist.txt 的简单字典文件:

echo -e "password123\nlabexuser\nsecretpass\nwrongpass\notherpass" > wordlist.txt

现在,运行 John the Ripper,并提供准备好的哈希文件和字典:

john --format=raw-sha1 --wordlist=wordlist.txt sha1_hashes_for_john.txt

让我们分解一下这个命令:

  • john: 调用 John the Ripper 的命令。
  • --format=raw-sha1: 指定输入的哈希是原始 SHA1 哈希。John 支持多种格式,指定正确的格式有助于其高效破解。
  • --wordlist=wordlist.txt: 告诉 John 使用 wordlist.txt 作为破解的字典。
  • sha1_hashes_for_john.txt: 包含待破解哈希的文件。

运行命令后,John 将尝试破解哈希。如果成功,它将显示破解出的密码。

你应该会看到类似以下的输出,表明已成功破解密码:

Using default input encoding: UTF-8
Loaded 3 password hashes with no different salts (Raw-SHA1 [SHA1])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
password123      (5d41402abc4b2a76b9719d911017c592070b4783)
labexuser        (1234567890abcdef1234567890abcdef12345678)
secretpass       (5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8)
3g 0:00:00:00 DONE (2023-10-27 10:30) 100.0% (ETA: 00:00:00) 3.000g/s 100.0p/s 100.0c/s 100.0C/s password123..secretpass
Session completed.

要再次查看破解出的密码,你可以使用 --show 选项:

john --show sha1_hashes_for_john.txt

此命令将显示 John 已成功破解并存储在其内部 pot 文件中的所有哈希。

password123:5d41402abc4b2a76b9719d911017c592070b4783
labexuser:1234567890abcdef1234567890abcdef12345678
secretpass:5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8

3 password hashes cracked, 0 left

分析 SHA1 破解性能

在此步骤中,你将简要分析 John the Ripper 破解 SHA1 哈希的性能。虽然我们的示例使用了非常小的字典和简单的密码,但在实际场景中,破解性能是一个关键因素。

John the Ripper 在其输出中提供了一些性能指标,例如“g/s”(每秒猜测次数)和“p/s”(每秒密码次数)。这些指标表明 John 每秒可以进行多少次密码尝试。

让我们重新运行破解命令并仔细观察输出:

john --format=raw-sha1 --wordlist=wordlist.txt sha1_hashes_for_john.txt

在输出中查找类似以下的行:

3g 0:00:00:00 DONE (2023-10-27 10:30) 100.0% (ETA: 00:00:00) 3.000g/s 100.0p/s 100.0c/s 100.0C/s password123..secretpass

这里,3.000g/s 表示 John 每秒处理 3 次猜测,而 100.0p/s 表示每秒处理 100 个密码。对于如此少量的哈希和微小的字典,破解几乎是瞬时的。

影响破解性能的因素:

  • 密码复杂度: 简单、常见的密码比复杂、唯一的密码破解得快得多。
  • 字典大小和质量: 更大、更相关的字典会增加破解的成功率,但也会增加所需时间。
  • 哈希算法: 一些哈希算法被设计为计算密集型(例如 bcrypt、scrypt),以减慢破解尝试的速度,而其他算法(如原始 SHA1)则相对较快。
  • 硬件: 破解机器的处理能力(CPU/GPU)对性能有显著影响。

这个简要分析表明,即使使用像 John the Ripper 这样强大的工具,原始密码的强度和哈希算法在破解哈希所需的时间中也起着至关重要的作用。

理解 SHA1 哈希特性

在此步骤中,你将更深入地理解 SHA1 哈希的特性,以及为什么在存储密码时使用更强的哈希算法至关重要。

SHA1 的关键特性:

  1. 固定输出大小: 无论输入大小如何,SHA1 始终生成一个 160 位(20 字节)的哈希值。这就是为什么你会看到一个 40 个字符的十六进制字符串。
  2. 单向函数: 从哈希值反向推导出原始输入在计算上是不可行的。这就是为什么破解依赖于暴力破解或字典攻击。
  3. 确定性: 相同的输入总是会产生相同的 SHA1 哈希。此属性对于验证数据完整性至关重要。
  4. 雪崩效应: 输入的微小变化(即使是单个比特)也会导致哈希输出发生巨大变化。这使得根据哈希相似性来猜测输入变得困难。

为什么 SHA1 被认为不适用于密码存储:

  • 碰撞攻击: 2017 年,针对 SHA1 的实际碰撞攻击被演示。当两个不同的输入产生相同的哈希输出时,就发生了碰撞。虽然找到碰撞并不直接泄露原始密码,但它破坏了哈希函数的完整性,并可能在各种攻击中被利用。
  • 速度: SHA1 的计算速度相对较快。这种速度,加上现代计算能力,使其容易受到暴力破解和字典攻击,特别是针对常见或弱密码。
  • 缺乏加盐(Salting): 如本实验所示,原始 SHA1 哈希本身不包含“加盐”。加盐是指在哈希之前向每个密码添加一个唯一的、随机的字符串。这可以防止预计算的彩虹表(rainbow tables)生效,并确保即使存储在同一数据库中,两个相同的密码也会产生不同的哈希。

对于安全的密码存储,如今推荐使用更强、更慢且加盐的哈希算法,如 bcryptscryptArgon2。这些算法被设计为计算密集型,使得暴力破解攻击更加耗时且成本更高。

本次实验演示了使用 SHA1 进行哈希破解的基本原理。它提醒我们使用健壮的哈希算法以及强壮、唯一的密码来保护敏感信息的重要性。

总结

在本实验中,你成功学会了如何从明文密码生成 SHA1 哈希,并为破解做准备。然后,你使用 John the Ripper 的字典模式破解了这些 SHA1 哈希,恢复了原始密码。此外,你还深入了解了影响哈希破解性能的因素,并理解了 SHA1 的关键特性,包括由于其速度和易受碰撞攻击的影响,它不再被认为是安全的密码存储方式。这次实践经验强化了使用强壮、唯一的密码以及 bcrypt、scrypt 或 Argon2 等现代、健壮的哈希算法进行安全密码管理的重要性。