少女祈祷中...

Windows认证机制

​ Windows 的认证机制也是一项基础,通过本文你能大致了解Windows认证机制,其中涉及常见的名词如NTLM哈希,PTH ,Kerberos协议,黄金票据、白银票据等等,希望师傅们看完能基本了解其含义和及其原理

Windows本地认证

密码存储路径:%SystemRoot%\system32\config\sam

NTLM Hash

NTLM Hash 是长度为32位由数字和字母组成的hash,支持Net NTLM 认证协议及本地认证

  • Windows本身不存储用户的明文密码
  • 当用户登录时候,会与本地SAM中的NTLM hash进行比较
  • 在NTLM Hash 之前还存在LM Hash

生成

from passlib.hash import nthash
h=nthash.hash('admin')

计算过程

如计算 admin的 NTLM Hash

  1. hex(16进制编码) -> 61646d696e
  2. Unicode -> 610064006d0069006e00
  3. MD4 -> 209c6174da490caeb422f3fa5a7ae634

本地认证流程

  1. Windows Logon Process (即 winlogon.exe),是Windows NT 用户登录程序,用于管理用户登录和退出
  2. LSASS 用于微软Windows系统的安全机制。用于本地安全和登录策略

LM Hash

计算过程

  1. 将所有小写字母转为大写字母
  2. 将密码转为16进制,分两组,填充为14个字符,空余位使用0x00字符填补
  3. 将密码分割为两个7个字节的的块
  4. 将每组转化为比特流,不足58bit的时候在左边加0
  5. 将比特流按照7比特一组,分出8组,末尾加0
  6. 将每组转化为16进制作为被加密的值,使用DES加密,使用字符串”KGS!@#%” 作为Key(0x4B47532140232425),得到8个结果,每个结果转化为16进制

若密码不超过7字节,后面一半是固定的:AA-D3-B4-35-B5-14-04-EE

  1. 连接两个加密字符串,得到LM哈希

Windows 网络认证

背景

在内网渗透中,经常会遇到工作组,工作组环境是一个逻辑上的网络环境(工作区) ,隶属于工作组的机器之间违法相互建立一个完美的信任机制,只能点对点,是比较落后的认知方式,没有信任机构

假设A主机与B主机属于同一个工作组环境,A想访问B上面的资源,需要将一个存在于B主机上的账户凭证发送给B,经过认证才能访问B

常见的服务:SMB服务 端口445

NTLM协议

即NT LAN Manager协议

概述

早期的SMB协议在网络传输明文口令,后来出现LAN Manager Challenge/Response 验证机制,简称LM,但因为简单很容易就会被破解

后面提出了WindowsNT挑战/响应验证机制,称之为NTLM 。现在已经有了更新的NTLMv2以及Kerberos验证体系

Challenge/Response

  1. 第一步 协商

客户端在这一步向服务器确认协议版本,是v1还是v2 …

  1. 第二步 质询

    服务端向客户端发送响应包

服务器接收到请求后生成一个16位的随机数,称之为“Challenge” 使用登录用户名对应的NTLM Hash加密加密 Challenge 生成Challenge1。同时,生成Challenge1后,将Challenge(16位随机字符)发送给客户端 // Net NTLM Hash = NTLM Hash( Challenge)

客户端接收到Challenge后,使用将要登录到账户对应的NTLM Hash加密Challenge生成Response ,然后将Response发送到服务端,这个Response 也就是Net-NTLM Hash

  1. 第三步 验证

客户端会发送一个响应包

服务端收到客户端的Response后,比对Chanllenge1与Response是否相等,若相等,则认证通过

注意:每一次产生的Chanllenge都不同

流程如图:

NTLM v2 协议

NTLM v1 与NTLM v2 最显著的区别就是Challenge 与加密算法不同,共同点就是加密的原料都是NTLM Hash

差异

  • Chanllenge v1 的是有8位 ,v2的有16位
  • Net-NTLM Hash: 加密算法 v1使用的DES ,v2的加密算法主要是HMAC-MD5

