Active Directory 02 - Windows Kerberos Authentication(Kerberos 协议鉴权)

news2024/11/17 3:08:18

写在最前

如果你是信息安全爱好者,如果你想考一些证书来提升自己的能力,那么欢迎大家来我的 Discord 频道 Northern Bay。邀请链接在这里:

https://discord.gg/9XvvuFq9Wb

我会提供备考过程中尽可能多的帮助,并分享学习和实践过程中的资源和心得,大家一起进步,一起 NB~


背景

本来对于 Kerberos 的鉴权过程我不想写了。但是有很多朋友问我,然后我又想了下,由于 Kerberos 鉴权过程中涉及了挺多的概念,并且过程一来一去,使用不同的主体先加密,后解密,一不小心,就会迷失在这些操作当中。不管是 Offensive Security 的课程,还是网上绝大多数的资料,从语言的组织,图例的使用,都不是很好。直到我读到这一篇文章的时候,我觉得作者(Jake Karnes)非常善于使用图例和一些视觉上的区分方式,很好地解释了整个 Kerberos 鉴权的过程,以及 3 种不同的 Active Delegation。

原文是关于 Bronze Bit Attack,但是作者为了更好的说明攻击原理,把整个 Kerberos 鉴权过程以及 Active Directory Delegation 讲得非常详细。我会借用他文章中的图片,然后加以调整,说明。

如果读完这篇文章,大家对 Kerberos 的鉴权过程还有不清楚的地方,那么,就请多看几遍吧 😄

后续

这篇文章之后,近期的计划就是承接这篇文章的内容,写一下 Active Directory Delegation(主要关于 protocol transition 的效用),再写一下 Bronze Bit Attack 的原理和利用。当然,参考文献都是 Jake Karnes 的研究结果。然后,我会写一些关于 Active Directory 证书鉴权的文章,最后当然是如何利用配置不当的证书做提权和后渗透维持。

开始吧!跟着走。

给域做个类比

我们把整个域(Active Directory)想象成一个游乐园,域中的各个服务,就想象成游乐园中的游乐项目。用户访问域中的服务,就想象成游客去游玩一个游乐项目

不过,这个游乐场有一个很大的特殊性,就是你进去之后,想要玩任何一个游乐项目,都要回到大门口,向检票员出示门票,然后才能享受这个游乐项目。

记住这个类比,很有用。

什么是 Kerberos

Kerberos 是一个协议,用来集中管理访问权限的协议。用户在 Kerberos 协议中,对想访问的服务,无需一次一次重复鉴权。所有鉴权,都由 Kerberos 统一管理,提升了用户体验,也增加了安全性。

Kerberos 最初由 MIT 开发,微软拿来改巴改巴,出了新的 RFC(RFC4120),自成了一派,延用至今。

这大致上就是 Kerberos 的作用和由来。

Kerberos Authentication

开始之前,需要知道 Domain Controller(域控)中保存了每个用户的 Secret Key(以下称:用户 Key),每个服务的 Secret Key(以下称:服务 Key),以及它自己的 Secret Key(以下称:KDC Key)。

Domain Controller

  • 域控,Key Distribution Center(KDC),就像是游乐场大门的检票员,负责检查每个游客的门票,并根据校验结果分发各个游乐项目的使用权

Key Distribution Center(KDC)

  • 保存了域中所有用户,所有服务,以及自身的 Secret Key;并负责分发各种门票(包括大门的,以及各个游乐项目的)

下图中,用户 Key(红色),服务 Key(绿色),KDC Key(灰色),都保存在域控的 KDC 中。这个图例中各个 Key 的颜色将会贯穿文章始终。

图片改编自https://www.netspi.com/blog/technical/network-penetration-testing/cve-2020-17049-kerberos-bronze-bit-theory/

Secret Key

  • Secret Key 即所有域中主体密码的哈希值(password hash)

我们剥个洋葱,一层一层深入下去。

洋葱第一层:域中用户通过 Kerberos 想要访问一个服务的过程

在域环境中,假设一个用户想通过 Kerberos 协议访问 Web 服务器(或任意服务),整个过程可以很简单地被分为三大步

第一步,用户向 Domain Controller 索取 Ticket Granting Ticket(TGT) ,以便访问域中的服务;
第二步,用户使用 TGT,向 Domain Controller 索取服务的“门票”(TGS);
第三步,用户向特定服务出示 TGS,使用该服务;

TGT

  • TGT 就像是游乐园的大门门票,只有有了这张门票,才有进一步享受游乐项目(域中的服务)的资格

