【THM】Hashing Basics(哈希基础知识)-学习
本文相关的TryHackMe实验房间链接:https://tryhackme.com/r/room/hashingbasics
本文相关内容:了解哈希函数及其在密码验证和文件完整性检查中的用途。
介绍
思考这样的场景:你刚刚下载了一个 6 GB 的文件,现在你想知道你所下载的副本文件是否与原始文件完全相同。你会怎么做?或者,如果有一位好心人将USB存储驱动器上的 6 GB 文件移交给你,你将如何确定它与你实际想要下载的文件相同呢?
上述两个问题的答案在于比较两个文件的哈希值;如果两个哈希值相等,则可以非常肯定地说这两个文件是相同的。但什么是哈希值呢?
哈希值是通过使用哈希函数计算得到的固定大小的字符或字符串。哈希函数能够接受任意大小的输入并且会返回固定长度的输出,即哈希值。我们将在本文的内容中介绍哈希函数和哈希值的各种令人兴奋的巧妙用法。
关于术语的说明:我们更喜欢“哈希函数-hash function”和“哈希值-hash value”术语,然而,我们偶尔也会将hash这个词作为动词来使用 以表示计算哈希值这一行为;此外,我们偶尔还会单独使用hash一词作为名词来指代哈希值。
学习目标
完成本文的内容学习之后,你将了解到:
- 什么是哈希函数和哈希冲突(碰撞);
- 哈希在身份验证系统中的作用;
- 如何识别已存储的哈希值;
- 如何破解哈希值;
- 如何使用哈希来进行数据完整性保护。
首先,让我们访问与本文相关的TryHackMe实验房间页面,并且在实验房间页面中点击“启动计算机”按钮来启动目标虚拟机以完成实验环境的部署。
目标机器将会以分屏视图启动。如果目标虚拟机不可见,请尝试点击实验房间页面顶部的蓝色显示拆分视图按钮。
在实验需要的时候,你还可以使用以下凭据并基于目标IP地址MACHINE_IP
来使用SSH远程访问目标虚拟机:
- Username:
user
- Password:
Tryhackme123!
哈希函数
什么是哈希函数?
哈希函数与加密不同。哈希函数在使用时没有密钥,并且我们基本上不可能(或者在计算上不切实际)从输出返回到输入。
哈希函数会接受一些任意大小的输入数据,并且能创建该数据的总结或摘要(digest)。哈希函数的输出具有固定大小,我们很难预测任何输入的输出,反之亦然。好的哈希算法的计算速度相对较快,而逆向计算(即从输出推导出输入)的速度则极其缓慢。在使用哈希函数时,输入数据的任何细微变化,即使是一位(bit)变化,都会导致输出发生显著变化。
让我们看一个例子。在下面的终端示例中,我们可以看到两个文件;第一个文件的内容包含字母 T,而第二个文件的内容包含字母 U。如果你在ASCII表中检查T和U或者使用hexdump
进行查看 ,你会注意到这两个字母有一位(bit)不同。
- 字母T的十六进制表示为
54
,它的二进制表示为01010100
; - 字母U的十六进制表示为
55
,它的二进制表示为01010101
。
因此,这两个文件仅有一位(bit)不同。但是,如果我们比较它们的MD5(Message-Digest Algorithm 5)哈希值、SHA1(Secure Hash Algorithm 1)哈希值或SHA-256(Secure Hash Algorithm 256)哈希值,我们就会发现它们的内容完全不同。如下所示,这些文件位于目标虚拟机上的~/Hashing-Basics/Task-2/
中。
strategos@g5000 ~> cat file1.txt
T⏎
strategos@g5000 ~> cat file2.txt
U⏎
strategos@g5000 ~> hexdump -C file1.txt
00000000 54 |T|
00000001
strategos@g5000 ~> hexdump -C file2.txt
00000000 55 |U|
00000001
strategos@g5000 ~> md5sum *.txt
b9ece18c950afbfa6b0fdbfa4ff731d3 file1.txt
4c614360da93c0a041b22e537de151eb file2.txt
strategos@g5000 ~> sha1sum *.txt
c2c53d66948214258a26ca9ca845d7ac0c17f8e7 file1.txt
b2c7c0caa10a0cca5ea7d69e54018ae0c0389dd6 file2.txt
strategos@g5000 ~> sha256sum *.txt
e632b7095b0bf32c260fa4c539e9fd7b852d0de454e9be26f24d0d6f91d069d3 file1.txt
a25513c7e0f6eaa80a3337ee18081b9e2ed09e00af8531c8f7bb2542764027e7 file2.txt
哈希函数的输出通常是原始字节,然后可再对其进行编码。常见的编码方式是base64或十六进制。 md5sum
、 sha1sum
、 sha256sum
和sha512sum
的输出都是十六进制格式。请记住,十六进制格式会将每个原始字节打印为两个十六进制数字。
为什么哈希很重要?
哈希(Hashing)在我们日常的互联网使用中扮演着至关重要的角色。与其他加密函数一样,哈希算法对用户来说是隐藏的。哈希算法有助于保护数据的完整性并确保密码的机密性。
思考下面这个使用哈希算法来保护你的网络安全的示例:
当你登录 TryHackMe 时,服务器会使用哈希算法来验证你的密码。事实上,根据良好的安全实践,服务器不会记录你的密码,而是会记录密码的哈希值。每当你想要登录时,服务器都会计算你提交的密码的哈希值并且与服务器中已记录的哈希值进行比对。同样,当你登录计算机时,哈希算法也会在验证密码方面发挥作用。你与哈希算法的交互比你想象中的要更加间接,而且它几乎每天都会与密码打交道。
什么是哈希碰撞?
哈希碰撞是指两个不同的输入产生相同的哈希输出。哈希函数的设计目标是尽可能避免发生碰撞。此外,哈希函数在设计时也考虑到了尽量防止攻击者故意制造(即设计)哈希碰撞。然而,由于哈希输入的数量几乎是无限的,而可能的哈希输出的数量是有限的,这会导致鸽笼效应。
举个数字示例,如果一个哈希函数生成一个 4 位(4-bit)哈希值,那么我们最多只有 16 个不同的哈希值。可能产生的哈希值总数为2number_of_bits=24=16 。发生碰撞的概率相对较高。
鸽笼效应是指物品(鸽子)的数量多于容器(鸽笼)的数量;有些容器必须容纳不止一件物品。换句话说,在这种情况下,哈希函数有固定数量的不同输出值,但你可以为其提供任意大小的输入。由于输入多于输出,某些输入必然会产生相同的输出。如果你有21只鸽子和16个鸽笼,那么总会有一些鸽子会共享鸽笼。因此,碰撞是不可避免的。然而,一个好的哈希函数可以确保发生哈希碰撞的概率可以忽略不计。
MD5 和 SHA1 都曾遭受攻击,由于它们能够制造哈希碰撞,所以它们现在被认为是不安全的哈希算法。然而,目前还没有攻击能够同时在两种算法中产生碰撞,因此如果你同时比较 MD5 和 SHA1 哈希值,你会发现它们是不同的。你可以在MD5碰撞演示页面查看MD5碰撞示例;此外,你也可以在Shattered网站上阅读SHA1碰撞攻击的详细信息。总之,你不应该信任这些容易发生碰撞的哈希算法(用于哈希密码或数据保护)。
答题
目标虚拟机上~/Hashing-Basics/Task-2
中的passport.jpg
文件的 SHA256 哈希值是多少?
cd ~/Hashing-Basics/Task-2
ls -la
sha256sum passport.jpg
77148c6f605a8df855f2b764bcc3be749d7db814f5f79134d2aa539a64b61f02
MD5 哈希函数的输出大小是多少字节?
tips:计算十六进制数字的数量并除以二。
根据本小节中给出的示例,我们可以知道MD5 哈希函数的输出是一个一共有32个字符的十六进制(hex)字符串,每个字符代表4位二进制,而一个字节有8位二进制,所以每个字符将代表半个字节,所以一共有 32*0.5= 16 个字节。
16
如果你有一个 8 位( 8-bit)哈希输出,那么有多少个可能的哈希值?
tips:2^8
256
不安全的密码存储-用于身份验证
哈希算法在网络安全中有很多用途。在本文的内容中,我们将重点关注哈希算法的两个用途:密码存储和数据完整性检查。当将哈希算法应用于身份验证时,我们指的是哈希算法的密码存储用途。
需要注意的是, 这不适用于密码管理器,因为密码管理器必须以明文形式检索密码 。另一方面, 身份验证机制只需要确认用户知道密码 ,就可以授予他们访问资源的权限;因此,身份验证机制中的密码存储情况与密码管理器不同。
不安全的密码存储示例
大多数 Web 应用程序都需要在某个时刻验证用户的密码。以明文形式存储这些密码是一种非常不安全的做法。你可能已经看到过一些公司数据库泄露的新闻报道。众所周知,许多人在各种账户(包括网上银行)上可能会使用相同的密码,因此泄露用户一个账户的密码就可能会危及该用户所有其他账户的安全。
当涉及密码存储时,我们将讨论以下三种不安全的做法:
- 以明文形式存储密码;
- 使用已弃用的加密方式存储密码;
- 使用不安全的哈希算法存储密码。
以明文形式存储密码
相当多的数据泄露事件都涉及明文密码泄露。你可能对 Kali Linux以及其他许多进攻性安全发行版本系统上的“rockyou.txt”密码列表并不陌生。这份密码列表来自 于RockYou信息泄露事件,RockYou是一家开发社交媒体应用程序和小部件的公司,他们以明文形式存储密码,结果导致该公司发生了数据泄露。这个密码文本文件包含了超过 1400 万个密码,你可以在/usr/share/wordlists
目录中找到rockyou.txt
。
strategos@g5000 /usr/share/wordlists> wc -l rockyou.txt
14344392 rockyou.txt
strategos@g5000 /usr/share/wordlists> head rockyou.txt
123456
12345
123456789
password
iloveyou
princess
1234567
rockyou
12345678
abc123
使用了不安全的加密算法
Adobe公司的著名数据泄露事件与上述提及的RockYou事件略有不同,该公司没有使用安全的哈希函数来存储密码的哈希值,而是使用了一种已弃用的加密格式来处理密码。此外,相关的密码提示也以纯文本形式存储,有时甚至还会包含密码本身。因此,明文密码可以相对快速地被检索出来。
使用了不安全的哈希函数
LinkedIn也在 2012 年遭遇过数据泄露事件。LinkedIn使用了一种不安全的哈希算法 SHA-1 来存储用户密码。此外,它还没有使用密码加盐技术。密码加盐是指在对密码进行哈希处理之前先向密码添加一个盐值( salt,即随机值)。
答题
rockyou.txt
文件中的第 20 个密码是什么?
tips:在Linux中使用命令head -n 20 /usr/share/wordlists/rockyou.txt
。
head -n 20 /usr/share/wordlists/rockyou.txt
qwerty
使用哈希算法进行安全密码存储
使用哈希存储密码
这时,哈希算法就派上用场了。如果我们不存储密码,而是使用安全的哈希函数并存储其哈希值,结果会怎样?这意味着我们永远不需要存储用户的密码,而且如果数据库发生泄露,攻击者也必须破解每个密码的哈希值才能知道实际的密码是什么。
这里有一个问题,如果两个用户使用了相同的密码该怎么办?由于哈希函数总是会将相同的输入转换为固定的输出,因此你将为这两个用户存储相同的密码哈希。这意味着如果有人破解了此哈希值,那么他们就可能可以访问多个帐户。这也意味着攻击者可以创建彩虹表来尝试破解密码哈希值。
彩虹表(Rainbow Table)是一个从哈希值到明文密码的查找表,基于该表,你可以快速地通过哈希值找出用户所使用的密码。彩虹表在用破解哈希值的时间换取硬盘空间,但创建它需要时间。下面是一个简单的彩虹表示例,此示例可以帮助你了解一个彩虹表的具体结构。
Hash | Password |
---|---|
02c75fb22c75b23dc963c7eb91a062cc | zxcvbnm |
b0baee9d279d34fa1dfd71aadb908c3f | 11111 |
c44a471bd78cc6c2fea32b9fe028d30a | asdfghjkl |
d0199f51d2728db6011945145a1b607a | basketball |
dcddb75469b4b4875094e14561e573d8 | 000000 |
e10adc3949ba59abbe56e057f20f883e | 123456 |
e19d5cd5af0378da05f63f891c7467af | abcd1234 |
e99a18c428cb38d5f260853678922e03 | abc123 |
fcea920f7412b5da7be0cf42b8c93759 | 1234567 |
4c5923b6a6fac7b7355f53bfe2b8f8c1 | inS3CyourP4$$ |
像CrackStation和Hashes.com这样的网站在内部使用了大量的彩虹表来提供 针对无盐哈希值的快速密码破解,显然在已排序的哈希列表中进行查找比直接尝试破解哈希值要更快。
防范彩虹表攻击
为了防范彩虹表攻击,我们可以在密码中添加盐值(salt)。盐值(salt)是存储在数据库中的随机生成的值,并且对于每个用户来说应该是唯一的。理论上,你可以对所有用户使用相同的盐值(salt),但重复的密码仍然会具有相同的哈希值,并且使用该盐值(salt)的密码仍然可能被用于创建彩虹表。
实际上在对密码进行哈希处理之前,盐值会被添加到密码的开头或结尾,这意味着即使每个用户使用相同的密码,也会有不同的密码哈希值。像Bcrypt和Scrypt这样的哈希函数会自动处理这个问题。盐值不需要保密。
安全存储密码的示例
你可以在网上找到许多优秀的指南,这些指南可以促进存储密码时的最佳安全实践。在采用这些安全实践之前,请先检查存储密码时是否有任何需要遵循的标准。请参考以下示例,了解如何在存储用户密码时遵循良好的安全实践:
- 选择一个安全的哈希函数,例如 Argon2、Scrypt、Bcrypt 或 PBKDF2;
- 在密码中添加一个唯一的盐值(salt),例如
Y4UV*^(=go_!
; - 将密码与唯一的盐值连接起来。例如,如果密码为
AL4RMc10k
,那么结果字符串将是AL4RMc10kY4UV*^(=go_!
; - 计算密码和盐值组合后的哈希值。在此示例中,基于我们所选的哈希算法,需要计算
AL4RMc10kY4UV*^(=go_!
的哈希值; - 存储哈希值以及被使用的唯一盐值(
Y4UV*^(=go_!
)。
使用加密来存储密码
在考虑保存身份验证密码的问题时,为什么我们不选择直接加密密码而是采用上面这些繁琐的步骤呢?原因是:即使我们在存储密码之前选择了使用安全的哈希算法来加密密码,我们仍然需要存储使用过的密钥;这样,如果有人获得了密钥,那么他们就可以轻松地解密所有密码。
在密码验证系统中,直接加密(encrypt)密码并不是最佳实践,原因如下:
-
加密可逆性
加密是双向操作(可通过密钥解密),而密码存储的核心要求是不可逆性。若数据库密钥泄露,攻击者可解密出原始密码,风险极高。 -
应采用哈希(Hashing)+ 加盐(Salting)
- 哈希是单向过程,无法还原明文,且应使用强哈希算法(如 Argon2、bcrypt、PBKDF2)。
- 加盐(随机值)可防止彩虹表攻击,确保相同密码的哈希结果不同。
-
加密的适用场景不同
加密适用于需还原数据的场景(如加密通信),而密码验证只需比对哈希值,无需知道原始密码。 -
合规性要求
现代安全标准(如 OWASP、NIST)明确要求密码必须哈希存储,而非加密。
例外情况:若系统需支持密码找回(而非重置),可能需加密,但这类设计本身存在安全隐患,更推荐通过其他验证方式(如邮件重置)。
综上,在密码验证系统中处理密码的正确做法是 哈希+加盐,而非简单的直接加密。
答题
使用上面的彩虹表手动检查哈希值“4c5923b6a6fac7b7355f53bfe2b8f8c1”。
inS3CyourP4$$
使用在线工具破解哈希值“5b31f93c09ad1d065c0491b764d04933”。
tisp:https://hashes.com/en/decrypt/hash
tryhackme
你应该在密码验证系统中直接加密密码吗?Yea/Nay(是/否)
Nay
识别密码哈希值
从防御性安全的角度来看,我们已经介绍了如何安全地存储身份验证系统的密码。让我们从进攻性安全的角度来解决这个问题;如果我们从哈希值开始,我们如何识别它的类型,并最终破解它以恢复原始密码?
虽然存在hashID等自动哈希识别工具,但它们对于许多格式的哈希值来说——识别结果并不可靠。对于带有前缀的哈希值,这些识别工具是可靠的。我们在使用工具时需要结合上下文环境,如果你在 Web 应用程序数据库中找到哈希值,则它更有可能是MD5 ,而不是NTLM (NT LAN Manager)。自动哈希识别工具经常会将这些哈希类型混淆,这就凸显了自我学习的重要性。
Linux密码
在Linux上,密码哈希值存储在/etc/shadow
中,通常只有 root 用户才能读取。它们曾经存储在/etc/passwd
中,任何人都可以读取。
shadow
文件包含密码信息。每行包含九个字段,用冒号 :
分隔。前两个字段是登录名和加密密码。有关其他字段的更多信息可以通过在Linux系统上执行man 5 shadow
命令来找到。
加密密码字段包含哈希密码短语,该密码短语由四个部分组成:前缀(算法 ID)、选项(参数)、salt(盐)值和哈希值。它以$prefix$options$salt$hash
格式保存。前缀指定了生成哈希值的哈希算法,这使得 Unix 和 Linux 风格的密码更容易识别。
下面是你可能遇到的一些最常见的 Unix 风格密码前缀的简要列表,它们按照使用强度递减的顺序被列出。你可以通过使用man 5 crypt
命令来检查手册页以了解有关它们的更多信息。
Prefix 前缀 | Algorithm 算法 |
---|---|
$y$ |
yescrypt 是一种可扩展的哈希方案,是新系统中的默认选择和推荐选择 |
$gy$ |
gost-yescrypt 使用 GOST R 34.11-2012 哈希函数和 yescrypt 哈希方法 |
$7$ |
scrypt 是一个基于密码的密钥派生函数 |
$2b$ , $2y$ , $2a$ , $2x$ |
bcrypt 是基于 Blowfish 分块密码的哈希,最初是为 OpenBSD 开发的,但在最新版本的 FreeBSD、NetBSD、Solaris 10 和较新版本以及多个Linux发行版本的系统中都受支持 |
$6$ |
sha512crypt 是基于 SHA-2 的哈希值,具有 512 位输出,最初是为 GNU libc 开发的,通常用于(较旧的) Linux系统中 |
$md5 |
SunMD5 最初是基于为 Solaris 开发的MD5算法的哈希值 |
$1$ |
md5crypt 最初是基于为 FreeBSD 开发的MD5算法的哈希值 |
现代Linux密码示例
请查看现代Linux系统的shadow
密码文件中的以下一行示例。
root@TryHackMe# sudo cat /etc/shadow | grep strategos
strategos:$y$j9T$76UzfgEM5PnymhQ7TlJey1$/OOSg64dhfF.TigVPdzqiFang6uZA4QA1pzzegKdVm4:19965:0:99999:7:::
上述字段之间以冒号分隔,其中最重要的信息是用户名、哈希算法、盐值和哈希值;在用户名称之后的第二个字段的格式为$prefix$options$salt$hash
。
tips:$prefix$options$salt$hash
对应的是——前缀(算法 ID)、选项(参数)、salt(盐)值和哈希值。
在上面的示例中,我们可以看到第二个字段一共有四个部分,用$
分隔:
y
表示使用的哈希算法, yescrypt算法;j9T
是传递给算法的参数;76UzfgEM5PnymhQ7TlJey1
是已使用的盐值;/OOSg64dhfF.TigVPdzqiFang6uZA4QA1pzzegKdVm4
是哈希值。
MS Windows密码
MS Windows 密码将使用 NTLM(MD4 的一种变体)进行哈希计算处理,它们看起来与MD4哈希和MD5哈希相同,因此根据上下文来确定具体的哈希类型非常重要。
在 MS Windows 上,密码哈希值存储在 SAM(Security Accounts Manager-安全帐户管理器)中。 MS Windows 试图阻止普通用户转储它们,但是仍然存在像mimikatz这样的工具可以用来尝试绕过MS Windows的安全机制。值得注意的是,在SAM中能够找到的哈希值又分为 NT 哈希和 LM 哈希。
Hashcat 哈希示例页面是查找更多哈希格式以及匹配哈希密码前缀的好地方,对于其他哈希类型,你通常需要检查其长度或编码,甚至对生成它们的应用程序进行一些研究,永远不要低估研究的力量。
答题
yescrypt 中的哈希大小是多少?
tips:研究或查看手册页,使用命令man 5 crypt
。
man 5 crypt
$y$[./A-Za-z0-9]+$[./A-Za-z0-9]{,86}$[./A-Za-z0-9]{43}
存储格式结构:\(y\)[params]\([salt(≤86字符)]\)[哈希(43字符)]
其哈希部分的固定长度为 43 个字符(Base64 编码),解码后实际哈希大小为 32 字节(256 位)。
Cisco-ASA MD5 所列出的哈希模式Hash-Mode是什么?
tips:检查 Hashcat 哈希示例页面。
Hash-Mode:2410
如果 Cisco-IOS 以$9$
开头,则它使用的是什么哈希算法?
tips:检查 Hashcat 哈希示例页面。
scrypt
密码破解
我们已经提到彩虹表是一种破解不使用盐值的哈希值的好方法,但是如果涉及到加盐哈希该怎么办?
你无法直接“解密”密码哈希值,因为它们不是常规的加密。你必须通过对许多不同的输入内容进行哈希计算(例如rockyou.txt
,因为它涵盖了许多可能的密码)来尝试破解密码哈希值,如果有可能的话 还会添加盐值并将其与目标哈希值进行比较。一旦匹配成功,你就会知道密码哈希的明文是什么。Hashcat和John the Ripper等工具通常会被用于实现破解哈希值的目的。
使用 GPU 破解密码
现代 GPU(Graphics Processing Units-图形处理单元)拥有数千个内核,它们专门从事数字图像处理和加速计算机图形学。尽管它们不能完成与CPU相同的工作,但它们非常擅长处理哈希函数中所涉及的一些数学计算。你可以使用显卡的算力快速破解多种哈希类型。一些哈希算法(例如 Bcrypt)的设计使得在GPU上进行哈希处理不会比使用CPU有任何的速度提升;这有助于它们对抗破解。
在虚拟机上破解?
值得一提的是,VM(Virtual Machines-虚拟机)通常无法访问主机的显卡。根据你所使用的虚拟化软件,你可以进行相关设置,但是会比较麻烦。此外,当你使用虚拟化操作系统中的 CPU 时,性能会发生下降,并且如果你的目的是破解哈希值时,你需要每一个额外的 CPU 周期。
如果你想运行Hashcat ,最好在你的主机上运行它,以充分利用GPU(如果可用)来执行哈希破解。如果你更喜欢MS Windows,那么你很幸运;MS Windows版本的hashcat工具可以在Hashcat网站上进行获取,你也可以通过PowerShell运行它。此外,你可以在虚拟机中让 Hashcat 与 OpenCL 一起协同工作,但速度可能会比在主机上进行破解要慢。
John the Ripper默认使用CPU并能在开箱即用的虚拟机中工作,但你可以在宿主机OS上运行它以获得更好的速度,从而避免任何虚拟化开销并充分利用CPU内核和线程。
尝试破解哈希值
本小节将提供一些哈希值,请尝试破解它们。你可以自行选择破解方式,使用在线工具、使用Hashcat或John the Ripper 。虽然你也可以使用在线彩虹表来解决本小节的问题,但是强烈建议你不要这样做,因为这会限制你的学习体验。对于本小节答题任务中的前三个,使用hashcat
和rockyou.txt
就足以找到答案。
Hashcat将使用 hashcat -m <hash_type> -a <attack_mode> hashfile wordlist
作为基本语法,其中 :
-m <hash_type>
以数字格式指定哈希类型。例如,-m 1000
表示NTLM 。检查官方文档(man hashcat
)和hashcat示例页面可以查找要使用的哈希类型代码。-a <attack_mode>
指定攻击模式。例如,-a 0
表示直接攻击,即依次尝试单词列表中的密码。hashfile
是包含了你要破解的哈希值的文件。wordlist
是你想要在攻击中使用的安全单词列表。
例如, hashcat -m 3200 -a 0 hash.txt /usr/share/wordlists/rockyou.txt
会将哈希类型视为Bcrypt并尝试匹配rockyou.txt
文件中的密码。
答题
使用hashcat
破解哈希$2a$06$7yoU3Ng8dHTXphAg913cyO6Bjs3K5lBnwq5FJyA6d01pMSrddr1ZG
,该值保存在 ~/Hashing-Basics/Task-6/hash1.txt
中 。
tips:检查 Hashcat 哈希示例页面以查找哈希类型。
cd ~/Hashing-Basics/Task-6/
hashcat -m 3200 -a 0 hash1.txt /usr/share/wordlists/rockyou.txt
85208520
使用hashcat
破解SHA2-256哈希9eb7ee7f551d2f0ac684981bd1f1e2fa4a37590199636753efe614d4db30e8e1
, 该值保存在 ~/Hashing-Basics/Task-6/hash2.txt
中 。
tips:使用在线哈希破解服务。
halloween
使用hashcat
破解哈希$6$GQXVvW4EuM$ehD6jWiMsfNorxy5SINsgdlxmAEl3.yif0/c3NqzGLa0P.S7KRDYjycw5bnYkF5ZtB8wQy8KnskuWQS3Yr1wQ0
,该值保存在 ~/Hashing-Basics/Task-6/hash3.txt
中 。
tips:检查 Hashcat 哈希示例页面以查找哈希类型。
hashcat -m 1800 -a 0 hash3.txt /usr/share/wordlists/rockyou.txt
spaceman
破解哈希值b6b0d451bbf6fed658659a9e7e5598fe
,该值保存在 ~/Hashing-Basics/Task-6/hash4.txt
中。
tips:使用在线哈希破解服务。
https://hashes.com/en/decrypt/hash
funforyou
使用哈希算法进行完整性检查
在第 3 小节中,我们提到我们将重点关注哈希算法的两个用途:密码存储和数据完整性检查。我们广泛讨论了哈希算法如何在身份验证系统中保护密码。在本小节中,我们将讨论如何使用哈希函数来检查文件的完整性。
数据完整性检查
哈希算法可用于检查文件是否被更改。在面对哈希函数时,如果你输入相同的数据,那么输出的数据会始终相同。如果哈希输入的单个位(bit)发生变化,那么输出的哈希值也会发生显著变化,如第二小节中所示。这意味着我们可以使用哈希算法来检查文件是否被修改,或者确保我们所下载的文件与Web服务器上的原始文件完全相同。下面列出的文本文件显示了两个 Fedora Workstation ISO 文件的 SHA256 哈希值。如果我们对已下载的文件运行sha256sum
命令所得到的哈希值与此签名文件中所列出的哈希值相同,那么我们就可以确信本地的文件与官方的原始文件数据是完全相同的。
root@AttackBox# head Fedora-Workstation-40-1.14-x86_64-CHECKSUM
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
# Fedora-Workstation-Live-osb-40-1.14.x86_64.iso: 2623733760 bytes
SHA256 (Fedora-Workstation-Live-osb-40-1.14.x86_64.iso) = 8d3cb4d99f27eb932064915bc9ad34a7529d5d073a390896152a8a899518573f
# Fedora-Workstation-Live-x86_64-40-1.14.iso: 2295853056 bytes
SHA256 (Fedora-Workstation-Live-x86_64-40-1.14.iso) = dd1faca950d1a8c3d169adf2df4c3644ebb62f8aac04c401f2393e521395d613
[...]
你还可以使用哈希算法来查找重复文件;如果两个文档具有相同的哈希值,则它们其实是同一个文档。这对于查找和删除重复文件而言是非常方便的。
HMAC(密钥哈希消息验证码)
HMAC(Keyed-Hash Message Authentication Code-密钥哈希消息验证码)是一种消息验证码 (MAC-message authentication code),它使用加密哈希函数与密钥相结合来验证数据的真实性和完整性。
HMAC可以用来确保创建HMAC的人与其所声称的身份相符,即可以确认其真实性;此外,它还能证明消息没有被修改或损坏,即能够维护其完整性。这是通过使用密钥来证明真实性并使用哈希算法来生成哈希值以证明其完整性来实现的。
以下步骤可以让你大致了解 HMAC 的工作原理:
- The secret key is padded to the block size of the hash function:密钥被填充到哈希函数的块(block) size。
- The padded key is XORed with a constant (usually a block of zeros or ones):填充的密钥与常数(通常是由0或1组成的块)进行异或运算。
- The message is hashed using the hash function with the XORed key:使用具有异或密钥的哈希函数对消息进行哈希计算处理。
- The result from Step 3 is then hashed again with the same hash function but using the padded key XORed with another constant:然后使用相同的哈希函数再次对步骤 3 的结果进行哈希计算处理,但使用填充密钥与另一个常数进行异或。
- The final output is the HMAC value, typically a fixed-size string:最终输出的是 HMAC 值,通常是一个固定大小的字符串。
下图可以清楚地解释上述步骤:
从技术上讲,HMAC 函数可以使用以下表达式来进行计算:
HMAC(K,M) = H((K⊕opad)||H((K⊕ipad)||M))
请注意,M 和 K 分别代表消息和密钥。
答题
~/Hashing-Basics/Task-7
中找到的libgcrypt-1.11.0.tar.bz2
的 SHA256 哈希值是什么?
cd ~/Hashing-Basics/Task-7
ls -la
sha256sum libgcrypt-1.11.0.tar.bz2
09120c9867ce7f2081d6aaa1775386b98c2f2f246135761aae47d81f58685b9c
HMAC-SHA512 (key = $pass)
的 hashcat 模式编号是多少?
tips:检查 Hashcat 哈希示例页面以查找哈希类型(hashcat 模式编号)。
1750
本文小结
本文从不同的角度介绍了哈希函数及其用途。接下来,让我们仔细区分哈希(hashing)、编码(encoding)和加密(encryption)这几个概念。
如前所述, 哈希是指对输入数据进行处理并生成哈希值(一个固定大小的字符串,也被称为摘要-digest)的过程。这个哈希值唯一地代表了输入数据,而输入数据的任何更改,无论多么小,都会导致对应的哈希值发生变化。哈希计算不应与加密或编码混淆;哈希计算是单向的,你无法逆转该过程来获取相关的原始数据。
编码是将数据从一种形式转换为另一种形式,以使其与特定系统兼容。 ASCII、UTF-8、UTF-16、UTF-32、ISO-8859-1 和 Windows-1252 是英语的有效编码方法。请注意,UTF-8、UTF-16 和 UTF-32 是 Unicode 编码,它们可以表示其他语言(例如阿拉伯语和日语)的字符。
发送或保存数据时常用的另一种编码类型并不针对任何特定语言。例如Base32编码和Base64编码。请查看以下使用base64
进行编码和解码的示例:
strategos@g5000 ~> base64
TryHackMe
VHJ5SGFja01lCg==
strategos@g5000 ~> base64 -d
VHJ5SGFja01lCg==
TryHackMe
编码不应与加密混淆,因为使用特定编码并不能保护消息的机密性。编码是可逆的;任何人都可以使用正确的工具来更改数据编码。
只有我们在前面的学习过程中所介绍过的加密技术,才能使用加密密码和密钥来保护数据的机密性。只要我们知道密码并且可以访问密钥,那么加密就是可逆的。
要继续学习与哈希相关的模块,请完成TryHackMe提供的John the Ripper实验房间;但是,如果你想获得有关密码学的更多深入信息,请考虑完成密码学简介实验房间,它深入探讨了更多与密码学相关的概念并且还展示了更多与密码学相关的工具。
答题
使用base64
解码RU5jb2RlREVjb2RlCg==
,保存为decode-this.txt
文件,并放置在~/Hashing-Basics/Task-8
文件夹中。相关的原始单词的内容是什么?
#base64 -d FILENAME
base64 -d ~/Hashing-Basics/Task-8/decode-this.txt
ENcodeDEcode