windows认证系列和域前置的简单了解
00x01.Windows之NTLM认证
NTLM认证主要有本地认证和网络认证两种方式
本地登陆时用户密码存储在SAM文件中,可以把它当作一个存储密码的数据库,所有的操作都在本地进行的。它将用户输入的密码转换为NTLM Hash,然后与SAM中的NTLM Hash进行比较。
网络认证则是基于一种Challenge/Response认证机制的认证模式。
windows本地认证基础知识
在本地登陆的情况下,操作系统会使用用户输入的密码作为凭据去与系统中的密码进行校验,如果成功的话表明验证通过。
操作系统的密码存储在C盘的目录下:%SystemRoot%\system32\config\sam
SAM用于储存本地所有用户的凭证信息,但是这并不代表着你可以随意去查看系统密码。
我们登陆系统的时候系统会自动读取SAM文件中的密码与我们输入的密码进行比对,如果认证相同则可以使用该机器。
windows自身是不会保存明文密码的,也就是说SAM中保存的不是明文而是Hash。
NTLM的认证过程
NTLM Hash是怎么样生成的呢?
当用户注销、重启、锁屏后,操作系统会让winlogon显示登陆界面,当winlogon.exe接收到账号密码输入之后,会将密码交给lsass进程,这个进程会存一份明文密码,将明文密码加密成NTLM Hash,对SAM数据库比较认证。
(winlogon.exe即Windows Logon Process,是Windows NT用户登陆程序,用于管理用户登录和退出。LSASS用于微软Windows系统的安全机制。它用于本地安全和登陆策略。)
比如当用户输入密码admin
的时候,操作系统会将admin转换为16进制
,经过Unicode转换
后,再调用MD4加密算法加密
,这个加密结果的十六进制
就是NTLM Hash
admin -> hex(16进制编码) = 61646d696e
61646d696e -> Unicode = 610064006d0069006e00
610064006d0069006e00 -> MD4 = 209c6174da490caeb422f3fa5a7ae634
加密脚本:
import hashlib
import binascii
Description = '''
NTLM计算过程
admin -> hex = 61646d696e
61646d696e-> Unicode = 610064006d0069006e00
610064006d0069006e00 -> MD4 = 209c6174da490caeb422f3fa5a7ae634
'''
print(Description)
Password = input('Your Password:')
hash = hashlib.new('md4',Password.encode('utf-16le')).digest()
hash_hex = binascii.hexlify(hash)
print('->' + str(hash_hex),'utf-8')
本地认证的流程
winlogon.exe -> 接收用户输入 -> lsass.exe -> (认证)
Windows Logon Process
(即 winlogon.exe
),是Windows NT
用户登 陆程序,用于管理用户登录和退出。
LSASS
用于微软Windows系统的安全机 制。它用于本地安全和登陆策略。
windows网络认证
在工作组中,无论是局域网中的一台机器还是很多机器,它们能够通信的话都无法相互建立一个完美的信任机制。只要有一个可以信任的信托机构,对两方进行认证,这样就有第三方来证实双方的可信任性。
在了解认证之前先了解一些SMB协议
:
SMB(ServerMessage Block)通信协议是微软(Microsoft)和英特尔(Intel)在1987年制定的协议,主要是作为Microsoft网络的通讯协议。SMB 是在会话层(session layer)和表示层(presentation layer)以及小部分应用层(application layer)的协议。SMB使用了NetBIOS的应用程序接口 (Application Program Interface,简称API),一般端口使用为139,445。另外,它是一个开放性的协议,允许了协议扩展——使得它变得更大而且复杂;大约有65个最上层的作业,而每个作业都超过120个函数,甚至Windows NT也没有全部支持到,最近微软又把 SMB 改名为 CIFS(CommonInternet File System),并且加入了许多新的特色。
早期SMB协议在网络上传输的是明文口令。后来出现LAN Manager ChallengeReponse 验证机制,简称LM。
微软提出了windowsNT挑战/响应验证机制,简称MTLM。现在已经更新到了V2版本以及加入了Kerberos验证体系
NTLM 协议
NTLM是一种网络认证协议,它是基于挑战(Chalenge)/响应(Response)认证机制的一种认证模式。(这个协议只支持Windows)
NTLM协议的认证共需要三个消息完成:协商 --> 挑战 --> 认证。
协商:主要用于确认双方协议版本、加密等级等
挑战:服务器在收到客户端的协商消息之后, 会读取其中的内容,并从中选择出自己所能接受的服务内容,加密等级,安全服务等等。并生成一个随机数challenge, 然后生成challenge消息返回给客户端。该消息就是挑战/响应认证机制的主要功能体现。
认证:验证主要是在挑战完成后,验证结果,是认证的最后一步。
质询的完整过程:
客户端向服务器端发送用户信息(用户名)请求
服务器接受到请求,生成一个16位的随机数,被称之为“Challenge”, 使用登录用户名对应的NTLM Hash加密Challenge(16位随机字符), 生成Challenge1。同时,生成Challenge1后,将Challenge(16位随机 字符)发送给客户端。
客户端接受到Challenge后,使用将要登录到账户对应的NTLM Hash加密Challenge生成Response,然后将Response发送至服务器端。
其中,经过NTLM Hash
加密Challenge
的结果在网络协议中称之为Net NTLM Hash
。
验证:服务器端收到客户端的Response
后,比对Chanllenge1
与Response
是否相等,若相等,则认证通过。
详细过程:
Server接收到Client发送的用户名后,判断本地账户列 表是否有用户名share_user 如果没有,返回认证失败 如果有,生成Chanllenge,并且从本地查找share_user对 应的NTLM Hash,使用NTLM Hash加密Chanllenge,生成一 个Net-NTLM Hash存在内存中,并将Chanllenge发送给Client。
Client接收到Chanllenge后,将自己提供的share_user的密码转换为NTLM Hash,使用NTLM Hash加密Chanllenge, 这个结果叫Response,表现形式是Net-NTLM Hash,最后将Response发送给Server。
Server接收到Client发送的Response,将Response与之 前的Net-NTLM Hash进行比较,如果相等,则认证通过。
注意:
Chanllenge是Server产生的一个16字节的随机数,每次认证都不同。
Response的表现形式是Net-NTLM Hash,它是由客户端 提供的密码Hash加密Server返回的Chanllenge产生的结果。
NTLM 协议 V1 与 V2的区别
NTLM v1与NTLM v2最显著的区别就是Challenge与加密算法不同,共同点就是加密的原料都是NTLM Hash。
Challage:NTLM v1的Challenge有8位,NTLM v2的Challenge为16位。
Net-NTLM Hash:NTLM v1的主要加密算法是DES,NTLM v2的主要加密算法是HMAC-MD5。
内网渗透常用端口
53
DNS服务,在使用中需要用到TCP/UDP 53端口,AD域的核心就是DNS服务器,AD通过DNS服务器定位资源
88
Kerberos服务,在使用中需要用到TCP/UDP 88端口,Kerberos密钥分发中心(KDC) 在该端口上侦听Ticket请求
135
135端口主要用于使用RPC协议并提供DCOM服务。
137
NetBIOS-NS(名称服务),在使用中需要用到TCP/UDP 137端口
139
Session Server(会话服务),在使用中需要用到TCP/UDP 139端口,允许两台计算机建立连接
389
LDAP服务(轻量级目录访问协议),在使用中需要用到TCP/UDP 389端口,如果需要使用SSL,需要使用636端口,
445
主要用于共享文件夹或共享打印,存在较多漏洞,如MS08-067、MS17-010
3268 Global Catalog(全局编录服务器),如果需要使用SSL,需要用到3269端口,主要用于用户登录时,负责验证用户身份的域控制器需要通过防火
墙,来向“全局编录”查询用户所隶属的通用组
NTLM身份验证
NTLM验证是一种Challenge/Response
验证机制,由三种消息组成:通常称为type 1(协商)
,类型type 2(质询)
和type 3(身份验证)
。
它基本上是这样工作的:
用户登录客户端电脑
(type 1)客户端向服务器发送type 1(协商)消息,它主要包含客户端支持和服务器请求的功能列表。
(type 2)服务器用type 2消息(质询)进行响应,这包含服务器支持和同意的功能列表。但是,最重要的是,它包含服务器产生的Challenge。
(type 3)客户端用type 3消息(身份验证)回复质询。用户接收到步骤3中的challenge之后,使用用户hash与challenge进行加密运算得到response,将response,username,challeng发给服务器。消息中的response是最关键的部分,因为它们向服务器证明客户端用户已经知道帐户密码。
服务器拿到type 3之后,使用challenge和用户hash进行加密得到response2与type 3发来的response进行比较。如果用户hash是存储在域控里面的话,那么没有用户hash,也就没办法计算response2。也就没法验证。这个时候用户服务器就会通过netlogon协议联系域控,建立一个安全通道,然后将type 1,type 2,type3 全部发给域控(这个过程也叫作Pass Through Authentication认证流程),域控使用challenge和用户hash进行加密得到response2,与type 3的response进行比较
下面简单介绍下三个过程,如果对于细节不感兴趣的话就可以忽略。
type 1 协商
这个过程是客户端向服务器发送type 1(协商)消息,它主要包含客户端支持和服务器请求的功能列表。
主要包含以下结构
抓包查看对应的信息如下
type 2 质询
这个过程是服务器用type 2消息(质询)
进行响应,这包含服务器支持和同意的功能列表。但是,最重要的是,它包含服务器产生的Challenge
。
主要 包含以下结构
type 3 身份验证
这个过程客户端接收到challenge
之后,使用用户hash
与challenge
进行加密运算得到response
,将response
,username
,challenge
发给服务器。消息中的response
是最关键的部分,因为它向服务器证明客户端用户已经知道帐户密码。
主要包含以下结构
这里的Challeng
不同于type2 的Challenge
,这里的Challenge
是一个随机的客户端nonce
。
MIC是校验和,设计MIC主要是为了防止这个包中途被修改
sessionkey
是在要求进行签名的时候用的,用来进行协商加密密钥,可能有些文章会说sessionkey
就是加密密钥,需要拥有用户hash
才能计算出来,因此攻击者算不出来,就无法加解密包。但是想想就不可能,这个session_key
已经在流量里面明文传输,那攻击者拿到之后不就可以直接加解密包了。当然这是后话,后面讲签名的时候会详细讲讲这个问题。
00x02.Windows之Kerberos认证
域认证Kerberos
域内认证不再是两台机器之间互相请求认证,而是通过第三方可信机构KDC(Key Distribute Center
)来实现整个认证体系
系统角色
参与域认证的三个角色:
- Client
- Server
- KDC(Key Distribution Center) = AD(Account Database)+ AS(Authenication Service)+ TGS(Ticket Granting Service)
从物理层面看,KDC的角色实际为域控制器(Domain Controller
),其中包含AD数据库
与AS服务
,TGS服务
。
Kerberos相关的几个概念:
KDC(Key Distribution Center):密钥分发中心
AS(Authentication Server):身份认证服务
TGT(Ticket Granting Ticket):由AS身份认证服务提供的票据也称为黄金票据,用于身份认证,存储在内存,默认有效期为10小时。
TGS(Ticket Granting Server):由TGS服务提供的票据也称为白银票据,用于发出所请求服务的票证。
AD,全称叫Account Database,被称作活动目录数据库,存放在域控NTDS.DIT文件中,存储域中所有用户的用户名和对应的NTLM Hash,KDC可以从AD中提取域中所有用户的NTLM Hash,这是Kerberos协议能够成功实现的基础。
AS,全称叫Authenication Service,是KDC的组件之一,处理初始请求并负责发出TGT给Client,用来完成对Client的身份验证。
TGS,全称叫Ticket Granting Service,也是KDC的组件之一,从AS那里拿到TGT之后,TGS再发出对某个特定服务或服务器访问的Ticket,这个Ticket允许对某个服务访问。
Kerbreros认证流程
下图显示了Client
、Server
、KDC
三者的协议交互过程。
Client向KDC发起服务请求,希望获取访问Server的权限。 KDC得到了这个消息,首先得判断Client是否是可信赖的, 也就是从AD数据库中寻找该用户是否可用来登录。这就是AS服务完成的工作,成功后,AS返回TGT给Client。
Client得到了TGT后,继续向KDC请求,希望获取访问Server的权限。KDC又得到了这个消息,这时候通过Client 消息中的TGT,判断出了Client拥有了这个权限,给了Client访问Server的权限Ticket。(TGS服务的任务)
Client得到Ticket后便可以使用这个Ticket成功访问Server。但是这个Ticket只能用来访问这个Server,如果要访问其他Server需要向KDC重新申请。
具体过程
1、用户登陆
- 用户输入 用户名 和 密码 信息
- 在客户端,用户输入的 密码 通过计算生成NTLM哈希作做为 CLIENT密钥
2、身份认证服务(AS)认证流程
2.1 客户端向AS发送认证请求
- 客户端向AS发送带有明文 用户名 的认证请求
2.2 AS确认Client端登录者用户身份
1、AS从AD数据库中查找该用户是否存在。
2、如果该 用户名 存在,则AS使用用户密码生成密钥,然后对响应消息Msg A进行加密。如果找不到,则将错误消息返回给客户端。
3、AS使用TGS密钥对Msg B进行加密。
4、AS将Msg A和Msg B返回给客户端。
5、客户端使用用户的密钥解密 Msg A。请注意,客户端无法解密 Msg B。
- TGT(Msg B)中包含如下信息:
– [Client/TGS SessionKey]
– Client ID
– Ticket有效时间
– Client 地址
6、从解密的 Msg A中提取的Client/TGS SessionKey
(Client/TGS 会话密钥)。
客户端无法解密Msg B,即无法解密TGT,解密需要TGS密钥,但是密钥存在于KDC上
需要了解:TGS密钥 == KDC Hash == krbtgt用户的NTLM Hash
AS响应的消息中有一条是属于Client的,但另外一条却属于TGS。
认证过程中的加密除哈希外均采用的是对称加密算法。
3、票据授予服务(TGS)认证流程
3.1 客户端向TGS发送请求服务授权请求
1、客户端发送消息 Msg C,以及 Msg D
- Msg C
– 要请求的服务ID, 即[Service ID]
– 上一步2.2中由AS为Client提供的TGT。 - Msg D
– 使用Client/TGS SessionKey
加密的Authenticator 1 {Client ID, Timestamp}
。
2、TGS获取两个请求 Msg C 和 Msg D,先从 Msg C中获取TGT以及服务ID。
3、TGS接下来使用TGS密钥(即krbtgt
用户的NTLM Hash
)解密TGT,从TGT中提取到 Client/TGS SessionKey
,TGS 现在有了Client/TGS SessionKey
。
4、TGS此时使用 Client/TGS SessionKey
解密Msg D,获得Authenticator 1 {Client ID, Timestamp}
。
5、TGS比较 Msg C以及 Msg D获取到的Client ID
。
6、如果相同TGS生成 Msg E以及Msg F,不同则报错误。
TGT在其生命周期内被缓存,并用于请求客户端需要的每个新服务票证。
CLIENT/TGS SESSIONKEY也由客户端缓存。
3.2 TGS为Client响应服务授权票据
1、客户端接收到TGS发送的 Msg E 以及Msg F
- Msg E使用 SERVICE密钥(服务器的NTLM HASH) 加密的 CLIENT-TO-SERVER TICKET,该Ticket中包含了如下信息:
– [Client/Server SessionKey]
– Client网络地址
– Ticket有效时间
– Client ID - Msg F使用 Client/TGS SessionKey加密的 Client/Server SessionKey
2、客户端使用 CLIENT/TGS SESSIONKEY
解密Msg F获得 CLIENT/SERVER SESSIONKEY
- Msg E使用了 [SERVICE密钥] 加密,该消息可视作是TGS给
Service Server
的消息,只不过由Client一起携带发送给Service Server
4.发送服务请求
4.1 Client向Service Server发送服务请求
1、客户端生成 Msg E 和 Msg G(Authenticator 2
)。
- Msg E 上一步3.2中,TGS为客户端响应的消息 Msg E。该消息可以理解为由客户端携带的消息。
- Msg G由
Client/Server SessionKey
加密的Authenticator 2
,包含{Client ID, Timestamp
}信息。
2、客户端将 Msg E 和 Msg G 发送到服务器(SS)。
3、服务器使用其自己的密钥对 Msg E(ticket)进行解密,得到 Client/Server SessionKey
4、服务器使用上一步得到的 Client/Server SessionKey
解密 Msg G
5、比较消息 Msg E 和 Msg G 中的Client ID
。
6、如果匹配,则将Msg H发送给客户端,以确认服务器身份和服务客户端请求的意愿(此部分是可选的)。
4.2 Service Server响应Client
1、客户端收到Msg H。
- Msg H是
Client/Server SessionKey
加密的时间戳
2、客户端使用 Client/Server SessionKey
解密Msg H。
3、客户端检查 Msg H 的时间戳。
4、客户端现在信任服务器,可以与服务器进行交互。
来自SS的响应(Msg H)是可选的。仅在客户端希望SS对其自身进行身份验证时才需要这样做(即相互身份验证)。
认证流程中需要关注的点,票据伪造的原理
-
2.2 AS确认Client端登录者用户身份
– KDC返回的Msg B:使用 TGS密钥(KDCHASH/KRBTGT用户NTLMHASH) 加密的TGT(Ticket-Granting-Ticket),当我们获取到krbtgt用户的NTLM哈希后,便可主动使用krbtgt用户的NTLM哈希做为TGS密钥来生成TGT发送给KDC,这样KDC如果通过解密伪造TGT获取到伪造的 [CLIENT/TGS SESSIONKEY] 可以成功解密 Authenticator 1 并完成与TGT中的数据进行比对,便成功骗过了KDC,也就是成功伪造了黄金票据 -
4.1 Client向SSService Server发送服务请求
– 客户端向服务器发送的为使用 SERVICE密钥(服务器的NTLMHASH) 加密的 CLIENT-TO-SERVER TICKET Ticket中包含用来供服务器解密Authenticator 2的 CLIENT/SERVER SESSIONKEY 。如果获取到了Service Server的NTLM Hash,便可伪造Ticket,和Authenticator 2 ,Service Server在接收到Ticket和Authenticator 2后可以使用自己的NTLM Hash正常解密完成比对,也就是成功伪造了白银票据1、黄金票据与白银票据需要拿到krbtgt或者server用户的hash,所以只能做为后门使用
2、白银票据利用之后无日志,所以比黄金票据更好
3、关于Service Hash,Service Hash其实是目标中一个用户名与hostname相同的用户的Hash
如hostname为PC-WIN7的服务器,对应的Hash就是Username : PC-WIN7$的哈希
黄金白银票据
白银票据
-
原理(伪造Server Hash被加密的Ticket)
Client 向Server 发起请求的时候,票据为Server Hash(Ticket)和Server Session Key(Client Info+Timestamp)而Server 除了Server Hash以外,其他都是不知道的;
从而,一旦知道了Server Hash后,就可以伪造Server Session Key并生成伪造的Ticket和伪造的Server Session Key(Client Info+Timestamp);
将伪造的Ticket使用Server Hash加密,就得到了伪造的Server Hash(Ticket);
最后将伪造的Server Hash(Ticket)和Server Session Key(Client Info+Timestamp)发送给Srever 即可以验证通过。 -
特点
需要目标服务的NTML Hash,即Server Hash;
不需要与KDC 交互;
只能访问指定服务器;
黄金票据
-
原理(伪造被krbtgt Hash加密的TGT)
在Client向AS 发送验证信息的时候,验证消息为:
Session Key(Client Info+Timestamp)
Client Info+Server Info
KDC Hash(TGT)
而AS 又是使用KDC Hash(krbtgt Hash)解密KDC Hash(TGT)得到TGT,并从TGT中获得session Key;
最后再利用Session Key去解密Session Key(Client Info+Timestamp)获得Client Info+Server Info,去对比未加密的Client Info+Server Info是否一致从而验证客户端身份;
所以,如果知道了KDC Hash(krbtgt Hash)就可以伪造session Key,从而伪造KDC Hash(TGT),进而发送伪造的:
Session Key(Client Info+Timestamp)
Client Info+Server Info
KDC Hash(TGT)
最终达到身份验证的目的; -
特点
需要KDC Hash(krbtgt Hash);
AS直接验证通过;
可以访问任意服务器;
00x03.域前置简单了解
原理
域前置(Domain fronting
),是一种隐藏连接真实端点来规避互联网审查的技术。在应用层上运作时,域前置使用户能通过 HTTPS 连接到被屏蔽的服务,而表面上像是在与另一个完全不同的站点通信。
假设有两个主机,域名分别为www.a.com
与www.b.com
。这两个主机都是被ip为1.1.1.1
的cdn
进行加速的。
这时候使用curl命令请求cdn 1.1.1.1
,并自定义host段为www.b.com
的话。就会返回www.b.com
的页面。
命令为:curl 1.1.1.1 -H "Host: www.b.com" -v
同理请求同样的cdn
,但是将host
改为www.a.com
,这时候就会返回A页面的信息。
如果将curl 后请求的ip改为 www.a.com
, host 改为 www.b.com
。命令为:
Curl www.a.com -H "Host: www.b.com" -v
上述命令还是显示的是www.b.com
的页面,所以最终请求的还是www.b.com
。
所以,域前置技术的核心基础设施是cdn
。
当使用https的时候(一般都会使用https,http明文流量容易被检测到),技术实现的核心是在不同的通信层使用不同的域名,DNS解析的时候跟TLS服务器名称指示(sin),的时候使用的是合法的CDN的域名或者ip(建议使用域名),但实际访问域名却是host上写的域名.
host头对于检查器是不可见的,但是对于接受https请求的前端服务器是可见的。
简单理解:
表面看,头部 CDN 通讯域名(我们看得到);
实际内部,尾部真实 IP(我们看不到)。
没有域名emmmm,贴上链接了解一下先
域前置技术的原理与CS上的实现
为你的C2配置一个完美的隐藏
域前置水太深,偷学六娃来隐身——域前置攻击复现
感言:
接触内网的第二天emmmmm,好家伙直接给我整的一愣一愣的,跪求佬们带带QAQ!!!
参考链接:
Windows内网协议学习NTLM篇之NTLM基础介绍
windows之NTLM认证
2.2.1 NTLM Messages
内网渗透——WINDOWS认证机制之KERBEROS
【渗透测试笔记】之【内网渗透——彻底理解Kerberos认证和黄金白银票据】