Lab 10 — Hardening AD as Code¶
Hands-on lab · ← Back to the module concept
Setup¶
git clone https://github.com/plaintext-security/plaintext-labs
cd plaintext-labs/active-directory/10-hardening-ad
make up # start the Samba4 DC + hardening-tools container
make demo # run dacledit ACL audit against the Corp DC
make shell # interactive shell
make down
The lab includes:
- Samba4 DC with the Corp misconfigurations from modules 02-09.
- A tools container with dacledit.py, ldapsearch, and Ansible.
- data/hardening-checklist.md — a CIS-aligned AD hardening checklist with the Corp gap analysis.
- data/ad-hardening.yml — a starter Ansible playbook documenting remediations as tasks.
All hardening is against your own lab domain. No external targets.
Scenario¶
You are the AD hardening lead at Corp, following the red team engagement from modules 02-08. Your job: run an automated posture audit to score the current state, identify the highest-risk findings, and produce an Ansible playbook that remediates the top 5 findings. The playbook should be reviewable, idempotent, and verifiable.
Do¶
-
[ ] Run the ACL posture audit. Read the ACLs on the three highest-risk objects (start with
IT-Admins) withdacledit.py. Identify: which principals have write rights, and do any non-default accounts appear? -
[ ] Audit Kerberoastable accounts. Run the ldapsearch from module 02 for SPNs. Count the accounts and their password ages from
data/corp-domain.md. Score: 3 Kerberoastable accounts with multi-year-old passwords = HIGH risk. -
[ ] Audit no-preauth accounts. Query for
DONT_REQUIRE_PREAUTH. Two accounts = HIGH risk. -
[ ] Audit unconstrained delegation. Query for the delegation flag. One non-DC account = HIGH risk.
-
[ ] Review
data/hardening-checklist.md. Go through each item. For the Corp domain, mark each as: Compliant / Non-compliant / Not Applicable. Calculate a rough score (compliant / total applicable). -
[ ] Review and extend
data/ad-hardening.yml. Open the Ansible playbook. It documents the remediations as tasks, withansible.builtin.debugtasks that print what the real remediation would do (since we can't apply changes via WinRM to a Samba4 container in this lab without extra setup). Add at least two tasks: - A task to remove the
DONT_REQUIRE_PREAUTHflag fromsvc-legacy - A task to rotate
svc-mssql's password to a random 25-char value
Have a model draft the task YAML; you verify the module name and parameter names against the Galaxy docs.
-
[ ] Apply two fixes to the live DC and prove the attack is dead (the build half). Authoring the playbook isn't the same as proving it works. The Ansible-over-WinRM path isn't wired against a Samba4 container — but the DC is fully mutable with
samba-tool, so prove your remediations actually close the holes. From the tools container, apply the two highest-value fixes directly: clearDONT_REQUIRE_PREAUTHonsvc-legacyand rotatesvc-mssql's password (the same changes your playbook tasks describe). Then re-run the attacks they were meant to break: the AS-REP roast againstsvc-legacymust now fail, and re-runposture-audit.pyto show the score climb and those HIGH findings cleared. Capture the before/after. A hardening playbook you never prove against the live domain is documentation, not a control. -
[ ] Write the measured posture delta. Using the real before/after from step 7 (not a conceptual estimate): how much did the score move, and how many module-08 attack paths are now broken? Note which findings your two applied fixes resolved versus which remain in the playbook for a WinRM-capable environment.
Success criteria — you're done when¶
- [ ] You have run
dacledit.pyand identified the ACL misconfigurations. - [ ] You have a completed posture checklist with Corp compliance scores.
- [ ] The Ansible playbook has at least 7 tasks (5 from the starter + 2 you added).
- [ ] Each task has a descriptive
name:and the correct module + parameters. - [ ] You applied two fixes to the live DC with
samba-tooland proved them: the AS-REP roast againstsvc-legacynow fails andposture-audit.pyshows those HIGH findings cleared. - [ ] You have a measured posture delta (from the real before/after), not a conceptual estimate.
Deliverables¶
data/hardening-checklist.md (with your Corp compliance annotations) + data/ad-hardening.yml (extended with your tasks) + posture-report.md (the scored gap analysis and the measured before/after posture delta, including the proof that the AS-REP roast against svc-legacy now fails). Commit all three.
Automate & own it¶
Required. Write posture-audit.py — a Python script that queries the DC via ldap3 and produces a scored posture report: checks for each risk category (Kerberoastable SPNs, no-preauth accounts, unconstrained delegation, privileged group size, GPO audit status), with a pass/fail and a severity rating. Have a model draft the LDAP queries for each check; you verify the filter strings and the flag values (e.g., userAccountControl bit values) against the Microsoft documentation. The output should be a clean, machine-readable JSON report. Commit it.
AI acceleration¶
Paste the hardening checklist items into a model and ask it to generate Ansible tasks for each. Review each task's module name against the microsoft.ad collection docs — the model frequently uses win_* module names that have been replaced. Also ask the model to add --check-mode compatibility to each task (idempotent, doesn't change state on a check run).
Connects forward¶
The posture audit script becomes the recurring measurement tool in module 11. The Ansible playbook is the "harden as code" deliverable for the track capstone. The detection rules from module 09 + the hardening from this module together define the "before and after" posture story.
Marketable proof¶
"I run automated Active Directory posture audits with dacledit and custom scripts, score findings against a CIS-aligned checklist, and express remediations as an Ansible playbook — reviewable, idempotent, and ready for a pull request."
Stretch¶
- Integrate the posture audit script into GitHub Actions: on every push, run the audit against the Samba4 lab DC (using
make upin CI) and post the score as a PR comment. Research whether Ansible's--checkmode can be used in CI to validate playbook syntax without applying changes. - Research LAPS (Local Administrator Password Solution) deployment via Ansible. Write a task that deploys the LAPS GPO setting to the Finance OU computer objects. What does LAPS prevent? What does it not prevent?
Comments
Sign in with GitHub to comment. Choose the type: Feedback (errors or suggestions on this page) · Hints (help for fellow learners — no spoilers) · General (anything else).