Skip to content

Commit

Permalink
wip: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rvazarkar committed Jun 7, 2024
1 parent ea6b097 commit ee7d009
Show file tree
Hide file tree
Showing 11 changed files with 674 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/CommonLib/Enums/LdapErrorCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
public enum LdapErrorCodes : int
{
Success = 0,
InvalidCredentials = 49,
Busy = 51,
ServerDown = 81,
LocalError = 82,
Expand Down
12 changes: 12 additions & 0 deletions src/CommonLib/Enums/LdapFailureReason.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace SharpHoundCommonLib.Enums;

public enum LdapFailureReason
{
None,
NoData,
FailedBind,
FailedRequest,
FailedAuthentication,
AuthenticationException,
Unknown
}
8 changes: 8 additions & 0 deletions src/CommonLib/Enums/NamingContexts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace SharpHoundCommonLib.Enums;

public enum NamingContexts
{
Default,
Configuration,
Schema,
}
2 changes: 2 additions & 0 deletions src/CommonLib/Exceptions/LdapAuthenticationException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ namespace SharpHoundCommonLib.Exceptions
{
public class LdapAuthenticationException : Exception
{
public readonly LdapException LdapException;
public LdapAuthenticationException(LdapException exception) : base("Error authenticating to LDAP", exception)
{
LdapException = exception;
}
}
}
4 changes: 1 addition & 3 deletions src/CommonLib/Exceptions/NoLdapDataException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ namespace SharpHoundCommonLib.Exceptions
{
public class NoLdapDataException : Exception
{
public int ErrorCode { get; set; }
public NoLdapDataException(int errorCode)
public NoLdapDataException()
{
ErrorCode = errorCode;
}
}
}
41 changes: 39 additions & 2 deletions src/CommonLib/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,42 @@ public static int Rid(this SecurityIdentifier securityIdentifier)
return rid;
}

public static bool GetNamingContextSearchBase(this LdapConnection connection, NamingContexts context,
out string searchBase)
{
var searchRequest =
new SearchRequest("", new LDAPFilter().AddAllObjects().GetFilter(), SearchScope.Base, null);
searchRequest.Controls.Add(new SearchOptionsControl(SearchOption.DomainScope));
SearchResponse response;
try
{
response = (SearchResponse)connection.SendRequest(searchRequest);
}
catch
{
searchBase = "";
return false;
}

if (response?.Entries == null || response.Entries.Count == 0)
{
searchBase = "";
return false;
}

var entry = response.Entries[0];
searchBase = context switch
{
NamingContexts.Default => entry.GetProperty(LDAPProperties.DefaultNamingContext),
NamingContexts.Configuration => entry.GetProperty(LDAPProperties.ConfigurationNamingContext),
NamingContexts.Schema => entry.GetProperty(LDAPProperties.SchemaNamingContext),
_ => throw new ArgumentOutOfRangeException(nameof(context), context, null)
};

searchBase = searchBase?.Trim().ToUpper();
return searchBase != null;
}

#region SearchResultEntry

