//Get interesting DACL if a target user has permission on it public static DACL GetMyInterestingACLOnObject(string targetDn, List <string> sidList) { logger.Debug($"Collecting Interesting ACLs on {targetDn}"); var interestingACEs = new Dictionary <string, List <string> >(); Regex gpoRx = new Regex(@"=(\{.+?\}),", RegexOptions.Compiled); var rules = GetAuthorizationRules(targetDn, out string ownerSID); if (rules == null) { return(null); } //Adapted from https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1#L3746 Regex rights = new Regex(@"(GenericAll)|(.*Write.*)|(.*Create.*)|(.*Delete.*)", RegexOptions.Compiled); //Regex replica = new Regex(@"(.*Replication.*)", RegexOptions.Compiled); //string[] dcsync = { "DS-Replication-Get-Changes", "DS-Replication-Get-Changes-All", "DS-Replication-Get-Changes-In-Filtered-Set" }; foreach (ActiveDirectoryAccessRule rule in rules) { var sid = rule.IdentityReference.ToString(); if (sidList.Contains(sid) || sidList.Contains(ownerSID)) { string IR = Helper.SIDNameSID(sid); string objType = rule.ObjectType.ToString(); string adRights = rule.ActiveDirectoryRights.ToString(); logger.Debug($"{targetDn}:{IR}: ADRights: {adRights} ObjectType: {objType}"); //Ignore the following extended rights //edacfd8f-ffb3-11d1-b41d-00a0c968f939 Apply-Group-Policy //ab721a55-1e2f-11d0-9819-00aa0040529b Send-To if ((rights.IsMatch(adRights) || adRights == "ExtendedRight") && rule.AccessControlType.ToString() == "Allow" && objType.ToLower() != "edacfd8f-ffb3-11d1-b41d-00a0c968f939" && objType.ToLower() != "ab721a55-1e2f-11d0-9819-00aa0040529b") { string userRights = null; if ((adRights == "ExtendedRight") && rule.AccessControlType.ToString() == "Allow") { //The ObjectType GUID maps to an extended right registered in the current forest schema, then that specific extended right is granted //Reference: https://www.blackhat.com/docs/us-17/wednesday/us-17-Robbins-An-ACE-Up-The-Sleeve-Designing-Active-Directory-DACL-Backdoors-wp.pdf userRights = Rights.ResolveRightsGuid(objType, true); } else { string schemaName = Rights.ResolveRightsGuid(objType, false); userRights = schemaName + $" ({adRights})"; } if (interestingACEs.ContainsKey(IR)) { interestingACEs[IR].Add(userRights); } else { interestingACEs.Add(IR, new List <string> { userRights }); } } } } //check owner string owner = Helper.SIDNameSID(ownerSID); if (interestingACEs.ContainsKey(owner)) { interestingACEs[owner].Add("Owner"); } string key; Match matchGPO = gpoRx.Match(targetDn); if (matchGPO.Success) { string gpoID = matchGPO.Groups[1].ToString().ToUpper(); string gpoName = GPO.GroupPolicies[gpoID]; key = gpoID + " " + gpoName; } else { key = targetDn; } if (interestingACEs == null || interestingACEs.Count == 0) { return(null); } return(new DACL { ObjectName = key, ACEs = interestingACEs }); }
//Get DACL for certificate authories, certificate templates public static DACL GetCSACL(string target, ActiveDirectorySecurity sec, out bool hasControlRights, bool getTemplateACL = false) { hasControlRights = false; var rules = sec.GetAccessRules(true, true, typeof(SecurityIdentifier)); if (rules == null) { return(null); } var ownerSID = sec.GetOwner(typeof(SecurityIdentifier)).ToString(); var ACEs = new Dictionary <string, List <string> >(); foreach (ActiveDirectoryAccessRule rule in rules) { string objType = rule.ObjectType.ToString(); string sid = rule.IdentityReference.ToString(); string IR = Helper.SIDNameSID(sid); string adRights = rule.ActiveDirectoryRights.ToString(); if (rule.ActiveDirectoryRights.ToString().Contains("ExtendedRight")) { //The ObjectType GUID maps to an extended right registered in the current forest schema, then that specific extended right is granted //Reference: https://www.blackhat.com/docs/us-17/wednesday/us-17-Robbins-An-ACE-Up-The-Sleeve-Designing-Active-Directory-DACL-Backdoors-wp.pdf adRights = adRights.Replace("ExtendedRight", $" [{Rights.ResolveRightsGuid(objType, true)} {rule.AccessControlType}]"); } logger.Debug($"{target}:{IR}: ADRights: {adRights} ObjectType: {objType} AccessControlType: {rule.AccessControlType}"); if (getTemplateACL)//Get ACL for certificate template { if (rule.AccessControlType.ToString() == "Allow" && Helper.IsLowPrivSid(sid)) { //If a low priv user has certain control over the template if (((rule.ActiveDirectoryRights & ActiveDirectoryRights.GenericAll) == ActiveDirectoryRights.GenericAll) || ((rule.ActiveDirectoryRights & ActiveDirectoryRights.WriteOwner) == ActiveDirectoryRights.WriteOwner) || ((rule.ActiveDirectoryRights & ActiveDirectoryRights.WriteDacl) == ActiveDirectoryRights.WriteDacl) //|| rule.ObjectType.ToString() == "0e10c968-78fb-11d2-90d4-00c04f79dc55" //Certificate-Enrollment || ((rule.ActiveDirectoryRights & ActiveDirectoryRights.WriteProperty) == ActiveDirectoryRights.WriteProperty && objType == "00000000-0000-0000-0000-000000000000")) { hasControlRights = true; if (ACEs.ContainsKey(IR)) { ACEs[IR].Add(adRights); } else { ACEs.Add(IR, new List <string> { adRights }); } } //If a low priv user can enroll else if ((rule.ActiveDirectoryRights.ToString().Contains("ExtendedRight")) && (objType.ToLower() == "0e10c968-78fb-11d2-90d4-00c04f79dc55" || objType == "00000000-0000-0000-0000-000000000000")) { if (ACEs.ContainsKey(IR)) { ACEs[IR].Add(adRights); } else { ACEs.Add(IR, new List <string> { adRights }); } } } } else//Get ACL for certificate authority { string csRights = ((CertificationAuthorityRights)rule.ActiveDirectoryRights).ToString(); if (ACEs.ContainsKey(IR)) { ACEs[IR].Add(csRights); } else { ACEs.Add(IR, new List <string> { csRights }); } } } if (ACEs.Count == 0) { return(null); } string owner = Helper.SIDNameSID(ownerSID); if (ACEs.ContainsKey(owner)) { ACEs[owner].Add("Owner"); } else { ACEs.Add(owner, new List <string> { "Owner" }); } return(new DACL { ObjectName = $"DACL on {target}", ACEs = ACEs }); }
//Get DACL on an object public static DACL GetACLOnObject(string targetDn) { logger.Debug($"Collecting ACLs on {targetDn}"); var ACEs = new Dictionary <string, List <string> >(); Regex gpoRx = new Regex(@"=(\{.+?\}),", RegexOptions.Compiled); var rules = GetAuthorizationRules(targetDn, out string ownerSID); if (rules == null) { return(null); } foreach (ActiveDirectoryAccessRule rule in rules) { var sid = rule.IdentityReference.ToString(); string IR = Helper.SIDNameSID(sid); string objType = rule.ObjectType.ToString(); string adRights = rule.ActiveDirectoryRights.ToString(); logger.Debug($"{targetDn}:{IR}: ADRights: {adRights} ObjectType: {objType} AccessControlType: {rule.AccessControlType}"); string userRights = null; if (adRights.Contains("ExtendedRight")) { //The ObjectType GUID maps to an extended right registered in the current forest schema, then that specific extended right is granted //Reference: https://www.blackhat.com/docs/us-17/wednesday/us-17-Robbins-An-ACE-Up-The-Sleeve-Designing-Active-Directory-DACL-Backdoors-wp.pdf userRights = Rights.ResolveRightsGuid(objType, true) + $" [{rule.AccessControlType}]"; userRights = adRights.Replace("ExtendedRight", $"[ExtendedRight: {userRights}]"); } else { string schemaName = Rights.ResolveRightsGuid(objType, false); userRights = schemaName + $" ({adRights} [{rule.AccessControlType}])"; } if (ACEs.ContainsKey(IR)) { ACEs[IR].Add(userRights); } else { ACEs.Add(IR, new List <string> { userRights }); } } string owner = Helper.SIDNameSID(ownerSID); if (ACEs.ContainsKey(owner)) { ACEs[owner].Add("Owner"); } else { ACEs.Add(owner, new List <string> { "Owner" }); } string key; Match matchGPO = gpoRx.Match(targetDn); if (matchGPO.Success) { string gpoID = matchGPO.Groups[1].ToString().ToUpper(); string gpoName = GPO.GroupPolicies[gpoID]; key = gpoID + " " + gpoName; } else { key = targetDn; } return(new DACL { ObjectName = key, ACEs = ACEs }); }