private void AddDnsAdmins(GraphObjectReference objectReference) { string[] properties = new string[] { "name", "objectSid" }; bool dnsAdminFound = false; WorkOnReturnedObjectByADWS callback = (ADItem x) => { objectReference.Objects[CompromiseGraphDataTypology.PrivilegedAccount].Add(new GraphSingleObject(x.ObjectSid.Value, GraphObjectReference.DnsAdministrators, CompromiseGraphDataObjectRisk.Medium)); dnsAdminFound = true; }; // we do a one level search just case the group is in the default position adws.Enumerate("CN=Users," + domainInfo.DefaultNamingContext, "(&(objectClass=group)(description=DNS Administrators Group))", properties, callback, "OneLevel"); if (!dnsAdminFound) { adws.Enumerate("CN=Users," + domainInfo.DefaultNamingContext, "(&(objectClass=group)(sAMAccountName=DNSAdmins))", properties, callback, "OneLevel"); } if (!dnsAdminFound) { // then full tree. This is an optimization for LDAP request adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectClass=group)(description=DNS Administrators Group))", properties, callback); } if (!dnsAdminFound) { adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectClass=group)(sAMAccountName=DNSAdmins))", properties, callback); } }
public void Export(string filename) { ADDomainInfo domainInfo = null; using (ADWebService adws = new ADWebService(Server, Port, Credential)) { domainInfo = adws.DomainInfo; DisplayAdvancement("Iterating through user objects (all except disabled ones)"); string[] properties = new string[] { "DistinguishedName", "sAMAccountName", "userAccountControl", "whenCreated", "lastLogonTimestamp", }; using (var sw = File.CreateText(filename)) { sw.WriteLine("SAMAccountName\tDN\tWhen Created\tLast Logon Timestamp"); WorkOnReturnedObjectByADWS callback = (ADItem x) => { sw.WriteLine(x.SAMAccountName + "\t" + x.DistinguishedName + "\t" + x.WhenCreated.ToString("u") + "\t" + x.LastLogonTimestamp.ToString("u") + "\t" + x.PwdLastSet.ToString("u")); }; adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectClass=user)(objectCategory=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(sAMAccountName=krbtgt)))", properties, callback); } DisplayAdvancement("Done"); } }
private void BuildDirectDelegationData() { if (domainInfo.ForestFunctionality < 2) { return; } var map = new Dictionary <string, List <string> >(StringComparer.OrdinalIgnoreCase); WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { foreach (var d in aditem.msDSAllowedToDelegateTo) { var spn = d.Split('/'); if (spn.Length < 2) { continue; } if (!map.ContainsKey(spn[1])) { map[spn[1]] = new List <string>(); } var sid = aditem.ObjectSid.Value; if (!map[spn[1]].Contains(sid)) { map[spn[1]].Add(sid); } } }; adws.Enumerate(domainInfo.DefaultNamingContext, "(&(msDS-AllowedToDelegateTo=*)((userAccountControl:1.2.840.113556.1.4.804:=16777216)))", new string[] { "objectSid", "msDS-AllowedToDelegateTo" }, callback); RelationFactory.InitializeDelegation(map); }
List <string> GetListOfComputerToExplore() { ADDomainInfo domainInfo = null; List <string> computers = new List <string>(); using (ADWebService adws = new ADWebService(Server, Port, Credential)) { domainInfo = adws.DomainInfo; string[] properties = new string[] { "dNSHostName", "primaryGroupID" }; WorkOnReturnedObjectByADWS callback = (ADItem x) => { computers.Add(x.DNSHostName); }; string filterClause = null; switch (ScanningMode) { case 3: filterClause = "(!(operatingSystem=*server*))"; break; case 4: filterClause = "(operatingSystem=*server*)"; break; } adws.Enumerate(domainInfo.DefaultNamingContext, "(&(ObjectCategory=computer)" + filterClause + "(!userAccountControl:1.2.840.113556.1.4.803:=2)(lastLogonTimeStamp>=" + DateTime.Now.AddDays(-60).ToFileTimeUtc() + "))", properties, callback); } return(computers); }
private ADDomainInfo GetDomainInformation(ADWebService adws) { ADDomainInfo domainInfo = null; domainInfo = adws.DomainInfo; if (adws.useLdap) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Performance warning: using LDAP instead of ADWS"); Console.ResetColor(); } // adding the domain sid string[] properties = new string[] { "objectSid", }; WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { domainInfo.DomainSid = aditem.ObjectSid; }; adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectClass=domain)(distinguishedName=" + domainInfo.DefaultNamingContext + "))", properties, callback); // adding the domain Netbios name string[] propertiesNetbios = new string[] { "nETBIOSName" }; adws.Enumerate("CN=Partitions," + domainInfo.ConfigurationNamingContext, "(&(objectCategory=crossRef)(systemFlags:1.2.840.113556.1.4.803:=3)(nETBIOSName=*)(nCName=" + domainInfo.DefaultNamingContext + "))", propertiesNetbios, (ADItem aditem) => { domainInfo.NetBIOSName = aditem.NetBIOSName; } , "OneLevel"); return(domainInfo); }
public void Export(string filename) { DisplayAdvancement("Starting"); using (ADWebService adws = new ADWebService(Server, Port, Credential)) { string[] propertiesLaps = new string[] { "schemaIDGUID" }; // note: the LDAP request does not contain ms-MCS-AdmPwd because in the old time, MS consultant was installing customized version of the attriute, * being replaced by the company name // check the oid instead ? (which was the same even if the attribute name was not) adws.Enumerate(adws.DomainInfo.SchemaNamingContext, "(name=ms-*-AdmPwd)", propertiesLaps, (ADItem aditem) => { LAPSSchemaId = aditem.SchemaIDGUID; }, "OneLevel"); using (StreamWriter sw = File.CreateText(filename)) { sw.WriteLine("DistinguishedName\tIdentity\tAccessRule"); var domainInfo = adws.DomainInfo; EnrichDomainInfo(adws, domainInfo); BuildUserList(adws, domainInfo); WorkOnReturnedObjectByADWS callback = ((ADItem x) => { if (x.NTSecurityDescriptor != null) { var Owner = x.NTSecurityDescriptor.GetOwner(typeof(SecurityIdentifier)); var match = MatchesUsersToCheck(Owner); if (match != null) { sw.WriteLine(x.DistinguishedName + "\t" + match.Value.Value + "\tOwner"); } foreach (ActiveDirectoryAccessRule accessrule in x.NTSecurityDescriptor.GetAccessRules(true, false, typeof(SecurityIdentifier))) { // ignore audit / denied ace if (accessrule.AccessControlType != AccessControlType.Allow) { continue; } match = MatchesUsersToCheck(accessrule.IdentityReference); if (!match.HasValue) { continue; } if (MatchesBadACL(accessrule)) { sw.WriteLine(x.DistinguishedName + "\t" + match.Value.Value + "\t" + accessrule.ActiveDirectoryRights.ToString()); } } } } ); DisplayAdvancement("Analyzing AD Objects"); adws.Enumerate(domainInfo.DefaultNamingContext, "(objectClass=*)", new string[] { "distinguishedName", "nTSecurityDescriptor" }, callback); DisplayAdvancement("Analyzing files"); CheckFilePermission(domainInfo, sw, adws); DisplayAdvancement("Done"); } } }
private ADItem Search(ADWebService adws, ADDomainInfo domainInfo, string userName) { ADItem output = null; WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { output = aditem; }; if (userName.StartsWith("S-1-5")) { adws.Enumerate(domainInfo.DefaultNamingContext, "(objectSid=" + ADConnection.EncodeSidToString(userName) + ")", properties, callback); if (output != null) { return(output); } } if (userName.StartsWith("CN=") && userName.EndsWith(domainInfo.DefaultNamingContext)) { adws.Enumerate(domainInfo.DefaultNamingContext, "(distinguishedName=" + ADConnection.EscapeLDAP(userName) + ")", properties, callback); if (output != null) { return(output); } } if (userName.Length <= 20) { adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" + ADConnection.EscapeLDAP(userName) + "))", properties, callback); if (output != null) { return(output); } } adws.Enumerate(domainInfo.DefaultNamingContext, "(cn=" + ADConnection.EscapeLDAP(userName) + ")", properties, callback); if (output != null) { return(output); } adws.Enumerate(domainInfo.DefaultNamingContext, "(displayName=" + ADConnection.EscapeLDAP(userName) + ")", properties, callback); if (output != null) { return(output); } return(output); }
public void Export(string filename) { DisplayAdvancement("Starting"); using (ADWebService adws = new ADWebService(Server, Port, Credential)) { using (StreamWriter sw = File.CreateText(filename)) { sw.WriteLine("DistinguishedName\tIdentity\tAccessRule"); var domainInfo = adws.DomainInfo; EnrichDomainInfo(adws, domainInfo); BuildUserList(adws, domainInfo); WorkOnReturnedObjectByADWS callback = ((ADItem x) => { if (x.NTSecurityDescriptor != null) { var Owner = x.NTSecurityDescriptor.GetOwner(typeof(SecurityIdentifier)); var match = MatchesUsersToCheck(Owner); if (match != null) { sw.WriteLine(x.DistinguishedName + "\t" + match.Value.Value + "\tOwner"); } foreach (ActiveDirectoryAccessRule accessrule in x.NTSecurityDescriptor.GetAccessRules(true, false, typeof(SecurityIdentifier))) { // ignore audit / denied ace if (accessrule.AccessControlType != AccessControlType.Allow) { continue; } match = MatchesUsersToCheck(accessrule.IdentityReference); if (!match.HasValue) { continue; } if (MatchesBadACL(accessrule)) { sw.WriteLine(x.DistinguishedName + "\t" + match.Value.Value + "\t" + accessrule.ActiveDirectoryRights.ToString()); } } } } ); DisplayAdvancement("Analyzing AD Objects"); adws.Enumerate(domainInfo.DefaultNamingContext, "(objectClass=*)", new string[] { "distinguishedName", "nTSecurityDescriptor" }, callback); DisplayAdvancement("Analyzing files"); CheckFilePermission(domainInfo, sw); DisplayAdvancement("Done"); } } }
private void EnrichDomainInfo(ADWebService adws, ADDomainInfo domainInfo) { // adding the domain sid string[] properties = new string[] { "objectSid", }; WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { domainInfo.DomainSid = aditem.ObjectSid; }; adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectClass=domain)(distinguishedName=" + domainInfo.DefaultNamingContext + "))", properties, callback); }
private void ExportPrimaryGroupData(ADWebService adws, ADDomainInfo domainInfo, RelationFactory relationFactory, List <int> primaryGroupIDs) { WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { relationFactory.AnalyzeADObject(aditem); }; foreach (int id in primaryGroupIDs) { adws.Enumerate(domainInfo.DefaultNamingContext, "(primaryGroupID=" + id + ")", properties, callback); } }
private void ExportSIDData(ADWebService adws, ADDomainInfo domainInfo, RelationFactory relationFactory, List <string> sids) { WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { relationFactory.AnalyzeADObject(aditem); }; foreach (string sid in sids) { adws.Enumerate(domainInfo.DefaultNamingContext, "(objectSid=" + ADConnection.EncodeSidToString(sid) + ")", properties, callback); } }
private void ExportCNData(ADWebService adws, ADDomainInfo domainInfo, RelationFactory relationFactory, List <string> cns) { WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { relationFactory.AnalyzeADObject(aditem); }; foreach (string cn in cns) { adws.Enumerate(domainInfo.DefaultNamingContext, "(distinguishedName=" + ADConnection.EscapeLDAP(cn) + ")", properties, callback); } }
private Dictionary <uint, string> BuildAllAttributeDictionnary(ADWebService adws) { var output = new Dictionary <uint, string>(); string[] properties = new string[] { "lDAPDisplayName", "attributeID" }; WorkOnReturnedObjectByADWS callback = (ADItem x) => { output[TransformOidToAttId(x.AttributeID, x.lDAPDisplayName)] = x.lDAPDisplayName; }; adws.Enumerate(adws.DomainInfo.SchemaNamingContext, "(&(objectclass=attributeSchema)(lDAPDisplayName=*))", properties, callback, "Subtree"); return(output); }
private ADItem Search(ADWebService adws, ADDomainInfo domainInfo, string userName) { ADItem output = null; string[] properties = new string[] { "distinguishedName", "displayName", "name", "objectSid", }; WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { output = aditem; }; if (userName.StartsWith("S-1-5")) { adws.Enumerate(domainInfo.DefaultNamingContext, "(objectSid=" + ADConnection.EncodeSidToString(userName) + ")", properties, callback); } adws.Enumerate(domainInfo.DefaultNamingContext, "(sAMAccountName=" + ADConnection.EscapeLDAP(userName) + ")", properties, callback); if (output != null) { return(output); } adws.Enumerate(domainInfo.DefaultNamingContext, "(cn=" + ADConnection.EscapeLDAP(userName) + ")", properties, callback); if (output != null) { return(output); } adws.Enumerate(domainInfo.DefaultNamingContext, "(displayName=" + ADConnection.EscapeLDAP(userName) + ")", properties, callback); if (output != null) { return(output); } return(output); }
List<string> GetListOfComputerToExplore() { ADDomainInfo domainInfo = null; List<string> computers = new List<string>(); using (ADWebService adws = new ADWebService(Server, Port, Credential)) { domainInfo = adws.DomainInfo; string[] properties = new string[] { "dNSHostName", "primaryGroupID" }; WorkOnReturnedObjectByADWS callback = (ADItem x) => { computers.Add(x.DNSHostName); }; adws.Enumerate(domainInfo.DefaultNamingContext, "(&(ObjectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=2)(lastLogonTimeStamp>=" + DateTime.Now.AddDays(-40).ToFileTimeUtc() + "))", properties, callback); } return computers; }
private ADDomainInfo GetDomainInformation(ADWebService adws) { ADDomainInfo domainInfo = null; domainInfo = adws.DomainInfo; if (adws.useLdap) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Performance warning: using LDAP instead of ADWS"); Console.ResetColor(); } // adding the domain sid string[] properties = new string[] { "objectSid", }; WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { domainInfo.DomainSid = aditem.ObjectSid; }; adws.Enumerate(domainInfo.DefaultNamingContext, "(&(objectClass=domain)(distinguishedName=" + domainInfo.DefaultNamingContext + "))", properties, callback); return(domainInfo); }
public void Enumerate(Action preambleWithReentry, string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope) { if (preambleWithReentry != null) { preambleWithReentry(); } try { connection.Enumerate(distinguishedName, filter, properties, callback, scope); } catch (Exception ex) { Trace.WriteLine("Exception: " + ex.Message); Trace.WriteLine("StackTrace: " + ex.StackTrace); if (fallBackConnection == null) { throw; } Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("The AD query failed. Using the alternative protocol (" + fallBackConnection.GetType().Name + ")"); Console.ResetColor(); if (preambleWithReentry != null) { preambleWithReentry(); } fallBackConnection.Enumerate(distinguishedName, filter, properties, callback, scope); } }
public void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope) { Enumerate(null, distinguishedName, filter, properties, callback, scope); }
public override void Export(string filename) { ADDomainInfo domainInfo = null; using (ADWebService adws = new ADWebService(Server, Port, Credential)) { domainInfo = adws.DomainInfo; int export = 0; using (StreamWriter sw = File.CreateText(filename)) { var header = new List <string>(); var hcprop = AddData.GetProperties(); header.Add("DistinguishedName"); header.Add("sAMAccountName"); header.Add("scriptPath"); header.Add("primaryGroupID"); header.Add("lastLogonTimestamp"); header.Add("pwdLastSet"); header.Add("whenCreated"); header.Add("objectClass"); header.Add("userAccountControl"); header.AddRange(hcprop); sw.WriteLine(string.Join("\t", header.ToArray())); WorkOnReturnedObjectByADWS callback = (ADItem x) => { var d = new AddData(); HealthcheckAnalyzer.ProcessAccountData(d, x, false); if ((++export % 500) == 0) { DisplayAdvancement("Exported: " + export); } var data = new List <string>(); data.Add(x.DistinguishedName); data.Add(x.SAMAccountName); data.Add(x.ScriptPath); data.Add(x.PrimaryGroupID.ToString()); data.Add(x.LastLogonTimestamp.ToString("u")); data.Add(x.PwdLastSet.ToString("u")); data.Add(x.WhenCreated.ToString("u")); data.Add(x.Class); data.Add(x.UserAccountControl.ToString()); foreach (var p in hcprop) { data.Add(d.PropertiesSet.Contains(p).ToString()); } sw.WriteLine(string.Join("\t", data.ToArray())); }; DisplayAdvancement("Starting"); adws.Enumerate(domainInfo.DefaultNamingContext, HealthcheckAnalyzer.userFilter, HealthcheckAnalyzer.userProperties, callback, "SubTree"); DisplayAdvancement("Done"); } } }
public override void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope) { EnumerateInternalWithADWS(distinguishedName, filter, properties, scope, (ItemListType items) => { if (items != null) { foreach (XmlElement item in items.Any) { ADItem aditem = null; try { aditem = ADItem.Create(item); } catch (Exception ex) { Console.WriteLine("Warning: unable to process element (" + ex.Message + ")\r\n" + item.OuterXml); Trace.WriteLine("Warning: unable to process element\r\n" + item.OuterXml); Trace.WriteLine("Exception: " + ex.Message); Trace.WriteLine(ex.StackTrace); } if (aditem != null) { callback(aditem); } } } } ); }
public abstract void EnumerateUsingWorkerThread(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope);
public override void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope) { Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] Running ldap enumeration"); Trace.WriteLine("BaseObject=" + scope); Trace.WriteLine("Filter=" + filter); Trace.WriteLine("distinguishedName=" + distinguishedName); Trace.WriteLine("scope=" + scope); IntPtr result; var r = ldap_search_s(connection, distinguishedName, StringToScope(scope), filter, properties, false, out result); if (r == -7) { // LDAP Error -7 (Bad search filter) // the filter contains a new attribute that the AD don't know - yet // just ignore it because the query will return nothing Trace.WriteLine("LDAP Error -7 (Bad search filter) - ignored"); return; } if (r != 0) { throw new LDAPException(r); } try { var entry = ldap_count_entries(connection, result); var j = result; for (int i = 0; i < entry; i++) { var data = new Dictionary <string, berval[]>(); foreach (var prop in properties) { data[prop] = GetValueBin(j, prop); } var aditem = ADItem.Create(data); callback(aditem); j = ldap_next_entry(connection, j); } } finally { ldap_memfree(result); } }
// translation securitydescriptor can take of lot of CPU public override void EnumerateUsingWorkerThread(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope) { BlockingQueue <ItemListType> queue = new BlockingQueue <ItemListType>(600); // background thread Thread workingthread = null; try { workingthread = new Thread( () => { ItemListType items = null; for (; ;) { if (!queue.Dequeue(out items)) { break; } foreach (XmlElement item in items.Any) { ADItem aditem = ADItem.Create(item); try { callback(aditem); } catch (Exception ex) { Trace.WriteLine("Exception in workerthread:" + ex.Message); Trace.WriteLine(ex.StackTrace); } } } Trace.WriteLine("Exiting worker thread"); } ); ReceiveItems callbackInternal = (ItemListType items) => { if (items != null) { queue.Enqueue(items); } } ; workingthread.Start(); EnumerateInternalWithADWS(distinguishedName, filter, properties, scope, callbackInternal); Trace.WriteLine("Done enumerating objects at: " + DateTime.Now); queue.Quit(); workingthread.Join(); Trace.WriteLine("Enumeration using worker thread complete"); } finally { queue.Quit(); if (workingthread != null) { if (workingthread.ThreadState == System.Threading.ThreadState.Running) { workingthread.Abort(); } } } }
public override void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope) { EnumerateInternalWithADWS(distinguishedName, filter, properties, scope, (ItemListType items) => { if (items != null) { foreach (XmlElement item in items.Any) { ADItem aditem = ADItem.Create(item); callback(aditem); } } } ); }
private void EnumerateInternalWithLDAP(string distinguishedName, string filter, string[] properties, string scope, WorkOnReturnedObjectByADWS callback) { Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] Running ldap enumeration"); Trace.WriteLine("BaseObject=" + scope); Trace.WriteLine("Filter=" + filter); DirectoryEntry entry; int numberOfObjectAlreadyExtracted = 0; try { if (Credential == null) { entry = new DirectoryEntry(@"LDAP://" + Server + (Port == 0 ? null : ":" + Port) + "/" + distinguishedName, null, null, AuthenticationTypes.ServerBind | AuthenticationTypes.Secure | (Port == 636 ? AuthenticationTypes.SecureSocketsLayer:0)); } else { entry = new DirectoryEntry(@"LDAP://" + Server + (Port == 0 ? null : ":" + Port) + "/" + distinguishedName, Credential.UserName, Credential.Password, AuthenticationTypes.ServerBind | AuthenticationTypes.Secure | (Port == 636 ? AuthenticationTypes.SecureSocketsLayer : 0)); } DirectorySearcher clsDS = new DirectorySearcher(entry); clsDS.SearchRoot = entry; clsDS.Filter = filter; clsDS.PageSize = 500; switch (scope) { case "OneLevel": clsDS.SearchScope = SearchScope.OneLevel; break; case "SubTree": clsDS.SearchScope = SearchScope.Subtree; break; case "Base": clsDS.SearchScope = SearchScope.Base; break; } bool nTSecurityDescriptor = false; foreach (string property in properties) { clsDS.PropertiesToLoad.Add(property); // prepare the flag for the ntsecuritydescriptor if (String.Compare("nTSecurityDescriptor", property, true) == 0) { nTSecurityDescriptor = true; } } Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "]Calling FindAll"); foreach (SearchResult sr in clsDS.FindAll()) { ADItem aditem = null; try { aditem = ADItem.Create(sr, nTSecurityDescriptor); } catch (Exception ex) { Console.WriteLine("Warning: unable to process element (" + ex.Message + ")\r\n" + sr.Path); Trace.WriteLine("Warning: unable to process element\r\n" + sr.Path); Trace.WriteLine("Exception: " + ex.Message); Trace.WriteLine(ex.StackTrace); } if (aditem != null) { callback(aditem); } numberOfObjectAlreadyExtracted++; } Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "]Enumeration successful"); } catch (DirectoryServicesCOMException ex) { Trace.WriteLine("[" + DateTime.Now.ToLongTimeString() + "]An exception occured"); Trace.WriteLine("ErrorCode: " + ex.ErrorCode); Trace.WriteLine("ExtendedError: " + ex.ExtendedError); Trace.WriteLine("ExtendedErrorMessage: " + ex.ExtendedErrorMessage); Trace.WriteLine("numberOfObjectAlreadyExtracted=" + numberOfObjectAlreadyExtracted); if (ex.ErrorCode == -2147023570) { Trace.WriteLine("Translating DirectoryServicesCOMException to UnauthorizedAccessException"); throw new UnauthorizedAccessException(ex.Message); } throw; } }
public override void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope) { EnumerateInternalWithLDAP(distinguishedName, filter, properties, scope, callback); }
public void Export(string filename) { ADDomainInfo domainInfo = null; using (ADWebService adws = new ADWebService(Server, Port, Credential)) { domainInfo = adws.DomainInfo; var computers = new List <Computer>(); DisplayAdvancement("Resolving LAPS attribute"); var attributeAdmPwd = "ms-Mcs-AdmPwd"; string[] propertiesLaps = new string[] { "name" }; // note: the LDAP request does not contain ms-MCS-AdmPwd because in the old time, MS consultant was installing customized version of the attriute, * being replaced by the company name // check the oid instead ? (which was the same even if the attribute name was not) adws.Enumerate(domainInfo.SchemaNamingContext, "(name=ms-*-AdmPwd)", propertiesLaps, (ADItem aditem) => { attributeAdmPwd = aditem.Name; }, "OneLevel"); DisplayAdvancement("LAPS attribute is " + attributeAdmPwd); DisplayAdvancement("Iterating through computer objects (all except disabled ones)"); string[] properties = new string[] { "DistinguishedName", "dNSHostName", "msDS-ReplAttributeMetaData", "whenCreated", "lastLogonTimestamp", "operatingSystem" }; WorkOnReturnedObjectByADWS callback = (ADItem x) => { var computer = new Computer() { DN = x.DistinguishedName, DNS = x.DNSHostName, WhenCreated = x.WhenCreated, LastLogonTimestamp = x.LastLogonTimestamp, OperatingSystem = x.OperatingSystem, }; if (x.msDSReplAttributeMetaData.ContainsKey(attributeAdmPwd)) { computer.HasLAPS = true; computer.LAPSLastChange = x.msDSReplAttributeMetaData[attributeAdmPwd].LastOriginatingChange; } computers.Add(computer); }; adws.Enumerate(domainInfo.DefaultNamingContext, "(&(ObjectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=2))", properties, callback); DisplayAdvancement("Looking for BitLocker information"); foreach (var computer in computers) { WorkOnReturnedObjectByADWS callbackBitLocker = (ADItem x) => { const string re1 = "CN=" + "([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\\\\\+|-)[0-9]{2}:[0-9]{2})\\{" + "([A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12})" + "\\},"; Regex r = new Regex(re1, RegexOptions.IgnoreCase | RegexOptions.Singleline); Match m = r.Match(x.DistinguishedName); if (m.Success) { computer.HasBitLocker = true; // + sign has to be escaped in LDAP var date = DateTime.Parse(m.Groups[1].ToString().Replace("\\+", "+")); if (computer.BitLockerLastChange < date) { computer.BitLockerLastChange = date; } //string guid = m.Groups[2].ToString(); } else { Trace.WriteLine("Object found but didn't match the regex: " + x.DistinguishedName); } var d = x.DistinguishedName; }; adws.Enumerate(computer.DN, "(objectClass=*)", null, callbackBitLocker, "OneLevel"); } DisplayAdvancement("Writing to file"); using (var sw = File.CreateText(filename)) { sw.WriteLine("DN\tDNS\tWhen Created\tLast Logon Timestamp\tOperating System\tHasLAPS\tLAPS changed date\tHasBitlocker\tBitlocker change date"); foreach (var computer in computers) { sw.WriteLine(computer.DN + "\t" + computer.DNS + "\t" + computer.WhenCreated.ToString("u") + "\t" + computer.LastLogonTimestamp.ToString("u") + "\t" + computer.OperatingSystem + "\t" + computer.HasLAPS + "\t" + (computer.HasLAPS ? computer.LAPSLastChange.ToString("u") : "") + "\t" + computer.HasBitLocker + "\t" + (computer.HasBitLocker ? computer.BitLockerLastChange.ToString("u") : "")); } } DisplayAdvancement("Done"); } }
private List <ADItem> Search(string userName, SearchType search = SearchType.Unknown) { List <ADItem> output = new List <ADItem>(); string searchString = null; string namingContext = domainInfo.DefaultNamingContext; switch (search) { default: case SearchType.Unknown: if (userName.StartsWith("S-1-5")) { output = Search(userName, SearchType.Sid); if (output != null) { return(output); } } if (userName.StartsWith("CN=") && userName.EndsWith(domainInfo.DefaultNamingContext)) { output = Search(userName, SearchType.DistinguishedName); if (output != null) { return(output); } } if (userName.Length <= 20) { output = Search(userName, SearchType.SAMAccountName); if (output != null) { return(output); } } output = Search(userName, SearchType.Name); if (output != null) { return(output); } output = Search(userName, SearchType.DisplayName); if (output != null) { return(output); } return(null); case SearchType.Sid: searchString = "(|(objectSid=" + ADConnection.EncodeSidToString(userName) + ")(sidhistory=" + ADConnection.EncodeSidToString(userName) + "))"; break; case SearchType.DistinguishedName: searchString = "(distinguishedName=" + ADConnection.EscapeLDAP(userName) + ")"; if (userName.EndsWith(domainInfo.ConfigurationNamingContext, StringComparison.InvariantCultureIgnoreCase)) { namingContext = domainInfo.ConfigurationNamingContext; } else if (userName.EndsWith(domainInfo.SchemaNamingContext, StringComparison.InvariantCultureIgnoreCase)) { namingContext = domainInfo.SchemaNamingContext; } break; case SearchType.SAMAccountName: searchString = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" + ADConnection.EscapeLDAP(userName) + "))"; break; case SearchType.Name: searchString = "(cn=" + ADConnection.EscapeLDAP(userName) + ")"; break; case SearchType.DisplayName: searchString = "(displayName=" + ADConnection.EscapeLDAP(userName) + ")"; break; case SearchType.PrimaryGroupId: searchString = "(primaryGroupID=" + userName + ")"; break; } WorkOnReturnedObjectByADWS callback = (ADItem aditem) => { output.Add(aditem); }; adws.Enumerate(namingContext, searchString, properties.ToArray(), callback); return(output); }
public void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback) { Enumerate(distinguishedName, filter, properties, callback, "Subtree"); }
public void EnumerateUsingWorkerThread(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope) { connection.EnumerateUsingWorkerThread(distinguishedName, filter, properties, callback, scope); }