Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session Enumeration as local Admin User #72

Merged
merged 1 commit into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ dotnet build

--statusinterval (Default: 30000) Interval in which to display status in milliseconds

--localadminsessionenum Specify if you want to use a dedicated LOCAL user for session enumeration

--localadminusername Specify the username of the localadmin for session enumeration

--localadminpassword Specify the password of the localadmin for session enumeration

-v (Default: 2) Enable verbose output. Lower is more verbose

--help Display this help screen.
Expand Down
3 changes: 3 additions & 0 deletions src/BaseContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ public string ResolveFileName(string filename, string extension, bool addTimesta
}

public EnumerationDomain[] Domains { get; set; }
public string LocalAdminUsername { get; set; }
public string LocalAdminPassword { get; set; }
public bool LocalAdminSessionEnum { get; set; }

// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
// ~Context()
Expand Down
4 changes: 4 additions & 0 deletions src/Client/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ public interface IContext
int Jitter { get; set; }
int PortScanTimeout { get; set; }

public string LocalAdminUsername { get; set; }

public string LocalAdminPassword { get; set; }

ResolvedCollectionMethod ResolvedCollectionMethods { get; set; }

/// <summary>
Expand Down
5 changes: 4 additions & 1 deletion src/Client/Flags.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Sharphound.Client
using SharpHoundCommonLib.OutputTypes;

namespace Sharphound.Client
{
public class Flags
{
Expand All @@ -24,5 +26,6 @@ public class Flags
public bool PrettyPrint { get; set; }
public bool SearchForest { get; set; }
public bool RecurseDomains { get; set; }
public bool DoLocalAdminSessionEnum { get; set; }
}
}
12 changes: 10 additions & 2 deletions src/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,16 @@ public class Options
[Option(HelpText = "Password for LDAP", Default = null)]
public string LDAPPassword { get; set; }

[Option(HelpText = "Override domain controller to pull LDAP from. This option can result in data loss",
Default = null)]
[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)]
Expand Down
2 changes: 1 addition & 1 deletion src/Runtime/ObjectProcessors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public ObjectProcessors(IContext context, ILogger log)
_ldapPropertyProcessor = new LDAPPropertyProcessor(context.LDAPUtils);
_domainTrustProcessor = new DomainTrustProcessor(context.LDAPUtils);
_computerAvailability = new ComputerAvailability(context.PortScanTimeout, skipPortScan: context.Flags.SkipPortScan, skipPasswordCheck: context.Flags.SkipPasswordAgeCheck);
_computerSessionProcessor = new ComputerSessionProcessor(context.LDAPUtils);
_computerSessionProcessor = new ComputerSessionProcessor(context.LDAPUtils, doLocalAdminSessionEnum: context.Flags.DoLocalAdminSessionEnum, localAdminUsername: context.LocalAdminUsername, localAdminPassword: context.LocalAdminPassword);
_groupProcessor = new GroupProcessor(context.LDAPUtils);
_containerProcessor = new ContainerProcessor(context.LDAPUtils);
_gpoLocalGroupProcessor = new GPOLocalGroupProcessor(context.LDAPUtils);
Expand Down
41 changes: 38 additions & 3 deletions src/Sharphound.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public IContext Initialize(IContext context, LDAPConfig options)
context.Flags.IsFaulted = true;
return context;
}

//Check some loop options
if (!context.Flags.Loop) return context;
//If loop is set, ensure we actually set options properly
Expand Down Expand Up @@ -429,7 +429,8 @@ await options.WithParsedAsync(async options =>
DCOnly = dconly,
PrettyPrint = options.PrettyPrint,
SearchForest = options.SearchForest,
RecurseDomains = options.RecurseDomains
RecurseDomains = options.RecurseDomains,
DoLocalAdminSessionEnum = options.DoLocalAdminSessionEnum
};

var ldapOptions = new LDAPConfig
Expand All @@ -454,7 +455,38 @@ await options.WithParsedAsync(async options =>
ldapOptions.Username = options.LDAPUsername;
ldapOptions.Password = options.LDAPPassword;
}

// Check to make sure both Local Admin Session Enum options are set if either is set

if (options.LocalAdminPassword != null && options.LocalAdminUsername == null ||
options.LocalAdminUsername != null && options.LocalAdminPassword == null)
{
logger.LogError("You must specify both LocalAdminUsername and LocalAdminPassword if using these options!");
return;
}

// Check to make sure doLocalAdminSessionEnum is set when specifying localadmin and password

if (options.LocalAdminPassword != null || options.LocalAdminUsername != null)
{
if (options.DoLocalAdminSessionEnum == false)
{
logger.LogError("You must use the --doLocalAdminSessionEnum switch in combination with --LocalAdminUsername and --LocalAdminPassword!");
return;
}
}

// Check to make sure LocalAdminUsername and LocalAdminPassword are set when using doLocalAdminSessionEnum

if (options.DoLocalAdminSessionEnum == true)
{
if (options.LocalAdminPassword == null || options.LocalAdminUsername == null)
{
logger.LogError("You must specify both LocalAdminUsername and LocalAdminPassword if using the --doLocalAdminSessionEnum option!");
return;
}
}

IContext context = new BaseContext(logger, ldapOptions, flags)
{
DomainName = options.Domain,
Expand All @@ -475,7 +507,10 @@ await options.WithParsedAsync(async options =>
LoopDuration = options.LoopDuration,
LoopInterval = options.LoopInterval,
ZipPassword = options.ZipPassword,
IsFaulted = false
IsFaulted = false,
LocalAdminUsername = options.LocalAdminUsername,
LocalAdminPassword = options.LocalAdminPassword

};

var cancellationTokenSource = new CancellationTokenSource();
Expand Down
Loading