Git Product home page Git Product logo

adcs-snippets's Introduction

adcs-snippets

Just a bunch of code snippets to identify and remediate common Active Directory Certificate Services issues.

Common Misconfiguration #1: Insufficient Auditing

Check current configuration

certutil -getreg CA\AuditFilter

If you receive a result like the following, auditing is not enabled:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\horse-CA1-CA-1\AuditFilter:

  AuditFilter REG_DWORD = 0
CertUtil: -getreg command completed successfully.

Enable all auditing

certutil –setreg CA\AuditFilter 127
net stop certsvc
net start certsvc

Notes:

  • These snippets must be run on each CA host individually.
  • Fully enabling auditing requires 2 additional GPO settings to be configured.

Common Misconfiguration #2: Single-Tier Architecture

Wonderful guide by Pete Long on building a two-tier PKI: https://www.petenetlive.com/KB/Article/0001309

Common Misconfiguration #3: Unsafe Ownership

Find Objects with Unsafe Owners

$ADRoot = (Get-ADRootDSE).rootDomainNamingContext

$Safe_Owners = "Enterprise Admins|Domain Admins|Administrators"

$ADCS_Objects = Get-ADObject -Filter * -SearchBase "CN=Public Key Services,CN=Services,CN=Configuration,$ADRoot" -SearchScope 2 -Properties *

$ADCS_Objects | Where-Object {
    $_.nTSecurityDescriptor.Owner -notmatch $Safe_Owners
} | Format-Table Name,DistinguishedName

Reset Owner to "Enterprise Admins"

$DNSRoot = (Get-ADDomain).DNSRoot
$StandardOwner = New-Object System.Security.Principal.NTAccount($DNSRoot, "Enterprise Admins")

$ADCS_Objects_BadOwner = $ADCS_Objects | Where-Object {
    $_.nTSecurityDescriptor.Owner -notmatch $Safe_Owners
}

$ADCS_Objects_BadOwner | ForEach-Object {
    $ObjectPath = "AD:$($_.DistinguishedName)"
    $ACL = Get-Acl -Path $ObjectPath
    $ACL.SetOwner($StandardOwner)
    Set-ACL -Path $ObjectPath -AclObject $ACL
}

Dangerous Misconfiguration #1: Unsafe ACLs

Find Objects with Dangerous ACLs

$Safe_Users = "Domain Admins|Enterprise Admins BUILTIN\\Administrators NT AUTHORITY\\SYSTEM|$env:userdomain\\Cert Publishers|$env:userdomain\\Administrator"

$DangerousRights = "GenericAll|WriteDacl|WriteOwner"

foreach ( $object in $ADCS_Objects ) {
    $BadACE = $object.nTSecurityDescriptor.Access | Where-Object {
        ( $.IdentityReference -notmatch $Safe_Users ) -and ( $_.ActiveDirectoryRights -match $DangerousRights )
    }
    if ( $BadACE ) {
        Write-Host "Object: $object" -ForegroundColor Red
        $BadACE
    }
}

Note: This snippet is very simple will likely return some false positives. CAs, PKI Admin users/groups, and other safe entities may end up in the results. This list should be a starting point for future investigation.

Dangerous Misconfiguration #2: Templates with Bad Configs

Find Templates with Bad Configs

$ClientAuthEKUs = "1\.3\.6\.1\.5\.5\.7\.3\.2|
    1\.3\.6\.1\.5\.2\.3\.4|
    1\.3\.6\.1\.4\.1\.311\.20\.2\.2|
    2\.5\.29\.37\.0"
    
$ADCS_Objects | Where-Object {
    ($_.ObjectClass -eq "pKICertificateTemplate") -and
    ($_.pkiExtendedKeyUsage -match $ClientAuthEKUs) -and
    ($_."msPKI-Certificate-Name-Flag" -band 1) -and
    !($_.'msPKI-Enrollment-Flag' -band 2) -and
    ( ($_."msPKI-RA-Signature" -eq 0) -or ($null -eq $_."msPKI-RA-Signature") )
} | Format-Table Name,DistinguishedName