/// <summary>
Expand Down Expand Up @@ -392,7 +428,8 @@ public static Label GetLabel(this SearchResultEntry entry)
objectType = Label.AIACA;
else if (entry.DistinguishedName.Contains(DirectoryPaths.NTAuthStoreLocation))
objectType = Label.NTAuthStore;
}else if (objectClasses.Contains(OIDContainerClass, StringComparer.InvariantCultureIgnoreCase))
}
else if (objectClasses.Contains(OIDContainerClass, StringComparer.InvariantCultureIgnoreCase))
{
if (entry.DistinguishedName.StartsWith(DirectoryPaths.OIDContainerLocation,
StringComparison.InvariantCultureIgnoreCase))
Expand All @@ -401,7 +438,7 @@ public static Label GetLabel(this SearchResultEntry entry)
{
if (entry.GetPropertyAsInt(LDAPProperties.Flags, out var flags) && flags == 2)
{
objectType = Label.IssuancePolicy;
objectType = Label.IssuancePolicy;
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/CommonLib/LDAPProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ public static class LDAPProperties
public const string CertificateTemplates = "certificatetemplates";
public const string CrossCertificatePair = "crosscertificatepair";
public const string Flags = "flags";
public const string DefaultNamingContext = "defaultnamingcontext";
public const string RootDomainNamingContext = "rootdomainnamingcontext";
public const string ConfigurationNamingContext = "configurationnamingcontext";
public const string SchemaNamingContext = "schemanamingcontext";
public const string NetbiosName = "netbiosName";
public const string DnsRoot = "dnsroot";
public const string ServerName = "servername";
Expand Down
21 changes: 13 additions & 8 deletions src/CommonLib/LDAPUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public LDAPUtils(NativeMethods nativeMethods = null, PortScanner scanner = null,
/// <exception cref="Exception"></exception>
public void SetLDAPConfig(LDAPConfig config)
{
_ldapConfig = config ?? throw new Exception("LDAP Configuration can not be null");
_ldapConfig = config ?? throw new ArgumentNullException(nameof(config), "LDAP Configuration can not be null");
//Close out any existing LDAP connections to request a new incoming config
foreach (var kv in _ldapConnections)
{
Expand Down Expand Up @@ -1517,6 +1517,7 @@ private async Task<LdapConnectionWrapper> CreateLDAPConnectionWrapper(string dom
//If a server has been manually specified, we should never get past this block for opsec reasons
if (_ldapConfig.Server != null)
{
_log.LogInformation("Server is set via config, attempting to create ldap connection to {Server}", _ldapConfig.Server);
if (!skipCache)
{
if (GetCachedConnection(_ldapConfig.Server, globalCatalog, out var conn))
Expand All @@ -1526,11 +1527,14 @@ private async Task<LdapConnectionWrapper> CreateLDAPConnectionWrapper(string dom
}

var singleServerConn = CreateLDAPConnection(_ldapConfig.Server, authType, globalCatalog);
if (singleServerConn == null) return new LdapConnectionWrapper()
{
Connection = null,
DomainInfo = null
};
if (singleServerConn == null) {
return new LdapConnectionWrapper
{
Connection = null,
DomainInfo = null
};
}

var cacheKey = new LDAPConnectionCacheKey(_ldapConfig.Server, globalCatalog);
_ldapConnections.AddOrUpdate(cacheKey, singleServerConn, (_, ldapConnection) =>
{
Expand All @@ -1546,6 +1550,7 @@ private async Task<LdapConnectionWrapper> CreateLDAPConnectionWrapper(string dom
//If our domain is STILL null, we're not going to get anything reliable, so exit out
if (domain == null)
{
_log.LogWarning("Initial domain name for new LDAP connection is null and/or unresolvable. Unable to create a new connection");
return new LdapConnectionWrapper
{
Connection = null,
Expand All @@ -1560,6 +1565,8 @@ private async Task<LdapConnectionWrapper> CreateLDAPConnectionWrapper(string dom
return conn;
}
}

_log.LogInformation("No cached LDAP connection found for {Domain}, attempting a new connection", domain);

var connectionWrapper = CreateLDAPConnection(domain, authType, globalCatalog);
//If our connection isn't null, it means we have a good connection
Expand Down Expand Up @@ -1669,7 +1676,6 @@ private async Task<LdapConnectionWrapper> CreateLDAPConnectionWithPortCheck(stri
await _portScanner.CheckPort(target, _ldapConfig.GetGCPort(false))))
{
return CreateLDAPConnection(target, authType, true);

}
}
else
Expand All @@ -1682,7 +1688,6 @@ await _portScanner.CheckPort(target, _ldapConfig.GetGCPort(false))))

return null;
}


private LdapConnectionWrapper CreateLDAPConnection(string target, AuthType authType, bool globalCatalog)
{
Expand Down
Loading

0 comments on commit ee7d009

Please sign in to comment.