Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/js/libs/ldap/adenum.go
2070 views
1
package ldap
2
3
import (
4
"fmt"
5
"strings"
6
7
"github.com/go-ldap/ldap/v3"
8
)
9
10
// LDAP makes you search using an OID
11
// http://oid-info.com/get/1.2.840.113556.1.4.803
12
//
13
// The one for the userAccountControl in MS Active Directory is
14
// 1.2.840.113556.1.4.803 (LDAP_MATCHING_RULE_BIT_AND)
15
//
16
// We can look at the enabled flags using a query like (!(userAccountControl:1.2.840.113556.1.4.803:=2))
17
//
18
// https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties
19
const (
20
FilterIsPerson = "(objectCategory=person)" // The object is a person.
21
FilterIsGroup = "(objectCategory=group)" // The object is a group.
22
FilterIsComputer = "(objectCategory=computer)" // The object is a computer.
23
FilterIsAdmin = "(adminCount=1)" // The object is an admin.
24
FilterHasServicePrincipalName = "(servicePrincipalName=*)" // The object has a service principal name.
25
FilterLogonScript = "(userAccountControl:1.2.840.113556.1.4.803:=1)" // The logon script will be run.
26
FilterAccountDisabled = "(userAccountControl:1.2.840.113556.1.4.803:=2)" // The user account is disabled.
27
FilterAccountEnabled = "(!(userAccountControl:1.2.840.113556.1.4.803:=2))" // The user account is enabled.
28
FilterHomedirRequired = "(userAccountControl:1.2.840.113556.1.4.803:=8)" // The home folder is required.
29
FilterLockout = "(userAccountControl:1.2.840.113556.1.4.803:=16)" // The user is locked out.
30
FilterPasswordNotRequired = "(userAccountControl:1.2.840.113556.1.4.803:=32)" // No password is required.
31
FilterPasswordCantChange = "(userAccountControl:1.2.840.113556.1.4.803:=64)" // The user can't change the password.
32
FilterCanSendEncryptedPassword = "(userAccountControl:1.2.840.113556.1.4.803:=128)" // The user can send an encrypted password.
33
FilterIsDuplicateAccount = "(userAccountControl:1.2.840.113556.1.4.803:=256)" // It's an account for users whose primary account is in another domain.
34
FilterIsNormalAccount = "(userAccountControl:1.2.840.113556.1.4.803:=512)" // It's a default account type that represents a typical user.
35
FilterInterdomainTrustAccount = "(userAccountControl:1.2.840.113556.1.4.803:=2048)" // It's a permit to trust an account for a system domain that trusts other domains.
36
FilterWorkstationTrustAccount = "(userAccountControl:1.2.840.113556.1.4.803:=4096)" // It's a computer account for a computer that is running old Windows builds.
37
FilterServerTrustAccount = "(userAccountControl:1.2.840.113556.1.4.803:=8192)" // It's a computer account for a domain controller that is a member of this domain.
38
FilterDontExpirePassword = "(userAccountControl:1.2.840.113556.1.4.803:=65536)" // Represents the password, which should never expire on the account.
39
FilterMnsLogonAccount = "(userAccountControl:1.2.840.113556.1.4.803:=131072)" // It's an MNS logon account.
40
FilterSmartCardRequired = "(userAccountControl:1.2.840.113556.1.4.803:=262144)" // When this flag is set, it forces the user to log on by using a smart card.
41
FilterTrustedForDelegation = "(userAccountControl:1.2.840.113556.1.4.803:=524288)" // When this flag is set, the service account (the user or computer account) under which a service runs is trusted for Kerberos delegation.
42
FilterNotDelegated = "(userAccountControl:1.2.840.113556.1.4.803:=1048576)" // When this flag is set, the security context of the user isn't delegated to a service even if the service account is set as trusted for Kerberos delegation.
43
FilterUseDesKeyOnly = "(userAccountControl:1.2.840.113556.1.4.803:=2097152)" // Restrict this principal to use only Data Encryption Standard (DES) encryption types for keys.
44
FilterDontRequirePreauth = "(userAccountControl:1.2.840.113556.1.4.803:=4194304)" // This account doesn't require Kerberos pre-authentication for logging on.
45
FilterPasswordExpired = "(userAccountControl:1.2.840.113556.1.4.803:=8388608)" // The user's password has expired.
46
FilterTrustedToAuthForDelegation = "(userAccountControl:1.2.840.113556.1.4.803:=16777216)" // The account is enabled for delegation.
47
FilterPartialSecretsAccount = "(userAccountControl:1.2.840.113556.1.4.803:=67108864)" // The account is a read-only domain controller (RODC).
48
49
)
50
51
// JoinFilters joins multiple filters into a single filter
52
// @example
53
// ```javascript
54
// const ldap = require('nuclei/ldap');
55
// const filter = ldap.JoinFilters(ldap.FilterIsPerson, ldap.FilterAccountEnabled);
56
// ```
57
func JoinFilters(filters ...string) string {
58
var builder strings.Builder
59
builder.WriteString("(&")
60
for _, s := range filters {
61
builder.WriteString(s)
62
}
63
builder.WriteString(")")
64
return builder.String()
65
}
66
67
// NegativeFilter returns a negative filter for a given filter
68
// @example
69
// ```javascript
70
// const ldap = require('nuclei/ldap');
71
// const filter = ldap.NegativeFilter(ldap.FilterIsPerson);
72
// ```
73
func NegativeFilter(filter string) string {
74
return fmt.Sprintf("(!%s)", filter)
75
}
76
77
// FindADObjects finds AD objects based on a filter
78
// and returns them as a list of ADObject
79
// @example
80
// ```javascript
81
// const ldap = require('nuclei/ldap');
82
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
83
// const users = client.FindADObjects(ldap.FilterIsPerson);
84
// log(to_json(users));
85
// ```
86
func (c *Client) FindADObjects(filter string) SearchResult {
87
c.nj.Require(c.conn != nil, "no existing connection")
88
sr := ldap.NewSearchRequest(
89
c.BaseDN, ldap.ScopeWholeSubtree,
90
ldap.NeverDerefAliases, 0, 0, false,
91
filter,
92
[]string{
93
"distinguishedName",
94
"sAMAccountName",
95
"pwdLastSet",
96
"lastLogon",
97
"memberOf",
98
"servicePrincipalName",
99
},
100
nil,
101
)
102
103
res, err := c.conn.Search(sr)
104
c.nj.HandleError(err, "ldap search request failed")
105
return *getSearchResult(res)
106
}
107
108
// GetADUsers returns all AD users
109
// using FilterIsPerson filter query
110
// @example
111
// ```javascript
112
// const ldap = require('nuclei/ldap');
113
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
114
// const users = client.GetADUsers();
115
// log(to_json(users));
116
// ```
117
func (c *Client) GetADUsers() SearchResult {
118
return c.FindADObjects(FilterIsPerson)
119
}
120
121
// GetADActiveUsers returns all AD users
122
// using FilterIsPerson and FilterAccountEnabled filter query
123
// @example
124
// ```javascript
125
// const ldap = require('nuclei/ldap');
126
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
127
// const users = client.GetADActiveUsers();
128
// log(to_json(users));
129
// ```
130
func (c *Client) GetADActiveUsers() SearchResult {
131
return c.FindADObjects(JoinFilters(FilterIsPerson, FilterAccountEnabled))
132
}
133
134
// GetAdUserWithNeverExpiringPasswords returns all AD users
135
// using FilterIsPerson and FilterDontExpirePassword filter query
136
// @example
137
// ```javascript
138
// const ldap = require('nuclei/ldap');
139
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
140
// const users = client.GetADUserWithNeverExpiringPasswords();
141
// log(to_json(users));
142
// ```
143
func (c *Client) GetADUserWithNeverExpiringPasswords() SearchResult {
144
return c.FindADObjects(JoinFilters(FilterIsPerson, FilterDontExpirePassword))
145
}
146
147
// GetADUserTrustedForDelegation returns all AD users that are trusted for delegation
148
// using FilterIsPerson and FilterTrustedForDelegation filter query
149
// @example
150
// ```javascript
151
// const ldap = require('nuclei/ldap');
152
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
153
// const users = client.GetADUserTrustedForDelegation();
154
// log(to_json(users));
155
// ```
156
func (c *Client) GetADUserTrustedForDelegation() SearchResult {
157
return c.FindADObjects(JoinFilters(FilterIsPerson, FilterTrustedForDelegation))
158
}
159
160
// GetADUserWithPasswordNotRequired returns all AD users that do not require a password
161
// using FilterIsPerson and FilterPasswordNotRequired filter query
162
// @example
163
// ```javascript
164
// const ldap = require('nuclei/ldap');
165
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
166
// const users = client.GetADUserWithPasswordNotRequired();
167
// log(to_json(users));
168
// ```
169
func (c *Client) GetADUserWithPasswordNotRequired() SearchResult {
170
return c.FindADObjects(JoinFilters(FilterIsPerson, FilterPasswordNotRequired))
171
}
172
173
// GetADGroups returns all AD groups
174
// using FilterIsGroup filter query
175
// @example
176
// ```javascript
177
// const ldap = require('nuclei/ldap');
178
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
179
// const groups = client.GetADGroups();
180
// log(to_json(groups));
181
// ```
182
func (c *Client) GetADGroups() SearchResult {
183
return c.FindADObjects(FilterIsGroup)
184
}
185
186
// GetADDCList returns all AD domain controllers
187
// using FilterIsComputer, FilterAccountEnabled and FilterServerTrustAccount filter query
188
// @example
189
// ```javascript
190
// const ldap = require('nuclei/ldap');
191
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
192
// const dcs = client.GetADDCList();
193
// log(to_json(dcs));
194
// ```
195
func (c *Client) GetADDCList() SearchResult {
196
return c.FindADObjects(JoinFilters(FilterIsComputer, FilterAccountEnabled, FilterServerTrustAccount))
197
}
198
199
// GetADAdmins returns all AD admins
200
// using FilterIsPerson, FilterAccountEnabled and FilterIsAdmin filter query
201
// @example
202
// ```javascript
203
// const ldap = require('nuclei/ldap');
204
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
205
// const admins = client.GetADAdmins();
206
// log(to_json(admins));
207
// ```
208
func (c *Client) GetADAdmins() SearchResult {
209
return c.FindADObjects(JoinFilters(FilterIsPerson, FilterAccountEnabled, FilterIsAdmin))
210
}
211
212
// GetADUserKerberoastable returns all AD users that are kerberoastable
213
// using FilterIsPerson, FilterAccountEnabled and FilterHasServicePrincipalName filter query
214
// @example
215
// ```javascript
216
// const ldap = require('nuclei/ldap');
217
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
218
// const kerberoastable = client.GetADUserKerberoastable();
219
// log(to_json(kerberoastable));
220
// ```
221
func (c *Client) GetADUserKerberoastable() SearchResult {
222
return c.FindADObjects(JoinFilters(FilterIsPerson, FilterAccountEnabled, FilterHasServicePrincipalName))
223
}
224
225
// GetADUserAsRepRoastable returns all AD users that are AsRepRoastable
226
// using FilterIsPerson, and FilterDontRequirePreauth filter query
227
// @example
228
// ```javascript
229
// const ldap = require('nuclei/ldap');
230
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
231
// const AsRepRoastable = client.GetADUserAsRepRoastable();
232
// log(to_json(AsRepRoastable));
233
// ```
234
func (c *Client) GetADUserAsRepRoastable() SearchResult {
235
return c.FindADObjects(JoinFilters(FilterIsPerson, FilterDontRequirePreauth))
236
}
237
238
// GetADDomainSID returns the SID of the AD domain
239
// @example
240
// ```javascript
241
// const ldap = require('nuclei/ldap');
242
// const client = new ldap.Client('ldap://ldap.example.com', 'acme.com');
243
// const domainSID = client.GetADDomainSID();
244
// log(domainSID);
245
// ```
246
func (c *Client) GetADDomainSID() string {
247
r := c.Search(FilterServerTrustAccount, "objectSid")
248
c.nj.Require(len(r.Entries) > 0, "no result from GetADDomainSID query")
249
for _, entry := range r.Entries {
250
if sid, ok := entry.Attributes.Extra["objectSid"]; ok {
251
if sid, ok := sid.([]string); ok {
252
return DecodeSID(sid[0])
253
} else {
254
c.nj.HandleError(fmt.Errorf("invalid objectSid type: %T", entry.Attributes.Extra["objectSid"]), "invalid objectSid type")
255
}
256
}
257
}
258
c.nj.HandleError(fmt.Errorf("no objectSid found"), "no objectSid found")
259
return ""
260
}
261
262