前言
很久以來我一直想寫關于組策略對象(GPO, Group Policy Objects)的內容,很高興終于可以開始了。
如果你對GPO不太熟悉,我強烈建議你閱讀Andy Robbins的“紅隊GPO和OU指南”。他介紹了GPO如何執行,如何使用BloodHound找到基于GPO控制的攻擊路徑,并解釋了執行這些攻擊的幾種方法。
在武器化方面,Will Schroeder發表了文章:濫用GPO權限,并在Powerview中實現了New-GPOImmediateTask。但是這個功能后來被刪除了,并帶有以下解釋:
不一致,手工操作更好
本系列文章的目的是演示如何枚舉這些濫用機會,并將其用于權限提升和實現持久化。
枚舉
有一些我們可能感興趣的權限,例如:
我之所以這樣認為,是因為它們是單獨授權的權限。例如:
因此,擁有的權限組合將取決于如何實現這種濫用。
創建GPO
在組策略管理控制臺(GPMC)中授權在域中創建GPO,如下:
可以用下面的方法在PowerView中進行枚舉:
PS > Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=testlab,DC=local" -ResolveGUIDs | Where-Object { $_.ObjectAceType -eq "Group-Policy-Container" }
AceQualifier : AccessAllowed
ObjectDN : CN=Policies,CN=System,DC=testlab,DC=local
ActiveDirectoryRights : CreateChild <--- CreateChild just means "Create GPO" in this context
ObjectAceType : Group-Policy-Container
ObjectSID :
InheritanceFlags : None
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1106 <--- SID of the user/group
AccessMask : 1
AuditFlags : None
IsInherited : False
AceFlags : None
InheritedObjectAceType : All
OpaqueLength : 0
PS > Convert-SidToName S-1-5-21-407754292-3742881058-3910138598-1106
LABDesktop Admins
GP-Link
Get-DomainOU向我們展示了活動目錄(Active Directory)中所有的組織單元。在這個例子中,我們只有默認的Domain Controllers和自定義的Workstations組織單元。
PS > Get-DomainOU
usncreated : 6031
systemflags : -1946157056
iscriticalsystemobject : True
gplink : [LDAP://CN={6AC1786C-016F-11D2-945F-00C04fB984F9},CN=Policies,CN=System,DC=testlab,DC=local;0] <--- GUID(s) of GPO(s) already linked to the OU
whenchanged : 06/01/2019 13:14:24
objectclass : {top, organizationalUnit}
showinadvancedviewonly : False
usnchanged : 6031
dscorepropagationdata : {06/01/2019 13:15:24, 01/01/1601 00:00:01}
name : Domain Controllers
description : Default container for domain controllers
distinguishedname : OU=Domain Controllers,DC=testlab,DC=local
ou : Domain Controllers
whencreated : 06/01/2019 13:14:24
instancetype : 4
objectguid : d312c411-7c7c-4fb7-b4f9-cbf0637b551f
objectcategory : CN=Organizational-Unit,CN=Schema,CN=Configuration,DC=testlab,DC=local
usncreated : 12790
name : Workstations
gplink : [LDAP://cn={7DD7A136-334C-47C1-8890-D9766D449EFA},cn=policies,cn=system,DC=testlab,DC=local;0] <--- GUID(s) of GPO(s) already linked to the OU
whenchanged : 07/01/2019 07:18:51
objectclass : {top, organizationalUnit}
usnchanged : 13118
dscorepropagationdata : {07/01/2019 07:18:51, 07/01/2019 07:17:22, 07/01/2019 07:14:37, 06/01/2019 13:52:27...}
distinguishedname : OU=Workstations,DC=testlab,DC=local
ou : Workstations
whencreated : 06/01/2019 13:28:56
instancetype : 4
objectguid : 4f733ab3-1809-4a31-b299-e07a3b7b4669
objectcategory : CN=Organizational-Unit,CN=Schema,CN=Configuration,DC=testlab,DC=local
ADUC(Active Directory Users and Computers)中的控制委派向導(Delegation of Control Wizard)具有“管理組策略鏈接”的預定義模板。它能幫助我們將不同類型的權限授予特定對象的主體。
在本例中,我們將它授予LABDesktop Admins組。
同樣地,我們可以在PowerView中通過將Get-DomainOu輸出到Get-DomainObjectAcl進行枚舉,并查找GP-Link ACE。
PS > Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | Where-Object { $_.ObjectAceType -eq "GP-Link" }
AceQualifier : AccessAllowed
ObjectDN : OU=Workstations,DC=testlab,DC=local <--- The OU Distinguished Name
ActiveDirectoryRights : ReadProperty, WriteProperty <--- WriteProperty (GP-Link is a property on the OU object that you can see in the Attribute Editor of ADUC)
ObjectAceType : GP-Link
ObjectSID :
InheritanceFlags : ContainerInherit <--- This will be interesting later
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1106 <--- SID of the user/group
AccessMask : 48
AuditFlags : None
IsInherited : False
AceFlags : ContainerInherit
InheritedObjectAceType : All
OpaqueLength : 0
修改GPO
我們還可以將Get-DomainGPO輸送到Get-DomainObjectAcl中,查找有哪些主體可以修改它們。在這里,我們查找與WriteProperty、WriteDacl或WriteOwner匹配的ActiveDirectoryRights。(在大多數情況下,我們只希望找到WriteProperty,但是擁有WriteDacl或WriteOwner使我們能夠將WriteProperty授予自己并修改GPO)。
我們給SecurityIdentifier添加了一個match項,所以我們只列出RIDs > 1000的,避免列出每個GPO的Domain Admins和Enterprise Admins等等。
PS > Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | Where-Object { $_.ActiveDirectoryRights -match "WriteProperty|WriteDacl|WriteOwner" -and $_.SecurityIdentifier -match "S-1-5-21-407754292-3742881058-3910138598-[d]{4,10}" }
AceType : AccessAllowed
ObjectDN : CN={7DD7A136-334C-47C1-8890-D9766D449EFA},CN=Policies,CN=System,DC=testlab,DC=local
ActiveDirectoryRights : CreateChild, DeleteChild, Self, WriteProperty, DeleteTree, Delete, GenericRead, WriteDacl, WriteOwner
OpaqueLength : 0
ObjectSID :
InheritanceFlags : None
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1105 <--- SID of the user/group
AccessMask : 983295
AuditFlags : None
AceFlags : None
AceQualifier : AccessAllowed
AceType : AccessAllowed
ObjectDN : CN={7DD7A136-334C-47C1-8890-D9766D449EFA},CN=Policies,CN=System,DC=testlab,DC=local
ActiveDirectoryRights : CreateChild, DeleteChild, ReadProperty, WriteProperty, GenericExecute
OpaqueLength : 0
ObjectSID :
InheritanceFlags : ContainerInherit
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1109 <--- SID of the user/group
AccessMask : 131127
AuditFlags : None
AceFlags : ContainerInherit
AceQualifier : AccessAllowed
PS > Get-DomainGPO | Where-Object { $_.DistinguishedName -eq "CN={7DD7A136-334C-47C1-8890-D9766D449EFA},CN=Policies,CN=System,DC=testlab,DC=local" } | Select-Object DisplayName
displayname
-----------
Workstation Policy
如GPMC的Details中所示,LABbwallace是這個名為WorkStation Policy的GPO的所有者。
GPO的創建者被自動顯式授權Edit settings(編輯設置)、delete(刪除)、modify security(修改安全性),這些安全性表現為Createchild、Deletechild、Self、WriteProperty、DeleteTree、Delete、GenericRead、WriteDacl、WriteOwner。
在本例中,LABtlockhart還被授予了編輯設置權限,即Createchild、Deletechild、ReadProperty、WriteProperty、GenericExecute。
映射GPO和OUs
這可以從幾個不同的角度來完成。你可能有一個有趣的GPO,并且希望知道單個GPO對應的是哪個組織單元和/或計算機;你可能希望列出適用于特定組織單元的每個GPO;或者你可能希望列出適用于特定計算機的每個GPO。
我們列出對應于ws-1.testlab.local的每個GPO,只顯示名稱和GUID。
PS > Get-DomainGPO -ComputerIdentity ws-1 -Properties Name, DisplayName
displayname name
----------- ----
Demo GPO {ECB75201-82D7-49F3-A0E0-86788EE7DC36}
Workstation Policy {7DD7A136-334C-47C1-8890-D9766D449EFA}
Default Domain Policy {31B2F340-016D-11D2-945F-00C04FB984F9}
在這里,GPO有一個Display Name、GUID和一個對象GUID,后兩者很容易混淆。
這里,我們列出了Demo GPO映射的每個組織單元。我們使用GUID在GPLink中搜索過濾器。
PS > Get-DomainOU -GPLink "{ECB75201-82D7-49F3-A0E0-86788EE7DC36}" -Properties DistinguishedName
distinguishedname
-----------------
OU=Domain Controllers,DC=testlab,DC=local
OU=Workstations,DC=testlab,DC=local
如果你需要知道這些組織單元中有哪些計算機,可以這樣做:
PS > Get-DomainComputer -SearchBase "LDAP://OU=Workstations,DC=testlab,DC=local" -Properties DistinguishedName
distinguishedname
-----------------
CN=WS-1,OU=Workstations,DC=testlab,DC=local
CN=WS-2,OU=Workstations,DC=testlab,DC=local
CN=WS-3,OU=Workstations,DC=testlab,DC=local
如果我們獲得Workstations組織單元的GPLink屬性(它告訴我們鏈接到它的每個GPO),結果將作為單個文本字符串返回,這意味著我們不能直接將其導入get-DomainGPO并找到它們相應的Display Names。
PS > Get-DomainOU -Identity "Workstations" -Properties GPLink
gplink
------
[LDAP://cn={ECB75201-82D7-49F3-A0E0-86788EE7DC36},cn=policies,cn=system,DC=testlab,DC=local;0][LDAP://cn={7DD7A136-334C-47C1-8890-D9766D449EFA},cn=policies,cn=system,DC=test...
但是我們可以這樣做:
PS > $GPLink = (Get-DomainOU -Identity "Workstations" -Properties GPLink).gplink
PS > [Regex]::Matches($GPLink, '(?<={)(.*?)(?=})') | Select-Object -ExpandProperty Value | ForEach-Object { Get-DomainGPO -Identity "{$_}" -Properties DisplayName }
displayname
-----------
Demo GPO
Workstation Policy
在這些示例中,一些聰明的讀者可能會注意到有些情況下通過繼承(例如默認域策略)返回了包含的GPO,而有些情況則不返回。
繼承
我發現繼承非常有趣,特別是當涉及到控制委派向導時。默認情況下,它將啟用該對象和所有子對象的繼承。
PS > Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | Where-Object { $_.ObjectAceType -eq "GP-Link" }
AceQualifier : AccessAllowed
ObjectDN : OU=Workstations,DC=testlab,DC=local
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType : GP-Link
ObjectSID :
InheritanceFlags : ContainerInherit <---
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1106
AccessMask : 48
AuditFlags : None
IsInherited : False <--- This OU *is not* inheriting from elsewhere
AceFlags : ContainerInherit <---
InheritedObjectAceType : All
OpaqueLength : 0
如果我們在內部創建一個新的組織單元,LABDesktop Admins將繼承相同的GP-Link權限。
AceQualifier : AccessAllowed
ObjectDN : OU=DAs,OU=Workstations,DC=testlab,DC=local <--- DA OU is a child of Workstation OU
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType : GP-Link
ObjectSID :
InheritanceFlags : ContainerInherit <---
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1106
AccessMask : 48
AuditFlags : None
IsInherited : True <--- This OU *is* inheriting
AceFlags : ContainerInherit, Inherited <---
InheritedObjectAceType : All
OpaqueLength : 0
如果我們只是手動將Workstations組織單元上的繼承修改為這個對象,則新的ACL(訪問控制列表, Access Control List)如下所示:
AceQualifier : AccessAllowed
ObjectDN : OU=Workstations,DC=testlab,DC=local
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType : GP-Link
ObjectSID :
InheritanceFlags : None <---
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1106
AccessMask : 48
AuditFlags : None
IsInherited : False <---
AceFlags : None <---
InheritedObjectAceType : All
OpaqueLength : 0
最后,如果有這樣的嵌套子級:
則DA組織單元將繼Workstations和Admins。因此,我們有一個用于 LABDesktop Admins的Workstations授權,以及一個用于LABTeam 2的Admins授權,DA組織單元將繼承這兩者。
AceQualifier : AccessAllowed
ObjectDN : OU=Workstations,DC=testlab,DC=local
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType : GP-Link
ObjectSID :
InheritanceFlags : ContainerInherit
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1106
AccessMask : 48
AuditFlags : None
IsInherited : False
AceFlags : ContainerInherit
InheritedObjectAceType : All
OpaqueLength : 0
AceQualifier : AccessAllowed
ObjectDN : OU=Admins,OU=Workstations,DC=testlab,DC=local
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType : GP-Link
ObjectSID :
InheritanceFlags : ContainerInherit
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1110
AccessMask : 48
AuditFlags : None
IsInherited : False
AceFlags : ContainerInherit
InheritedObjectAceType : All
OpaqueLength : 0
AceQualifier : AccessAllowed
ObjectDN : OU=Admins,OU=Workstations,DC=testlab,DC=local
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType : GP-Link
ObjectSID :
InheritanceFlags : ContainerInherit
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1106
AccessMask : 48
AuditFlags : None
IsInherited : True
AceFlags : ContainerInherit, Inherited
InheritedObjectAceType : All
OpaqueLength : 0
AceQualifier : AccessAllowed
ObjectDN : OU=DAs,OU=Admins,OU=Workstations,DC=testlab,DC=local
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType : GP-Link
ObjectSID :
InheritanceFlags : ContainerInherit
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1110
AccessMask : 48
AuditFlags : None
IsInherited : True
AceFlags : ContainerInherit, Inherited
InheritedObjectAceType : All
OpaqueLength : 0
AceQualifier : AccessAllowed
ObjectDN : OU=DAs,OU=Admins,OU=Workstations,DC=testlab,DC=local
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType : GP-Link
ObjectSID :
InheritanceFlags : ContainerInherit
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-407754292-3742881058-3910138598-1106
AccessMask : 48
AuditFlags : None
IsInherited : True
AceFlags : ContainerInherit, Inherited
InheritedObjectAceType : All
OpaqueLength : 0
我覺得關于枚舉的介紹已經夠多了!接下來的文章,我們將從一些濫用開始。