Net- NTLM 利用
最后更新于
最后更新于
在上一篇文章Windows内网协议学习NTLM篇之发起NTLM请求里面,讲了12种发起NTLM请求的方式。这篇文章接着上文,主要讲解拿到NTLM 请求之后的进一步利用。有Net-NTLM Hash的破解(v1 和 v2)以及Relay到支持NTLM SSP的协议,事实上,只要是支持NTLM SSP的协议,都可以Relay过去,本文主要讲的是几种比较常遇到,且能达到命令执行效果的,SMB,EWS,LDAP。
先上结论。只要获取到Net-NTLM v1,都能破解为NTLM hash。与密码强度无关。
具体操作如下。
修改Responder.conf
里面的Challenge为1122334455667788
(使用SpiderLabs版本的 话默认是1122334455667788
,但该版本已经停止更新了,建议使用lgandx版本,这一版本默认为Random
,需要修改)
将type2里面的NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY位置0。
如果知道发来的请求一定是SMB 协议的话,Responder里面加上--lm
参数即可,
其他协议就得去找改协议发送type2 处的代码,修改NegoFlags位。
比如Http协议的话,需要修改packets.py里面的NTLM_Challenge类。
原来是NegoFlags的值是\x05\x02\x89\xa2
,改成\x05\x02\x81\xa2
然后获取到Net-NTLM v1。再使用ntlmv1-multi里面的ntlmv1.py转换. 获取到Net-NTLM v1是win10::WIN10-1:F1586DA184365E9431C22EF206F5A2C918659E1B1FD7F64D:F1586DA184365E9431C22EF206F5A2C918659E1B1FD7F64D:1122334455667788
转化完的格式就是NTHASH:F1586DA184365E9431C22EF206F5A2C918659E1B1FD7F64D
再将转化完的格式用crack.sh破解即可。
下面简要探究下原理,如果没有兴趣的可以直接跳过。看下一小节。
之前在NTLM基础介绍里面有简单介绍了下Net-NTLM v1的加密方式
将 16字节的NTLM hash空填充为21个字节,然后分成三组,每组7字节,作为3DES加密算法的三组密钥,加密Server发来的Challenge。 将这三个密文值连接起来得到response。
但是在实践中发现,加密方式的表述是有点问题的,或者说是不完整的。上面的只是Net-NTLM v1的一种加密方式,Net-NTLM v1还有另外一种加密方式。我们下面来探讨下这两种加密方式以及利用
(1)加密方式1
就是前面提到的那种。
将 16字节的NTLM hash空填充为21个字节,然后分成三组,每组7字节
将三组(每组7字节)经过运算后作为DES加密算法的密钥
运算的细节是每组七个字节再转化为8小组,每个小组7个比特位。然后7个比特位进行奇偶校验后算出第8个比特位,刚好是1个字节,8个小组,每小组一个字节,凑成8个字节的密钥。
加密Server Challenge
将这三个密文值连接起来得到response。
那这种加密方式存在什么问题呢。
总共三组,每组8个字节作为key,加密Server Challenge获取response。
每组可以分开计算,已知加密内容和加密后的密文算key。使用des算法,key是八个字节。
我们控制Server Challenge为1122334455667788,然后建立从key到response的彩虹表。就可以在知道response的情况下获取key。所幸crack.sh这个网站已经帮我们弄好了,在Challenge为1122334455667788的情况下。一分钟之内就能获取ntlm hash,而且是免费的。这也是我们为啥要把Challenge设置为1122334455667788,而不是随机。
使用ntlmv1-multi里面的ntlmv1.py转换.然后复制NTHASH:E0F8C5B5E45247B4175698B99DBB5557CCD9241EA5A55CFB
到crack.sh破解,填上邮箱,等到一分钟左右就能收到ntlm hash了。
(2)加密方式2
跟第一种加密方式基本一样。最本质的区别就在于,第一种加密方式的加密内容是Server Challenge。而这种加密方式是拼接8字节Server Challenge和8字节Client Challenge后,求其MD5,然后取MD5值的前8字节做为加密内容。
我们可以控制Server Challenge为固定的值,但是没法控制Client Challenge的值。也就是说我们没法控制加密的内容为固定的值。
第一种是加密的内容为固定的1122334455667788的话,我们只需要建立从key到response的映射就行。而这种加密方式的话。加密的内容也是不固定的,计算的成本高多了。
总而言之,这种加密方式不好破解,其实我们也可以不让客户端不用这种加密方式,就使用第一种加密方式。且看下面的分析。
在我们的Responder加上--lm
的情况下获取到的Net-NTLM v1 hash是采用第一种加密方式,但是只针对smb协议有效,在我的测试中,即使加了--lm
参数,收到的请求是Http协议的情况底下,拿到的Net-NTLM v1也是采用第二种加密方式,我们不好破解。所以我又去研究了下什么情况底下采用第一种加密方式,什么情况底下采用第二种加密方式。
在这篇[文章](http://d1iv3.me/2018/12/08/LM-Hash%E3%80%81NTLM-Hash%E3%80%81Net-NTLMv1%E3%80%81Net-NTLMv2%E8%AF%A6%E8%A7%A3/)里面有提及到,当ntlm的flag位NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY置为1的情况底下,会采用第二种加密方式,否则就会采用第一种加密方式,我们可以看下impacket里面计算Net-NTLM v1的相关代码
可以很清楚的看到,当NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY位置为1的时候,加密的内容不是server challenge,而是md5 hash 运算过的server challeng+client challent的前8位。也就是说是第二种加密方式。
那NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY flag来自于哪里呢。我们知道ntlm分为type1,type2,type3。计算response就在type 3里面,NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY flag位就来自于type2。而type 2 里面的内容正常就是我们返回给客户端的。
也就是说,客户端选择加密方式1还是加密方式2,这个是由我们可以控制的。只需要我们把NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY位置为0,那么客户端就会选择加密方式1.并且Server Challenge为1122334455667788的情况下。我们用crack.sh快速免费有效得破解。获取到用户的NTLM Hash。
那怎么将NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY位置为0,我们一般都是使用现成的工具Resonder来获取Net-NTLM Hash。之前说过加上--lm
参数就可以将NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY位置为0。
这个时候还有一个小问题没有解决,那就是Resonder加上--lm
,为什么只针对smb 协议有效。其他协议无效。
我去读了下Responder的代码。
加上--lm
参数之后,调用的模块就是SMB1LM
发现她用的是老板本的smb实现。而这个版本的实现是在smb 协商版本的时候就将challenge返回,并且将NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY置为0.
而且也仅仅是实现了smb协议,并没有实现其他协议。
但是完全可以不用老板本的smb实现。这里面最本质的地方在于NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY置为0.而这个flag位并不一定需要用到旧版本的smb才能置位。只需要修改NTLM SSP里面的flag位就行
在各个协议里面的NTLM SSP里面,修改flag位,我们找到Responder里面type2的NTLM SSP的flag位赋值的地方即可。
Responder里面的NTLM SSP实现没有通用性。比如smb部分的实现,在packets.py里面的SMBSession1Data类里面。
默认是0xe2898215(跟图里面不一样?大端小端)
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY对应的是第13位,改为0,也就是0xe2818215
改下就行
http的话在packets.py里面的NTLM_Challenge类里面
Responder的NTLM SSP没有通用性,这个挺难受的,其他协议的话,大家自己找吧。跟下代码挺快的。
在Net-NTLM Hash的破解里面,如果是v1的话,拿到Net-NTLM就相当于拿NTLM HASH.这个时候就没有Relay的必要性了,但是在实际中遇到的例子往往不会是v1,而是v2。这个时候密码强度高一点,基本就跑不出来了,这种情况底下,不妨试一试Relay。
能直接relay到smb服务器,是最直接最有效的方法。可以直接控制该服务器(包括但不限于在远程服务器上执行命令,上传exe到远程命令上执行,dump 服务器的用户hash等等等等)。
主要有两种场景
工作组环境
这个实用性比较差。在工作组环境里面,工作组中的机器之间相互没有信任关系,每台机器的账号密码Hash只是保存在自己的SAM文件中,这个时候Relay到别的机器,除非两台机器的账号密码一样(如果账号密码一样,我为啥不直接pth呢),不然没有别的意义了,这个时候的攻击手段就是将机器reflect回机子本身。因此微软在ms08-068中对smb reflect到smb 做了限制。这个补丁在CVE-2019-1384(Ghost Potato)被绕过。将在下篇文章里面详细讲。
域环境
域环境底下域用户的账号密码Hash保存在域控的 ntds.dit里面。如下没有限制域用户登录到某台机子,那就可以将该域用户Relay到别人的机子,或者是拿到域控的请求,将域控Relay到普通的机子,比如域管运维所在的机子。(为啥不Relay到其他域控,因为域内就域控默认开启smb签名)
下面演示使用几款工具在域环境底下,从域控relay到普通机器执行命令
Exchange的认证也是支持NTLM SSP的。我们可以relay的Exchange,从而收发邮件,代理等等。在使用outlook的情况下还可以通过homepage或者下发规则达到命令执行的效果。而且这种Relay还有一种好处,将Exchange开放在外网的公司并不在少数,我们可以在外网发起relay,而不需要在内网,这是最刺激的。
配合homepage 能够实现命令执行的效果
homepage的简易demo代码如下
不管是杀伤力巨大的8581还是1040。Relay到ldap都在里面发挥着巨大的作用。
relay 到ldap的话,能干嘛呢
这里着重介绍三种通用性比较强的利用思路。这三种在impacket里面的ntlmrelayx都有实现。(这三种通用性比较强而已,实际中这个的利用比较灵活,需要通过 nTSecurityDescriptor分析用户在域内对哪些acl有权限,什么权限。关于acl怎么深入利用,这里不再展开,后面在ldap篇会详细说明)
高权限用户
如果NTLM发起用户在以下用户组
Enterprise admins
Domain admins
Built-in Administrators
Backup operators
Account operators
那么就可以将任意用户拉进该组,从而使该用户称为高权限用户,比如域管
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的权限
这个案例的典型例子就是Exchange Windows Permissions组,我们将在下一篇介绍8581的 时候详细说下这个用户组的权限。
普通用户权限
在server2012r2之后,如果没有以上两个权限。可以通过设置基于资源的约束委派。
在NTLM发起者属性马上到!S-AllowedToActOnBehalfOfOtherIdentity里面添加一条ace,可以让任何机器用户和服务用户可以控制该用户(NTLM发起者)。
在Responder如果想获取到这种加密方式的话,要加上参数--lm
(仅限于smb 协议)
具体操作是
在Responder默认获取到的就是这种加密方式(没有加--lm
)
使用ntlmv1-multi里面的ntlmv1-ssp.py转换.到crack.sh破解。这种方式要钱的,而且还不一定能解的出来。
Net-NTLM v2 现在也没有什么比较好用的破解方式,一般就是利用hashcat 离线爆破明文密码,能不能跑出来就看字典里面有没有了。使用hashcat进行字典破解
impacket 的底下的smbrelayx.py
impacket 的底下的ntlmrelayx.py
Responder底下的MultiRelay.py
下面演示通过NtlmRelayToEWS(事实上,工具挺多的。其他的大家可以上github自己找)来实现Relay2ews
放置于web服务器。在NtlmRelayToEWS 里面通过-u 参数指定。