## https://sploitus.com/exploit?id=072A2B91-1987-5144-B193-728DEAF9626A
# Active Directory Hardening & Mutual Pentest Lab
A self-contained lab where I built a Windows Server 2025 domain controller with Active Directory, hardened it against CIS/STIG baselines, and then attacked my own build to verify the hardening actually held up.
**PingCastle domain risk score: 50/100 β 30/100**
| Before | After |
|---|---|
|  |  |
## Context
This was originally scoped as a paired blue team / red team exercise (harden your own component, then pentest your partner's), but I ended up completing it solo β meaning I built, hardened, *and* attacked the same environment myself. That has an obvious limitation (see [Notes & limitations](#notes--limitations)), but it also meant I got to validate my own hardening decisions end-to-end.
## Environment
- **Domain Controller:** Windows Server 2025 with Active Directory
- **Client:** domain-joined Windows client
- **Attacker box:** Kali Linux VM
- **Assessment tools:** [PingCastle](https://www.pingcastle.com/), STIG Viewer
- **Offensive tools:** Nmap, CrackMapExec, Metasploit
## What I did
### 1. Baseline assessment
Ran an initial PingCastle scan and a first attack pass against the *unhardened* domain to establish a baseline (Domain Risk Level: 50/100).
### 2. Hardening
Focused on two areas, following CIS and DISA STIG baselines:
**Active Directory / GPO**
- Enabled Hardened UNC Paths
- Enforced NTLMv2, blocked LM/NTLM authentication
- Set `ms-DS-MachineAccountQuota` from 10 β 0 to prevent unauthorized computer joins to the domain
- Used PingCastle's findings directly to prioritize which GPO settings to fix first
**OS baseline (Windows Server)**
- Disabled unnecessary services (Print Spooler, Remote Registry, Xbox-related services on the client)
- Enforced password length/complexity and rotation policy
- Enabled Windows Firewall logging, including dropped packets
- Deployed Sysmon with logs surfaced in Event Viewer
I intentionally stopped short of maximum hardening β pushing every PingCastle rule to green risks breaking legitimate functionality, and the goal was a realistic, defensible baseline rather than a lab that's technically secure but unusable.
### 3. Re-test
Re-ran PingCastle post-hardening: **Domain Risk Level dropped from 50/100 to 30/100**, with the clearest gains in the *Stale Object* and *Privileged Accounts* indicators.
### 4. Pentest against my own hardened build
Repeated the original attack sequence against the hardened environment:
| Test | Before hardening | After hardening |
|---|---|---|
| Port 139 (NetBIOS) | β | Closed |
| Port 445 (SMB) | Open | Open, but SMB signing enforced (`signing:True`) |
| EternalBlue (MS17-010) via Metasploit | β | Not vulnerable |
SMB signing being enforced is the notable result here β it doesn't close the port, but it meaningfully raises the cost of a man-in-the-middle attack against SMB traffic. The firewall logs also confirmed that even failed attack attempts were captured, which matters as much as blocking the attack outright.
See [`docs/pentest-findings.md`](docs/pentest-findings.md) for full command output and screenshots.
## Repo structure
```
.
βββ README.md
βββ docs/
β βββ hardening-report.md # Full write-up of hardening decisions and rationale
β βββ pentest-findings.md # Full write-up of the attack/verification steps
βββ screenshots/
βββ pingcastle-before.png
βββ pingcastle-after.png
βββ firewall-log-connection-attempt.png
βββ metasploit-eternalblue-test.png
```
## Notes & limitations
- This lab was originally designed to be done in pairs, with one person hardening and the other independently attacking β that setup avoids the obvious bias of testing your own work. I completed it solo, so treat the pentest results as a sanity check on my own hardening rather than a fully independent red-team assessment.
- The environment is a lab domain, not a production one β some settings (like the aggressive `MachineAccountQuota` change) would need a change-management conversation in a real environment before rolling out.
- Given more time, the natural next step would have been centralizing logs with Wazuh rather than relying on local Event Viewer/Sysmon output.
## Tools referenced
[PingCastle](https://www.pingcastle.com/) Β· [DISA STIG Viewer](https://public.cyber.mil/stigs/srg-stig-tools/) Β· [Nmap](https://nmap.org/) Β· [CrackMapExec](https://github.com/Porchetta-Industries/CrackMapExec) Β· [Metasploit Framework](https://www.metasploit.com/)