Professional bachelor's (ASS&R)Production4 min read

Auditing and hardening a production Active Directory

A directory that had never been audited since it was created, which I measured with PingCastle and then fixed in production, one weakness at a time.

Context
Production · small business, 808 objects, two Windows Server domain controllers
Period
June – September 2026
My role
Led independently; account changes approved by management
Tools
PingCastle · PowerShell · GPO · auditpol · repadmin

In short

The problem

An 808-object Active Directory that had never been audited: a PingCastle score of 100/100, the worst possible, and no test environment.

What I did

I ranked the findings by real-world risk and fixed them in production: SMBv1, krbtgt, NTLMv1, privileged accounts and 169 stale objects.

The result

“Anomalies” score down from 100 to 74, 169 stale objects deleted, SMBv1 removed from the controller and existing Golden Tickets invalidated, with no unplanned downtime.

100 → 74PingCastle “Anomalies” score
169stale objects deleted
11 yearsage of the krbtgt password before rotation

Context

The directory had been created with the company and never audited since. It held 808 objects for about twenty real users: former employees, machines that no longer existed, leftovers from an Exchange server migrated to Microsoft 365.

Two constraints: no test environment, so every command ran on the production controllers; and no unannounced downtime, with management sign-off for any change to an account.

PingCastle console: choosing the domain to analyse, starting the task and detecting about 808 objects; the domain name is masked.
Fig. 1Running the PingCastle 3.5 audit in privileged healthcheck mode on the production domain: about 808 Active Directory objects analysed.

What I did

  1. Measure, then prioritiseFirst PingCastle scan: 100/100 in three of the four categories. I ranked the findings by what an attacker could do with them, not only by points.
  2. Remove SMBv1 without breaking anythingFive days of SMBv1 access auditing: none. Disabled, uninstalled, then the primary controller rebooted while the second one handled authentication.
  3. Rotate krbtgt twiceIts password had not changed in 11 years: a Golden Ticket forged during that time was still valid. Two rotations five days apart invalidate it.
  4. Clean up accounts without deleting directlyEach object was disabled, moved to a “Quarantine” OU, observed, and only then deleted: 100 computers and 69 accounts in total.
  5. Close weak access pathsNTLMv1 and LM refused by GPO, 11 admin accounts protected against delegation, minimum password length raised from 1 to 10 characters, advanced auditing sent to the Wazuh SIEM.
See technical details
Initial findingRiskPoints
SMBv1 enabled on the domain controllerUnauthenticated remote code execution (EternalBlue)100
krbtgt unchanged for 4,019 daysGolden Tickets still valid50
74% of computer accounts inactiveReusable accounts nobody watches30
Administrators without the “sensitive account” flagCredential theft through Kerberos delegation20
NTLMv1 and LM acceptedHashes that can be captured and cracked quickly15

PowerShell · removing SMBv1

# Listen before cutting: who still uses SMBv1?
Set-SmbServerConfiguration -AuditSmb1Access $true -Force
Get-WinEvent -LogName "Microsoft-Windows-SMBServer/Audit" | Where-Object Id -eq 3000

# No access in 5 days: disable, then uninstall
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart

# After the reboot (the second controller handles authentication):
# force replication to check it resumes without errors
repadmin /syncall /AdeP

PowerShell · quarantine (excerpt)

$quarantaine = "OU=Quarantaine,DC=corp,DC=local"
Import-Csv .\postes_inactifs.csv | ForEach-Object {
    $pc = Get-ADComputer $_.Name
    Disable-ADAccount -Identity $pc
    Move-ADObject -Identity $pc.DistinguishedName -TargetPath $quarantaine
    Add-Content C:\Temp\log_postes.txt "$(Get-Date -Format s);$($pc.Name);quarantaine"
}
Windows security policy setting window: LAN Manager authentication level set to send NTLM version 2 responses only.
Fig. 2Domain controller policy set to “Send NTLMv2 response only, refuse LM and NTLM”, which shuts out LM/NTLMv1 authentication.
Two extracts of the domain password policy: before, complexity disabled and a minimum length of 1 character; after, complexity enabled and 10 characters.
Fig. 3Domain password policy before and after the fix: minimum length raised from 1 to 10 characters and complexity enabled.
Two audit policy tables: before, almost every category is set to No auditing; after, directory access, logons, account management and privilege use are audited for success and failure.
Fig. 4Domain controller audit policy before and after: key categories move from “No auditing” to “Success, Failure”.
FixMITRE ATT&CK technique mitigated
SMBv1 uninstalledT1210 · exploitation of remote services (EternalBlue, MS17-010)
Double krbtgt rotationT1558.001 · Golden Ticket: tickets already forged are invalidated, not those a new theft of the key would allow
NTLMv1 and LM refusedT1557 · authentication interception: captured LM and NTLMv1 responses no longer crack in minutes
Stale accounts deletedT1078 · valid accounts: fewer dormant accounts to hijack
MachineAccountQuota set to 0T1136.002 · domain account creation (computer accounts)

The incident

A privileged account can no longer log in remotely

Problem

A few minutes after their account was added to the Protected Users group, their remote desktop connection was refused.

Fix

Removed from the group, delegation reset, session fully closed: access restored the same day. Since then, I test every addition on a non-critical account with the same usage, and I warn the user beforehand.

Results

At the last scan, in August 2026, SMBv1 was uninstalled, the krbtgt password was less than ten days old, LM and NTLMv1 were refused, and a standard user could no longer join a machine to the domain. Work that required a maintenance window was handed to management as a roadmap.

PingCastle gauge for the Anomalies category, at 74 out of 100.
Fig. 5Final PingCastle scan (August 2026): the “Anomalies” category brought down from 100 to 74/100.

What I would improve

  • Enable the Active Directory Recycle Bin and back up the controllers' system state before any deletion.
  • Use Microsoft's krbtgt reset script, which checks replication between each step.
  • Aim for a 12-character minimum, as recommended by ANSSI (the French cybersecurity agency), and deploy advanced auditing through GPO.

Skills

  • Active Directory security audit
  • Kerberos and privileged accounts
  • GPO
  • PowerShell
  • Change management in production
  • Communicating risk to management