Judge - Complete Penetration Testing Walkthrough
Introduction
This is a complete walkthrough and writeup for the Judge machine from the Ronin66 lab. Judge is an Assumed Breach engagement — we start with a set of low-privilege domain credentials and a single DC running Windows Server 2019. The goal is to work through the ACL chain that BloodHound exposes, abuse a GPO we can write to, and land Domain Admin.
Tools Used: NetExec, BloodHound, bloodyAD, smbclient, strings, pygpoabuse, Evil-WinRM
Difficulty: Easy / Medium
Key Techniques: BloodHound enumeration, ForceChangePassword abuse, SMB share credential hunting, GPO abuse (GenericWrite / WriteDacl / WriteOwner → scheduled task), Domain Admin via gpupdate /force
Starting Credentials: d.taylor (low-privilege domain user)
Environment:
- Domain:
judge.local - DC:
DC01— Windows 10 / Server 2019 Build 17763 x64 - DC IP:
172.16.18.13
BloodHound Enumeration
Collecting with NetExec
We begin with BloodHound collection straight over LDAP using our starting credentials — no need to drop a collector binary on the box:
1 | netexec ldap 172.16.18.13 -u 'd.taylor' -p '<REDACTED>' --bloodhound --dns-server 172.16.18.13 -c All --dns-tcp |
We load the resulting zip into BloodHound and start tracing attack paths from d.taylor.
ACL Abuse — ForceChangePassword on s.wilson
Finding the Edge
BloodHound shows that d.taylor holds ForceChangePassword over s.wilson. That edge lets us reset the account’s password without knowing the current one.
Resetting the Password
We use bloodyAD to set a new password for s.wilson:
1 | bloodyAD --host "172.16.18.13" -d "judge.local" -u "d.taylor" -p '<REDACTED>' set password "s.wilson" "<REDACTED>" |

We now control s.wilson.
SMB Enumeration — SCRIPTS Share
Checking Share Access
With s.wilson‘s new credentials we enumerate available shares:
1 | netexec smb 172.16.18.13 -u 's.wilson' -p '<REDACTED>' --shares |

s.wilson has read access to the SCRIPTS share — a classic AD artefact that often hides credentials.
Pulling the Share Contents
We connect to the share and grab everything inside:
1 | smbclient //172.16.18.13/script -U 'judge.local\s.wilson%<REDACTED>' |
A file called mount.bat catches our eye. We carve strings out of it:
1 | strings mount.bat |

The batch file contains a hardcoded credential for the user e.brown.
ACL Abuse — GPO Takeover via e.brown
BloodHound — Permissions Over Default Domain Policy
Back in BloodHound we check what e.brown can do. The account holds three powerful edges over the Default Domain Policy GPO ({31B2F340-016D-11D2-945F-00C04FB984F9}):
GenericWriteWriteDaclWriteOwner

That combination is effectively full control — we can take ownership, rewrite the DACL, and modify the GPO itself. Since the Default Domain Policy applies to every computer in the domain, any code we inject runs everywhere on the next GPO refresh.
Taking Ownership
First we set the owner of the GPO to e.brown so we can freely modify its DACL:
1 | bloodyAD --host "172.16.18.13" -d "judge.local" -u "e.brown" -p '<REDACTED>' \ |
Granting GenericAll
With ownership established we grant ourselves GenericAll on the GPO object, removing any remaining permission barriers:
1 | bloodyAD --host "172.16.18.13" -d "judge.local" -u "e.brown" -p '<REDACTED>' \ |
Injecting a Scheduled Task via pygpoabuse
Now we write a scheduled task into the GPO that adds e.brown to Domain Admins on the next policy refresh. We use the -f flag to append to the existing ScheduledTasks.xml rather than overwrite it — overwriting would break the existing policy and create noise:
1 | python3 pygpoabuse.py judge.local/'e.brown':'<REDACTED>' \ |
Triggering the GPO — Domain Admin
Forcing a Policy Update
We open a WinRM session as e.brown and force an immediate GPO refresh:
1 | evil-winrm -i dc01.judge.local -u 'e.brown' -p '<REDACTED>' |
1 | gpupdate /force |
We close the session and reconnect. On the second login the scheduled task has already fired and e.brown is a Domain Admin.

The DC is ours.
Conclusion
Judge was a clean ACL-chain box that rewarded reading the BloodHound output carefully and following the privilege edges in order:
- ForceChangePassword —
d.taylor→s.wilson, no brute force needed - SCRIPTS share —
mount.bathanded use.brown‘s credential in plaintext - GPO abuse —
WriteOwner+WriteDacl+GenericWriteover the Default Domain Policy is full domain compromise waiting to happen;pygpoabusemade it a one-liner gpupdate /force— instant task execution, no waiting for the 90-minute refresh cycle
The lesson: ACL edges on GPOs — especially the Default Domain Policy — are some of the most dangerous misconfigurations in Active Directory. A single account with WriteOwner there can own the entire domain in under five minutes.
Tools Used
- NetExec
- BloodHound
- bloodyAD
- smbclient
- strings
- pygpoabuse
- Evil-WinRM