Skip to content

Commit

Permalink
Merge pull request #40 from LuemmelSec/dev
Browse files Browse the repository at this point in the history
Added option to do Session Enumeration as local Admin User
  • Loading branch information
JonasBK authored Oct 30, 2023
2 parents ef2b8b3 + 8040bdd commit cba800e
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 7 deletions.
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 string[] 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 @@ -23,5 +25,6 @@ public class Flags
public bool DCOnly { get; set; }
public bool PrettyPrint { get; set; }
public bool SearchForest { 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 @@ -76,8 +76,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 @@ -38,7 +38,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);

Check failure on line 41 in src/Runtime/ObjectProcessors.cs

View workflow job for this annotation

GitHub Actions / Build (Debug)

The best overload for 'ComputerSessionProcessor' does not have a parameter named 'doLocalAdminSessionEnum'

Check failure on line 41 in src/Runtime/ObjectProcessors.cs

View workflow job for this annotation

GitHub Actions / Build (Debug)

The best overload for 'ComputerSessionProcessor' does not have a parameter named 'doLocalAdminSessionEnum'

Check failure on line 41 in src/Runtime/ObjectProcessors.cs

View workflow job for this annotation

GitHub Actions / Build (Release)

The best overload for 'ComputerSessionProcessor' does not have a parameter named 'doLocalAdminSessionEnum'

Check failure on line 41 in src/Runtime/ObjectProcessors.cs

View workflow job for this annotation

GitHub Actions / Build (Release)

The best overload for 'ComputerSessionProcessor' does not have a parameter named 'doLocalAdminSessionEnum'
_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 @@ -103,7 +103,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 @@ -370,7 +370,8 @@ await options.WithParsedAsync(async options =>
CollectAllProperties = options.CollectAllProperties,
DCOnly = dconly,
PrettyPrint = options.PrettyPrint,
SearchForest = options.SearchForest
SearchForest = options.SearchForest,
DoLocalAdminSessionEnum = options.DoLocalAdminSessionEnum,
};

var ldapOptions = new LDAPConfig
Expand All @@ -395,7 +396,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 @@ -416,7 +448,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

0 comments on commit cba800e

Please sign in to comment.