GithubHelp home page GithubHelp logo

adaudit's Introduction

adaudit

This PowerShell script is designed to conduct a comprehensive audit of Microsoft Active Directory, focusing on identifying common security vulnerabilities and weaknesses. Its execution facilitates the pinpointing of critical areas that require reinforcement, thereby fortifying your infrastructure against prevalent tactics used in lateral movement or privilege escalation attacks targeting Active Directory.

_____ ____     _____       _ _ _
|  _  |    \   |  _  |_ _ _| |_| |_
|     |  |  |  |     | | | . | |  _|
|__|__|____/   |__|__|___|___|_|_|
                 by phillips321

If you have any decent powershell one liners that could be used in the script please let me know. I'm trying to keep this script as a single file with no requirements on external tools (other than ntdsutil and cmd.exe)

Run directly on a DC using a DA. If you don't trust the code I suggest reading it first and you'll see it's all harmless! (But shouldn't you be doing that anyway with code you download off the net and then run as DA??)

What this does

  • Device Information
    • Get-HostDetails
  • Domain Audit
    • Get-LastWUDate
    • Get-DCEval
    • Get-TimeSource
    • Get-PrivilegedGroupMembership
    • Get-MachineAccountQuota
    • Get-DefaultDomainControllersPolicy
    • Get-SMB1Support
    • Get-FunctionalLevel
    • Get-DCsNotOwnedByDA
    • Get-ReplicationType
    • Get-RecycleBinState
    • Get-CriticalServicesStatus
    • Get-RODC
  • Domain Trust Audit
    • Get-DomainTrusts
  • User Accounts Audit
    • Get-InactiveAccounts
    • Get-DisabledAccounts
    • Get-LockedAccounts
    • Get-AdminAccountChecks
    • Get-NULLSessions
    • Get-PrivilegedGroupAccounts
    • Get-ProtectedUsers
  • Password Information Audit
    • Get-AccountPassDontExpire
    • Get-UserPasswordNotChangedRecently
    • Get-PasswordPolicy
    • Get-PasswordQuality
  • Dumps NTDS.dit
    • Get-NTDSdit
  • Computer Objects Audit
    • Get-OldBoxes
  • GPO audit (and checking SYSVOL for passwords)
    • Get-GPOtoFile
    • Get-GPOsPerOU
    • Get-SYSVOLXMLS
    • Get-GPOEnum
  • Check Generic Group AD Permissions
    • Get-OUPerms
  • Check For Existence of LAPS in domain
    • Get-LAPSStatus
  • Check For Existence of Authentication Polices and Silos
    • Get-AuthenticationPoliciesAndSilos
  • Check for insecure DNS zones
    • Get-DNSZoneInsecure
  • Check for newly created users and groups
    • Get-RecentChanges
  • Check for ADCS vulnerabiltiies, ESC1,2,3,4 and 8.
  • Check for high value kerberoastable accounts
  • Check for ASREPRoastable accounts
  • Check for dangerous ACL permissions on Users, Groups and Computers.
  • Check LDAP and LDAPs settings (Signing, null sessions etc )

Runtime Args

The following switches can be used in combination

  • -installdeps installs optionnal features (DSInternals)
  • -hostdetails retrieves hostname and other useful audit info
  • -domainaudit retrieves information about the AD such as functional level
  • -trusts retrieves information about any doman trusts
  • -accounts identifies account issues such as expired, disabled, etc...
  • -passwordpolicy retrieves password policy information
  • -ntds dumps the NTDS.dit file using ntdsutil
  • -oldboxes identified outdated OSs like XP/2003 joined to the domain
  • -gpo dumps the GPOs in XML and HTML for later analysis
  • -ouperms checks generic OU permission issues
  • -laps checks if LAPS is installed
  • -authpolsilos checks for existence of authentication policies and silos
  • -insecurednszone checks for insecure DNS zones
  • -recentchanges checks for newly created users and groups (last 30 days)
  • -adcs checks for ADCS vulnerabiltiies, ESC1,2,3,4 and 8.
  • -acl checks for dangerous ACL permissions on Users, Groups and Computers.
  • -spn checks for high value kerberoastable accounts
  • -asrep checks for ASREPRoastable accounts
  • -ldapsecurity checks for multiple LDAP issues
  • -exclude allows you to exclude specific checks when using adaudit.ps1 -all -exclude ouperms,ntds,adcs"
  • -select allows you to exclude specific checks when using adaudit.ps1 -all "gpo,ntds,acl"
  • -all runs all checks, e.g. AdAudit.ps1 -all