Fix #1 for Templates with Bad Configs - Remove Ability to Set a SAN

$ADCS_Objects_BadConfig = $ADCS_Objects | Where-Object {
    ($_.ObjectClass -eq "pKICertificateTemplate") -and
    ($_.pkiExtendedKeyUsage -match $ClientAuthEKUs) -and
    ($_."msPKI-Certificate-Name-Flag" -band 1) -and
    !($_.'msPKI-Enrollment-Flag' -band 2) -and
    ( ($_."msPKI-RA-Signature" -eq 0) -or ($null -eq $_."msPKI-RA-Signature") )
}

$ADCS_Objects_BadConfig | ForEach-Object {
    $_."msPKI-Certificate-Name-Flag" = 0
}

Fix #2 for Templates with Bad Configs - Require Manager Approval (generally less impactful)

$ADCS_Objects_BadConfig = $ADCS_Objects | Where-Object {
    ($_.ObjectClass -eq "pKICertificateTemplate") -and
    ($_.pkiExtendedKeyUsage -match $ClientAuthEKUs) -and
    ($_."msPKI-Certificate-Name-Flag" -band 1) -and
    !($_.'msPKI-Enrollment-Flag' -band 2) -and
    ( ($_."msPKI-RA-Signature" -eq 0) -or ($null -eq $_."msPKI-RA-Signature") )
}

$ADCS_Objects_BadConfig | ForEach-Object {
    $_."msPKI-Enrollment-Flag" = 2
}

Dangerous Misconfiguration #3: Dangerous Flag on CA

Check if the Flag is Set

certutil -getreg policy\EditFlags

Unset the Dangerous Flag

certutil -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2

adcs-snippets's People

Contributors

trimarcjake avatar jakehildreth avatar

Stargazers

TheL0singEdge avatar Rusty avatar beerandgin avatar Dave Hardy avatar Mike Judd avatar Justin Emmons avatar  avatar  avatar  avatar  avatar cocoonk1d avatar 1mm0rt41PC avatar 3v1i avatar Bert Mueller avatar  avatar Kr0ff avatar Denis Isakov avatar Jake Smith avatar Ondrej Sebela avatar Ståle Pettersen avatar snovvcrash avatar Cory Plastek avatar  avatar  avatar Santiago Squarzon avatar  avatar @JaekelEDV avatar Fabian Bader avatar  avatar Jim avatar

Watchers

 avatar  avatar  avatar

adcs-snippets's Issues

Missing files?

The README mentions two subdirectories and files that are not included in this repo. Is that by design or mistake?
• CA\AuditFilter
• policy\EditFlags

MsPKI-Certificate-Name-Flag

Hi. I might be wrong and I didn't test it yet, but you are filtering the above setting for a 1 in "Find Templates with Bad Configs". Wouldn't a 9 be equally critical? I mean for renewals, it seems to be locked by this option, but isn't it the same risk for new certs as with a 1?

Get-ADRootDSE : The server has rejected the client credentials.

Hi,
I ran into a small issue when running the PowerShell commands. I received the following error “Get-ADRootDSE : The server has rejected the client credentials.”. We have hardened our AD environment, which I suspect is why the commands did not work. After digging around and testing, modified the code as below to get things working.

$auth = Get-Credential
$ADRoot = (Get-ADRootDSE -Credential $auth).rootDomainNamingContext
$Safe_Owners = "Enterprise Admins|Domain Admins|Administrators"
$ADCS_Objects = Get-ADObject -Credential $auth -Filter * -SearchBase "CN=Public Key Services,CN=Services,CN=Configuration,$ADRoot" -SearchScope 2 -Properties *
$ADCS_Objects | Where-Object {
$_.nTSecurityDescriptor.Owner -notmatch $Safe_Owners
} | Format-Table Name,DistinguishedName

I hope this helps someone who had the same issue.

Regards
Stephen

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.