TGS

  • TGS 就像是单个游乐项目的入场券,只有拿着这个,才能游玩特定的游乐项目

就那么简单。

重要信息:

  • 一个用户的 TGT,是非常重要的数据;如果你获得了一个用户的 TGT,那么意味着你可以代表这个用户,访问这个用户可以访问的任意服务;
  • 再进一步,也就是说如果你获取了 Domain Admin 的 TGT,那么你就拿下了整个域;

洋葱第二层:解剖获取 Ticket Granting Ticket(TGT)的过程

域是一个游乐场,我们要进去,第一步必须问检票员拿到大门的门票。

获取大门门票的过程,就是向 KDC 获取 TGT 的过程,这个过程,被称为 Authentication Server Request(AS_REQ)

Authentication Server Request(AS_REQ)

修改一下 Jake Karnes 的时序图。

在这里插入图片描述

步骤说明:

  1. 用户登录,密码经过哈希获得 用户 Key(红色)
  2. 使用 用户 Key(红色)加密当前时间戳
  3. 向 KDC 发起 Authentication Server Request(AS_REQ),把加密的 时间戳用户名 一起发送给 KDC;
  4. KDC 将通过 用户名,找到保存在域中的 用户 Key(红色)
  5. KDC 用找到的 用户 Key(红色),解密时间戳;
  6. 如果第 5 步解密成功,说明了该用户通过了 KDC 的 Key 验证,那么 KDC 会生成一个 随机的 logon session key(紫色)
  7. KDC 发送 Authentication Server Reply(AS_REP) 给用户,包含了 TGT 以及其他加密数据;

Timestamp 时间戳校验的作用

  • 时间戳校验是防止第三方使用窃取的老旧时间戳来发起 replay attack;所以 KDC 必须保证每个鉴权请求都在其所允许的时间范围内,通常是 3-5 分钟;
  • 因此有时候,如果你在对域控使用工具的时候,你的系统时间和域时间相差太大,一些命令就会执行失败,这也就是时间戳校验的结果;

Authentication Server Reply(AS_REP)解析

Authentication Server Request(AS_REQ) 的最后一步中,KDC 会将 TGT 等数据加密并发送给用户。

如下图。

图片来自https://www.netspi.com/blog/technical/network-penetration-testing/cve-2020-17049-kerberos-bronze-bit-theory/

拆解一下。

  1. 这是整个响应数据的 非加密 部分;cname 就是整个鉴权过程中的用户名;张三李四等等;
  2. 这个部分使用 用户 Key(红色) 加密;包含了:
    • Authentication Server Request 过程中 KDC 生成的随机 logon session key(紫色)
    • 一些元信息,如 Flags(该票据是否 forwardable,之后的文章中会讲到);sname,服务的名称,Authentication Server Request 请求的服务是 Ticket Granting Service(krbtgt);
  3. 这个部分,也就是 TGT,使用 KDC Key(灰色) 加密,是用户无法解密的;用户就是用这个 TGT 来进行后续的服务鉴权(类比成,出示这个门票,才可以购买特定游乐项目的入场券);

重要信息:

  • 这里,用户在接到 KDC 的响应之后,就会用自己 用户 Key(红色),解密第二部分信息,取出 logon session key(紫色),和第三部分 TGT 一起,保存起来,供之后使用
  • 此时,拥有 TGT 的用户,就是拿到了游乐园门票的游客,获得了进入游乐园大门(域)的资格

洋葱第三层:解剖获取 Ticket Granting Service(TGS)的过程

这里,用户可以凭借之前获取的 TGT,来获取服务的使用权限。

就像我们说的,这就是你向游乐园的检票员出示门票,然后获取相应游乐项目入场券的过程。这个过程,被称为 Ticket Granting Service Request(TGS_REQ)

Ticket Granting Service Request(TGS_REQ)

修改一下 Jake Karnes 的时序图。

图片来自https://www.netspi.com/blog/technical/network-penetration-testing/cve-2020-17049-kerberos-bronze-bit-theory/

