//https://support.microsoft.com/en-us/kb/243330 public static string ConvertSIDToName(string sid) { if (SIDNameMapping.ContainsKey(sid)) { return(SIDNameMapping[sid]); } switch (sid) { case "S-1-0": return("Null Authority"); case "S-1-0-0": return("Nobody"); case "S-1-1": return("World Authority"); case "S-1-1-0": return("Everyone"); case "S-1-2": return("Local Authority"); case "S-1-2-0": return("Local"); case "S-1-2-1": return("Console Logon"); case "S-1-3": return("Creator Authority"); case "S-1-3-0": return("Creator Owner"); case "S-1-3-1": return("Creator Group"); case "S-1-3-2": return("Creator Owner Server"); case "S-1-3-3": return("Creator Group Server"); case "S-1-3-4": return("Owner Rights"); case "S-1-4": return("Non-unique Authority"); case "S-1-5": return("NT Authority"); case "S-1-5-1": return("Dialup"); case "S-1-5-2": return("Network"); case "S-1-5-3": return("Batch"); case "S-1-5-4": return("Interactive"); case "S-1-5-6": return("Service"); case "S-1-5-7": return("Anonymous"); case "S-1-5-8": return("Proxy"); case "S-1-5-9": return("Enterprise Domain Controllers"); case "S-1-5-10": return("Principal Self"); case "S-1-5-11": return("Authenticated Users"); case "S-1-5-12": return("Restricted Code"); case "S-1-5-13": return("Terminal Server Users"); case "S-1-5-14": return("Remote Interactive Logon"); case "S-1-5-15": return("This Organization"); case "S-1-5-17": return("This Organization"); case "S-1-5-18": return("Local System"); case "S-1-5-19": return("Local Service"); case "S-1-5-20": return("Network Service"); case "S-1-5-80-0": return("All Services"); case "S-1-5-32-544": return("BUILTIN\\Administrators"); case "S-1-5-32-545": return("BUILTIN\\Users"); case "S-1-5-32-546": return("BUILTIN\\Guests"); case "S-1-5-32-547": return("BUILTIN\\Power Users"); case "S-1-5-32-548": return("BUILTIN\\Account Operators"); case "S-1-5-32-549": return("BUILTIN\\Server Operators"); case "S-1-5-32-550": return("BUILTIN\\Print Operators"); case "S-1-5-32-551": return("BUILTIN\\Backup Operators"); case "S-1-5-32-552": return("BUILTIN\\Replicators"); case "S-1-5-32-554": return("BUILTIN\\Pre-Windows 2000 Compatible Access"); case "S-1-5-32-555": return("BUILTIN\\Remote Desktop Users"); case "S-1-5-32-556": return("BUILTIN\\Network Configuration Operators"); case "S-1-5-32-557": return("BUILTIN\\Incoming Forest Trust Builders"); case "S-1-5-32-558": return("BUILTIN\\Performance Monitor Users"); case "S-1-5-32-559": return("BUILTIN\\Performance Log Users"); case "S-1-5-32-560": return("BUILTIN\\Windows Authorization Access Group"); case "S-1-5-32-561": return("BUILTIN\\Terminal Server License Servers"); case "S-1-5-32-562": return("BUILTIN\\Distributed COM Users"); case "S-1-5-32-569": return("BUILTIN\\Cryptographic Operators"); case "S-1-5-32-573": return("BUILTIN\\Event Log Readers"); case "S-1-5-32-574": return("BUILTIN\\Certificate Service DCOM Access"); case "S-1-5-32-575": return("BUILTIN\\RDS Remote Access Servers"); case "S-1-5-32-576": return("BUILTIN\\RDS Endpoint Servers"); case "S-1-5-32-577": return("BUILTIN\\RDS Management Servers"); case "S-1-5-32-578": return("BUILTIN\\Hyper-V Administrators"); case "S-1-5-32-579": return("BUILTIN\\Access Control Assistance Operators"); case "S-1-5-32-580": return("BUILTIN\\Access Control Assistance Operators"); default: string name; try { //https://stackoverflow.com/questions/499053/how-can-i-convert-from-a-sid-to-an-account-name-in-c-sharp name = new SecurityIdentifier(sid).Translate(typeof(NTAccount)).ToString(); } catch { string dn = Searcher.LdapInfo.DomainSID.Contains(sid) ? Searcher.LdapInfo.RootDN : Searcher.LdapInfo.ForestDN; name = (string)Searcher.GetSingleAttributeValue(dn, string.Format("(objectSid={0})", sid), "name"); if (name == null) { name = sid; } } //Need to check if key exists, Async may get error if (!SIDNameMapping.ContainsKey(sid)) { SIDNameMapping.Add(sid, name); } return(name); } }
//Retrieve IP from LDAP dnsRecord only public static Dictionary <string, Dictionary <string, string> > GetDNS(bool searchForest = false) { Dictionary <string, Dictionary <string, string> > dnsDict = new Dictionary <string, Dictionary <string, string> >(); string dDnsDn = "DC=DomainDnsZones," + Searcher.LdapInfo.RootDN;//not searching from "CN=MicrosoftDNS,DC=DomainDnsZones,"; string fDnsDn = "DC=ForestDnsZones," + Searcher.LdapInfo.ForestDN; string queryZones = @"(&(objectClass=dnsZone)(!(DC=*arpa))(!(DC=RootDNSServers)))"; string[] dnsZoneAttrs = { "name" }; var dnsZoneSearchResult = searchForest ? Searcher.GetResultEntries(new LDAPSearchString { DN = fDnsDn, Filter = queryZones, ReturnAttributes = dnsZoneAttrs, Scope = SearchScope.Subtree }).ToList() : Searcher.GetResultEntries(new LDAPSearchString { DN = dDnsDn, Filter = queryZones, ReturnAttributes = dnsZoneAttrs, Scope = SearchScope.Subtree }).ToList(); //excluding objects that have been removed string queryRecord = @"(&(objectClass=*)(!(DC=@))(!(DC=*DnsZones))(!(DC=*arpa))(!(DC=_*))(!dNSTombstoned=TRUE))"; string[] dnsAttrs = { "dnsRecord" }; byte[] dnsByte = null; string ip = null; string hostname = null; foreach (var dnsZone in dnsZoneSearchResult) { Dictionary <string, string> dnsRecordDict = new Dictionary <string, string>(); var dnsResponse = Searcher.GetResultEntries(new LDAPSearchString { DN = dnsZone.DistinguishedName, Filter = queryRecord, Scope = SearchScope.OneLevel, ReturnAttributes = dnsAttrs }).ToList(); foreach (var dnsResult in dnsResponse) { //If have permission to view the record if (dnsResult.Attributes.Contains("dnsRecord")) { dnsByte = ((byte[])dnsResult.Attributes["dnsRecord"][0]); ip = ResolveDNSRecord(dnsByte); if (ip == string.Empty || ip == null) { continue; } hostname = dnsResult.DistinguishedName; if (!dnsRecordDict.ContainsKey(hostname.ToUpper())) { dnsRecordDict.Add(hostname.ToUpper(), ip); } } } if (!dnsDict.ContainsKey(dnsZone.DistinguishedName.ToUpper())) { dnsDict.Add(dnsZone.DistinguishedName.ToUpper(), dnsRecordDict); } } return(dnsDict); }
//Get DACL for LAPS public static List <DACL> GetLAPSACL() { logger.Debug("Getting ACLs for LAPS"); var laspDACLList = new List <DACL>(); var lapsACEs = new Dictionary <string, List <string> >(); var lapsResults = Searcher.GetResultEntries(new LDAPSearchString { DN = Searcher.LdapInfo.TargetSearchBase, Filter = "(ms-Mcs-AdmPwdExpirationTime=*)", Scope = SearchScope.Subtree }).ToList(); if (lapsResults == null || lapsResults.Count == 0) { logger.Debug("No LAPS enabled machine can be found"); return(null); } Regex ous = new Regex(@",(CN=.*|OU=.*)", RegexOptions.Compiled); //Only target the first degree OU var lapsOUs = lapsResults.Select(entry => ous.Match(entry.DistinguishedName).Groups[1].Value).Distinct().ToList(); Regex rights = new Regex(@"(.*Read.*)", RegexOptions.Compiled); foreach (string targetDn in lapsOUs) { var rules = GetAuthorizationRules(targetDn, out string ownerSID); foreach (ActiveDirectoryAccessRule rule in rules) { string sid = rule.IdentityReference.ToString(); string adRights = rule.ActiveDirectoryRights.ToString(); string objectType = rule.ObjectType.ToString(); //{2537B2BE-3CE2-459E-A86A-B7949C1D361C}: ms-Mcs-AdmPwd if (rights.IsMatch(adRights) && objectType.ToUpper() == "2537B2BE-3CE2-459E-A86A-B7949C1D361C") { string IR = Helper.SIDNameSID(sid); string userRights = $"ms-Mcs-AdmPwd ({adRights})"; if (lapsACEs.ContainsKey(IR)) { lapsACEs[IR].Add(userRights); } else { lapsACEs.Add(IR, new List <string> { userRights }); } } } string owner = Helper.SIDNameSID(ownerSID); if (lapsACEs.ContainsKey(owner)) { lapsACEs[owner].Add("Owner"); } else { lapsACEs.Add(owner, new List <string> { "Owner" }); } laspDACLList.Add(new DACL { ObjectName = targetDn, ACEs = lapsACEs }); } return(laspDACLList); }
//1. Iterate each OU/Domain/Site: "gplink" & "gpoptions" //2. Find GPOs that are linked to each OU/Domain/Site //3. Iterate each GPO to find out if they have WMI filters: "gPCWQLFilter" //4. Find the WMI policy and check if the policy is filtered out: "msWMI-Parm2" public IResult Collect(SearchString searchstring) { AppliedGPOSearchString searchString = (AppliedGPOSearchString)searchstring; var ouList = CollectMyOUs(searchString.SAMAccountName); if (ouList == null) { return(null); } AppliedGPOs = new Dictionary <string, Dictionary <string, string> >(); Regex gpoRx = new Regex(@"=(\{.+?\}),", RegexOptions.Compiled); Regex gpoptionRx = new Regex(@";(\d)", RegexOptions.Compiled); foreach (string ouDN in ouList) { bool isBlocking = false; bool isEnforced = false; bool isDenied = false; var linkedGPOs = new Dictionary <string, string>(); using (var ouEntry = Searcher.GetDirectoryEntry(ouDN)) { //Linked GPOs & Enforcement if (ouEntry.Properties.Contains("gplink")) { string[] gplinkArrary = Regex.Split(ouEntry.Properties["gplink"][0].ToString(), @"\]\["); if (gplinkArrary == null) { break; } foreach (var gplinkString in gplinkArrary) { if (gplinkString.Replace(" ", "") == string.Empty) { continue; } Match matchGPO = gpoRx.Match(gplinkString); Match matchGpoption = gpoptionRx.Match(gplinkString); string gpoID = matchGPO.Groups[1].ToString().ToUpper(); //[LDAP://cn={E8D8C72C-3AAB-496C-90CD-C5F44F0AF10C},cn=policies,cn=system,DC=corplab,DC=local;0] //0: Default: The GPO Link is not ignored and is not an enforced GPO. //1: The GPO Link MUST be ignored. //2: The GPO Link is an enforced GPO. isEnforced = (int.Parse(matchGpoption.Groups[1].ToString()) == 2); string gpoDn = "CN=" + gpoID + ",CN=Policies,CN=System," + Searcher.LdapInfo.RootDN; try//in case the gpo was deleted { string gpoName = GPO.GroupPolicies[gpoID]; //SecurityFiltering: Check if the target GPO applied to the current user isDenied = IsDeniedPolicy(searchString.SAMAccountName, gpoDn); gpoName = isDenied ? (gpoName + " [X Denied]") : gpoName; gpoName = isEnforced ? (gpoName + " [Enforced]") : gpoName; linkedGPOs.Add(gpoID, gpoName); } catch { _logger.Warn($"GPO {gpoID} was probably deleted."); } } } //If a OU blocks inheritance if (ouEntry.Properties.Contains("gpOptions")) { //OUs that block inheritance will only ignore non-enforecd GPO //OU Attribute: gPOptions=1 Block Inheritance isBlocking = (int)ouEntry.Properties["gpOptions"][0] == 1; } } string ou = isBlocking ? (ouDN + " [Blocking Inheritance]") : ouDN; AppliedGPOs.Add(ou, linkedGPOs); } return(new DDResult { Title = searchString.Title, Result = AppliedGPOs }); }
public static List <DACL> ACLScan(string user, List <string> groupSIDs) { if (user == null) { return(null); } var ACLList = new List <DACL>(); //1. Locate the user var targetEntry = Searcher.GetResultEntry(new LDAPSearchString { DN = Searcher.LdapInfo.TargetSearchBase, Filter = $"(sAMAccountName={user})", Scope = SearchScope.Subtree }); if (targetEntry == null) { return(null); } var targetSid = new SecurityIdentifier((byte[])targetEntry.Attributes["objectsid"][0], 0).ToString(); //2. Get user nested group sid groupSIDs.Add(targetSid); //Iterate all objects var partitions = new string[] { Searcher.LdapInfo.RootDN, Searcher.LdapInfo.ConfigDN, Searcher.LdapInfo.SchemaDN }; if (Searcher.LdapInfo.TargetSearchBase != Searcher.LdapInfo.RootDN) { var allObjects = Searcher.GetResultEntries(new LDAPSearchString { DN = Searcher.LdapInfo.TargetSearchBase, Filter = "(ObjectCategory=*)", Scope = SearchScope.Subtree }); foreach (var obj in allObjects) { var acl = GetMyInterestingACLOnObject(obj.DistinguishedName, groupSIDs); if (acl != null) { ACLList.Add(acl); } } } else { foreach (var partition in partitions) { var allObjects = Searcher.GetResultEntries(new LDAPSearchString { DN = partition, Filter = "(ObjectCategory=*)", Scope = SearchScope.Subtree }); foreach (var obj in allObjects) { var acl = GetMyInterestingACLOnObject(obj.DistinguishedName, groupSIDs); if (acl != null) { ACLList.Add(acl); } } } } return(ACLList); }