彻底理解Windows认证

发布于 2021-11-29  40 次阅读


Windows本地登录

在我们使用一台windows系统的时候,首先要做的第一点,就是登录这台windows系统。这个登录过程其实就是一个账号密码比较的过程。将我们输入的数据,与本地存储的账号密码做比较,如果相同,则登录成功,反之,登录失败。

由此我们可以引发出,一个新的问题,我们的密码存储在哪里呢?

  • 密码数据存储位置:C:\Windows\System32\config
  • 当我们登录系统的时候,系统回自动的读取SAM文件中的“密码”与我们输入的密码做对比,如果相同,证明认证成功。
image-20211017073854541

那么,在SAM文件中,我们的密码的表现形式是怎么样的呢?

  • Winodws本事不存储用户的明文密码,它会将用户的明文密码经过加密算法后存储在SAM数据库中。这里我们可以把密码校验的形式理解为:我们下载了一个软件,对这个软件进行一次MD5加密。如果说这个软件不发生改变,每次MD5运算之后得到的结果都是一样的。用自己得到的MD5值与该软件官方公布的MD5值进行比较,可以达到验证软件是否被篡改的目的。

那么在windows中对密码进行的加密运算又是什么呢?

  • NTLM (NT LAN Manager) Hash 是支持Net NTLM认证协议及本地认证过程中的一个重要参与物,其长度为32位,由数字和字母组成。
  • 当用户登录时,将用户输入的明文密码也加密成NTML Hash,与Sam数据库中的NTLM Hash 进行比较。
  • NTLM Hash的前身时LM Hash,目前基本淘汰,但是存在于一些比较古老的windows版本中。

NTLM Hash 的产生过程:

image-20211017080155939
  • admin经过 Hex(十六进制编码)得到 61646d696e
  • 61646d696e 经过 Unicode 编码 得到 610064006d0069006e00
  • 610064006d0069006e00 经过MD4 得到 209c6174da490caeb422f3fa5a7ae634 也就是NTLM Hash的值

总结本地认证的流程:

image-20211017081925862
  • Windows Logon Process(即winlogon.exe),是windows NT用户登录程序,用于管理用户的登录和退出。通俗点说,也就是如下图的登录页面。
image-20211017082321587
  • LSASS 用于微软Windows系统的安全机制。它用于本地安全和登录策略。

Windows网络认证

  • 在内网渗透中,经常遇到工作组的环境,而工作组环境是一个逻辑上的网络环境(工作区),隶属于工作组的机器之间无法互相简历一个完美的信任机制,只能点对点,是比较落后的认证方式,没有信托机构。
  • 假设A主机与B主机属于同一个工作组环境,A想访问B主机上的资料,需要将一个存在于B主机上的账号凭证发送到B主机,经过认证才能够访问B主机上的资源
  • 最常见的服务:SMB服务 端口:445

NTLM 协议的产生:

  • 早期SMB协议在网络上传输明文口令。后来出现LAN Manager Challenge/Response验证机制,简称LM,他是如此简单以助于很容易就被破解。
  • 因此微软提出了WindowsNT挑战/相应验证机制,称之为NTLM。现在已经有了更新的NTLMv2以及Kerberos验证体系。

NTLM协议 挑战/响应:

  • 第一步协商:一些低版本的windows操作系统,可能不支持v1v2,仅仅支持LM协议。微软为了高版本操作系统和低版本操作系统的兼容性,要进行协商。例如:A要访问B,会向B发送协议版本,B确认该协议版本是否支持。
  • 第二部质询:
    • 客户端向服务端发送用户信息(用户名)请求
    • 服务端接受请求,根据用户名在SAM数据库进行查找,如果未找到,登录失败,如果成功找到,生成一个16位的随机数,被称为challenge,并且根据查找结果使用登录用户名对应的NTLM HashChallenge加密生成Challenge1。同时,生成Challenge1后,将Challenge发送给客户端。challenge1本质上叫 Net NTLM Hash, 它是缓存在内存中的。因此可以的到一个等式Net NTLM Hash = NTLM Hash(Challenge)
    • 客户端接受到Challenge后,使用将要登录到账号对应的NTLM HashChallenge生成Response,然后将Response发送至服务端
    • 服务端收到客户端的Response后,比对Challenge1Response是否相等,若相等,则认证通过。
