From e88dad44567d826d3e4ea21ca1ead1774ca1cfa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20B=C3=BClow=20Knudsen?= <12843299+JonasBK@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:49:42 +0200 Subject: [PATCH] Write gPLink abuse (#607) * feat: adding Organizational Units GenericWrite and ManageGPLink compromise edge ; adding OU GenericAll abuse warning about adminCount=1 objects * Renaming ManageGPLink edge to WriteGPLink; additional elements added to help texts related to Organizational Units GPLink exploitation * Additional Organizational Units ACLs (#567) * feat: adding Organizational Units GenericWrite and WriteGPLink compromise edge ; adding OU GenericAll abuse warning about adminCount=1 objects * feat: GenericWrite and WriteGPLink for Domain --------- Co-authored-by: Quentin Roland Co-authored-by: q-roland <115217858+q-roland@users.noreply.github.com> --- packages/cue/bh/ad/ad.cue | 8 + packages/go/graphschema/ad/ad.go | 7 +- .../HelpTexts/GenericAll/LinuxAbuse.tsx | 125 +++++++++++++ .../HelpTexts/GenericAll/References.tsx | 11 ++ .../HelpTexts/GenericAll/WindowsAbuse.tsx | 173 ++++++++++++++++- .../HelpTexts/GenericWrite/LinuxAbuse.tsx | 94 ++++++++++ .../HelpTexts/GenericWrite/References.tsx | 11 ++ .../HelpTexts/GenericWrite/WindowsAbuse.tsx | 92 ++++++++- .../components/HelpTexts/Owns/LinuxAbuse.tsx | 132 +++++++++++++ .../HelpTexts/Owns/WindowsAbuse.tsx | 176 +++++++++++++++++- .../HelpTexts/WriteDacl/LinuxAbuse.tsx | 125 +++++++++++++ .../HelpTexts/WriteDacl/WindowsAbuse.tsx | 171 ++++++++++++++++- .../HelpTexts/WriteGPLink/General.tsx | 54 ++++++ .../HelpTexts/WriteGPLink/LinuxAbuse.tsx | 46 +++++ .../HelpTexts/WriteGPLink/Opsec.tsx | 34 ++++ .../HelpTexts/WriteGPLink/References.tsx | 37 ++++ .../HelpTexts/WriteGPLink/WindowsAbuse.tsx | 41 ++++ .../HelpTexts/WriteGPLink/WriteGPLink.tsx | 31 +++ .../HelpTexts/WriteOwner/LinuxAbuse.tsx | 132 +++++++++++++ .../HelpTexts/WriteOwner/WindowsAbuse.tsx | 176 +++++++++++++++++- .../src/components/HelpTexts/index.tsx | 2 + .../bh-shared-ui/src/graphSchema.ts | 4 + .../views/Explore/ExploreSearch/edgeTypes.tsx | 1 + 23 files changed, 1667 insertions(+), 16 deletions(-) create mode 100644 packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/General.tsx create mode 100644 packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/LinuxAbuse.tsx create mode 100644 packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/Opsec.tsx create mode 100644 packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/References.tsx create mode 100644 packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/WindowsAbuse.tsx create mode 100644 packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/WriteGPLink.tsx diff --git a/packages/cue/bh/ad/ad.cue b/packages/cue/bh/ad/ad.cue index 3af47cb6e4..cfc7d5acd8 100644 --- a/packages/cue/bh/ad/ad.cue +++ b/packages/cue/bh/ad/ad.cue @@ -1115,6 +1115,11 @@ WriteAccountRestrictions: types.#Kind & { schema: "active_directory" } +WriteGPLink: types.#Kind & { + symbol: "WriteGPLink" + schema: "active_directory" +} + GetChangesInFilteredSet: types.#Kind & { symbol: "GetChangesInFilteredSet" schema: "active_directory" @@ -1329,6 +1334,7 @@ RelationshipKinds: [ RemoteInteractiveLogonPrivilege, SyncLAPSPassword, WriteAccountRestrictions, + WriteGPLink, RootCAFor, DCFor, PublishedTo, @@ -1384,6 +1390,7 @@ ACLRelationships: [ GetChangesAll, GetChangesInFilteredSet, WriteAccountRestrictions, + WriteGPLink, SyncLAPSPassword, DCSync, ManageCertificates, @@ -1426,6 +1433,7 @@ PathfindingRelationships: [ AddKeyCredentialLink, SyncLAPSPassword, WriteAccountRestrictions, + WriteGPLink, GoldenCert, ADCSESC1, ADCSESC3, diff --git a/packages/go/graphschema/ad/ad.go b/packages/go/graphschema/ad/ad.go index 0c5a2ba963..d4a792849c 100644 --- a/packages/go/graphschema/ad/ad.go +++ b/packages/go/graphschema/ad/ad.go @@ -78,6 +78,7 @@ var ( RemoteInteractiveLogonPrivilege = graph.StringKind("RemoteInteractiveLogonPrivilege") SyncLAPSPassword = graph.StringKind("SyncLAPSPassword") WriteAccountRestrictions = graph.StringKind("WriteAccountRestrictions") + WriteGPLink = graph.StringKind("WriteGPLink") RootCAFor = graph.StringKind("RootCAFor") DCFor = graph.StringKind("DCFor") PublishedTo = graph.StringKind("PublishedTo") @@ -851,13 +852,13 @@ func Nodes() []graph.Kind { return []graph.Kind{Entity, User, Computer, Group, GPO, OU, Container, Domain, LocalGroup, LocalUser, AIACA, RootCA, EnterpriseCA, NTAuthStore, CertTemplate, IssuancePolicy} } func Relationships() []graph.Kind { - return []graph.Kind{Owns, GenericAll, GenericWrite, WriteOwner, WriteDACL, MemberOf, ForceChangePassword, AllExtendedRights, AddMember, HasSession, Contains, GPLink, AllowedToDelegate, GetChanges, GetChangesAll, GetChangesInFilteredSet, TrustedBy, AllowedToAct, AdminTo, CanPSRemote, CanRDP, ExecuteDCOM, HasSIDHistory, AddSelf, DCSync, ReadLAPSPassword, ReadGMSAPassword, DumpSMSAPassword, SQLAdmin, AddAllowedToAct, WriteSPN, AddKeyCredentialLink, LocalToComputer, MemberOfLocalGroup, RemoteInteractiveLogonPrivilege, SyncLAPSPassword, WriteAccountRestrictions, RootCAFor, DCFor, PublishedTo, ManageCertificates, ManageCA, DelegatedEnrollmentAgent, Enroll, HostsCAService, WritePKIEnrollmentFlag, WritePKINameFlag, NTAuthStoreFor, TrustedForNTAuth, EnterpriseCAFor, CanAbuseUPNCertMapping, CanAbuseWeakCertBinding, IssuedSignedBy, GoldenCert, EnrollOnBehalfOf, OIDGroupLink, ExtendedByPolicy, ADCSESC1, ADCSESC3, ADCSESC4, ADCSESC5, ADCSESC6a, ADCSESC6b, ADCSESC7, ADCSESC9a, ADCSESC9b, ADCSESC10a, ADCSESC10b, ADCSESC13, SyncedToEntraUser} + return []graph.Kind{Owns, GenericAll, GenericWrite, WriteOwner, WriteDACL, MemberOf, ForceChangePassword, AllExtendedRights, AddMember, HasSession, Contains, GPLink, AllowedToDelegate, GetChanges, GetChangesAll, GetChangesInFilteredSet, TrustedBy, AllowedToAct, AdminTo, CanPSRemote, CanRDP, ExecuteDCOM, HasSIDHistory, AddSelf, DCSync, ReadLAPSPassword, ReadGMSAPassword, DumpSMSAPassword, SQLAdmin, AddAllowedToAct, WriteSPN, AddKeyCredentialLink, LocalToComputer, MemberOfLocalGroup, RemoteInteractiveLogonPrivilege, SyncLAPSPassword, WriteAccountRestrictions, WriteGPLink, RootCAFor, DCFor, PublishedTo, ManageCertificates, ManageCA, DelegatedEnrollmentAgent, Enroll, HostsCAService, WritePKIEnrollmentFlag, WritePKINameFlag, NTAuthStoreFor, TrustedForNTAuth, EnterpriseCAFor, CanAbuseUPNCertMapping, CanAbuseWeakCertBinding, IssuedSignedBy, GoldenCert, EnrollOnBehalfOf, OIDGroupLink, ExtendedByPolicy, ADCSESC1, ADCSESC3, ADCSESC4, ADCSESC5, ADCSESC6a, ADCSESC6b, ADCSESC7, ADCSESC9a, ADCSESC9b, ADCSESC10a, ADCSESC10b, ADCSESC13, SyncedToEntraUser} } func ACLRelationships() []graph.Kind { - return []graph.Kind{AllExtendedRights, ForceChangePassword, AddMember, AddAllowedToAct, GenericAll, WriteDACL, WriteOwner, GenericWrite, ReadLAPSPassword, ReadGMSAPassword, Owns, AddSelf, WriteSPN, AddKeyCredentialLink, GetChanges, GetChangesAll, GetChangesInFilteredSet, WriteAccountRestrictions, SyncLAPSPassword, DCSync, ManageCertificates, ManageCA, Enroll, WritePKIEnrollmentFlag, WritePKINameFlag} + return []graph.Kind{AllExtendedRights, ForceChangePassword, AddMember, AddAllowedToAct, GenericAll, WriteDACL, WriteOwner, GenericWrite, ReadLAPSPassword, ReadGMSAPassword, Owns, AddSelf, WriteSPN, AddKeyCredentialLink, GetChanges, GetChangesAll, GetChangesInFilteredSet, WriteAccountRestrictions, WriteGPLink, SyncLAPSPassword, DCSync, ManageCertificates, ManageCA, Enroll, WritePKIEnrollmentFlag, WritePKINameFlag} } func PathfindingRelationships() []graph.Kind { - return []graph.Kind{Owns, GenericAll, GenericWrite, WriteOwner, WriteDACL, MemberOf, ForceChangePassword, AllExtendedRights, AddMember, HasSession, Contains, GPLink, AllowedToDelegate, TrustedBy, AllowedToAct, AdminTo, CanPSRemote, CanRDP, ExecuteDCOM, HasSIDHistory, AddSelf, DCSync, ReadLAPSPassword, ReadGMSAPassword, DumpSMSAPassword, SQLAdmin, AddAllowedToAct, WriteSPN, AddKeyCredentialLink, SyncLAPSPassword, WriteAccountRestrictions, GoldenCert, ADCSESC1, ADCSESC3, ADCSESC4, ADCSESC5, ADCSESC6a, ADCSESC6b, ADCSESC7, ADCSESC9a, ADCSESC9b, ADCSESC10a, ADCSESC10b, ADCSESC13, DCFor, SyncedToEntraUser} + return []graph.Kind{Owns, GenericAll, GenericWrite, WriteOwner, WriteDACL, MemberOf, ForceChangePassword, AllExtendedRights, AddMember, HasSession, Contains, GPLink, AllowedToDelegate, TrustedBy, AllowedToAct, AdminTo, CanPSRemote, CanRDP, ExecuteDCOM, HasSIDHistory, AddSelf, DCSync, ReadLAPSPassword, ReadGMSAPassword, DumpSMSAPassword, SQLAdmin, AddAllowedToAct, WriteSPN, AddKeyCredentialLink, SyncLAPSPassword, WriteAccountRestrictions, WriteGPLink, GoldenCert, ADCSESC1, ADCSESC3, ADCSESC4, ADCSESC5, ADCSESC6a, ADCSESC6b, ADCSESC7, ADCSESC9a, ADCSESC9b, ADCSESC10a, ADCSESC10b, ADCSESC13, DCFor, SyncedToEntraUser} } func IsACLKind(s graph.Kind) bool { for _, acl := range ACLRelationships() { diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/LinuxAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/LinuxAbuse.tsx index 6509402fa6..65a32ec099 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/LinuxAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/LinuxAbuse.tsx @@ -342,6 +342,77 @@ const LinuxAbuse: FC = ( {'pyLAPS.py --action get -d "DOMAIN" -u "ControlledUser" -p "ItsPassword"'} + + Generic Descendent Object Takeover + + The simplest and most straight forward way to obtain control of the objects of the domain is to + apply a GenericAll ACE on the domain that will inherit down to all object types. This can be + done using Impacket's dacledit (cf. "grant rights" reference for the link). + + + + { + "dacledit.py -action 'write' -rights 'FullControl' -inheritance -principal 'JKHOLER' -target-dn 'DomainDistinguishedName' 'domain'/'user':'password'" + } + + + + Now, the "JKOHLER" user will have full control of all descendent objects of each type. + + + Objects for which ACL inheritance is disabled + + + The compromise vector described above relies on ACL inheritance and will not work for objects + with ACL inheritance disabled, such as objects protected by AdminSDHolder (attribute + adminCount=1). This observation applies to any user or computer with inheritance disabled, + including objects located in nested OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on a domain + object through an alternative attack vector. Indeed, with GenericAll permissions over a domain + object, you may make modifications to the gPLink attribute of the domain. The ability to alter + the gPLink attribute of a domain may allow an attacker to apply a malicious Group Policy Object + (GPO) to all of the domain user and computer objects (including the ones located in nested OUs). + This can be exploited to make said child objects execute arbitrary commands through an immediate + scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. + ); case 'GPO': @@ -399,6 +470,60 @@ const LinuxAbuse: FC = ( right you want to apply to precisely which kinds of descendent objects. Refer to the Windows Abuse info for this. + + Objects for which ACL inheritance is disabled + + + It is important to note that the compromise vector described above relies on ACL inheritance and + will not work for objects with ACL inheritance disabled, such as objects protected by + AdminSDHolder (attribute adminCount=1). This observation applies to any OU child user or + computer with ACL inheritance disabled, including objects located in nested sub-OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on an OU through + an alternative attack vector. Indeed, with GenericAll permissions over an OU, you may make + modifications to the gPLink attribute of the OU. The ability to alter the gPLink attribute of an + OU may allow an attacker to apply a malicious Group Policy Object (GPO) to all of the OU's child + user and computer objects (including the ones located in nested sub-OUs). This can be exploited + to make said child objects execute arbitrary commands through an immediate scheduled task, thus + compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + ); case 'Container': diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/References.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/References.tsx index a165c36117..0e7b04d5d0 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/References.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/References.tsx @@ -136,6 +136,17 @@ const References: FC = () => { href='https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab'> https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab +
+ + https://labs.withsecure.com/publications/ou-having-a-laugh + +
+ + https://www.synacktiv.com/publications/ounedpy-exploiting-hidden-organizational-units-acl-attack-vectors-in-active-directory + ); }; diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/WindowsAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/WindowsAbuse.tsx index 7168bd842d..6f3fd7128a 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/WindowsAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericAll/WindowsAbuse.tsx @@ -15,7 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 import { FC } from 'react'; -import { Typography } from '@mui/material'; +import { Link, Typography } from '@mui/material'; import { EdgeInfoProps } from '../index'; const WindowsAbuse: FC = ({ @@ -423,6 +423,7 @@ const WindowsAbuse: FC = case 'Domain': return ( <> + DCSync attack Full control of a domain object grants you both DS-Replication-Get-Changes as well as DS-Replication-Get-Changes-All rights. The combination of these rights allows you to perform the @@ -430,6 +431,124 @@ const WindowsAbuse: FC = {'lsadump::dcsync /domain:testlab.local /user:harmj0y'} + + Generic Descendent Object Takeover + + The simplest and most straight forward way to obtain control of the objects of the domain is to + apply a GenericAll ACE on the domain that will inherit down to all object types. This can be + done using PowerView. This time we will use the New-ADObjectAccessControlEntry, which gives us + more control over the ACE we add to the domain object. + + + + Next, we will fetch the GUID for all objects. This should be + '00000000-0000-0000-0000-000000000000': + + + + {'$Guids = Get-DomainGUIDMap\n' + + "$AllObjectsPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'All'} | select -ExpandProperty name"} + + + + Then we will construct our ACE. This command will create an ACE granting the "JKHOLER" user full + control of all descendant objects: + + + + { + "$ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity 'JKOHLER' -Right GenericAll -AccessControlType Allow -InheritanceType All -InheritedObjectType $AllObjectsPropertyGuid" + } + + + Finally, we will apply this ACE to the domain: + + + {'$DomainDN = "DC=dumpster,DC=fire"\n' + + '$dsEntry = [ADSI]"LDAP://$DomainDN"\n' + + "$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'\n" + + '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + + '$dsEntry.PsBase.CommitChanges()'} + + + + Now, the "JKOHLER" user will have full control of all descendent objects of each type. + + + Targeted Descendent Object Takeoever + + + If you want to be more targeted with your approach, it is possible to specify precisely what + right you want to apply to precisely which kinds of descendent objects. You could, for example, + grant a user "ForceChangePassword" permission against all user objects, or grant a security + group the ability to read every GMSA password under a certain OU. Below is an example taken from + PowerView's help text on how to grant the "ITADMIN" user the ability to read the LAPS password + from all computer objects in the "Workstations" OU: + + + + {'$Guids = Get-DomainGUIDMap\n' + + "$AdmPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'ms-Mcs-AdmPwd'} | select -ExpandProperty name\n" + + "$CompPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'Computer'} | select -ExpandProperty name\n" + + '$ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity itadmin -Right ExtendedRight,ReadProperty -AccessControlType Allow -ObjectType $AdmPropertyGuid -InheritanceType All -InheritedObjectType $CompPropertyGuid\n' + + '$OU = Get-DomainOU -Raw Workstations\n' + + '$DsEntry = $OU.GetDirectoryEntry()\n' + + "$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'\n" + + '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + + '$dsEntry.PsBase.CommitChanges()'} + + + Objects for which ACL inheritance is disabled + + + The compromise vector described above relies on ACL inheritance and will not work for objects + with ACL inheritance disabled, such as objects protected by AdminSDHolder (attribute + adminCount=1). This observation applies to any user or computer with inheritance disabled, + including objects located in nested OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on a domain + object through an alternative attack vector. Indeed, with GenericAll permissions over a domain + object, you may make modifications to the gPLink attribute of the domain. The ability to alter + the gPLink attribute of a domain may allow an attacker to apply a malicious Group Policy Object + (GPO) to all of the domain user and computer objects (including the ones located in nested OUs). + This can be exploited to make said child objects execute arbitrary commands through an immediate + scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. + ); case 'GPO': @@ -526,6 +645,58 @@ const WindowsAbuse: FC = '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + '$dsEntry.PsBase.CommitChanges()'} + + Objects for which ACL inheritance is disabled + + + It is important to note that the compromise vector described above relies on ACL inheritance and + will not work for objects with ACL inheritance disabled, such as objects protected by + AdminSDHolder (attribute adminCount=1). This observation applies to any OU child user or + computer with ACL inheritance disabled, including objects located in nested sub-OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on an OU through + an alternative attack vector. Indeed, with GenericAll permissions over an OU, you may make + modifications to the gPLink attribute of the OU. The ability to alter the gPLink attribute of an + OU may allow an attacker to apply a malicious Group Policy Object (GPO) to all of the OU's child + user and computer objects (including the ones located in nested sub-OUs). This can be exploited + to make said child objects execute arbitrary commands through an immediate scheduled task, thus + compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + ); default: diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/LinuxAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/LinuxAbuse.tsx index cc8382ac9b..c1d8776950 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/LinuxAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/LinuxAbuse.tsx @@ -192,6 +192,100 @@ const LinuxAbuse: FC = ({ targetType }) => { ); + case 'OU': + return ( + <> + + With GenericWrite permissions over an OU, you may make modifications to the gPLink attribute of + the OU. The ability to alter the gPLink attribute of an OU may allow an attacker to apply a + malicious Group Policy Object (GPO) to all of the OU's child user and computer objects + (including the ones located in nested sub-OUs). This can be exploited to make said child items + execute arbitrary commands through an immediate scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + + + ); + case 'Domain': + return ( + <> + + With GenericWrite permission over a domain object, you may make modifications to the gPLink + attribute of the domain. The ability to alter the gPLink attribute of a domain may allow an + attacker to apply a malicious Group Policy Object (GPO) to all of the domain user and computer + objects (including the ones located in nested OUs). This can be exploited to make said child + items execute arbitrary commands through an immediate scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. + + + ); default: return null; } diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/References.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/References.tsx index 5728473e2c..df693573af 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/References.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/References.tsx @@ -78,6 +78,17 @@ const References: FC = () => { href='https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab'> https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab +
+ + https://labs.withsecure.com/publications/ou-having-a-laugh + +
+ + https://www.synacktiv.com/publications/ounedpy-exploiting-hidden-organizational-units-acl-attack-vectors-in-active-directory + ); }; diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/WindowsAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/WindowsAbuse.tsx index 3b9cba989a..99f0de6f29 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/WindowsAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/GenericWrite/WindowsAbuse.tsx @@ -15,7 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 import { FC } from 'react'; -import { Typography } from '@mui/material'; +import { Link, Typography } from '@mui/material'; import { EdgeInfoProps } from '../index'; const WindowsAbuse: FC = ({ sourceName, sourceType, targetName, targetType }) => { @@ -257,6 +257,96 @@ const WindowsAbuse: FC = ({ sourceName, sourceType, targetName, t ); + case 'OU': + return ( + <> + + With GenericWrite permissions over an OU, you may make modifications to the gPLink attribute of + the OU. The ability to alter the gPLink attribute of an OU may allow an attacker to apply a + malicious Group Policy Object (GPO) to all of the OU's child user and computer objects + (including the ones located in nested sub-OUs). This can be exploited to make said child items + execute arbitrary commands through an immediate scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + + + ); + case 'Domain': + return ( + <> + + With GenericWrite permission over a domain object, you may make modifications to the gPLink + attribute of the domain. The ability to alter the gPLink attribute of a domain may allow an + attacker to apply a malicious Group Policy Object (GPO) to all of the domain user and computer + objects (including the ones located in nested OUs). This can be exploited to make said child + items execute arbitrary commands through an immediate scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. + + + ); default: return null; } diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/Owns/LinuxAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/Owns/LinuxAbuse.tsx index 472130d3d5..fc0f469840 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/Owns/LinuxAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/Owns/LinuxAbuse.tsx @@ -430,6 +430,77 @@ const LinuxAbuse: FC = ( {'pyLAPS.py --action get -d "DOMAIN" -u "ControlledUser" -p "ItsPassword"'} + + Generic Descendent Object Takeover + + The simplest and most straight forward way to obtain control of the objects of the domain is to + apply a GenericAll ACE on the domain that will inherit down to all object types. This can be + done using Impacket's dacledit (cf. "grant rights" reference for the link). + + + + { + "dacledit.py -action 'write' -rights 'FullControl' -inheritance -principal 'JKHOLER' -target-dn 'DomainDistinguishedName' 'domain'/'user':'password'" + } + + + + Now, the "JKOHLER" user will have full control of all descendent objects of each type. + + + Objects for which ACL inheritance is disabled + + + The compromise vector described above relies on ACL inheritance and will not work for objects + with ACL inheritance disabled, such as objects protected by AdminSDHolder (attribute + adminCount=1). This observation applies to any user or computer with inheritance disabled, + including objects located in nested OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on a domain + object through an alternative attack vector. Indeed, with GenericAll permissions over a domain + object, you may make modifications to the gPLink attribute of the domain. The ability to alter + the gPLink attribute of a domain may allow an attacker to apply a malicious Group Policy Object + (GPO) to all of the domain user and computer objects (including the ones located in nested OUs). + This can be exploited to make said child objects execute arbitrary commands through an immediate + scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. + ); case 'GPO': @@ -509,6 +580,67 @@ const LinuxAbuse: FC = ( right you want to apply to precisely which kinds of descendent objects. Refer to the Windows Abuse info for this. + + Objects for which ACL inheritance is disabled + + + It is important to note that the compromise vector described above relies on ACL inheritance and + will not work for objects with ACL inheritance disabled, such as objects protected by + AdminSDHolder (attribute adminCount=1). This observation applies to any OU child user or + computer with ACL inheritance disabled, including objects located in nested sub-OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on an OU through + an alternative attack vector. Indeed, with GenericAll permissions over an OU, you may make + modifications to the gPLink attribute of the OU. The ability to alter the gPLink attribute of an + OU may allow an attacker to apply a malicious Group Policy Object (GPO) to all of the OU's child + user and computer objects (including the ones located in nested sub-OUs). This can be exploited + to make said child objects execute arbitrary commands through an immediate scheduled task, thus + compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + ); case 'Container': diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/Owns/WindowsAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/Owns/WindowsAbuse.tsx index b8a6230477..851d682596 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/Owns/WindowsAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/Owns/WindowsAbuse.tsx @@ -15,7 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 import { FC } from 'react'; -import { Typography } from '@mui/material'; +import { Link, Typography } from '@mui/material'; import { EdgeInfoProps } from '../index'; const WindowsAbuse: FC = ({ @@ -585,6 +585,128 @@ const WindowsAbuse: FC = {'Remove-DomainObjectAcl -Credential $Cred -TargetIdentity testlab.local -Rights DCSync'} + + + Alternatively, you can grant GenericAll on the domain and execute one of the follwing attacks. + + + Generic Descendent Object Takeover + + The simplest and most straight forward way to obtain control of the objects of the domain is to + apply a GenericAll ACE on the domain that will inherit down to all object types. This can be + done using PowerView. This time we will use the New-ADObjectAccessControlEntry, which gives us + more control over the ACE we add to the domain object. + + + + Next, we will fetch the GUID for all objects. This should be + '00000000-0000-0000-0000-000000000000': + + + + {'$Guids = Get-DomainGUIDMap\n' + + "$AllObjectsPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'All'} | select -ExpandProperty name"} + + + + Then we will construct our ACE. This command will create an ACE granting the "JKHOLER" user full + control of all descendant objects: + + + + { + "$ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity 'JKOHLER' -Right GenericAll -AccessControlType Allow -InheritanceType All -InheritedObjectType $AllObjectsPropertyGuid" + } + + + Finally, we will apply this ACE to the domain: + + + {'$DomainDN = "DC=dumpster,DC=fire"\n' + + '$dsEntry = [ADSI]"LDAP://$DomainDN"\n' + + "$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'\n" + + '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + + '$dsEntry.PsBase.CommitChanges()'} + + + + Now, the "JKOHLER" user will have full control of all descendent objects of each type. + + + Targeted Descendent Object Takeoever + + + If you want to be more targeted with your approach, it is possible to specify precisely what + right you want to apply to precisely which kinds of descendent objects. You could, for example, + grant a user "ForceChangePassword" permission against all user objects, or grant a security + group the ability to read every GMSA password under a certain OU. Below is an example taken from + PowerView's help text on how to grant the "ITADMIN" user the ability to read the LAPS password + from all computer objects in the "Workstations" OU: + + + + {'$Guids = Get-DomainGUIDMap\n' + + "$AdmPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'ms-Mcs-AdmPwd'} | select -ExpandProperty name\n" + + "$CompPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'Computer'} | select -ExpandProperty name\n" + + '$ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity itadmin -Right ExtendedRight,ReadProperty -AccessControlType Allow -ObjectType $AdmPropertyGuid -InheritanceType All -InheritedObjectType $CompPropertyGuid\n' + + '$OU = Get-DomainOU -Raw Workstations\n' + + '$DsEntry = $OU.GetDirectoryEntry()\n' + + "$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'\n" + + '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + + '$dsEntry.PsBase.CommitChanges()'} + + + Objects for which ACL inheritance is disabled + + + The compromise vector described above relies on ACL inheritance and will not work for objects + with ACL inheritance disabled, such as objects protected by AdminSDHolder (attribute + adminCount=1). This observation applies to any user or computer with inheritance disabled, + including objects located in nested OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on a domain + object through an alternative attack vector. Indeed, with GenericAll permissions over a domain + object, you may make modifications to the gPLink attribute of the domain. The ability to alter + the gPLink attribute of a domain may allow an attacker to apply a malicious Group Policy Object + (GPO) to all of the domain user and computer objects (including the ones located in nested OUs). + This can be exploited to make said child objects execute arbitrary commands through an immediate + scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. + ); case 'GPO': @@ -745,6 +867,58 @@ const WindowsAbuse: FC = '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + '$dsEntry.PsBase.CommitChanges()'} + + Objects for which ACL inheritance is disabled + + + It is important to note that the compromise vector described above relies on ACL inheritance and + will not work for objects with ACL inheritance disabled, such as objects protected by + AdminSDHolder (attribute adminCount=1). This observation applies to any OU child user or + computer with ACL inheritance disabled, including objects located in nested sub-OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on an OU through + an alternative attack vector. Indeed, with GenericAll permissions over an OU, you may make + modifications to the gPLink attribute of the OU. The ability to alter the gPLink attribute of an + OU may allow an attacker to apply a malicious Group Policy Object (GPO) to all of the OU's child + user and computer objects (including the ones located in nested sub-OUs). This can be exploited + to make said child objects execute arbitrary commands through an immediate scheduled task, thus + compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + ); default: diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteDacl/LinuxAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteDacl/LinuxAbuse.tsx index 1037411b41..d44aa67f9c 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteDacl/LinuxAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteDacl/LinuxAbuse.tsx @@ -432,6 +432,77 @@ const LinuxAbuse: FC = ( {'pyLAPS.py --action get -d "DOMAIN" -u "ControlledUser" -p "ItsPassword"'} + + Generic Descendent Object Takeover + + The simplest and most straight forward way to obtain control of the objects of the domain is to + apply a GenericAll ACE on the domain that will inherit down to all object types. This can be + done using Impacket's dacledit (cf. "grant rights" reference for the link). + + + + { + "dacledit.py -action 'write' -rights 'FullControl' -inheritance -principal 'JKHOLER' -target-dn 'DomainDistinguishedName' 'domain'/'user':'password'" + } + + + + Now, the "JKOHLER" user will have full control of all descendent objects of each type. + + + Objects for which ACL inheritance is disabled + + + The compromise vector described above relies on ACL inheritance and will not work for objects + with ACL inheritance disabled, such as objects protected by AdminSDHolder (attribute + adminCount=1). This observation applies to any user or computer with inheritance disabled, + including objects located in nested OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on a domain + object through an alternative attack vector. Indeed, with GenericAll permissions over a domain + object, you may make modifications to the gPLink attribute of the domain. The ability to alter + the gPLink attribute of a domain may allow an attacker to apply a malicious Group Policy Object + (GPO) to all of the domain user and computer objects (including the ones located in nested OUs). + This can be exploited to make said child objects execute arbitrary commands through an immediate + scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. + ); case 'GPO': @@ -511,6 +582,60 @@ const LinuxAbuse: FC = ( right you want to apply to precisely which kinds of descendent objects. Refer to the Windows Abuse info for this. + + Objects for which ACL inheritance is disabled + + + It is important to note that the compromise vector described above relies on ACL inheritance and + will not work for objects with ACL inheritance disabled, such as objects protected by + AdminSDHolder (attribute adminCount=1). This observation applies to any OU child user or + computer with ACL inheritance disabled, including objects located in nested sub-OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on an OU through + an alternative attack vector. Indeed, with GenericAll permissions over an OU, you may make + modifications to the gPLink attribute of the OU. The ability to alter the gPLink attribute of an + OU may allow an attacker to apply a malicious Group Policy Object (GPO) to all of the OU's child + user and computer objects (including the ones located in nested sub-OUs). This can be exploited + to make said child objects execute arbitrary commands through an immediate scheduled task, thus + compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + ); case 'Container': diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteDacl/WindowsAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteDacl/WindowsAbuse.tsx index bb6cfa7085..9a5163a1a1 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteDacl/WindowsAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteDacl/WindowsAbuse.tsx @@ -548,25 +548,126 @@ const WindowsAbuse: FC = {'Remove-DomainObjectAcl -Credential $Cred -TargetIdentity testlab.local -Rights DCSync'} + + + Alternatively, you can grant GenericAll on the domain and execute one of the follwing attacks. + + Generic Descendent Object Takeover - You can also abuse this without using Windows-based tooling if you are operating from a Linux - host. DCSync.py from n00py will let you authenticate with either a plaintext password, NT hash, - or kerberos ticket: + The simplest and most straight forward way to obtain control of the objects of the domain is to + apply a GenericAll ACE on the domain that will inherit down to all object types. This can be + done using PowerView. This time we will use the New-ADObjectAccessControlEntry, which gives us + more control over the ACE we add to the domain object. + + + + Next, we will fetch the GUID for all objects. This should be + '00000000-0000-0000-0000-000000000000': + + + + {'$Guids = Get-DomainGUIDMap\n' + + "$AllObjectsPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'All'} | select -ExpandProperty name"} + - To grant the "n00py" user DCSync permissions, authenticating as the user "n00py" with the - password "Password123": + Then we will construct our ACE. This command will create an ACE granting the "JKHOLER" user full + control of all descendant objects: + { - "./dcsync.py -dc dc01.n00py.local -t 'CN=n00py,OU=Employees,DC=n00py,DC=local' n00pyAdministrator:Password123" + "$ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity 'JKOHLER' -Right GenericAll -AccessControlType Allow -InheritanceType All -InheritedObjectType $AllObjectsPropertyGuid" } + + Finally, we will apply this ACE to the domain: + + + {'$DomainDN = "DC=dumpster,DC=fire"\n' + + '$dsEntry = [ADSI]"LDAP://$DomainDN"\n' + + "$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'\n" + + '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + + '$dsEntry.PsBase.CommitChanges()'} + + + + Now, the "JKOHLER" user will have full control of all descendent objects of each type. + + + Targeted Descendent Object Takeoever + + + If you want to be more targeted with your approach, it is possible to specify precisely what + right you want to apply to precisely which kinds of descendent objects. You could, for example, + grant a user "ForceChangePassword" permission against all user objects, or grant a security + group the ability to read every GMSA password under a certain OU. Below is an example taken from + PowerView's help text on how to grant the "ITADMIN" user the ability to read the LAPS password + from all computer objects in the "Workstations" OU: + + + + {'$Guids = Get-DomainGUIDMap\n' + + "$AdmPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'ms-Mcs-AdmPwd'} | select -ExpandProperty name\n" + + "$CompPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'Computer'} | select -ExpandProperty name\n" + + '$ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity itadmin -Right ExtendedRight,ReadProperty -AccessControlType Allow -ObjectType $AdmPropertyGuid -InheritanceType All -InheritedObjectType $CompPropertyGuid\n' + + '$OU = Get-DomainOU -Raw Workstations\n' + + '$DsEntry = $OU.GetDirectoryEntry()\n' + + "$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'\n" + + '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + + '$dsEntry.PsBase.CommitChanges()'} + + + Objects for which ACL inheritance is disabled + + + The compromise vector described above relies on ACL inheritance and will not work for objects + with ACL inheritance disabled, such as objects protected by AdminSDHolder (attribute + adminCount=1). This observation applies to any user or computer with inheritance disabled, + including objects located in nested OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on a domain + object through an alternative attack vector. Indeed, with GenericAll permissions over a domain + object, you may make modifications to the gPLink attribute of the domain. The ability to alter + the gPLink attribute of a domain may allow an attacker to apply a malicious Group Policy Object + (GPO) to all of the domain user and computer objects (including the ones located in nested OUs). + This can be exploited to make said child objects execute arbitrary commands through an immediate + scheduled task, thus compromising them. + + - Source:{' '} - - https://github.com/n00py/DCSync + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. ); @@ -709,6 +810,58 @@ const WindowsAbuse: FC = '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + '$dsEntry.PsBase.CommitChanges()'} + + Objects for which ACL inheritance is disabled + + + It is important to note that the compromise vector described above relies on ACL inheritance and + will not work for objects with ACL inheritance disabled, such as objects protected by + AdminSDHolder (attribute adminCount=1). This observation applies to any OU child user or + computer with ACL inheritance disabled, including objects located in nested sub-OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on an OU through + an alternative attack vector. Indeed, with GenericAll permissions over an OU, you may make + modifications to the gPLink attribute of the OU. The ability to alter the gPLink attribute of an + OU may allow an attacker to apply a malicious Group Policy Object (GPO) to all of the OU's child + user and computer objects (including the ones located in nested sub-OUs). This can be exploited + to make said child objects execute arbitrary commands through an immediate scheduled task, thus + compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + ); default: diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/General.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/General.tsx new file mode 100644 index 0000000000..4573188cf9 --- /dev/null +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/General.tsx @@ -0,0 +1,54 @@ +// Copyright 2023 Specter Ops, Inc. +// +// Licensed under the Apache License, Version 2.0 +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +import { FC } from 'react'; +import { groupSpecialFormat } from '../utils'; +import { EdgeInfoProps } from '../index'; +import { Typography } from '@mui/material'; + +const General: FC = ({ sourceName, sourceType, targetType, targetName }) => { + return ( + <> + + {groupSpecialFormat(sourceType, sourceName)} has the permissions to modify the gPLink attribute of{' '} + {targetType} {targetName}. + + + + The ability to alter the gPLink attribute may allow an attacker to apply a malicious Group Policy Object + (GPO) to all child user and computer objects (including the ones located in nested OUs). This can be + exploited to make said child objects execute arbitrary commands through an immediate scheduled task, + thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the domain and + to create machine accounts. Alternatively, an already compromised domain-joined machine may be used to + perform the attack. Note that the attack vector implementation is not trivial and will require some + setup. + + + + Alternatively, the ability to modify the gPLink attribute can be exploited in conjunction with write + permissions on a GPO. In such a situation, an attacker could first inject a malicious scheduled task in + the controlled GPO, and then link the GPO to the target through its gPLink attribute, making all child + users and computers apply the malicious GPO and execute arbitrary commands. + + + ); +}; + +export default General; diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/LinuxAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/LinuxAbuse.tsx new file mode 100644 index 0000000000..7e8cd14243 --- /dev/null +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/LinuxAbuse.tsx @@ -0,0 +1,46 @@ +// Copyright 2023 Specter Ops, Inc. +// +// Licensed under the Apache License, Version 2.0 +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +import { FC } from 'react'; +import { Link, Typography } from '@mui/material'; + +const LinuxAbuse: FC = () => { + return ( + <> + + From a Linux machine, the WriteGPLink permission may be abused using the{' '} + + OUned.py + {' '} + exploitation tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will attempt to + fetch and apply the malicious GPO. + + + ); +}; + +export default LinuxAbuse; diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/Opsec.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/Opsec.tsx new file mode 100644 index 0000000000..d6ad61bec0 --- /dev/null +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/Opsec.tsx @@ -0,0 +1,34 @@ +// Copyright 2023 Specter Ops, Inc. +// +// Licensed under the Apache License, Version 2.0 +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +import { FC } from 'react'; +import { Typography } from '@mui/material'; + +const Opsec: FC = () => { + return ( + + The present attack vector relies on the execution of a malicious Group Policy Object. In case some objects + in the target Organizational Unit are unable to apply said Group Policy Object (for instance, because these + objects cannot reach the attacker's machine in the internal network), events related to failed GPO + application will be created. Furthermore, the execution of this attack will result in the modification of + the gPLink property of the target Organizational Unit. The property should be reset to its original value + after attack execution to avoid detection and ensure the OU child items can apply their legitimate Group + Policy Objects again. + + ); +}; + +export default Opsec; diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/References.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/References.tsx new file mode 100644 index 0000000000..4034040c63 --- /dev/null +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/References.tsx @@ -0,0 +1,37 @@ +// Copyright 2023 Specter Ops, Inc. +// +// Licensed under the Apache License, Version 2.0 +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +import { FC } from 'react'; +import { Link, Box } from '@mui/material'; + +const References: FC = () => { + return ( + + + https://labs.withsecure.com/publications/ou-having-a-laugh + +
+ + https://www.synacktiv.com/publications/ounedpy-exploiting-hidden-organizational-units-acl-attack-vectors-in-active-directory + +
+ ); +}; + +export default References; diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/WindowsAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/WindowsAbuse.tsx new file mode 100644 index 0000000000..1738a1e862 --- /dev/null +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/WindowsAbuse.tsx @@ -0,0 +1,41 @@ +// Copyright 2023 Specter Ops, Inc. +// +// Licensed under the Apache License, Version 2.0 +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +import { FC } from 'react'; +import { Link, Typography } from '@mui/material'; + +const WindowsAbuse: FC = () => { + return ( + <> + + From a domain-joined compromised Windows machine, the WriteGPLink permission may be abused through + Powermad, PowerView and native Windows functionalities. For a detailed outline of exploit requirements + and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will attempt to + fetch and apply the malicious GPO. + + + ); +}; + +export default WindowsAbuse; diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/WriteGPLink.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/WriteGPLink.tsx new file mode 100644 index 0000000000..e6081de4e4 --- /dev/null +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteGPLink/WriteGPLink.tsx @@ -0,0 +1,31 @@ +// Copyright 2023 Specter Ops, Inc. +// +// Licensed under the Apache License, Version 2.0 +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +import General from './General'; +import WindowsAbuse from './WindowsAbuse'; +import LinuxAbuse from './LinuxAbuse'; +import Opsec from './Opsec'; +import References from './References'; + +const WriteGPLink = { + general: General, + windowsAbuse: WindowsAbuse, + linuxAbuse: LinuxAbuse, + opsec: Opsec, + references: References, +}; + +export default WriteGPLink; diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteOwner/LinuxAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteOwner/LinuxAbuse.tsx index bee38cee9d..7f8a3cb5fa 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteOwner/LinuxAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteOwner/LinuxAbuse.tsx @@ -468,6 +468,77 @@ const LinuxAbuse: FC = ({ sourceName, targ {'pyLAPS.py --action get -d "DOMAIN" -u "ControlledUser" -p "ItsPassword"'} + + Generic Descendent Object Takeover + + The simplest and most straight forward way to obtain control of the objects of the domain is to + apply a GenericAll ACE on the domain that will inherit down to all object types. This can be + done using Impacket's dacledit (cf. "grant rights" reference for the link). + + + + { + "dacledit.py -action 'write' -rights 'FullControl' -inheritance -principal 'JKHOLER' -target-dn 'DomainDistinguishedName' 'domain'/'user':'password'" + } + + + + Now, the "JKOHLER" user will have full control of all descendent objects of each type. + + + Objects for which ACL inheritance is disabled + + + The compromise vector described above relies on ACL inheritance and will not work for objects + with ACL inheritance disabled, such as objects protected by AdminSDHolder (attribute + adminCount=1). This observation applies to any user or computer with inheritance disabled, + including objects located in nested OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on a domain + object through an alternative attack vector. Indeed, with GenericAll permissions over a domain + object, you may make modifications to the gPLink attribute of the domain. The ability to alter + the gPLink attribute of a domain may allow an attacker to apply a malicious Group Policy Object + (GPO) to all of the domain user and computer objects (including the ones located in nested OUs). + This can be exploited to make said child objects execute arbitrary commands through an immediate + scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. + ); case 'GPO': @@ -565,6 +636,67 @@ const LinuxAbuse: FC = ({ sourceName, targ right you want to apply to precisely which kinds of descendent objects. Refer to the Windows Abuse info for this. + + Objects for which ACL inheritance is disabled + + + It is important to note that the compromise vector described above relies on ACL inheritance and + will not work for objects with ACL inheritance disabled, such as objects protected by + AdminSDHolder (attribute adminCount=1). This observation applies to any OU child user or + computer with ACL inheritance disabled, including objects located in nested sub-OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on an OU through + an alternative attack vector. Indeed, with GenericAll permissions over an OU, you may make + modifications to the gPLink attribute of the OU. The ability to alter the gPLink attribute of an + OU may allow an attacker to apply a malicious Group Policy Object (GPO) to all of the OU's child + user and computer objects (including the ones located in nested sub-OUs). This can be exploited + to make said child objects execute arbitrary commands through an immediate scheduled task, thus + compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a Linux machine, the gPLink manipulation attack vector may be exploited using the{' '} + + OUned.py + {' '} + tool. For a detailed outline of exploit requirements and implementation, you can refer to{' '} + + the article associated to the OUned.py tool + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + ); case 'Container': diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteOwner/WindowsAbuse.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteOwner/WindowsAbuse.tsx index 374477e1e1..6db98428f0 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteOwner/WindowsAbuse.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/WriteOwner/WindowsAbuse.tsx @@ -15,7 +15,7 @@ // SPDX-License-Identifier: Apache-2.0 import { FC } from 'react'; -import { Typography } from '@mui/material'; +import { Link, Typography } from '@mui/material'; import { EdgeInfoProps } from '../index'; const WindowsAbuse: FC = ({ @@ -672,6 +672,128 @@ const WindowsAbuse: FC = Cleanup for the owner can be done by using Set-DomainObjectOwner once again + + + Alternatively, you can grant GenericAll on the domain and execute one of the follwing attacks. + + + Generic Descendent Object Takeover + + The simplest and most straight forward way to obtain control of the objects of the domain is to + apply a GenericAll ACE on the domain that will inherit down to all object types. This can be + done using PowerView. This time we will use the New-ADObjectAccessControlEntry, which gives us + more control over the ACE we add to the domain object. + + + + Next, we will fetch the GUID for all objects. This should be + '00000000-0000-0000-0000-000000000000': + + + + {'$Guids = Get-DomainGUIDMap\n' + + "$AllObjectsPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'All'} | select -ExpandProperty name"} + + + + Then we will construct our ACE. This command will create an ACE granting the "JKHOLER" user full + control of all descendant objects: + + + + { + "$ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity 'JKOHLER' -Right GenericAll -AccessControlType Allow -InheritanceType All -InheritedObjectType $AllObjectsPropertyGuid" + } + + + Finally, we will apply this ACE to the domain: + + + {'$DomainDN = "DC=dumpster,DC=fire"\n' + + '$dsEntry = [ADSI]"LDAP://$DomainDN"\n' + + "$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'\n" + + '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + + '$dsEntry.PsBase.CommitChanges()'} + + + + Now, the "JKOHLER" user will have full control of all descendent objects of each type. + + + Targeted Descendent Object Takeoever + + + If you want to be more targeted with your approach, it is possible to specify precisely what + right you want to apply to precisely which kinds of descendent objects. You could, for example, + grant a user "ForceChangePassword" permission against all user objects, or grant a security + group the ability to read every GMSA password under a certain OU. Below is an example taken from + PowerView's help text on how to grant the "ITADMIN" user the ability to read the LAPS password + from all computer objects in the "Workstations" OU: + + + + {'$Guids = Get-DomainGUIDMap\n' + + "$AdmPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'ms-Mcs-AdmPwd'} | select -ExpandProperty name\n" + + "$CompPropertyGuid = $Guids.GetEnumerator() | ?{$_.value -eq 'Computer'} | select -ExpandProperty name\n" + + '$ACE = New-ADObjectAccessControlEntry -Verbose -PrincipalIdentity itadmin -Right ExtendedRight,ReadProperty -AccessControlType Allow -ObjectType $AdmPropertyGuid -InheritanceType All -InheritedObjectType $CompPropertyGuid\n' + + '$OU = Get-DomainOU -Raw Workstations\n' + + '$DsEntry = $OU.GetDirectoryEntry()\n' + + "$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'\n" + + '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + + '$dsEntry.PsBase.CommitChanges()'} + + + Objects for which ACL inheritance is disabled + + + The compromise vector described above relies on ACL inheritance and will not work for objects + with ACL inheritance disabled, such as objects protected by AdminSDHolder (attribute + adminCount=1). This observation applies to any user or computer with inheritance disabled, + including objects located in nested OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on a domain + object through an alternative attack vector. Indeed, with GenericAll permissions over a domain + object, you may make modifications to the gPLink attribute of the domain. The ability to alter + the gPLink attribute of a domain may allow an attacker to apply a malicious Group Policy Object + (GPO) to all of the domain user and computer objects (including the ones located in nested OUs). + This can be exploited to make said child objects execute arbitrary commands through an immediate + scheduled task, thus compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given domain as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of a domain can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target domain + through its gPLink attribute, making all child users and computers apply the malicious GPO and + execute arbitrary commands. + ); case 'GPO': @@ -843,6 +965,58 @@ const WindowsAbuse: FC = '$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)\n' + '$dsEntry.PsBase.CommitChanges()'} + + Objects for which ACL inheritance is disabled + + + It is important to note that the compromise vector described above relies on ACL inheritance and + will not work for objects with ACL inheritance disabled, such as objects protected by + AdminSDHolder (attribute adminCount=1). This observation applies to any OU child user or + computer with ACL inheritance disabled, including objects located in nested sub-OUs. + + + + In such a situation, it may still be possible to exploit GenericAll permissions on an OU through + an alternative attack vector. Indeed, with GenericAll permissions over an OU, you may make + modifications to the gPLink attribute of the OU. The ability to alter the gPLink attribute of an + OU may allow an attacker to apply a malicious Group Policy Object (GPO) to all of the OU's child + user and computer objects (including the ones located in nested sub-OUs). This can be exploited + to make said child objects execute arbitrary commands through an immediate scheduled task, thus + compromising them. + + + + Successful exploitation will require the possibility to add non-existing DNS records to the + domain and to create machine accounts. Alternatively, an already compromised domain-joined + machine may be used to perform the attack. Note that the attack vector implementation is not + trivial and will require some setup. + + + + From a domain-joined compromised Windows machine, the gPLink manipulation attack vector may be + exploited through Powermad, PowerView and native Windows functionalities. For a detailed outline + of exploit requirements and implementation, you can refer to{' '} + + this article + + . + + + + Be mindful of the number of users and computers that are in the given OU as they all will + attempt to fetch and apply the malicious GPO. + + + + Alternatively, the ability to modify the gPLink attribute of an OU can be exploited in + conjunction with write permissions on a GPO. In such a situation, an attacker could first inject + a malicious scheduled task in the controlled GPO, and then link the GPO to the target OU through + its gPLink attribute, making all child users and computers apply the malicious GPO and execute + arbitrary commands. + ); default: diff --git a/packages/javascript/bh-shared-ui/src/components/HelpTexts/index.tsx b/packages/javascript/bh-shared-ui/src/components/HelpTexts/index.tsx index e36414362a..1b481da430 100644 --- a/packages/javascript/bh-shared-ui/src/components/HelpTexts/index.tsx +++ b/packages/javascript/bh-shared-ui/src/components/HelpTexts/index.tsx @@ -106,6 +106,7 @@ import SyncLAPSPassword from './SyncLAPSPassword/SyncLAPSPassword'; import TrustedBy from './TrustedBy/TrustedBy'; import TrustedForNTAuth from './TrustedForNTAuth/TrustedForNTAuth'; import WriteAccountRestrictions from './WriteAccountRestrictions/WriteAccountRestrictions'; +import WriteGPLink from './WriteGPLink/WriteGPLink'; import WriteDacl from './WriteDacl/WriteDacl'; import WriteOwner from './WriteOwner/WriteOwner'; import WritePKIEnrollmentFlag from './WritePKIEnrollmentFlag/WritePKIEnrollmentFlag'; @@ -190,6 +191,7 @@ const EdgeInfoComponents = { DCSync: DCSync, SyncLAPSPassword: SyncLAPSPassword, WriteAccountRestrictions: WriteAccountRestrictions, + WriteGPLink: WriteGPLink, DumpSMSAPassword: DumpSMSAPassword, AZMGAddMember: AZMGAddMember, AZMGAddOwner: AZMGAddOwner, diff --git a/packages/javascript/bh-shared-ui/src/graphSchema.ts b/packages/javascript/bh-shared-ui/src/graphSchema.ts index 93b613481e..095d8c6533 100644 --- a/packages/javascript/bh-shared-ui/src/graphSchema.ts +++ b/packages/javascript/bh-shared-ui/src/graphSchema.ts @@ -108,6 +108,7 @@ export enum ActiveDirectoryRelationshipKind { RemoteInteractiveLogonPrivilege = 'RemoteInteractiveLogonPrivilege', SyncLAPSPassword = 'SyncLAPSPassword', WriteAccountRestrictions = 'WriteAccountRestrictions', + WriteGPLink = 'WriteGPLink', RootCAFor = 'RootCAFor', DCFor = 'DCFor', PublishedTo = 'PublishedTo', @@ -218,6 +219,8 @@ export function ActiveDirectoryRelationshipKindToDisplay(value: ActiveDirectoryR return 'SyncLAPSPassword'; case ActiveDirectoryRelationshipKind.WriteAccountRestrictions: return 'WriteAccountRestrictions'; + case ActiveDirectoryRelationshipKind.WriteGPLink: + return 'WriteGPLink'; case ActiveDirectoryRelationshipKind.RootCAFor: return 'RootCAFor'; case ActiveDirectoryRelationshipKind.DCFor: @@ -643,6 +646,7 @@ export function ActiveDirectoryPathfindingEdges(): ActiveDirectoryRelationshipKi ActiveDirectoryRelationshipKind.AddKeyCredentialLink, ActiveDirectoryRelationshipKind.SyncLAPSPassword, ActiveDirectoryRelationshipKind.WriteAccountRestrictions, + ActiveDirectoryRelationshipKind.WriteGPLink, ActiveDirectoryRelationshipKind.GoldenCert, ActiveDirectoryRelationshipKind.ADCSESC1, ActiveDirectoryRelationshipKind.ADCSESC3, diff --git a/packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/edgeTypes.tsx b/packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/edgeTypes.tsx index b140d7c5cc..cd219576bb 100644 --- a/packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/edgeTypes.tsx +++ b/packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/edgeTypes.tsx @@ -90,6 +90,7 @@ export const AllEdgeTypes: Category[] = [ ActiveDirectoryRelationshipKind.AddAllowedToAct, ActiveDirectoryRelationshipKind.AddKeyCredentialLink, ActiveDirectoryRelationshipKind.WriteAccountRestrictions, + ActiveDirectoryRelationshipKind.WriteGPLink, ActiveDirectoryRelationshipKind.WriteSPN, ], },