adaudit's People

Contributors

cool34000 avatar danti1988 avatar fuggles-5555 avatar kennymaccormik avatar phillips321 avatar thehodown avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adaudit's Issues

I get this error below

Hi
Version 4.1 works ok


The lasted lines from 878 to 886

#Dirty fix for .nessus characters (will do this properly or as a function later. Will need more characters adding here...)
$originalnessusoutput = Get-Content $outputdir\adaudit.nessus
$nessusoutput = $originalnessusoutput -Replace "&", "&"
$nessusoutput = $nessusoutput -Replace "`“", """
$nessusoutput = $nessusoutput -Replace "ü", "u"
$nessusoutput | Out-File $outputdir\adaudit-replaced.nessus

$endtime = get-date
Write-Both "[*] Script end time $endtime"


Version 4.2 didn't works


The lasted lines from 879 to 888
#Dirty fix for .nessus characters (will do this properly or as a function later. Will need more characters adding here...)
$originalnessusoutput = Get-Content $outputdir\adaudit.nessus
$nessusoutput = $originalnessusoutput -Replace "&", "&"
$nessusoutput = $nessusoutput -Replace "`“", """
$nessusoutput = $nessusoutput -Replace "ü", "u"
$nessusoutput | Out-File $outputdir\adaudit-replaced.nessus
~
$endtime = get-date
Write-Both "[*] Script end time $endtime"
~

I run this commando
PS C:\Users\Administrator\Downloads\ADaudit-master> .\AdAudit.ps1 -all


