-
Notifications
You must be signed in to change notification settings - Fork 254
Expand file tree
/
Copy pathOptions.cs
More file actions
297 lines (235 loc) · 13.6 KB
/
Options.cs
File metadata and controls
297 lines (235 loc) · 13.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommandLine;
using Microsoft.Extensions.Logging;
using Sharphound.Client;
using SharpHoundCommonLib.Enums;
namespace Sharphound
{
public class Options
{
// Options that affect what is collected
[Option('c', "collectionmethods", Default = new[] { "Default" },
HelpText =
"Collection Methods: Group, LocalGroup, LocalAdmin, RDP, DCOM, PSRemote, Session, Trusts, ACL, Container, ComputerOnly, GPOLocalGroup, GPOUserRights, LoggedOn, ObjectProps, SPNTargets, UserRights, Default, DCOnly, CARegistry, DCRegistry, CertServices, WebClientService, LdapServices, SmbInfo, NTLMRegistry, All")]
public IEnumerable<string> CollectionMethods { get; set; }
[Option('d', "domain", Default = null, HelpText = "Specify domain to enumerate")]
public string Domain { get; set; }
[Option('s', "searchforest", Default = false, HelpText = "Search all available domains in the forest")]
public bool SearchForest { get; set; }
[Option("recursedomains", Default = false, HelpText = "Recurse domain trusts to search")]
public bool RecurseDomains { get; set; }
[Option(HelpText = "Stealth Collection (Prefer DCOnly whenever possible!)")]
public bool Stealth { get; set; }
[Option('f', "ldapfilter", HelpText = "Add an LDAP filter to the pregenerated filter.", Default = null)]
public string LdapFilter { get; set; }
[Option(HelpText = "Base DistinguishedName to start the LDAP search at", Default = null)]
public string DistinguishedName { get; set; }
[Option(HelpText = "Path to file containing computer names to enumerate", Default = null)]
public string ComputerFile { get; set; }
// Options that affect output of SharpHound
[Option(HelpText = "Directory to output file too", Default = ".")]
public string OutputDirectory { get; set; }
[Option(HelpText = "String to prepend to output file names")]
public string OutputPrefix { get; set; }
[Option(HelpText = "Filename for cache (Defaults to a machine specific identifier)", Default = null)]
public string CacheName { get; set; }
[Option(HelpText = "Keep cache in memory and don't write to disk")]
public bool MemCache { get; set; }
[Option(HelpText = "Rebuild cache and remove all entries", Default = false)]
public bool RebuildCache { get; set; }
[Option(HelpText = "Use random filenames for output", Default = false)]
public bool RandomFileNames { get; set; }
[Option(HelpText = "Filename for the zip", Default = null)]
public string ZipFilename { get; set; }
[Option(HelpText = "Don't zip files", Default = false)]
public bool NoZip { get; set; }
[Option(HelpText = "Password protects the zip with the specified password", Default = null)]
public string ZipPassword { get; set; }
[Option(HelpText = "Adds a CSV tracking requests to computers", Default = false)]
public bool TrackComputerCalls { get; set; }
[Option(HelpText = "Pretty print JSON", Default = false)]
public bool PrettyPrint { get; set; }
// Connection options
[Option(HelpText = "Username for LDAP", Default = null)]
public string LDAPUsername { get; set; }
[Option(HelpText = "Password for LDAP", Default = null)]
public string LDAPPassword { get; set; }
[Option(HelpText = "Do the session enumeration with local admin credentials instead of domain credentials", Default = false)]
public bool DoLocalAdminSessionEnum { get; set; }
[Option(HelpText = "Username for local Administrator to be used if DoLocalAdminSessionEnum is set", Default = null)]
public string LocalAdminUsername { get; set; }
[Option(HelpText = "Password for local Administrator to be used if DoLocalAdminSessionEnum is set", Default = null)]
public string LocalAdminPassword { get; set; }
[Option(HelpText = "Override domain controller to pull LDAP from. This option can result in data loss", Default = null)]
public string DomainController { get; set; }
[Option(HelpText = "Override port for LDAP", Default = 0)]
public int LDAPPort { get; set; }
[Option(HelpText = "Override port for LDAPS", Default = 0)]
public int LDAPSSLPort { get; set; }
[Option(HelpText = "Only connect to LDAP SSL, disallowing fallback", Default = false)]
public bool ForceSecureLDAP { get; set; }
[Option(HelpText = "Disables certificate verification when using LDAPS", Default = false)]
public bool DisableCertVerification { get; set; }
[Option(HelpText = "Disables Kerberos Signing/Sealing", Default = false)]
public bool DisableSigning { get; set; }
//Options that affect how enumeration is performed
[Option(HelpText = "Skip checking if 445 is open", Default = false)]
public bool SkipPortCheck { get; set; }
[Option(HelpText = "Timeout for port checks in milliseconds", Default = 10000)]
public int PortCheckTimeout { get; set; }
[Option(HelpText = "Skip check for PwdLastSet when enumerating computers", Default = false)]
public bool SkipPasswordCheck { get; set; }
[Option(HelpText = "Exclude domain controllers from session/localgroup enumeration (mostly for ATA/ATP)",
Default = false)]
public bool ExcludeDCs { get; set; }
[Option(HelpText = "Add a delay after computer requests in milliseconds")]
public int Throttle { get; set; }
[Option(HelpText = "Add jitter to throttle (percent)")]
public int Jitter { get; set; }
[Option('t', "threads", HelpText = "Number of threads to run enumeration with", Default = 50)]
public int Threads { get; set; }
[Option(HelpText = "Skip registry session enumeration")]
public bool SkipRegistryLoggedOn { get; set; }
[Option(HelpText = "Override the username to filter for NetSessionEnum", Default = null)]
public string OverrideUserName { get; set; }
[Option(HelpText = "Override DNS suffix for API calls")]
public string RealDNSName { get; set; }
[Option(HelpText = "Collect all LDAP properties from objects")]
public bool CollectAllProperties { get; set; }
[Option(HelpText = "Split the main ldap query into smaller chunks to attempt to reduce server load")]
public bool PartitionLdapQueries { get; set; }
//Loop Options
[Option('l', "Loop", HelpText = "Loop computer collection")]
public bool Loop { get; set; }
[Option(HelpText = "Loop duration (hh:mm:ss - 05:00:00 is 5 hours, default: 2 hrs)")]
public TimeSpan LoopDuration { get; set; }
[Option(HelpText = "Add delay between loops (hh:mm:ss - 00:03:00 is 3 minutes)")] public TimeSpan LoopInterval { get; set; }
//Misc Options
[Option(HelpText = "Interval in which to display status in milliseconds", Default = 30000)]
public int StatusInterval { get; set; }
[Option('v', HelpText = "Enable verbose output", Default = (int)LogLevel.Information)]
public int Verbosity { get; set; }
internal bool ResolveCollectionMethods(ILogger logger, out CollectionMethod resolved, out bool dconly)
{
var arr = CollectionMethods.Count() == 1
? CollectionMethods.First().Split(',')
: CollectionMethods.ToArray();
resolved = CollectionMethod.None;
dconly = false;
foreach (var baseMethod in arr)
{
CollectionMethodOptions option;
try
{
option = (CollectionMethodOptions)Enum.Parse(typeof(CollectionMethodOptions), baseMethod, true);
}
catch
{
logger.LogCritical("Failed to parse collection method {baseMethod}", baseMethod);
return false;
}
resolved |= option switch
{
CollectionMethodOptions.Group => CollectionMethod.Group,
CollectionMethodOptions.Session => CollectionMethod.Session,
CollectionMethodOptions.LoggedOn => CollectionMethod.LoggedOn,
CollectionMethodOptions.Trusts => CollectionMethod.Trusts,
CollectionMethodOptions.ACL => CollectionMethod.ACL,
CollectionMethodOptions.ObjectProps => CollectionMethod.ObjectProps,
CollectionMethodOptions.RDP => CollectionMethod.RDP,
CollectionMethodOptions.DCOM => CollectionMethod.DCOM,
CollectionMethodOptions.LocalAdmin => CollectionMethod.LocalAdmin,
CollectionMethodOptions.PSRemote => CollectionMethod.PSRemote,
CollectionMethodOptions.SPNTargets => CollectionMethod.SPNTargets,
CollectionMethodOptions.Container => CollectionMethod.Container,
CollectionMethodOptions.GPOLocalGroup => CollectionMethod.GPOLocalGroup,
CollectionMethodOptions.GPOUserRights => CollectionMethod.GPOUserRights,
CollectionMethodOptions.LocalGroup => CollectionMethod.LocalGroups,
CollectionMethodOptions.UserRights => CollectionMethod.UserRights,
CollectionMethodOptions.Default => CollectionMethod.Default,
CollectionMethodOptions.DCOnly => CollectionMethod.DCOnly,
CollectionMethodOptions.ComputerOnly => CollectionMethod.ComputerOnly,
CollectionMethodOptions.CARegistry => CollectionMethod.CARegistry,
CollectionMethodOptions.DCRegistry => CollectionMethod.DCRegistry,
CollectionMethodOptions.CertServices => CollectionMethod.CertServices,
CollectionMethodOptions.WebClientService => CollectionMethod.WebClientService,
CollectionMethodOptions.LdapServices => CollectionMethod.LdapServices,
CollectionMethodOptions.SmbInfo => CollectionMethod.SmbInfo,
CollectionMethodOptions.NTLMRegistry => CollectionMethod.NTLMRegistry,
// Re-introduce this when we're ready for Event Log collection
// CollectionMethodOptions.EventLogs => CollectionMethod.EventLogs,
CollectionMethodOptions.All => CollectionMethod.All,
CollectionMethodOptions.None => CollectionMethod.None,
_ => throw new ArgumentOutOfRangeException()
};
if (option == CollectionMethodOptions.DCOnly) dconly = true;
}
if (Stealth)
{
var updates = new List<string>();
if ((resolved & CollectionMethod.LoggedOn) != 0)
{
resolved ^= CollectionMethod.LoggedOn;
updates.Add("[-] Removed LoggedOn");
}
var localGroupRemoved = false;
if ((resolved & CollectionMethod.RDP) != 0)
{
localGroupRemoved = true;
resolved ^= CollectionMethod.RDP;
updates.Add("[-] Removed RDP Collection");
}
if ((resolved & CollectionMethod.DCOM) != 0)
{
localGroupRemoved = true;
resolved ^= CollectionMethod.DCOM;
updates.Add("[-] Removed DCOM Collection");
}
if ((resolved & CollectionMethod.PSRemote) != 0)
{
localGroupRemoved = true;
resolved ^= CollectionMethod.PSRemote;
updates.Add("[-] Removed PSRemote Collection");
}
if ((resolved & CollectionMethod.LocalAdmin) != 0)
{
localGroupRemoved = true;
resolved ^= CollectionMethod.LocalAdmin;
updates.Add("[-] Removed LocalAdmin Collection");
}
if ((resolved & CollectionMethod.CARegistry) != 0)
{
resolved ^= CollectionMethod.CARegistry;
updates.Add("[-] Removed CARegistry Collection");
}
if ((resolved & CollectionMethod.DCRegistry) != 0)
{
resolved ^= CollectionMethod.DCRegistry;
updates.Add("[-] Removed DCRegistry Collection");
}
if ((resolved & CollectionMethod.NTLMRegistry) != 0)
{
resolved ^= CollectionMethod.NTLMRegistry;
updates.Add("[-] Removed NTLMRegistry Collection");
}
if (localGroupRemoved)
{
resolved |= CollectionMethod.GPOLocalGroup;
updates.Add("[+] Added GPOLocalGroup");
}
if (updates.Count > 0)
{
var updateString = new StringBuilder();
updateString.AppendLine("Updated Collection Methods to Reflect Stealth Options");
foreach (var update in updates) updateString.AppendLine(update);
logger.LogInformation("{Update}", updateString.ToString());
}
}
logger.LogInformation("Resolved Collection Methods: {resolved}", resolved.GetIndividualFlags());
return true;
}
}
}