步骤说明:

  1. 同样的,用户需要 加密一个时间戳;不同的是,这次不是用用户 Key,而是用 Authentication Server Request(AS_REQ)过程中 KDC 生成的 logon session key(紫色) 来加密;
  2. 用户向 KDC 发起 Ticket Granting Service Request(TGS_REQ),发送 3 样东西:
    • 加密的 时间戳
    • TGT
    • 以及 想要访问的目标服务名称
  3. 由于 TGT 是用 KDC Key(灰色) 加密的,因此,KDC 会使用 KDC Key(灰色)TGT 进行解密;
  4. 解密之后,KDC 获取封装在 TGT 中的 logon session key(紫色)
  5. KDC 使用该 logon session key(紫色),解密时间戳;
  6. 如果第 5 步解密成功,说明该用户的 TGT 有效(因为用户使用 logon session key(紫色) 加密的时间戳,可以用 TGT 中的 logon session key(紫色) 解密;换句话说,用户持有的 logon session key(紫色) 与 TGT 中的 logon session key(紫色) 一致),这时,KDC 会再生成一个随机的 service session key(黄色)
  7. KDC 发送 Ticket Granting Server Reply(TGS_REP) 给用户,包含了 Service Ticket(TGS),以及其他加密数据;

Ticket Granting Server Reply(TGS_REP)解析

Ticket Granting Service Request(TGS_REQ) 的最后一步中,KDC 会将 TGS 等数据加密并发送给用户。

如下图。

图片来自https://www.netspi.com/blog/technical/network-penetration-testing/cve-2020-17049-kerberos-bronze-bit-theory/

拆解一下。

  1. 这是整个响应数据的 非加密 部分;cname 就是整个服务权限请求过程中的用户名;张三李四等等;
  2. 这个部分使用 logon session key(紫色) 加密;包含了:
    • Ticket Granting Service Request(TGS_REQ)过程中 KDC 生成的随机 service session key(黄色)
    • 一些元信息,如 Flags(该票据是否 forwardable,之后的文章中会讲到);sname,服务的名称;
  3. 这个部分,也就是 TGS,使用 服务 Key(绿色) 加密,是用户无法解密的;用户就是用这个 TGS 来访问域中的目标服务(类比成,拿着这个入场券,去享受游乐项目);
  4. Privilege Attribute Certificate,包含了额外的用户元数据,如他们的用户组,他们的权限等;这个部分会有两个加密签名,一个是 服务 Key(绿色)加密的签名,一个是 KDC Key(灰色)加密的签名

PAC

  • PAC 中的两个签名用于防止第三方篡改 PAC 来提权;由于 PAC 包含了一个用户的权限信息,一旦篡改,那么普通用户就可以获得管理员权限;
  • 签名就是用来校验 PAC 的一致性;

重要信息-1:

  • 这里,用户在接到 KDC 的响应之后,就会用保存的 logon session key(紫色),解密第二部分信息,取出 service session key(黄色),和第三部分 TGS 一起,保存起来,供之后使用
  • 此时,拥有 TGS 的用户,就是拿到了某一个特定游乐项目的入场券,可以去游玩了

重要信息-2:

  • 可以看到上图中的第 2 部分,是用用户持有的 logon session key(紫色) 加密的,所以这个部分中的任何内容,都是用户可以篡改的;
  • 综上,如果我们拿下了这个用户,就可以作为这个用户,发起 TGS 请求,然后任意篡改服务名称(Rubeus 的 /altservice 功能),来访问任意服务;

洋葱第四层:解剖获取用户访问服务的过程

此时,用户可以凭借之前获取的 TGS,来访问具体服务了。

就像我们说的,这就是你拿着单个游乐项目的入场券,进去high了。

再次借用 Jake Karnes 的时序图。

图片来自https://www.netspi.com/blog/technical/network-penetration-testing/cve-2020-17049-kerberos-bronze-bit-theory/

步骤说明:

  1. 用户使用 Ticket Granting Service Request(TGS_REQ) 过程中获取的 service session key(黄色) 加密当前时间戳;
  2. 用户向 目标服务 发起 Application Request(AP_REQ),发送 3 样东西:
    • 加密的 时间戳
    • Service Ticket(TGS)
    • 以及 自己的用户名
  3. 目标服务使用 服务 Key(绿色) 解密 Service Ticket(TGS)
  4. 目标服务取出封装在 TGS 中的 service session key(黄色)
  5. 目标服务使用 service session key(黄色) 解密用户加密过的时间戳;并对其进行校验;
  6. 目标服务使用 服务 Key(绿色) 校验 PAC 文件的 服务签名;(可选)目标服务也可以选择将 PAC 文件 发送给 KDC,让其进一步校验 KDC 签名
  7. 上述校验全部通过,用户就可以畅通无阻地使用该服务了;

至此,整个 Kerberos 的鉴权过程已经说完了。

总结

可以看出规律,下一步的加密,都是用上一步生成的 session key;而上一步生成的 session key,都会放在 KDC 的响应中传回给用户保存。

另外,也只需要记住,TGT 使用 KDC Key 加密(也就是 krbtgt 的 hash),TGS 使用 服务 Key(服务的 password hash) 来加密。