Pass The Hash

即PTH (哈希传递)

介绍

哈希传递是能够在不需要账户明文密码的情况下完成认证的一个技术

在获取不到明文密码,破解不了NTLM Hash的情况下进行横向移动

条件

  • 被认证的主机能够访问到服务器
  • 需要知道被传递认证的用户名
  • 需要被传递认证用户的NTLM Hash

原理

其实知道了NTLM协议的认证的流程,原理就很简单,发送给服务端的Resposne是通过NTLM Hash 和 Chanllenge 生成的,因此直接使用Hash 就可以生成正确的Response

这也是正常的NTLM 认证流程

工具

常见的工具有:

  • Smbmap
  • CrackMapExec
  • Smbexec
  • Metasploit
  • ……..

如使用CrackMapExec

cme smb 192.168.3.5 -u administrator -H dab7de8feecac65faf9fdc6cac3a9 -x whoami

域认证

Kerberoes协议

Active Directory

概念

Active Directory存储了有关网络对象的信息,并且让管理员能快速查找和使用这些信息。Active Directory 使用了结构化的数据存储方式,并以此作为基础对目录信息进行合乎逻辑的分层组织

网络对象分为:用户、用户组、计算机、域、组织单位以及安全策略等

作用

服务器及其客户端计算机管理、用户管理、资源管理、桌面配置、应用系统支撑

Kerberoes

Kerberos是一种网络认证协议,设计目标是通过密钥系统为客户机和服务器应用程序提供认证服务。无需基于主机地址的信任,不需要网络上所有主机的网络安全。并假定网络上传送的数据包可以被任意读取、修改插入数据。在上面情况下,Kerberos作为一种可信任的第三方认证服务,通过传统的密码技术(共享密钥)执行认证服务

涉及到三个角色:Client、Server、KDC(Key Distribution Center) = DC (域控)

KDC

  • AD (account database):存储所有client的白名单,只有存在于白名单的Client才能顺利申请到TGT
  • Authentication Service( AS ): 为client 生成TGT的服务
  • Ticket Grantig Service(TGS): 为Client 生成某个服务的ticket 的服务

关系如图:

域认证流程

其中涉及 的密钥加密一般都是 使用对应机器的 NTLM Hash 加密

第一次通信

概述:client 向 kerberos 服务请求,希望获取访问权限,kerberos 服务器首先判断client是否可信,也就是通过白名单和黑名单,通过后AS返回TGT给client

具体流程:

① 客户端用户向KDC以明文的方式发起请求。该次请求中携带了自己的用户名,主机IP,和当前时间戳(AS_REQ)
②KDC当中的AS(Authentication Server)接收请求(AS是KDC中专门用来认证客户端身份的认证服务器)后去kerberos认证数据库中根据用户名查找是否存在该用户,此时只会查找是否有相同用户名的用户,并不会判断身份的可靠性;
③ 如果没有该用户名,认证失败,服务结束;如果存在该用户名,则AS认证中心便认为用户存在,此时便会返回响应给客户端,其中包含两部分内容:

  • 第一部分内容称为TGT,他叫做票据授予票据,客户端后面的流程需要使用TGT去KDC中的TGS(票据授予中心)获取访问网络服务所需的Ticket(服务授予票据),TGT中包含的内容有kerberos数据库中存在的该客户端的Name,IP,当前时间戳,客户端
    **即将访问的TGS的Name,TGT的有效时间以及一把用于客户端和TGS间进行通信的Session_key(CT_SK)**。整个TGT使用TGS密钥加密,客户端是解密不了的,由于密钥从没有在网络中传输过,所以也不存在密钥被劫持破解的情况。
  • 第二部分内容是使用客户端密钥(域控默认存储了所有机器的密钥,client,server)加密的一段内容,其中包括用于客户端和TGS间通信的Session_key(CT_SK),客户端即将访问的TGS的Name以及TGT的有效时间,和一个当前时间戳 。该部分内容使用客户端密钥加密,所以客户端在拿到该部分内容时可以通过自己的密钥解密。如果是一个假的客户端,那么他是不会拥有真正客户端的密钥的,因为该密钥也从没在网络中进行传输过。这也同时认证了客户端的身份,如果是假客户端会由于解密失败从而终端认证流程。