image-20211017093057594

NTLM v1 和 NTLM v2 协议

  • NTLM v1NTLM v2最显著的区别就是Challenge与加密算法不同,共同点就是加密的原料都是NTLM Hash
  • Challenge:NTLM v1 的 Challenge有8位,NTLM v2Challenge为16位
  • Net-NTLM Hash: NTLM v1 的主要加密算法是DESNTLM v2的主要加密算法是HMAC-MD5

Pass The Hash(哈希传递):

在内网渗透中,我们经常会需要住区管理员的密码、NTLM Hash,通过搜集这些信息有助于我们扩大战果,尤其是域环境下。

  • 哈希传递时能提供在不要账号明文密码的情况下完成认证的一个技术
  • 哈希传递的作用:解决我们舌头中获取不到明文密码,破解不了NTLM Hash而又想扩大战果的问题。

必要条件:

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

Active Directory

  • Active Directory 存储了有关网络对象的信息,并且让管理员和用户能够轻松地查找和使用这些信息。Active Directory使用了一种结构化的数据存储方式,并以此作为基础对目录信息进行合乎逻辑的分层组织
image-20211017103008939
  • 网络对象分为:用户、用户组、计算机、域、组织单位以及安全策略等

域认证体系 - Kerbroes

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

参与域认证的成员:ClientserverKDC

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

(从物理层面来看,AD与KDC均为域控制器)

明确概念:

  • client:客服端,也就是发起访问请求的主机
  • server:服务端,也就是提供访问的主机
  • KDC:密钥分发中心,相当于是信托机构提供密钥生成和验证。在KDC中还有两个部分
    • Authentication Service:身份验证服务,简称AS
    • Ticket Granting Service:票据验证服务, 简称TGS
  • DCDomain Controller的缩写,即域控制器
    • DC中有一个特殊用户叫做:krbtgt,它是一个无法登录的账户,是在创建域时系统自动创建的,在整个kerberos认证中会多次用到它的Hash值去做验证。
  • ADActive Directory的缩写,即活动目录。
    • AD会维护一个Account Database(账户数据库). 它存储了域中所有用户的密码Hash和白名单。只有账户密码都在白名单中的Client才能申请到TGT

域认证的粗略流程:

  • clientKerberos服务请求,希望获取访问server的权限。Kerberos得到了这个消息,首先会判断client是否是可信赖的,也就是白名单和名单的说法。这就是AS服务完成的工作,通过在AD中存储黑名单和白名单来区分client。成功后,返回ASTGTclient
  • client得到了TGT后,继续向Kerberos请求,希望获取访问Server的权限。Kerberos又得到了这个消息,这时候通过client消息中的TGT,判断出了client拥有了这个权限,给了client访问server的权限ticket
  • client得到ticket后,终于可以成功访问server。这个ticket知识针对这个server,其他server需要向TGS申请

域认证的详细流程:

第一步,Client与AS交互

准备:用户在client中输入账号密码后,client会对密码进行Hash Code,加密之后的值我们叫做Master key

请求:client先向KDC的AS发送Authenticator,我们叫它Authenticator1。为了确保Autenticator1仅限于自己和KDC知道,Client使用自己的Master key对其的主体部分进行加密

内容:

  • 经过Client用户的密码hash code生成的Master key加密的TimeStamp(一个当前的时间戳)
  • Client的一些信息,比如用户名

响应:

  • AS接收到Authenticator1后,会根据Client提交的用户名在AD中寻找是否在白名单中,然后查询到该用户名的密码,并提取到Client对应的Master key,对TimeStamp(时间戳)进行解密,如果是一个合法的Timestamp,就证明了Client提供的用户名和密码是存在AD中的,并且AS提取到的Timestamp不能超过5分钟,否则AS就会直接拒绝Client的请求。
  • TimeStamp验证通过后,AS会给Client发送一个由Client的Master key加密过的Logon Session Key和一个TGT(client-server-ticket)

