• NTLM深入分析


    LMhash&NTLMhash

    已知windows密码都不是明文保存的,都是以hash的形式放在了本地sam内,域内的密码hash则保存在了域控的ntds.dit内
    
    导入的密码hash如下:
    Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:CCEF208C6485269C20DB2CAD21734FE7:::
    LMhash:
    AAD3B435B51404EEAAD3B435B51404EE
    NTLMhash:
    CCEF208C6485269C20DB2CAD21734FE7
    

    LMhash

    全称为LAN Manager Hash
    
    计算方式:
    用户的密码转换为大写,密码转换为16进制字符串,不足14字节将会用0来再后面补全。
    密码的16进制字符串被分成两个7byte部分。每部分转换成比特流,并且长度位56bit,长度不足使用0在左边补齐长度
    再分7bit为一组,每组末尾加0,再组成一组
    上步骤得到的二组,分别作为key为"KGS!@#$%"进行DES加密
    将加密后的两组拼接在一起,得到最终LM HASH值
    

    加密方式

    #coding=utf-8
    import re
    import binascii
    from pyDes import *
    def DesEncrypt(str, Des_Key):
        k = des(binascii.a2b_hex(Des_Key), ECB, pad=None)
        EncryptStr = k.encrypt(str)
        return binascii.b2a_hex(EncryptStr)
    
    def group_just(length,text):
        # text 00110001001100100011001100110100001101010011011000000000
        text_area = re.findall(r'.{%d}' % int(length), text) # ['0011000', '1001100', '1000110', '0110011', '0100001', '1010100', '1101100', '0000000']
        text_area_padding = [i + '0' for i in text_area] #['00110000', '10011000', '10001100', '01100110', '01000010', '10101000', '11011000', '00000000']
        hex_str = ''.join(text_area_padding) # 0011000010011000100011000110011001000010101010001101100000000000
        hex_int = hex(int(hex_str, 2))[2:].rstrip("L") #30988c6642a8d800
        if hex_int == '0':
            hex_int = '0000000000000000'
        return hex_int
    
    def lm_hash(password):
        # 1. 用户的密码转换为大写,密码转换为16进制字符串,不足14字节将会用0来再后面补全。
        pass_hex = password.upper().encode("hex").ljust(28,'0') #3132333435360000000000000000
        print(pass_hex) 
        # 2. 密码的16进制字符串被分成两个7byte部分。每部分转换成比特流,并且长度位56bit,长度不足使用0在左边补齐长度
        left_str = pass_hex[:14] #31323334353600
        right_str = pass_hex[14:] #00000000000000
        left_stream = bin(int(left_str, 16)).lstrip('0b').rjust(56, '0') # 00110001001100100011001100110100001101010011011000000000
        right_stream = bin(int(right_str, 16)).lstrip('0b').rjust(56, '0') # 00000000000000000000000000000000000000000000000000000000
        # 3. 再分7bit为一组,每组末尾加0,再组成一组
        left_stream = group_just(7,left_stream) # 30988c6642a8d800
        right_stream = group_just(7,right_stream) # 0000000000000000
        # 4. 上步骤得到的二组,分别作为key 为 "KGS!@#$%"进行DES加密。
        left_lm = DesEncrypt('KGS!@#$%',left_stream) #44efce164ab921ca
        right_lm = DesEncrypt('KGS!@#$%',right_stream) # aad3b435b51404ee
        # 5. 将加密后的两组拼接在一起,得到最终LM HASH值。
        return left_lm + right_lm
    
    if __name__ == '__main__':
        hash = lm_hash("123456")
    

    安全问题

    密码长度最大只能为14个字符
    密码不区分大小写,在生成哈希值之前,所有密码都将转换为大写
    查看我们的加密过程,就可以看到使用的是分组的DES,如果密码强度是小于7位,那么第二个分组加密后的结果肯定是AAD3B435B51404EEAAD3B435B51404EE,如果我们看到lm hash的结尾是aad3b435b51404ee,就可以很轻易的发现密码强度少于7位
    一个14个字符的密码分成7 + 7个字符,并且分别为这两个半部分计算哈希值。这种计算哈希值的方式使破解难度大大降低,这使得14个字符的密码的有效强度等于,7个字符的密码的两倍,该密码的复杂度明显低于  14个字符的密码的理论强度。
    Des密码强度不高
    

    NTLMhash

    为了解决LMhash而推出的NTLM协议,下方为版本支持情况
    

    这里我们的机器是2012的环境,从上图可以知道是不使用lmhash的,因为如果使用空密码或者LMhash进行存储的话抓的密码LMhash部分就是AAD3B435B51404EEAAD3B435B51404EE,LMhash并没有什么价值,所以着重关注NTLMhash即可
    
    考虑到一些工具需要填写固定的hash密码的格式,也就是必须要有LMhash,所以可以将LMhash部分全部填0,结合当前环境
    原来密码:
    AAD3B435B51404EEAAD3B435B51404EE:CCEF208C6485269C20DB2CAD21734FE7
    现在密码:
    00000000000000000000000000000000:CCEF208C6485269C20DB2CAD21734FE7
    
    计算方式:
    将用户密码转换为十六进制格式。
    将十六进制格式的密码进行Unicode编码。
    使用MD4摘要算法对Unicode编码数据进行Hash计算
    

    加密方式

    python2 -c 'import hashlib,binascii; print binascii.hexlify(hashlib.new("md4", "Admin12345".encode("utf-16le")).digest())'
    
    此处同我们获取到的密码hash一致
    

    NTLM身份验证

    主要是一种challenge/response的验证机制,由三种消息组成,通常为type1协商、type2质询、type3身份验证
    
    1、用户登录客户端电脑
    2、客户端向服务器发送type 1协商请求,包含客户端支持和服务器请求的功能列表
    3、服务器用type 2质询进行响应,这包含服务器支持和同意的功能列表,同时包含服务器产生的Challenge其实也就是个字符串
    4、客户端用type 3身份验证回复质询,用户接收到上一步中的challenge之后,使用用户hash与challenge进行加密运算得到response,将response,username,challeng发给服务器,其中reponse向服务器证明客户端用户已经知道帐户密码。
    5、服务器拿到type 3之后,使用challenge和用户hash进行加密得到response2与type 3发来的response进行比较。如果用户hash是存储在域控里面的话,那么没有用户hash,也就没办法计算response2。也就没法验证。这个时候用户服务器就会通过netlogon协议联系域控,建立一个安全通道,然后将type 1,type 2,type3 全部发给域控(这个过程也叫作Pass Through Authentication认证流程)
    6、域控使用challenge和用户hash进行加密得到response2,与type 3的response进行比较
    

    抓包分析整个阶段的数据包
    

    type1协商

    官方文档:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/b34032e5-3aae-4bc6-84c3-c6d80eadf7f2
    
    客户端向服务器发生协商消息,包含客户端支持和服务端请求的功能列表
    

    type2质询

    官方文档:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/801a4681-8809-4be9-ab0d-61dcfe762786
    
    包含服务器支持和统一的功能列表,产生challenge为eb759c11e09dbb2b
    

    type3身份验证

    官方文档:
    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/033d32cc-88f9-4483-9bf2-b273055038ce
    
    用户接收到上一步中的challenge之后,使用用户hash与challenge进行加密运算得到response,将response,username,challeng发给服务器,其中reponse向服务器证明客户端用户已经知道帐户密码
    
    如下这里的challenge为e3d463fde72d2e3f,其实就是加密后的
    Response为7427b887027d29fceb6f49963ba9007201010000000000004a881d1672e9d601e3d463fde72d2e3f0000000002000e0052004f004f0054004b004900540001000e004f005700410032003000310033000400160072006f006f0074006b00690074002e006f0072006700030026004f005700410032003000310033002e0072006f006f0074006b00690074002e006f00720067000500160072006f006f0074006b00690074002e006f0072006700070008004a881d1672e9d60106000400020000000800300030000000000000000000000000200000f1b5d13b0a0b1ac4bb031cf68b7998834190b70a212dc594e727ec58921d61750a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0033002e00310034003400000000000000000000000000
    

    Net-ntlm hash

    在type3身份验证阶段的响应具备六种类型的响应
    
    LM(LAN Manager)响应 - 由大多数较早的客户端发送,这是“原始”响应类型。
    
    NTLM v1响应 - 这是由基于NT的客户端发送的,包括Windows 2000和XP。
    
    NTLMv2响应 - 在Windows NT Service Pack 4中引入的一种较新的响应类型。它替换启用了 NTLM版本2的系统上的NTLM响应。
    
    LMv2响应 - 替代NTLM版本2系统上的LM响应。
    
    NTLM2会话响应 - 用于在没有NTLMv2身份验证的情况下协商NTLM2会话安全性时,此方案会更改LM NTLM响应的语义。
    
    匿名响应 - 当匿名上下文正在建立时使用; 没有提供实际的证书,也没有真正的身份验证。“存 根”字段显示在类型3消息中。
    这六种使用的加密流程一样,都是前面我们说的Challenge/Response 验证机制,区别在Challenge和加密算法不同。
    
    
    关于NTLMv1&v2
    NTLMv2是16位的Challenge,而v1是8位的Challenge
    NTLMv1是将 16字节的NTLM hash空填充为21个字节,然后分成三组,每组7比特,作为3DES加密算法的三组密钥,加密Server发来的Challenge。 将这三个密文值连接起来得到response。
    
    而v2是的加密算法是。
    (1). 将Unicode后的大写用户名与Unicode后的身份验证目标(在Type 3消息的"TargetName"字段中指定的域或服务器名称)拼在一起。请注意,用户名将转换为大写,而身份验证目标区分大小写,并且必须与“TargetName”字段中显示的大小写匹配。使用16字节NTLM哈希作为密钥,得到一个值。
    (2) 构建一个blob信息
    (3). 使用16字节NTLMv2哈希作为密钥,将HMAC-MD5消息认证代码算法加密一个值(来自type 2的Challenge与Blob拼接在一起)。得到一个16字节的NTProofStr。
    (4). 将NTProofStr与Blob拼接起来形成得到response。
    至于选择哪个版本的响应由LmCompatibilityLevel决定。
    
    验证机制里边包含了Net-ntlm hash,NTLM v1响应和NTLMv2响应对应的就是Net-ntlm hash分为Net-ntlm hash v1和Net-ntlm hash v2
    
    Net-ntlm v1的格式为:
    username::hostname:LM response:NTLM response:challenge
    Net-ntlm v2的格式为:
    username::domain:challenge:HMAC-MD5:blob
    

    关于NTLMv2

    已知格式如下
    username::domain:challenge:HMAC-MD5:blob
    
    challenge为ntlm server challenge  eb759c11e09dbb2b
    domain可以从数据包获得
    HMAC-MD5为NTProofStr  7427b887027d29fceb6f49963ba90072
    NTLMv2的Response  7427b887027d29fceb6f49963ba9007201010000000000004a881d1672e9d601e3d463fde72d2e3f0000000002000e0052004f004f0054004b004900540001000e004f005700410032003000310033000400160072006f006f0074006b00690074002e006f0072006700030026004f005700410032003000310033002e0072006f006f0074006b00690074002e006f00720067000500160072006f006f0074006b00690074002e006f0072006700070008004a881d1672e9d60106000400020000000800300030000000000000000000000000200000f1b5d13b0a0b1ac4bb031cf68b7998834190b70a212dc594e727ec58921d61750a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0033002e00310034003400000000000000000000000000
    blob为Response减去NTProofStr的后半部分  01010000000000004a881d1672e9d601e3d463fde72d2e3f0000000002000e0052004f004f0054004b004900540001000e004f005700410032003000310033000400160072006f006f0074006b00690074002e006f0072006700030026004f005700410032003000310033002e0072006f006f0074006b00690074002e006f00720067000500160072006f006f0074006b00690074002e006f0072006700070008004a881d1672e9d60106000400020000000800300030000000000000000000000000200000f1b5d13b0a0b1ac4bb031cf68b7998834190b70a212dc594e727ec58921d61750a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0033002e00310034003400000000000000000000000000
    
    结合hashcat效果如下
    hashcat -m 5600 Administrator::ROOTKIT:eb759c11e09dbb2b:7427b887027d29fceb6f49963ba90072:01010000000000004a881d1672e9d601e3d463fde72d2e3f0000000002000e0052004f004f0054004b004900540001000e004f005700410032003000310033000400160072006f006f0074006b00690074002e006f0072006700030026004f005700410032003000310033002e0072006f006f0074006b00690074002e006f00720067000500160072006f006f0074006b00690074002e006f0072006700070008004a881d1672e9d60106000400020000000800300030000000000000000000000000200000f1b5d13b0a0b1ac4bb031cf68b7998834190b70a212dc594e727ec58921d61750a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0033002e00310034003400000000000000000000000000 pass.txt --force
    

    SSP&SSPI

    SSPI

    Security Support Provider Interface
    
    Windows 定义的一套接口,此接口定义了与安全有关的功能函数, 用来获得验证、信息完整性、信息隐私等安全功能,就是定义了一套接口函数用来身份验证,签名等,但是没有具体的实现
    

    SSP

    Security Support Provider
    
    根据SSPI所生成的具体产物,简称SSP,如微软的NTLMSSP为NTLM认证的实现提供了基本功能,是windowsSSPI的一种实现,除了NTLMSSP外还有kerberos,Cred SSP,Digest SSP等等
    
    数据包内可以发现ntlm信息是放在GSS-API内,产生GSSAPI的原因是因为SSPI是GSSAPI的专有变体,进行了扩展并具有许多特定于Windows的数据类型
    

    LmCompatibilityLevel

    用来确定网络登录使用的质询/响应身份验证协议。此选项会影响客户端使用的身份验证协议的等级、协商的会话安全的等级以及服务器接受的身份验证的等级
    
    发送 LM NTLM 响应:
    客户端使用 LM 和 NTLM 身份验证,而决不会使用 NTLMv2 会话安全;域控制器接受 LM、NTLM 和 NTLMv2 身份验证
    
    发送 LM & NTLM:
    如果协商一致,则使用 NTLMv2 会话安全: 客户端使用 LM 和 NTLM 身份验证,并且在服务器支持时使用 NTLMv2 会话安全;域控制器接受 LM、NTLM 和 NTLMv2 身份验证
    
    仅发送 NTLM 响应:
    客户端仅使用 NTLM 身份验证,并且在服务器支持时使用 NTLMv2 会话安全;域控制器接受 LM、NTLM 和 NTLMv2 身份验证
    
    仅发送 NTLMv2 响应:客户端仅使用 NTLMv2 身份验证,并且在服务器支持时使用 NTLMv2 会话安全;域控制器接受 LM、NTLM 和 NTLMv2 身份验证
    
    仅发送 NTLMv2 响应拒绝 LM: 客户端仅使用 NTLMv2 身份验证,并且在服务器支持时使用 NTLMv2 会话安全;域控制器拒绝 LM (仅接受 NTLM 和 NTLMv2 身份验证)
    
    仅发送 NTLMv2 响应拒绝 LM & NTLM:客户端仅使用 NTLMv2 身份验证,并且在服务器支持时使用 NTLMv2 会话安全;域控制器拒绝 LM 和 NTLM (仅接受 NTLMv2 身份验证)
    

    安全问题

    pth

    此处在type3阶段时候客户端是使用用户的hash进行计算的,而不是基于密码,因此在登录时候是可以用hash进行登录的,针对防范pth微软推出补丁kb2871997进行缓解,当然这个也可以方法mimikatz抓取明文密码
    
    关于kb2871997只能进行缓解,是因为他对于本地的administrator(rid为500,操作系统只核对rid忽略用户名)和本地管理员组的域用户都是不受影响的
    
    也就是说rid为500的用户、本地管理员组的域用户在打补丁后都是可以pth
    

    常用操作

    mimikatz
    impacket组件
    msf
    

    ntlm信息泄露

    如下已知返回challenge时候将同时发送操作系统相关信息,如主机名、BIOS名等等,如果能够伪造第一阶段的typ1的请求,就能如下拿到服务器返回第二阶段type2的信息
    
    ntlm认证通常适用于多协议,如http、smb、ldap等
    

    C#版本的smb_version

    using System;
    using System.Data;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Collections;
    using System.Collections.Generic;
    using System.Threading;
    using System.Diagnostics;
    using System.IO;
    using System.Security.Cryptography;
    using System.Net;
    using System.Net.Sockets;
    using System.Reflection;
    using System.Runtime;
    using System.Runtime.InteropServices;
    
    namespace Zcg.Tests
    {
        class smbver
        {
            static byte[] d1 ={
        0x00, 0x00, 0x00, 0x85, 0xFF, 0x53, 0x4D, 0x42, 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xC8, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02, 0x50, 0x43, 0x20, 0x4E, 0x45, 0x54, 0x57, 0x4F, 
        0x52, 0x4B, 0x20, 0x50, 0x52, 0x4F, 0x47, 0x52, 0x41, 0x4D, 0x20, 0x31, 0x2E, 0x30, 0x00, 0x02, 
        0x4C, 0x41, 0x4E, 0x4D, 0x41, 0x4E, 0x31, 0x2E, 0x30, 0x00, 0x02, 0x57, 0x69, 0x6E, 0x64, 0x6F, 
        0x77, 0x73, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x57, 0x6F, 0x72, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x70, 
        0x73, 0x20, 0x33, 0x2E, 0x31, 0x61, 0x00, 0x02, 0x4C, 0x4D, 0x31, 0x2E, 0x32, 0x58, 0x30, 0x30, 
        0x32, 0x00, 0x02, 0x4C, 0x41, 0x4E, 0x4D, 0x41, 0x4E, 0x32, 0x2E, 0x31, 0x00, 0x02, 0x4E, 0x54, 
        0x20, 0x4C, 0x4D, 0x20, 0x30, 0x2E, 0x31, 0x32, 0x00
    };
            static byte[] d2 ={
        0x00, 0x00, 0x01, 0x0A, 0xFF, 0x53, 0x4D, 0x42, 0x73, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 
        0x00, 0x00, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0x0A, 0x01, 0x04, 0x41, 0x32, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0xA0, 0xCF, 0x00, 0x60, 
        0x48, 0x06, 0x06, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x02, 0xA0, 0x3E, 0x30, 0x3C, 0xA0, 0x0E, 0x30, 
        0x0C, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0A, 0xA2, 0x2A, 0x04, 
        0x28, 0x4E, 0x54, 0x4C, 0x4D, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x82, 0x08, 
        0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x05, 0x02, 0xCE, 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x57, 0x00, 0x69, 0x00, 0x6E, 0x00, 
        0x64, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 
        0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 
        0x20, 0x00, 0x33, 0x00, 0x37, 0x00, 0x39, 0x00, 0x30, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 
        0x72, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x61, 0x00, 
        0x63, 0x00, 0x6B, 0x00, 0x20, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x69, 0x00, 
        0x6E, 0x00, 0x64, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 
        0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 
        0x33, 0x00, 0x20, 0x00, 0x35, 0x00, 0x2E, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    static byte[] d3={
    0x81,0x00,0x00,0x44,0x20,0x43,0x4b,0x46,0x44,0x45,0x4e,0x45,0x43,0x46,0x44,0x45
    ,0x46,0x46,0x43,0x46,0x47,0x45,0x46,0x46,0x43,0x43,0x41,0x43,0x41,0x43,0x41,0x43
    ,0x41,0x43,0x41,0x43,0x41,0x00,0x20,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43
    ,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43,0x41,0x43
    ,0x41,0x43,0x41,0x43,0x41,0x41,0x41,0x00
    };
            static void Main(string[] args)
            {
                Console.WriteLine("SMB Version Detection tool 0.1");
                Console.WriteLine("Part of GMH's fuck Tools, Code By zcgonvh.
    ");
                if (args.Length < 1) { Console.WriteLine("usage: smbver host [port]"); return; }
                string host = args[0];
                int port = 445;
                try { port = int.Parse(args[1]); }
                catch { }
                try
                {
                    byte[] buf = new byte[1024];
                    Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    sock.Connect(host, port);
                    if(port==139)
                    {
                      sock.Send(d3);
                      sock.Receive(buf);
                    }
                    sock.Send(d1);
                    sock.Receive(buf);
                    sock.Send(d2);
                    sock.Receive(buf);
                    int len = BitConverter.ToInt16(buf, 43);
                    string[] ss = Encoding.Unicode.GetString(buf, len + 47, buf.Length - len - 47).Split('');
                    Console.WriteLine("native os: " + ss[0]);
                    Console.WriteLine("native lan manager: " + ss[1]);
                    int off = 0;
                    for (int i = 47; i < len - 7; i++)
                    {
                        if (buf[i] == 'N' && buf[i + 1] == 'T' && buf[i + 2] == 'L' && buf[i + 3] == 'M' && buf[i + 4] == 'S' && buf[i + 5] == 'S' && buf[i + 6] == 'P') { off = i; break; }
                    }
                    byte[] ntlm = new byte[len];
                    Array.Copy(buf, off, ntlm, 0, len);
                    len = BitConverter.ToInt16(ntlm, 0xc);
                    off = BitConverter.ToInt16(ntlm, 0x10);
                    Console.WriteLine("negotiate target: " + Encoding.Unicode.GetString(ntlm, off, len));
                    Console.WriteLine("os major version: " + ntlm[off - 8]);
                    Console.WriteLine("os minor version: " + ntlm[off - 7]);
                    Console.WriteLine("os build number: " + BitConverter.ToInt16(ntlm, off - 6));
                    Console.WriteLine("ntlm current revision: " + ntlm[off - 1]);
                    off += len;
                    int type = BitConverter.ToInt16(ntlm, off);
                    while (type != 0)
                    {
                        off += 2;
                        len = BitConverter.ToInt16(ntlm, off);
                        off += 2;
                        switch (type)
                        {
                            case 1:
                                {
                                    Console.WriteLine("NetBIOS computer name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                    break;
                                }
                            case 2:
                                {
                                    Console.WriteLine("NetBIOS domain name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                    break;
                                }
                            case 3:
                                {
                                    Console.WriteLine("DNS computer name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                    break;
                                }
                            case 4:
                                {
                                    Console.WriteLine("DNS domain name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                    break;
                                }
                            case 5:
                                {
                                    Console.WriteLine("DNS tree name: " + Encoding.Unicode.GetString(ntlm, off, len));
                                    break;
                                }
                            case 7:
                                {
                                    Console.WriteLine("time stamp: {0:o}", DateTime.FromFileTime(BitConverter.ToInt64(ntlm, off)));
                                    break;
                                }
                            default:
                                {
                                    Console.Write("Unknown type {0}, data: ", type);
                                    for (int i = 0; i < len; i++)
                                    {
                                        Console.Write(ntlm[i + off].ToString("X2"));
                                    }
                                    Console.WriteLine();
                                    break;
                                }
                        }
                        off += len;
                        type = BitConverter.ToInt16(ntlm, off);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("err: " + ex);
                }
            }
        }
    }
    

    msf的smb_version

    ntlm relay

    原先的传输方式
    

    中间出现攻击者,改变传输方式如下
    
    可以知道攻击者作为中间人,将来自用户的type1发送给服务器,将服务器的type2发送给用户,用户加入challenge计算完成后中间人再发送给服务器,服务器验证后,直接给与中间人相关权限
    

    后续将细论ntlm relay
    
  • 相关阅读:
    JAVA 关键字
    github 上传代码到仓库

    创建链表及使用
    关于MAP文件的使用(转贴)
    styledcomponent使用(一)
    关于EDM模型中多个实体之间循环引用导致保存数据失败的解决方案一例
    C#格式化字符串
    [原]存取AVD设备SD卡中的文件
    NSStirng、NSArray、以及枚举(Method小集合)
  • 原文地址:https://www.cnblogs.com/Yang34/p/14277168.html
Copyright © 2020-2023  润新知