Error
At C:\Users\Administrator\Downloads\ADaudit-master\AdAudit.ps1:882 char:48

  • $nessusoutput = $nessusoutput -Replace "`“", """
  •                                            ~
    

Unexpected token '&' in expression or statement.
At C:\Users\Administrator\Downloads\ADaudit-master\AdAudit.ps1:883 char:41

  • $nessusoutput = $nessusoutput -Replace "ü", "u"
  •                                     ~~~~~~~~
    

Unexpected token 'ü", "u"
$nessusoutput | Out-File $outputdir\adaudit-replaced.nessus
$endtime = get-date
Write-Both "[*]' in expression or statement.
At C:\Users\Administrator\Downloads\ADaudit-master\AdAudit.ps1:887 char:41

  • Write-Both "[*] Script end time $endtime"
  •                                     ~
    

The string is missing the terminator: ".
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken

Best regards
Henrik

Account created dates

Hi, thanks for sharing. I was wondering whether you could add something to identify newly created accounts to the effects of:

$DateCutOff = (Get-Date).AddDays(-30)
Get-ADUser -Filter * -Properties whenCreated | where {$_.whenCreated -gt $DateCufOff} | FT Name, whenCreated

New checks

Hi,

How/Where do you retrieve Nessus KB numbers?
I want to add a few tests but I'd like to point to the corresponding KB if it exists

Thanks

Azure headless AD cloud review

Hi,

I would like to run a AD Audit against a headless (non graphical) Azure AD in my tenancy. I have access to powershell as DA remotely, but was unsure if there where was a method where the results could be mapped back to my workstation rather than the server?

Thanks in advance.

No way to contact =(

Hi,

Your site is down and I cannot find any other way to contact you. I'd like to share some simple code I think will be useful to you

function Get-UserWithJoinPermissions{#Looks for groups that have domain join permissions assigned
    $AllowedJoin = @();
    $AllGPOs = Get-GPO -All | sort DisplayName;
    foreach ($GPO in $AllGPOs){
        $GPOreport = Get-GPOReport -Guid $GPO.id -ReportType Xml;
        $permissionindex = $GPOreport.IndexOf('<q1:Name>SeMachineAccountPrivilege</q1:Name>');
        if($permissionindex -gt 0){
            $xmlreport = [xml]$GPOreport;
            foreach ($member in (($xmlreport.GPO.Computer.ExtensionData.Extension.UserRightsAssignment | ? name -eq 'SeMachineAccountPrivilege').member) ){
                $obj = New-Object -TypeName psobject;
                $obj | Add-Member -MemberType NoteProperty -Name GPO -Value $GPO.DisplayName;
                $obj | Add-Member -MemberType NoteProperty -Name SID -Value $member.sid.'#text';
                $obj | Add-Member -MemberType NoteProperty -Name Name -Value $member.name.'#text';

                $AllowedJoin += $obj;
            }
        }
    }
    foreach($record in $AllowedJoin){
        Write-Both "    [+] GPO [$($record.GPO)] allows object [$($record.Name)] with SID [$($record.SID)] to join computers to domain"
    }
}

function Get-PrivelegedGroupMembership{#List Domain Admins, Enterprise Admins and Schema Admins members
    $SchemaMemebers = Get-ADGroup 'Schema Admins' | Get-ADGroupMember;
    $EnterpriseMemebers = Get-ADGroup 'Enterprise Admins' | Get-ADGroupMember;
    $DomainAdminsMemebers = Get-ADGroup 'Domain Admins' | Get-ADGroupMember;
    if($SchemaMemebers.count -ne 0){
            Write-Both "    [!] Schema Admins not empty!!!"
        foreach($member in $SchemaMemebers){
            Write-Both "        [-] $($member.objectClass) $($member.name)"
        }
    }
    if($EnterpriseMemebers.count -ne 0){
            Write-Both "    [!] Enterprise Admins not empty!!!"
        foreach($member in $EnterpriseMemebers){
            Write-Both "        [-] $($member.objectClass) $($member.name)"
        }
    }
    Write-Both "    [+] Domain Admins members"
    foreach($member in $DomainAdminsMemebers){
        Write-Both "        [-] $($member.objectClass) $($member.name)"
    }
}

Get-Acl : The object name has bad syntax

I was getting a "Get-Acl : The object name has bad syntax" when the Get-OUPerms function was running. According to this reddit post, it's a known issue. I simply changed Get-Acl AD:$object to Get-Acl "Microsoft.ActiveDirectory.Management.dll\ActiveDirectory:://RootDSE/$object" and everything seems to be working again. By the way, thanks for taking the time to create and share this script. It pulls all the good stuff I would care about and saved me many hours by not having to put something together myself.

Prepare for other languages

Hi,

There are 2 checks with the Administrator name hardcoded (check if the account has been renamed/replaced)
This name depends on your OS language so we can't use the SID to compute it.

To fix the hardcoded checks and make it more reliable, I've added a array to store the default Administrator name for different languages (far from being complete).
$AdministratorTranslation = @("Administrator","Administrateur","Administrador")

Disabled accounts taken into statistics

Looks like script counts disabled accounts in following reports:

  • inactive users
  • old passwords
  • passwords that do not expire
  • computers with old OS

Such accounts are disabled and usually kept for audit purposes, should be included in above provided figures I think.

anyway - nice work!

Inaccurate Inactive Account List

Line 249 uses "-TimeSpan 180". The comment on line 246 indicates that the intention here is to list accounts that have not been active for 180 days but on my Windows Server 2012 R2 machine with PowerShell 4.0 that is not the actual outcome. The "180" is some time period that is shorter than 180 days.

Changing the "180" to (New-TimeSpan -Days 180) gave more accurate results:

$inactiveaccounts = Search-ADaccount -AccountInactive -Timespan (New-TimeSpan -Days 180) -UsersOnly

Top rate tool for doing a basic audit. Thank you for the work.

Issue with running on Windows 2008R2 32bit

Missing expression after unary operator '-'.
At C:\Users\Administrator\Downloads\adaudit-master\adaudit-master\AdAudit.ps1:6 char:10

  •     -  <<<< added check for transitive trusts
    

Result File

Hello

Thank you for the work done with this script, would it be possible to have a single result file in HTML format for example

Thank you

Password Complexity returns incorrect result.

Hi

I recently ran the script on a server and noticed it returned an incorrect complexity enable result.
We determined that an alternate command fixed the issue.

Instead of using
(Get-ADDefaultDomainPasswordPolicy).PasswordComplexity
Which may return a blank.

Using the following
(Get-ADDefaultDomainPasswordPolicy).ComplexityEnabled
Returns “True” as expected.

Thanks for a great tool.

Fix for other languages

Hi,

Group names should be retrieved from their known SIDs.

# Users/Groups SIDs
$AdministratorSID      = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-500"
$DomainAdminsSID       = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-512"
$DomainUsersSID        = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-513"
$DomainControllersSID  = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-516"
$SchemaAdminsSID       = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-518"
$EnterpriseAdminsSID   = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-519"
$ProtectedUsersSID     = ((Get-ADDomain -Current LoggedOnUser).domainsid.value)+"-525"
EveryOneSID            = New-Object System.Security.Principal.SecurityIdentifier "S-1-1-0"
$AuthenticatedUsersSID = New-Object System.Security.Principal.SecurityIdentifier "S-1-5-11"

# Users/Groups real names
$Administrators        = (Get-AD -Identity S-1-5-32-544).SamAccountName
$Users                 = (Get-AD -Identity S-1-5-32-545).SamAccountName
$Administrator         = (Get-AD -Identity $AdministratorSID).SamAccountName
$DomainAdmins          = (Get-AD -Identity $DomainAdminsSID).SamAccountName
$DomainUsers           = (Get-AD -Identity $DomainUsersSID).SamAccountName
$DomainControllers     = (Get-AD -Identity $DomainControllersSID).SamAccountName
$SchemaAdmins          = (Get-AD -Identity $SchemaAdminsSID).SamAccountName
$EnterpriseAdmins      = (Get-AD -Identity $EnterpriseAdminsSID).SamAccountName
$ProtectedUsers        = (Get-AD -Identity $ProtectedUsersSID).SamAccountName
$EveryOne              = $EveryOneSID.Translate([System.Security.Principal.NTAccount]).Value
$AuthenticatedUsers    = $AuthenticatedUsersSID.Translate([System.Security.Principal.NTAccount]).Value

Using these variables, I was able to make it work on a French version of Active Directory.
Don't know how to send the modified version up here...

Active Directory Groups

Would it be possible to include a list of all empty groups and the last time they were potentially modified?

Include DSInternals?

Hi,

I'm testing DSInternals PS Module and I found it very nice.
https://github.com/MichaelGrafnetter/DSInternals

It quickly generates a password quality report like this (empty for this example) :

Active Directory Password Quality Report
----------------------------------------

Passwords of these accounts are stored using reversible encryption:

LM hashes of passwords of these accounts are present:

These accounts have no password set:

Passwords of these accounts have been found in the dictionary:

These groups of accounts have the same passwords:

These computer accounts have default passwords:

Kerberos AES keys are missing from these accounts:

Kerberos pre-authentication is not required for these accounts:

Only DES encryption is allowed to be used with these accounts:

These accounts are susceptible to the Kerberoasting attack:

These administrative accounts are allowed to be delegated to a service:

Passwords of these accounts will never expire:

These accounts are not required to have a password:

These accounts that require smart card authentication have a password:

It's easy to install as it's in PSGallery (at least for WS 2016+): Install-Module -Name DSInternals
It would be great to add this toy to go deeper in password auditing, but I don't know how much to integrate it as it needs to be installed first.

What do you think about it?
I think the better way to integrate it would be to do the checks only if the module is found and tell the user to download/install it manually if not present (I wouldn't like a script to do this for me)

Method Not Found - op_Division

Hi,

Has anyone seen the below on a Windows2012R2 machine?
Does this relate to this reference?

[+] PS>Import-Module Grouper.psm1 ; Invoke-AuditGPOReport -Path C:\GPOReport.xml -Level 3
Method invocation failed because [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection] does not contain a
method named 'op_Division'.

At C:\Users\Administrator\Desktop\xxxxx\AdAudit.ps1:258 char:9

  •     Write-Progress -Activity "Identifying which GPOs apply to which OUs..."  ...
    
  •   + CategoryInfo          : InvalidOperation: (op_Division:String) [], RuntimeException
      + FullyQualifiedErrorId : MethodNotFound
    

adaudit.nessus

Hello

With which software do you recommend using the adaudit.nessus file?

Thank you

Administrators Group

Useful to list the "Administrators" group for the domain as well
These lines have been added throughout the script, although not fully tested yet

$script:Administrators                 = New-Object System.Security.Principal.SecurityIdentifier "S-1-5-32-544"
Write-Both "    [+] Administrators               : $Administrators"

if(($Administrators | measure).count -ne 0){
        Write-Both "    [!] Administrators!!!"
    foreach($member in $Administrators){
        Add-Content -Path "$outputdir\administrators.txt" -Value "$($member.objectClass) $($member.SamAccountName) $($member.Name)"
    }
}

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.