注意:

  • TGT的内容:经过KDC中的krbtgt的密码Hash加密的 Logon Session Key(登录会话密钥) 和 TimeStamp(时间戳)TGS会话密钥、用户信息、TGT到期时间。
  • Logon Session Key是什么:ClientKDC发起对TGT的申请,”我需要一张TGT用以申请获取用以访问所有ServerTicket”。KDC在收到该申请请求后,生成一个用于该ClientKDC进行安全通信的Session Key(SKDC-Client,也被称为Logon Session Key)。这里KDC不会保存SKDC-Client。需要注意的是SKDC-Client是一个Session Key,他具有自己的生命周期,同时TGTSession相互关联,当Logon Session Key过期,TGT也就宣告失效,此后Client不得不重新向KDC申请新的TGTKDC将会生成一个不同Session Key和与之关联的TGT
  • 第二步会有一个Session Key,是用于ClientServer之间通信的Session Key(SServer-Client)

数据请求概括:

image-20211017135809720

客户端发送的数据概要:

image-20211017140048797

KDC发送数据概要

image-20211017140248978

第二步,Client 与 TGS 的交互

请求:Client通过自己的Master key对第一部分解密获得Logon Session key之后,携带这TGTTGS发送请求。Client是解不开TGT的,它作为一个Client通过身份验证的票提交给TGS

内容:

  • TGTClient通过于AS交互获得的TGTTGTKDCMaster key进行加密
  • Authenticator2Client端使用 Logon Session Key对其进行加密,Authenticator2实际上就是关于Client的一些信息和当前时间的一个Timestamp,用以证明当初 TGT 的拥有者是否就是自己。

TGS收到Client请求,验证其真实身份: TGS在发给Client真正的Ticket之前,先得验证Client提供的那个TGT是否是AS颁发给它的,于是它得通过Client 提供的 Authenticator2 来证明。但是 Authentication2 是通过 ClientLogon Session Key 进行加密的,而TGS并没有保存这个 Logon Session Key 。所以 TGS 先得通过自己的 Master Key{krbtgt的密码hash处理}Client 提供的 TGT 进行解密,从而获得Client InfoLogon Session Key(SKDC-Client),再通过这个Logon Session Key解密Authenticator2,获得Client Info,对两个Client Info进行比较,进而验证对方的真实身份

响应:

  • 经过 Logon session key加密的ClientServer之间的Session Key
  • 经过ServerMaster Key进行加密的ST(Service Ticket)
  • Ticket大体包含以下一些内容:
    • Session Key(SServer-Client)
    • Domain name\Client
    • Ticket的到期时间

Client 收到TGS的响应,使用 Logon session key,解密第一部分后获得 Session Key (注意区分 Logon Session Key 与 Session Key 分别是什么步骤获得的,及其的区别)。有了 Session KeyST(Service Ticket)Client就可以直接和 Server进行交互,而无须在通过 KDC作中间人了。

image-20211017140543215

第三步,Client 与 Server 的交互--双向验证

server验证Client:

  • Client通过与TGS交互获得访问ServerSession Key,然后为了证明自己就是ST(Service Ticket)的真正所有者,会将Authenticator和时间戳提取出来,并使用Session Key进行加密。最后将这个被加密过的Authenticator3ST作为请求数据包发送给Server。此外还包含一个Flag用于表示Client是否需要进行双向验证
  • Server接收到Request之后,首先通过自己的Master Key(krbtgt的密码hash处理)解密ST,从而获得Session Key。然后通过解密出来的Session Key再去解密Authenticator3 ,进而验证对方的身份。如果验证成功,且时间戳不长于5min,就让 Client 访问对应的资源,否则就会直接拒绝对方的请求。
image-20211017140949393

双向验证:

到目前为止,服务端已经完成了对客户端的验证,但是,整个认证过程还没有结束。接下来就是Client对Server进行验证以确保Client所访问的不是一个钓鱼服务.

Client验证Server:

Server需要将Authenticator3中解密出来的Timestamp再次用Session Key进行加密,并发送给Client。Client再用缓存Session Key进行解密,如果Timestamp和之前的内容完全一样,则可以证明此时的Server是它想访问的Server

白银票据

该技术解决的问题是,不需要进行Kerberos前两层验证,直接进行与server的验证

