1 背景 小伙伴使用SMB协议将扫描完的文件发送到电脑上,但提示密码错误,尽管密码是正确的。本文记录了解决问题的过程,包括Netbios、NTLM认证和Windows本地组策略的相关配置。 PS:由于只能进行远程测试,因此在虚拟环境中进行了测试,以下IP地址仅供参考: 实际环境: 小伙伴IP:192.168.9.11 打印机IP:192.168.9.252 同事IP:192.168.9.31 实验环境: 虚拟机:192.168.182.129 所有网络都是可达的,端口都是开放的。 2 权限检查 小伙伴的电脑上没有截图,因此这里使用自己的虚拟机进行示例。
检查文件夹的权限:属性->共享->高级共享->权限 控制面板->所有控制面板项->网络和共享中心->高级共享设置,启用密码保护 本地组策略->计算机配置->Windows设置->安全设置->用户权限分配 黑白名单:需要远程访问的用户或组既要在白名单中,又不能在黑名单中。
3 NTLM 为了节约纸张,先找了小伙伴的同事尝试使用net use命令进行测试,结果提示网络密码错误。既然提示密码错误,就抓包查看认证信息。本次抓包使用的是NTLMv2认证协议。先将密码计算为NTLM hash,而NTLM认证是Challenge/Response机制,Response需要根据NTLM hash计算。简述NTLM认证过程: 服务端发送Challenge 客户端使用NTLM hash与Challenge计算Response,发送给服务端 服务端使用本地存储的NTLM hash与Challenge计算,与客户端发送的Response比较,相同则认证成功。 NTLMv1与NTLMv2的区别:Challenge位数不同,v1是8字节,v2是16字节。v1将16字节的NTLM hash空填充为21个字节,然后分成三组,每组7比特,作为3DES加密算法的三组密钥,加密Server发来的Challenge。将这三个密文值连接起来得到Response。v2使用16字节NTLMv2哈希作为密钥,将HMAC-MD5消息认证代码算法加密一个值(Challenge与Blob拼接在一起),得到一个16字节的NTProofStr。Blob结构如下:
import hashlib,binascii
def ntlm_hash(password):
hash = hashlib.new("md4",password.encode("utf-16le")).digest()
return hash
3.1 NTLM hash 以密码123456为例: 转十六进制:313233343536 转Unicode(utf-16le):310032003300340035003600 MD4 hash:32ed87bdb5fdc5e9cba88547376818d4
3.2 NTLMv2 演示如何从Wireshark中抓取信息,并利用hashcat破解密码。NTLMv2的格式为: username::domain:challenge:NTProofStr:blob challenge
hashcat -m 5600 -a 0 administrator:::c772777d484e72b0:9430...000
NTLMv2 Response是NTProofStr+blob,前16字节为NTProofStr,剩余部分为Blob。username和domain,此处domain为空。利用hashcat进行破解。
-m:指定类型,5600表示NTLM v2 -a:0表示使用字典 密码已打码,不再公开。密码是正确的,因此很可能是小伙伴电脑上的配置问题导致即使密码正确也提示密码错误。 4 Windows本地组策略 在检查完密码发送后发现密码是正确的,只能寻找其他原因。再次搜索到相关组策略设置。 本地组策略->计算机配置->Windows设置->安全设置->安全选项 网络安全:LAN管理器身份验证级别(PS:这个搜到的最多,每个配置下基本就是字面意思,但是我试了几个都没效果,因为通过3.2部分的内容可以知道不是协商失败,而是认证的时候失败了)
网络安全:限制NTLM:传入NTLM流量。尽管没有明确指定允许所有,但并没有起到作用。还有一些与NTLM相关的配置,但不是当前问题的关键。后来小伙伴的同事有空了,只能直接使用打印机进行测试。抓包后发现,打印机使用的是基于Netbios的SMBv1协议,而不是445端口的SMBv2。因此,需要学习Netbios和SMBv1(也称为CIFS)。
5 Netbios 参考Wiki上的描述,NetBIOS是一个API,在不同协议上有不同的实现。 NetBIOS:1983年由IBM推出,用于IBM PC网络局域网上的软件通信的API。 NBF协议:1985年IBM推出NetBIOS Extended User Interface (NetBEUI),扩展了基础NetBIOS API,用于令牌环网。 NBX协议:基于IPX/SPX的NetBIOS实现,1986年由Novell推出。 NBT:基于TCP/IP的NetBIOS实现,RFC 1001:NBT的概念和方法、RFC 1002:NBT的详细规范。显然抓包的数据是NBT。NetBIOS提供三种不同的服务: 打印机首先通过UDP 137端口进行名称到IP的转换。 然后通过TCP 139端口进行认证和文件传输,涉及到CIFS协议。 6 CIFS6.1 介绍 根据微软文档,CIFS也是SMB,可以理解为SMB中用于文件传输的部分。
SMB_Header{
UCHAR Protocol[4];
UCHAR Command;
SMB_ERROR Status;
UCHAR Flags;
USHORT Flags2;
USHORT PIDHigh;
UCHAR SecurityFeatures[8];
USHORT Reserved;
USHORT TID;
USHORT PIDLow;
USHORT UID;
USHORT MID;
}
文档下载发现页数超过700页,无法全部阅读,只关注需要了解的部分。需要了解的是Negotiate和Session Setup AndX。 6.2 SMB消息结构 参考微软文档的2.2.3 SMB Message Structure部分。SMB消息结构由三部分组成: 变长数据块(Data Block) 6.2.1 SMB Header
SMB_Parameters{
UCHAR WordCount;
}
SMB_Data{
USHORT ByteCount;
Bytes{
UCHAR Dialects[];
}
}
SMB_Dialect{
UCHAR BufferFormat;
OEM_STRING DialectString;
}
关注的是Command和SMBERROR Status。Command:1个字节,表示当前命令。SMBERROR Status:4个字节,服务端返回给客户端的错误信息。关注的Command有Negotiate(0x72)和Session Setup AndX(0x73)。SMBERROR Status由三部分组成: 1字节ErrorClass 1字节保留 2字节ErrorCode ErrorClass和ErrorCode对应表见微软文档2.2.2.4 SMB Error Classes and Codes。 6.3 SMBCOMNEGOTIATE(0x72) 参考微软文档的2.2.4.52 SMBCOM_NEGOTIATE (0x72)部分。用于初始化SMB连接,所有SMB消息前必须先发送该命令。 6.3.1 Request
SMB_Parameters{
UCHAR WordCount;
Words{
USHORT DialectIndex;
UCHAR SecurityMode;
USHORT MaxMpxCount;
USHORT MaxNumberVcs;
ULONG MaxBufferSize;
ULONG MaxRawSize;
ULONG SessionKey;
ULONG Capabilities;
FILETIME SystemTime;
SHORT ServerTimeZone;
UCHAR ChallengeLength;
}
}
SMB_Data{
USHORT ByteCount;
Bytes{
UCHAR Challenge[];
SMB_STRING DomainName[];
}
}
Parameter部分无内容,因此WordCount填充0x00。ByteCount:Bytes内容的长度。Bytes:可用认证协议列表,单个为SMB_Dialect结构体。BufferFormat:固定为0x02。DialectString:认证协议名称字符串。 6.3.2 Response 根据选择的认证协议不同,结构体内容也不同,这里只关注NTLM认证。
SMB_Parameters{
UCHAR WordCount;
Words{
UCHAR AndXCommand;
UCHAR AndXReserved;
USHORT AndXOffset;
USHORT MaxBufferSize;
USHORT MaxMpxCount;
USHORT VcNumber;
ULONG SessionKey;
USHORT OEMPasswordLen;
USHORT UnicodePasswordLen;
ULONG Reserved;
ULONG Capabilities;
}
}
SMB_Data{
USHORT ByteCount;
Bytes{
UCHAR OEMPassword[];
UCHAR UnicodePassword[];
UCHAR Pad[];
SMB_STRING AccountName[];
SMB_STRING PrimaryDomain[];
SMB_STRING NativeOS[];
SMB_STRING NativeLanMan[];
}
}
关注的是Data部分,会返回Challenge值。 6.4 SMBCOMSESSIONSETUPANDX (0x73) 参考微软文档的2.2.4.53 SMBCOMSESSIONSETUPANDX (0x73)部分。用于NTLM认证登录。 6.4.1 Request
关注的是Data部分,由于选择的认证不同,意义也不同,这里是NTLM认证的情况下的说明。OEMPassword:LM response(v1或v2)。UnicodePassword:NTLM response(v1或v2)。AccountName:用户名。PrimaryDomain:域名或计算机名。其中OEMPassword和UnicodePassword的意义在3.2.4.2.4 User Authentication中有说明。
SMB_Parameters{
UCHAR WordCount;
Words{
UCHAR AndXCommand;
UCHAR AndXReserved;
USHORT AndXOffset;
USHORT Action;
}
}
SMB_Data{
USHORT ByteCount;
Bytes{
UCHAR Pad[];
SMB_STRING NativeOS[];
SMB_STRING NativeLanMan[];
SMB_STRING PrimaryDomain[];
}
}
6.4.2 Response 这部分不再关注,仅列出结构体。认证失败时没有内容,根据SMB Header中的Error Class 0x01和Error Code 0x05判断。 7 NTLMv1 演示如何从Wireshark中抓取信息,并利用hashcat破解密码。NTLMv1的格式为: username::hostname:LM response:NTLM response:challenge 需要的字段已在上述内容中说明。 challenge
hashcat64.exe -m 5500 -a 0 administrator::aaa:aba89b38ddfe21a...:20c41a8ddd3f8...:b204217...
其他信息 利用hashcat进行破解,发现密码是正确的。 8 脑洞 提示是网络密码错误,但通过抓包分析发现密码是正确的。既然Windows认证使用的是NTLM,那么远程桌面连接密码错误也是一个可能的原因。在搜索文件共享密码错误的解决方案无果后,转而搜索远程桌面连接密码错误的解决方案,结果找到了一个令人意外的组策略配置项。远程桌面连接密码错误 本地组策略->计算机配置->Windows设置->安全设置->安全选项 网络访问:本地账户的共享和安全模型(设置为经典)。