ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Windows内网协议学习NTLM篇之NTLM基础介绍

2020-07-09 19:38:18  阅读:448  来源: 互联网

标签:LM hash Windows type NTLM hex 密码 Hash 内网


原文链接:https://www.anquanke.com/post/id/193149

 

0x00 前言

这个系列文章主要讲ntlm认证相关的内容。以及着重介绍ntlm两大安全问题–PTH和ntlm_relay。

ntlm篇分为四篇文章

第1篇文章也是本文,这篇文章主要简单介绍一些基础概念以及引进一些相关的漏洞,比如Pass The Hash以及ntlm_relay。

其余三篇文章的内容全部都是讲ntlm_relay,这个安全问题是ntlm篇的重点内容。

第2篇文章主要讲触发windows向攻击者发起ntlm请求的一些方式,比如大家耳熟能详的打印机漏洞。

第3篇文章主要讲的是攻击者接收到ntlm请求之后做的事,如爆破Net-ntlm,又或者relay到SMB,HTTP,Exchange,LDAP等。

第4篇文章主要回顾一下从上世纪ntlmrelay被提出来,微软从08年开始为ntlmrelay陆陆续续推出的一些补丁以及绕过,如ms08068,MS16-075,CVE-2015-0005,CVE-2018-8581,CVE-2019-1040,CVE2019-1384。以及ntlm relay的一些缓解措施。

0x01 LM Hash & NTLM Hash

windows内部是不保存明文密码的,只保存密码的hash。

其中本机用户的密码hash是放在 本地的SAM文件 里面,域内用户的密码hash是存在域控的NTDS.DIT文件 里面。那hash的格式是怎么样的呢?

在Windows系统导出密码的时候,经常看到这样的密码格式

Administrator:500:AAD3B435B51404EEAAD3B435B51404EE:31D6CFE0D16AE931B73C59D7E0C089C0:::

其中的AAD3B435B51404EEAAD3B435B51404EE是LM Hash

31D6CFE0D16AE931B73C59D7E0C089C0是NTLM Hash

下面详细介绍下这两种hash格式。

1. LM Hash

全称是LAN Manager Hash, windows最早用的加密算法,由IBM设计。

LM Hash的计算:

  1. 用户的密码转换为大写,密码转换为16进制字符串,不足14字节将会用0来再后面补全。
  2. 密码的16进制字符串被分成两个7byte部分。每部分转换成比特流,并且长度位56bit,长度不足使用0在左边补齐长度
  3. 再分7bit为一组,每组末尾加0,再组成一组
  4. 上步骤得到的二组,分别作为key 为 “KGS!@#$%”进行DES加密。
  5. 将加密后的两组拼接在一起,得到最终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")

  

 

LM加密算法存在一些固有的漏洞

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

2. NTLM Hash

为了解决LM加密和身份验证方案中固有的安全弱点,Microsoft 于1993年在Windows NT 3.1中引入了NTLM协议。下面是各个版本对LM和NTLM的支持。

其中

也就是说从Windows Vista 和 Windows Server 2008开始,默认情况下只存储NTLM Hash,LM Hash将不再存在。(因此后面我们介绍身份认证的时候只介绍Net-ntlm,不再介绍net-lm)如果空密码或者不储蓄LM Hash的话,我们抓到的LM Hash是AAD3B435B51404EEAAD3B435B51404EE。

所以在win7 中我们看到抓到LM Hash都是AAD3B435B51404EEAAD3B435B51404EE,这里的LM Hash并没有价值。

但某些工具的参数需要填写固定格式LM hash:NT hash,可以将LM hash填0(LM hash可以为任意值),即00000000000000000000000000000000:NT hash。

接下来讲下NTLM Hash的计算

1.先将用户密码转换为十六进制格式。

2.将十六进制格式的密码进行Unicode编码。

3.使用MD4摘要算法对Unicode编码数据进行Hash计算

python2 -c 'import hashlib,binascii; print binascii.hexlify(hashlib.new("md4", "p@Assword!123".encode("utf-16le")).digest())'

 

NTLM验证是一种Challenge/Response 验证机制,由三种消息组成:通常称为type 1(协商),类型type 2(质询)和type 3(身份验证)。

它基本上是这样工作的:

  1. 用户登录客户端电脑
  2. (type 1)客户端向服务器发送type 1(协商)消息,它主要包含客户端支持和服务器请求的功能列表。
  3. (type 2)服务器用type 2消息(质询)进行响应,这包含服务器支持和同意的功能列表。但是,最重要的是,它包含服务器产生的Challenge。
  4. (type 3)客户端用type 3消息(身份验证)回复质询。用户接收到步骤3中的challenge之后,使用用户hash与challenge进行加密运算得到response,将response,username,challeng发给服务器。消息中的response是最关键的部分,因为它们向服务器证明客户端用户已经知道帐户密码。
  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进行比较

下面简单介绍下三个过程,如果对于细节不感兴趣的话就可以忽略。

1. type 1 协商

这个过程是客户端向服务器发送type 1(协商)消息,它主要包含客户端支持和服务器请求的功能列表。

主要包含以下结构

抓包查看对应的信息如下

如果想仔细理解每个字段的值请阅读官方文档NEGOTIATE_MESSAGE

2. type 2 质询

这个过程是服务器用type 2消息(质询)进行响应,这包含服务器支持和同意的功能列表。但是,最重要的是,它包含服务器产生的Challenge。

主要 包含以下结构

其中最主要的信息是challenge。后面加密验证依赖于challenge

抓包查看对应的信息如下

如果想仔细理解每个字段的值请阅读官方文档CHALLENGE_MESSAGE

3. type 3 身份验证

这个过程客户端接收到challenge之后,使用用户hash与challenge进行加密运算得到response,将response,username,challenge发给服务器。消息中的response是最关键的部分,因为它向服务器证明客户端用户已经知道帐户密码。

主要包含以下结构

这里的Challeng不同于type2 的Challenge,这里的Challenge是一个随机的客户端nonce。

MIC是校验和,设计MIC主要是为了防止这个包中途被修改

sessionkey是在要求进行签名的时候用的,用来进行协商加密密钥,可能有些文章会说sessionkey就是加密密钥,需要拥有用户hash才能计算出来,因此攻击者算不出来,就无法加解密包。但是想想就不可能,这个session_key已经在流量里面明文传输,那攻击者拿到之后不就可以直接加解密包了。当然这是后话,后面讲签名的时候会详细讲讲这个问题。

抓包查看对应的信息如下

如果想仔细理解每个字段的值请阅读官方文档AUTHENTICATE_MESSAGE

 

标签:LM,hash,Windows,type,NTLM,hex,密码,Hash,内网
来源: https://www.cnblogs.com/panpanwelcome/p/13275589.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有