至此,第一次通信完成。

第二次通信

概述:client 得到了TGT 后 继续向kerberos请求 ,希望获取server的权限,kerberos通过TGT 判断client是否拥有权限,然后给client访问server的权限的ticket

具体流程:

客户端行为:
①客户端使用CT_SK (SessionKey加密将自己的客户端信息发送给KDC,其中包括客户端名,IP,时间戳;
②客户端将自己想要访问的Server服务以明文的方式发送给KDC;
③客户端将使用TGS密钥加密的TGT也原封不动的也携带给KDC;

TGS行为:
① 此时KDC中的TGS(票据授予服务器)收到了来自客户端的请求。他首先根据客户端明文传输过来的Server服务IP查看当前kerberos系统中是否存在可以被用户访问的该服务。如果不存在,认证失败结束。如果存在,继续接下来的认证。
②TGS使用自己的密钥将TGT中的内容进行解密,此时他看到了经过AS认证过后并记录的用户信息,一把Session_KEY即CT_SK,还有时间戳信息,他会现根据时间戳判断此次通信是否真是可靠有无超出时延。
③如果时延正常,则TGS会使用CK_SK对客户端的第一部分内容进行解密(使用CT_SK加密的客户端信息),取出其中的用户信息和TGT中的用户信息进行比对,如果全部相同则认为客户端身份正确,方可继续进行下一步。
④此时KDC将返回响应给客户端,响应内容包括:

  • 第一部分:用于客户端访问网络服务的使用Server密码加密的ST(Servre Ticket),其中包括客户端的Name,IP,需要访问的网络服务的地址Server IP,ST的有效时间,时间戳以及用于客户端和服务端之间通信的CS_SK(Session Key)。
  • 第二部分:使用CT_SK加密的内容,其中包括CS_SK和时间戳,还有ST的有效时间。由于在第一次通信的过程中,AS已将CT_SK通过客户端密码加密交给了客户端,且客户端解密并缓存了CT_SK,所以该部分内容在客户端接收到时是可以自己解密的。

至此,第二次通信完成。

第三次通信

概述:_此时的客户端收到了来自KDC(TGS)的响应,并使用缓存在本地的CT_SK解密了第二部分内容(第一部分内容中的ST是由Server密码加密的,客户端无法解密),检查时间戳无误后取出其中的CS_SK准备向服务端发起最后的请求。

具体流程

客户端:
① 客户端使用CK_SK将自己的主机信息和时间戳进行加密作为交给服务端的第一部分内容,然后将ST(服务授予票据)作为第二部分内容都发送给服务端。

服务端:

​ ① 服务器此时收到了来自客户端的请求,他会使用自己的密钥,即Server密钥将客户端第二部分内容进行解密,核对时间戳之后将其中的CS_SK取出,使用CS_SK将客户端发来的第一部分内容进行解密,从而获得经过TGS认证过后的客户端信息,此时他将这部分信息和客户端第二部分内容带来的自己的信息进行比对,最终确认该客户端就是经过了KDC认证的具有真实身份的客户端,是他可以提供服务的客户端。此时服务端返回一段使用CT_SK加密的表示接收请求的响应给客户端,在客户端收到请求之后,使用缓存在本地的CS_ST解密之后也确定了服务端的身份(其实服务端在通信的过程中还会使用数字证书证明自己身份)。

​ 至此,第三次通信完成。此时也代表着整个kerberos认证的完成,通信的双方都确认了对方的身份,此时便可以放心的进行整个网络通信了。

总结

​ 整个kerberos认证的过程较为复杂,三次通信中都使用了密钥,且密钥的种类一直在变化,并且为了防止网络拦截密钥,这些密钥都是临时生成的Session Key,即他们只在一次Session会话中起作用,即使密钥被劫持,等到密钥被破解可能这次会话都早已结束。
这为整个kerberos认证过程保证了较高的安全性。以下补充两个kerberos认证的整体流图,一个是kerberos认证的时序图,一个是kerberos认证的示意图,望能加深kerberos认证印象~~
示意图

白银票据(Silver Ticket)

特点:

  • 不需要域KDC进行交互,(不需要拥有域账号)
  • 需要知道目标服务的(对应计算机名的)NTLM Hash (条件)
  • 只能针对对应的一个服务,不能访问所有的服务

概述:Ticket = Server Hash ( Server Session Key + Client Info + end Time )

当拥有Server Hash 时候,我们就可以伪造一个KDC认证的一个Ticket.

其中Server Session Key 是 KDC 生成的 用于服务器和客户端通信的会话key,也就是随机字符串,所以可以进行任意伪造

伪造

Mimikatz

  • kerberos::list :列出票据
  • kerberos::purge :清除票据
mimikazt.exe "privilege::debug" "sekurlsa::logonpasswords" "exit" >log.txt

伪造票据: mimikatz “kerberod::golden /domain:<域名> /sid:<域sid> /target:<目标服务器主机名> /service:<服务类型> /rc4: /user:<用户名> /ptt” exit

  • (/ptt 注入到内存)
  • 用户名可以随意

只能针对服务器上面的某些服务进行伪造,伪造服务类型如下:

防御

  • 尽量保证服务器凭证不被窃取
  • 开启PAC(Privileged Attribute Certificate)特权属性证书保护功能,PAC主要是规定服务器将票据发送给kerberos服务,由kerberos服务验证票据是否有效

开启方式:将注册表中HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl\Lsa\Kerberos\Parameters中的ValidateKdcPacSignature 设置为1

黄金票据(Golden Ticket)

特点/条件:

  1. 需要与KDC通信
  2. 需要krbtgt 用户的hash (也就是KDC hash)

可以不断伪造TGT,然后根据TGT 拿到对应的Ticket ,再去访问服务

伪造:mimikatz “kerberod::golden /domain:<域名> /sid:<域sid> /rc4: /user:<用户名> /ptt” exit

Access Token

Access Token(访问令牌),它是一个描述进程或者线程安全上下文的一个对象。不同用户登录计算机后,都会生成一个Access Token ,这个Token 在用户创建进程或者线程时候会被使用,不断拷贝。(对应着A创建进程,而B无法访问)

种类:主令牌、模拟令牌

一般情况下,用户双击运行一个程序,都会拷贝explorer.exe的Access Token

当用户注销后,系统将会使主令牌切换为模拟令牌,不会将令牌清除,只有在重启机器后才会清除

组成

  • 用户账户的安全标识符 (SID)
  • 用户所属组的SID
  • 用于标识当前登录会话的登录SID
  • 用户或用户组所拥有的权限列表
  • 所有者SID
  • 访问控制列表
  • 访问令牌的来源
  • 令牌是主要令牌还是模拟令牌
  • 限制SID的可选列表
  • 目前的模拟等级
  • 其他统计数据

SID

Security Identifiers 安全标识符 是一个唯一的字符串,他可以表示一个账户、一个用户组、或者是一次登录。通常他还有一个SID固定列表,例如:Everyone

SID 的表现形式:

  1. 域SID -用户ID
  2. 计算机SID-用户ID
  3. SID列表都会存储在域控的AD或者计算机本地账户数据库中

Token 令牌伪造

Access Token 产生过程:

每个进程创建的时候会根据登录会话权限由LSA (Local Security Authority)分配一个Token (如果CreateProcess时自己指定了Token,LSA会用该Token,否则就用父进程Token 的一份拷贝)

只有计算机重启,才会清空令牌,那么可以使用多种工具查看目前系统上存在的模拟令牌:

  • Incognito
  • Powershell -Invoke-TokenManipulation.ps1
  • Cobalt Strike -steal_token
  • Mimkatz 中的 token::list

MSF 模块:

Reference