附录

类比对应关系

主体类比
游乐园
服务游乐园的游乐项目
KDC游乐园大门检票员
TGT游乐园大门门票
TGS游乐园特定游乐项目的入场券
获取 TGT游乐园大门检票员检票的过程
获取 TGS向游乐园大门检票员出示大门门票,获取单个游乐项目入场券的过程
用户访问特定服务用户游玩游乐园中的特定游乐项目

域主体名词一览

主体备注
Domain Controller域控,包含 KDC
User域用户;如张三,李四
Service域中的服务;如 Web,数据库

域概念一览

概念备注
KDC Key(KDC Secret Key)域控的 password hash,也是 krbtgt 账户的 password hash
用户 Key(User Secret Key)用户账户的 password hash
服务 Key(Service Secret Key)服务账户的 password hash
Timestamp时间戳,每个鉴权请求都必须发送当前时间戳做校验,防止 replay attack
Session Key鉴权请求过程中 KDC 生成的随机数据,用来加密时间戳以请求 TGS 以及访问服务
AS_REQAuthentication Service Request,用户向 KDC 发起登录鉴权的请求;
AS_REPAuthentication Service Reply,KDC 校验用户成功之后,返回给用户 TGT
TGS_REQTicket Granting Service Request,用户向 KDC 发起的服务访问鉴权请求
TGS_REPTicket Granting Service Reply,KDC 校验用户 TGT 成功之后,返回给用户 TGS
AP_REQApplication Request,用户向目标服务发起的服务访问鉴权请求,鉴权成功,用户将可以使用该服务
PACPrivilege Attribute Certificate,用户元数据,包含了额外的用户信息,如用户ID,用户全名,登录次数,用户权限等;PAC 文件带有服务和KDC的加密签名,用于校验 PAC,防止第三方篡改 PAC 来提权

参考链接

  • https://www.netspi.com/blog/technical/network-penetration-testing/cve-2020-17049-kerberos-bronze-bit-theory/
  • https://en.wikipedia.org/wiki/Kerberos_(protocol)
  • https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962
  • https://blog.netwrix.com/2023/01/10/what-is-the-kerberos-pac/
  • https://www.secureauth.com/blog/kerberos-delegation-spns-and-more/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/339288.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从0到1一步一步玩转openEuler--11 openEuler基础配置-设置磁盘调度算法

11 openEuler基础配置-设置磁盘调度算法 文章目录11 openEuler基础配置-设置磁盘调度算法11.1 设置磁盘调度算法11.1.1 临时修改调度策略11.1.2 永久设置调度策略11.1 设置磁盘调度算法 本节介绍如何设置磁盘调度算法。 11.1.1 临时修改调度策略 例如将所有IO调度算法修改为…

js逆向-某头条_signature参数

前言 头条的加密参数_signature其实可以通过搜索来直接定位到关键位置,我们换种定位的方法 定位 先查看下堆栈,直接在第一个XMLHttpRequest.send的位置下上断点,然后下拉触发断点 这个位置还有其他请求,这里只看/api/pc/list…

2023 AIME 答案与解析 - 第二期(完结)

原题目 Find the number of cubic polynomials where and are integers in such that there is a unique integer with 绿树教育中心独家解析 是一个有两个整数根的三次方程,因此它有三个整数根。所以, 或 ,其中 。 「Case 1」 ,则…

关于spring bean的生命周期的个人理解(根据官方文档学习)

首先说一下Servlet的生命周期:实例化,初始init,接受service,销毁destroy; spring上下文中的Bean 生命周期也是类似,如下: (1)实例化Bean 对于Bean Factory容器&#xf…

elasticsearch更新和删除

文档更新文档的更新经历三个步骤,检索、修改、重新索引部分更新在原有文档已经存在的情况下,可以对原有的文档部分字段更新,使用POST请求,发送到/_update如果文档是不存在的,更新操作是失败的存在则更新,不…

Qt C++ 自定义仪表盘控件02

简介仪表盘是工控领域不可缺少的一类软件UI元素,通常出现在各类电子看板软件上,以及一些高级的上位机软件界面上,目的是将繁杂的数据转化为可视化的图表能大幅提高后台管理效率。本文分享了几个经典常用的仪表盘控件,在项目中可以…

利用升序定时器链表处理非活动连接

参考自游双《Linux高性能服务器编程》 背景 服务器同常需要定期处理非活动连接:给客户发一个重连请求,或关闭该连接,或者其他。我们可以通过使用升序定时器链表处理非活动连接,下面的代码利用alarm函数周期性的触发SIGALRM信号&a…

