@@ -65,72 +65,75 @@ rule ldap_queries
65
65
// Description: Enumerate all of the domain controllers for all domains in a forest
66
66
// Reference: N/A
67
67
$ string19 = /\( Get \- ADForest \)\. Domains \s \| \s \%\{ \s Get \- ADDomainController \s \- Filter \s. {0,1000 } \s \- Server \s \$ _ \s \} / nocase ascii wide
68
+ // Description: used by Rubeus and S4UTomato tools
69
+ // Reference: N/A
70
+ $ string20 = /\( msds \- supportedencryptiontypes \= 0 \)\( msds \- supportedencryptiontypes \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 4 \)\)\) / nocase ascii wide
68
71
// Description: Query to find service accounts which are typically high-privileged and targeted for privilege escalation
69
72
// Reference: https://github.com/mthcht/ThreatHunting-Keywords
70
- $ string20 = /\( objectCategory \= person \)\( objectClass \= user \)\( serviceAccount \= TRUE \) / nocase ascii wide
73
+ $ string21 = /\( objectCategory \= person \)\( objectClass \= user \)\( serviceAccount \= TRUE \) / nocase ascii wide
71
74
// Description: Enumerate Domain Admins
72
75
// Reference: https://gist.github.com/jsecurity101/9c7e94f95b8d90f9252d64949562ba5d
73
- $ string21 = /\( objectclass \= group \)\( samaccountname \= domain \s admins \) / nocase ascii wide
76
+ $ string22 = /\( objectclass \= group \)\( samaccountname \= domain \s admins \) / nocase ascii wide
74
77
// Description: Accounts Trusted for Delegation
75
78
// Reference: https://gist.github.com/jsecurity101/9c7e94f95b8d90f9252d64949562ba5d
76
- $ string22 = /\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 524288 \) / nocase ascii wide
79
+ $ string23 = /\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 524288 \) / nocase ascii wide
77
80
// Description: enumeration of Domain Password Policies
78
81
// Reference: https://github.com/swarleysez/AD-common-queries
79
- $ string23 = /\[ ADSI \] . {0,1000 } \s \| \s Select \- Object \s \- Property \s. {0,1000 } lockoutDuration / nocase ascii wide
82
+ $ string24 = /\[ ADSI \] . {0,1000 } \s \| \s Select \- Object \s \- Property \s. {0,1000 } lockoutDuration / nocase ascii wide
80
83
// Description: enumeration of Domain Password Policies
81
84
// Reference: https://github.com/swarleysez/AD-common-queries
82
- $ string24 = /\[ ADSI \] . {0,1000 } \s \| \s Select \- Object \s \- Property \s. {0,1000 } lockoutThreshold / nocase ascii wide
85
+ $ string25 = /\[ ADSI \] . {0,1000 } \s \| \s Select \- Object \s \- Property \s. {0,1000 } lockoutThreshold / nocase ascii wide
83
86
// Description: enumeration of Domain Password Policies
84
87
// Reference: https://github.com/swarleysez/AD-common-queries
85
- $ string25 = /\[ ADSI \] . {0,1000 } \s \| \s Select \- Object \s \- Property \s. {0,1000 } minPwdLength / nocase ascii wide
88
+ $ string26 = /\[ ADSI \] . {0,1000 } \s \| \s Select \- Object \s \- Property \s. {0,1000 } minPwdLength / nocase ascii wide
86
89
// Description: enumeration of Domain Admins group members
87
90
// Reference: https://github.com/swarleysez/AD-common-queries
88
- $ string26 = /\[ ADSI \] . {0,1000 } LDAP \:\/\/ CN \= Domain \s Admins . {0,1000 } \| \s ForEach \- Object \s \{\[ adsi \]\" LDAP \:\/\/\$ _ \"\}\; \s. {0,1000 } \. distinguishedname / nocase ascii wide
91
+ $ string27 = /\[ ADSI \] . {0,1000 } LDAP \:\/\/ CN \= Domain \s Admins . {0,1000 } \| \s ForEach \- Object \s \{\[ adsi \]\" LDAP \:\/\/\$ _ \"\}\; \s. {0,1000 } \. distinguishedname / nocase ascii wide
89
92
// Description: get LDAP properties for password settings directly
90
93
// Reference: https://github.com/swarleysez/AD-common-queries
91
- $ string27 = /\[ ADSI \] . {0,1000 } LDAP \:\/\/ dc \= . {0,1000 } \s \| \s Select \s \- Property \s pwdProperties / nocase ascii wide
94
+ $ string28 = /\[ ADSI \] . {0,1000 } LDAP \:\/\/ dc \= . {0,1000 } \s \| \s Select \s \- Property \s pwdProperties / nocase ascii wide
92
95
// Description: find user descriptions in Active Directory:
93
96
// Reference: https://github.com/swarleysez/AD-common-queries
94
- $ string28 = /\[ adsisearcher \]\"\(\&\( objectCategory \= person \)\( objectClass \= user \)\(\!\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\)\)\"\; \s \$ users \s \= \s \$ searchUsers \. FindAll \(\)\; \s \$ userProps \s \= \s \$ users \. Properties \; \s \$ userProps \s \| \s Where \- Object \s \{\$ _ \. description \} / nocase ascii wide
97
+ $ string29 = /\[ adsisearcher \]\"\(\&\( objectCategory \= person \)\( objectClass \= user \)\(\!\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\)\)\"\; \s \$ users \s \= \s \$ searchUsers \. FindAll \(\)\; \s \$ userProps \s \= \s \$ users \. Properties \; \s \$ userProps \s \| \s Where \- Object \s \{\$ _ \. description \} / nocase ascii wide
95
98
// Description: find all disabled user accounts
96
99
// Reference: https://github.com/swarleysez/AD-common-queries
97
- $ string29 = /\[ adsisearcher \]\"\(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\)\" / nocase ascii wide
100
+ $ string30 = /\[ adsisearcher \]\"\(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\)\" / nocase ascii wide
98
101
// Description: get a count of all inter domain trust accounts
99
102
// Reference: https://github.com/swarleysez/AD-common-queries
100
- $ string30 = /\[ adsisearcher \]\"\(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2560 \)\(\!\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\)\)\" / nocase ascii wide
103
+ $ string31 = /\[ adsisearcher \]\"\(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2560 \)\(\!\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\)\)\" / nocase ascii wide
101
104
// Description: Detection of all accounts with 'Password Not Required'
102
105
// Reference: https://github.com/swarleysez/AD-common-queries
103
- $ string31 = /\[ adsisearcher \]\"\(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 32 \)\(\!\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\)\) / nocase ascii wide
106
+ $ string32 = /\[ adsisearcher \]\"\(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 32 \)\(\!\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\)\) / nocase ascii wide
104
107
// Description: Enumerate all Domain Controllers
105
108
// Reference: https://web.archive.org/web/20240109000256/https://cyberdom.blog/2024/01/07/defender-for-identity-hunting-for-ldap/
106
- $ string32 = /\[ adsisearcher \]\'\(\&\( objectCategory \= computer \)\( primaryGroupID \= 516 \)\)\'\)\. FindAll \(\) / nocase ascii wide
109
+ $ string33 = /\[ adsisearcher \]\'\(\&\( objectCategory \= computer \)\( primaryGroupID \= 516 \)\)\'\)\. FindAll \(\) / nocase ascii wide
107
110
// Description: Enumerate all accounts that do not require a password
108
111
// Reference: https://jsecurity101.medium.com/uncovering-adversarial-ldap-tradecraft-658b2deca384
109
- $ string33 = /\[ adsisearcher \]\'\(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 32 \)\)\'\)\. FindAll \(\) / nocase ascii wide
112
+ $ string34 = /\[ adsisearcher \]\'\(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 32 \)\)\'\)\. FindAll \(\) / nocase ascii wide
110
113
// Description: ADSI query to retrieve all active user accounts with non-expiring passwords
111
114
// Reference: https://github.com/swarleysez/AD-common-queries
112
- $ string34 = /\[ adsisearcher \] . {0,1000 } \(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 66048 \)\(\!\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\) / nocase ascii wide
115
+ $ string35 = /\[ adsisearcher \] . {0,1000 } \(\&\( objectCategory \= person \)\( objectClass \= user \)\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 66048 \)\(\!\( userAccountControl \: 1 \. 2 \. 840 \. 113556 \. 1 \. 4 \. 803 \:\= 2 \)\) / nocase ascii wide
113
116
// Description: Discover all Domain Controller in the domain using ADSI
114
117
// Reference: https://adsecurity.org/?p=299
115
- $ string35 = /\[ System \. DirectoryServices \. ActiveDirectory \. Domain \]\:\: GetCurrentDomain \(\)\. DomainControllers / nocase ascii wide
118
+ $ string36 = /\[ System \. DirectoryServices \. ActiveDirectory \. Domain \]\:\: GetCurrentDomain \(\)\. DomainControllers / nocase ascii wide
116
119
// Description: Discover all Global Catalogs in the forest using ADSI
117
120
// Reference: https://adsecurity.org/?p=299
118
- $ string36 = /\[ System \. DirectoryServices \. ActiveDirectory \. Forest \]\:\: GetCurrentForest \(\)\. GlobalCatalogs / nocase ascii wide
121
+ $ string37 = /\[ System \. DirectoryServices \. ActiveDirectory \. Forest \]\:\: GetCurrentForest \(\)\. GlobalCatalogs / nocase ascii wide
119
122
// Description: query for the primary domain controller within the forest
120
123
// Reference: https://github.com/swarleysez/AD-common-queries
121
- $ string37 = /\[ System \. DirectoryServices \. ActiveDirectory \. Forest \]\:\: GetCurrentForest \(\)\. RootDomain \. PDCRoleOwner \. Name / nocase ascii wide
124
+ $ string38 = /\[ System \. DirectoryServices \. ActiveDirectory \. Forest \]\:\: GetCurrentForest \(\)\. RootDomain \. PDCRoleOwner \. Name / nocase ascii wide
122
125
// Description: cmdlets to get computer information about Domain Controllers
123
126
// Reference: https://adsecurity.org/?p=299
124
- $ string38 = /get \- ADComputer \s \- filter \s \{ \s PrimaryGroupID \s \- eq \s \" 516 \" \s \} \s \- properties \s PrimaryGroupID / nocase ascii wide
127
+ $ string39 = /get \- ADComputer \s \- filter \s \{ \s PrimaryGroupID \s \- eq \s \" 516 \" \s \} \s \- properties \s PrimaryGroupID / nocase ascii wide
125
128
// Description: identifying accounts with 'Password Not Required
126
129
// Reference: https://github.com/swarleysez/AD-common-queries
127
- $ string39 = /Get \- ADUser \s \- filter \s. {0,1000 } \s \- Properties \s SamAccountName \, \s PasswordNotRequired \s \| \s where \s \{ \s \$ _ \. passwordnotrequired \s \- eq \s \" true \" \s \} \s \| \s where \s \{\$ _ \. enabled \s \- eq \s \" true \"\} / nocase ascii wide
130
+ $ string40 = /Get \- ADUser \s \- filter \s. {0,1000 } \s \- Properties \s SamAccountName \, \s PasswordNotRequired \s \| \s where \s \{ \s \$ _ \. passwordnotrequired \s \- eq \s \" true \" \s \} \s \| \s where \s \{\$ _ \. enabled \s \- eq \s \" true \"\} / nocase ascii wide
128
131
// Description: querying accounts that have not been logged into for over 90 days
129
132
// Reference: https://github.com/swarleysez/AD-common-queries
130
- $ string40 = /Get \- ADUser \s \- properties \s. {0,1000 } \s \- filter \s \{\( lastlogondate \s \- notlike \s \" . {0,1000 } \" \s \- OR \s lastlogondate \s \- le \s \$ 90days \) \s \- AND \s \( passwordlastset \s \- le \s \$ 90days \) \s \- AND \s \( enabled \s \- eq \s \$ True \) \s \- and \s \( PasswordNeverExpires \s \- eq \s \$ false \) \s \- and \s \( whencreated \s \- le \s \$ 90days \)\} / nocase ascii wide
133
+ $ string41 = /Get \- ADUser \s \- properties \s. {0,1000 } \s \- filter \s \{\( lastlogondate \s \- notlike \s \" . {0,1000 } \" \s \- OR \s lastlogondate \s \- le \s \$ 90days \) \s \- AND \s \( passwordlastset \s \- le \s \$ 90days \) \s \- AND \s \( enabled \s \- eq \s \$ True \) \s \- and \s \( PasswordNeverExpires \s \- eq \s \$ false \) \s \- and \s \( whencreated \s \- le \s \$ 90days \)\} / nocase ascii wide
131
134
// Description: Red Teams and adversaries may leverage [Adsisearcher] to enumerate domain groups for situational awareness and Active Directory Discovery
132
135
// Reference: https://research.splunk.com/endpoint/089c862f-5f83-49b5-b1c8-7e4ff66560c7/
133
- $ string41 = /powershell . {0,1000 } \[ adsisearcher \] . {0,1000 } \( objectcategory \= group \) . {0,1000 } findAll \(\) / nocase ascii wide
136
+ $ string42 = /powershell . {0,1000 } \[ adsisearcher \] . {0,1000 } \( objectcategory \= group \) . {0,1000 } findAll \(\) / nocase ascii wide
134
137
135
138
condition :
136
139
any of them
0 commit comments