白银票据的特点

  • 不需要和KDC进行交互
  • 需要目标服务的NTLM Hash

白银票据构造原理

image-20211017141643940

Ticket = Server Hash(Server Session Key + Client info + End Time)

当拥有Server Hash时,我们就可以伪造一个不经过KDC认证的一个TicketServer Session Key在未发送Ticket之前,服务器时不知道Server Session Key是什么的,所以一切凭据都来源于Server Hash

白银票据伪造

使用工具Mimikatz

image-20211017142732959

导出目标服务器的hash

image-20211017142910810

使用命令伪造票据

image-20211017143140234白银票据的缺点

由于白银票据需要目标服务器的Hash,所以没办法生成对应域内所有服务器的票据,也不能通过TGT申请。因此只能针对服务器上的某些服务器伪造,伪造的服务类型列别如下:

image-20211017143515435

白银票据的防御

  • 尽量保证服务器凭证不被窃取
  • 开启PAC(Privileged Attribute Certificate)特权属性证书保护功能,
    • PAC主要是规定服务器将票据发送给Kerberos服务,由Kerberos服务验证票据是否有效
    • 开启方式:将注册表中HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters中的ValidateKdcPacSignature设置为1
  • 加固服务器本身对外的服务

黄金票据

也就是用来伪造TGT凭证,绕过KDC三层验证的第一层,因为ASTGS之间没有通知机制,TGS收到消息就会做出相应。

黄金票据的特点

  • 需要与KDC通讯
  • 需要Krbtgt用户的hash

黄金票据伪造

使用工具MSF kiwi或者使用 CS一把梭也可以使用猕猴桃

msf kiwi使用截图

image-20211017145408658
image-20211017150416140
image-20211017152015778

猕猴桃使用

image-20211017152208365

黄金票据防御

  • 尽量保证服务器凭证不被窃取
  • 经常更新krbtgt密码,使得原有的凭据失效
  • 不允许域管账号登录其他服务器

Tickets总结

  • 黄金票据:从攻击面来看,获取krbtgt用户的hash后,可以在域中进行持久性的隐藏,并且日志无法溯源,但是需要拿到DC权限,使用黄金票据能贵在一个域环境中长时间控制整个域
  • 白银票据:从攻击面来看,伪造白银票据的难度比伪造黄金票据的难度较小,因为一个域中的服务器如果对外开放的话,非常容易被入侵,并且容易被转储Server Hash

Windows Access Token

  • 描述:Windows Token其实叫Access Token(访问令牌),他是一个描述进程或者线程安全上下文的一个对象。不同的用户登录计算机后,都会生成一个Access Token,这个Token在用户创建进程或者线程时会被使用,不断的拷贝,这也就解释了A用户创建一个进程而该进程没有B用户的权限。
  • 种类:Access Token分为两种(主令牌、模拟令牌)
  • 一般情况下,用户双击运行一个程序,都会拷贝explorer.exeAccess Token
  • 当用户注销后,系统将会使主令牌切换为模拟令牌,不会将令牌清除,只有在重启机器后才会清除

令牌组成

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

SID 安全标识符

  • SID 安全标识符是一个唯一的字符串,它可以代表一个账户,一个用户组,或者一次登录。通常它还有一个SID固定列表,例如Everyone这种已经内置的账户,默认拥有固定的SID
  • SID的表现形式:
    • 域SID-用户ID
    • 计算机SID-用户ID
    • SID列表都会存储在域控的AD或者计算机账户数据库中

令牌产生过程

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

令牌假冒防御

禁止Domain Admins登录对外且未作安全加固的服务器,因为一旦服务器被入侵,域管理员的令牌可能会被攻击者假冒,从而控制DC

如果想要清楚假冒,重启服务器即可。

总结反思

参考师傅们的文章,大体捋顺了一遍windows认证的思路,收获是很丰富的,但是明显感觉细节的地方不足。后续会在实战中,进一步的弥补细节上的缺漏。

参考文章

https://www.cnblogs.com/zpchcbd/p/12235193.html

https://www.bilibili.com/video/BV1S4411q7Cw?from=search&seid=9235004178719298606&spm_id_from=333.337.0.0

https://www.jianshu.com/p/23a4e8978a30