半人半妖时代来啦

未来是半人半妖时代!!! 碳基生命与硅基生命结合 趣讲大白话:人和机器结合是大趋势 *********** 人工智能就是宗~教 科技宗~教的一支最强势的教派 日常使用智能机器的人就是信众 维护机器的人就是牧师 创造这…

【mock】手把手带你用mock写自定义接口+mock常用语法

mock自定义接口完整流程 官网语法规范:https://github.com/nuysoft/Mock/wiki/Syntax-Specification 首先: 要有一个项目,我这里是vue3项目,以下从vue3项目搭建开始,已搭建好的请直接看2 1.空目录下新建vue3项目 运行创建项目命令: 在bash中:(文件路径处输入cm…

【计组】内存和总线--《深入浅出计算机组成原理》(十)

课程链接:深入浅出计算机组成原理_组成原理_计算机基础-极客时间 一、虚拟内存和内存保护 日常使用的操作系统下,程序不能直接访问物理内存。内存需要被分成固定大小的页(Page),再通过虚拟内存地址(Virtu…

卡通形象人物2 写代码-睡觉 丝滑如德芙

目录 本次实现效果 目录结构 index static/css/style.css static/js/script.js 结语: 前期回顾 【 css动画 】—— 把你喜欢css动画嵌入到浏览器中_0.活在风浪里的博客-CSDN博客常用酷炫动画999合集,代码直接复制可用,总用你想找的…

【Java】 JAVA Notes

JAVA语言帮助笔记Java的安装与JDKJava命名规范JAVA的数据类型自动类型转换强制类型转换JAVA的运算符取余运算结果的符号逻辑运算的短路运算三元运算符运算符优先级JAVA的流程控制分支结构JAVA类Scanner类Math 类random方法获取随机数Java的安装与JDK JDK安装网站:h…

AXI 总线协议学习笔记(4)

引言 前面两篇博文从简单介绍的角度说明了 AXI协议规范。 AXI 总线协议学习笔记(2) AXI 总线协议学习笔记(3) 从本篇开始,详细翻译并学习AXI协议的官方发布规范。 文档中的时序图说明: AXI指&#xff1…

基础面试题:堆和栈的区别

面试题:堆和栈的区别(往往讲的是内存zha) 为什么说访问栈栈比访问堆快些? 目录 一、数据结构中的堆栈 1、数据结构中的堆 1)堆的定义 2)堆的效率 2、 数据结构中的栈 二、内存中的堆栈 1、内存堆的定义…

Stm32 for arduino STM32G071GBU6 I2C and SERIAL

文件目录: C:\Users\Administrator\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.3.0\variants\STM32G0xx\G071G(6-8-B)U_G081GBU boards_entry.txt Generic G071GBUx GenG0.menu.pnum.GENERIC_G071GBUXGeneric G071GBUx GenG0.menu.pnum.GENERIC…

SpringMVC:统一异常处理(11)

统一异常处理1. 说明2. 问题描述3. 异常处理器使用3.1 创建异常处理器类3.2 让程序抛出异常3.3 测试4. 项目异常处理方案4.1 异常分类4.2 异常解决方案4.3 异常解决方案的具体实现4.4 测试5. 总结1. 说明 \quad本篇文章是在文章SpringMVC:SSM整合(Spring…

【Vuex 源码学习】第六篇 - Vuex 的模块收集

一,前言 上一篇,主要介绍了 Vuex 中 Mutations 和 Actions 的实现,主要涉及以下几个点: 将 options 选项中定义的 mutation 方法绑定到 store 实例的 mutations 对象;创建并实现 commit 方法(同步&#x…

最近挺火的人工智能chatGPT注册

文章目录1.前提预备1.1 短信接收平台1.2 ip加速,不做说明2.注册chatGPT步骤2.1 进入chat.openai.com网址后,点击sign up2.2 可以使用qq邮箱注册2.3 填写好邮箱,然后点击Continue,然后再填写密码2.4 之后在qq邮箱进行验证注册(注意&#xff1a…

C++入门——内存管理

C入门——内存管理 C/C内存分布 分类是为了更好的管理 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char* pChar3 "abcd";int* ptr1 (…

Java、JSP环境保护与宣传网站的设计与实现

技术:Java、JSP等摘要:本文对环境保护与宣传网站的设计和开发过程进行了详细地分析与叙述。按照系统开发的实际操作流程以及论文编写的规范,论文内容从系统概述、系统分析、系统设计和系统实现这四大模块对系统的开发过程分别进行了阐述。系统…