public void GetACL(string targetDn = null) { IDisplay displayer = new DisplayDACL(); DACLResult result = new DACLResult(); if (targetDn == null) { displayer.DisplayTitle("Interesting ACL on the Domain Object"); var domainAcl = DACL.GetInterestingACLOnObject(Searcher.LdapInfo.RootDN); result.Result = new List <DACL> { domainAcl }; displayer.DisplayResult(result); displayer.DisplayTitle("Interesting ACL on Group Policy Objects"); var gposDN = GPO.GetAllGPODNList(); result.Result = AsyncCollection.GetInterestingACLAsync(gposDN).Result; displayer.DisplayResult(result); displayer.DisplayTitle("LAPS Password View Access"); result.Result = DACL.GetLAPSACL(); displayer.DisplayResult(result); } else { displayer.DisplayTitle($"DACL on {targetDn.ToUpper()}"); result.Result = new List <DACL> { DACL.GetACLOnObject(targetDn) }; displayer.DisplayResult(result); } }
public static async Task <List <DACL> > GetACLAsync(List <string> targetDnList) { var tasks = new List <Task <DACL> >(); foreach (string targetDn in targetDnList) { tasks.Add(Task.Run(() => DACL.GetACLOnObject(targetDn))); } var aclList = (await Task.WhenAll(tasks)).ToList(); return(aclList); }
public static ADCS GetADCS(SearchResultEntry csEntry) { logger.Debug("Collecting ADCS"); string enrollServers = null; List <string> certTemplates = new List <string>(); List <X509Certificate2> caCertificates = new List <X509Certificate2>(); DACL acl; string caHostname = csEntry.Attributes["dnshostname"][0].ToString(); string caName = csEntry.Attributes["name"][0].ToString(); string whenCreated = Helper.ConvertWhenCreated(csEntry.Attributes["whencreated"][0].ToString()).ToString(); var enrollmentEndpoints = AsyncCollection.TestEnrollmentEndpointsAsync(caName, caHostname).Result; PkiCertificateAuthorityFlags flags = (PkiCertificateAuthorityFlags)Enum.Parse(typeof(PkiCertificateAuthorityFlags), csEntry.Attributes["flags"][0].ToString()); //The target attribute may not exist foreach (string attribute in csEntry.Attributes.AttributeNames) { if (attribute == "certificatetemplates") { foreach (var certTemp in csEntry.Attributes[attribute]) { certTemplates.Add(Encoding.UTF8.GetString((byte[])certTemp)); } } if (attribute == "mspki-enrollment-servers") { enrollServers = csEntry.Attributes[attribute][0].ToString().Replace("\n", ","); } if (attribute == "cacertificate") { caCertificates = GetCaCertificate(csEntry.Attributes[attribute]); } } bool allowSuppliedSAN = false; bool usingLDAP; var remoteReg = Helper.ReadRemoteReg(caHostname, RegistryHive.LocalMachine, $"SYSTEM\\CurrentControlSet\\Services\\CertSvc\\Configuration\\{caName}\\PolicyModules\\CertificateAuthority_MicrosoftDefault.Policy"); //If the remote registry cannot be accessed, using LDAP to retrieve security descriptor instead usingLDAP = remoteReg == null ? true : false; if (usingLDAP) { acl = DACL.GetACLOnObject(csEntry.DistinguishedName); } else { int editFlags = (remoteReg == null) ? 0 : (int)(remoteReg).GetValue("EditFlags"); allowSuppliedSAN = ((editFlags & 0x00040000) == 0x00040000); //Reading DACL from the remote registry, nTSecurityDescriptor from LDAP does not have the necessary information var regSec = (byte[])(Helper.ReadRemoteReg(caHostname, RegistryHive.LocalMachine, $"SYSTEM\\CurrentControlSet\\Services\\CertSvc\\Configuration\\{caName}")).GetValue("Security"); var regSecDescriptor = new ActiveDirectorySecurity(); regSecDescriptor.SetSecurityDescriptorBinaryForm(regSec, AccessControlSections.All); acl = DACL.GetCSACL($"{caHostname}:{RegistryHive.LocalMachine}:SYSTEM\\CurrentControlSet\\Services\\CertSvc\\Configuration\\{caName}", regSecDescriptor, out _, false); } return(new ADCS() { flags = flags, caCertificates = caCertificates, allowUserSuppliedSAN = allowSuppliedSAN, CAName = caName, whenCreated = whenCreated, dnsHostName = caHostname, enrollServers = enrollServers, DACL = acl, certTemplates = certTemplates, enrollmentEndpoints = enrollmentEndpoints }); }
public static CertificateTemplate GetInterestingCertTemplates(SearchResultEntry certTemplateResultEntry) { bool isPublished = false; string publishedBy = null; ActiveDirectorySecurity adRights = new ActiveDirectorySecurity(); byte[] ldapSecBytes = (byte[])certTemplateResultEntry.Attributes["ntsecuritydescriptor"][0]; adRights.SetSecurityDescriptorBinaryForm(ldapSecBytes, AccessControlSections.All); var acl = DACL.GetCSACL(certTemplateResultEntry.DistinguishedName, adRights, out bool hasControlRights, true); var enrollFlag = (msPKIEnrollmentFlag)Enum.Parse(typeof(msPKIEnrollmentFlag), certTemplateResultEntry.Attributes["mspki-enrollment-flag"][0].ToString()); var raSig = int.Parse(certTemplateResultEntry.Attributes["mspki-ra-signature"][0].ToString()); var certNameFlag = (msPKICertificateNameFlag)Enum.Parse(typeof(msPKICertificateNameFlag), (unchecked ((uint)(Convert.ToInt32(certTemplateResultEntry.Attributes["mspki-certificate-name-flag"][0].ToString())))).ToString()); List <string> ekus = new List <string>(); List <string> ekuNames = new List <string>(); if (certTemplateResultEntry.Attributes.Contains("pkiextendedkeyusage")) { foreach (byte[] eku in certTemplateResultEntry.Attributes["pkiextendedkeyusage"]) { string ekuStr = Encoding.UTF8.GetString(eku); ekus.Add(ekuStr); ekuNames.Add(new Oid(ekuStr).FriendlyName); } } //If a low priv user has control rights over the templates if (hasControlRights) { foreach (var ca in ADCS.CertificateServices) { var certInCa = ca.certTemplates.FirstOrDefault(caCerts => caCerts.Contains(certTemplateResultEntry.Attributes["name"][0].ToString())); if (certInCa != null) { isPublished = true; publishedBy = ca.CAName; } } return(new CertificateTemplate { IsPublished = isPublished, PublishedBy = publishedBy, CertNameFlag = certNameFlag, RaSigature = raSig, EnrollFlag = enrollFlag, TemplateCN = certTemplateResultEntry.Attributes["cn"][0].ToString(), TemplateDisplayName = certTemplateResultEntry.Attributes["displayName"][0].ToString(), ExtendedKeyUsage = ekuNames, DACL = DACL.GetACLOnObject(certTemplateResultEntry.DistinguishedName)//retrieve the complete DACL instead of interesting ACEs }); } //If a low priv user can enroll else if (acl != null) { logger.Debug("Checking manager approval..."); //Check if manager approval is enabled if (!enrollFlag.HasFlag(msPKIEnrollmentFlag.PEND_ALL_REQUESTS)) { logger.Debug(certTemplateResultEntry.DistinguishedName); logger.Debug("Checking authorized signatures..."); //Check if authorized signatures are required if (raSig <= 0) { logger.Debug(certTemplateResultEntry.DistinguishedName); logger.Debug("Checking EKUs & ENROLLEE_SUPPLIES_SUBJECT ..."); //Check if ENROLLEE_SUPPLIES_SUBJECT is enabled and a low priv user can request a cert for authentication //Check if the template has dangerous EKUs logger.Debug(certTemplateResultEntry.DistinguishedName); if ((certNameFlag.HasFlag(msPKICertificateNameFlag.ENROLLEE_SUPPLIES_SUBJECT) && HasAuthenticationEKU(ekus)) || HasDanagerousEKU(ekus)) { logger.Debug(certTemplateResultEntry.DistinguishedName); foreach (var ca in ADCS.CertificateServices) { var certInCa = ca.certTemplates.FirstOrDefault(caCerts => caCerts.Contains(certTemplateResultEntry.Attributes["name"][0].ToString())); if (certInCa != null) { isPublished = true; publishedBy = ca.CAName; } } if (acl.ACEs.Count != 0) { return(new CertificateTemplate { IsPublished = isPublished, PublishedBy = publishedBy, CertNameFlag = certNameFlag, RaSigature = raSig, EnrollFlag = enrollFlag, TemplateCN = certTemplateResultEntry.Attributes["cn"][0].ToString(), TemplateDisplayName = certTemplateResultEntry.Attributes["displayName"][0].ToString(), ExtendedKeyUsage = ekuNames, DACL = DACL.GetACLOnObject(certTemplateResultEntry.DistinguishedName)//retrieve the complete DACL instead of interesting ACEs }); } } } } } return(null); }