Starting the box
Link to the box: https://app.hackthebox.com/machines/DarkCorp.
Port Scan
We start off the box by running a port scan on the provided IP.Attacker Linux
Terminal Output
- Port 22 (SSH) is open running OpenSSH 9.2p1 on Debian
- Port 80 (Web Server) is open running nginx 1.22.1
- The HTTP title indicates “DripMail” - likely an email service
- The underlying OS is Linux (Debian)
Edit the Hosts file
As always, we edit the/etc/hosts file to add the hostname:
Attacker Linux
/etc/hosts
Initial Foothold
Enumerating Port 80: Web Server (drip.htb)
Let’s check out the web server athttp://drip.htb:
Subdomain Enumeration
We’ll enumerate subdomains to find additional targets:Attacker Linux
Terminal Output
- Nice. We found a new target:
mail.drip.htb - Remember to add this into our hosts file
/etc/hosts
Manual Enumeration
We can sign up for an account athttp://drip.htb/register:
Credentials
http://mail.drip.htb, and there is a welcome email:
Terminal Output
Terminal Output
- The service is running Roundcube Webmail 1.6.7
- This version is potentially vulnerable to CVE-2024-42009
Terminal Output
- Security engineer:
[email protected]- This is likely our target
RoundCube XSS (CVE-2024-42009)
Researching the vulnerability:- Government Emails at Risk: Critical Cross-Site Scripting Vulnerability in Roundcube Webmail | Sonar
- CVE-2024-42009: A Cross-Site Scripting vulnerability in Roundcube through 1.5.7 and 1.6.x through 1.6.7 allows a remote attacker to steal and send emails of a victim via a crafted e-mail message that abuses a Desanitization issue in
message_body()inprogram/actions/mail/show.php
bgcolor from the body tag:
Vulnerable Regex
- This regex removes any
bgcoloralongside some optional quotation marks anywhere within the body tag - We can trick the regex into breaking other attributes
- The regex removes
bgcolor=foo", causing the syntax to break and allowing ouronanimationstarthandler to execute
http://drip.htb/index#contact:
HTTP Request
- The
content=htmlparameter is crucial for the payload to work - Success! The XSS triggers when the recipient opens the email
Stealing bcase’s Email
Let’s craft a payload to steal emails from[email protected]. First, we’ll test with a simple fetch:
- Note: We need to use single quotes inside the
onanimationstarthandler to avoid breaking the syntax
[email protected]:
HTTP Request
Terminal Output
- New domain discovered:
dev-a3f1-01.drip.htb - We need to reset bcase’s password to access the dashboard
Terminal Output
- We can now reset bcase’s password and access the dashboard
Discovering the Development Dashboard
Additional Hostname Enumeration
Let’s take a step back. We noticed that we haven’t addeddarkcorp as a domain to our hosts file yet. This is important for CTF boxes:
Attacker Linux
/etc/hosts
darkcorp.htb:
Attacker Linux
- No additional subdomains found
Directory Enumeration on darkcorp.htb
Let’s run directory enumeration ondarkcorp.htb:
Attacker Linux
Terminal Output
- We found a
/dashboarddirectory with multiple subdirectories - The structure suggests this is a Flask application
/authenticationlooks particularly interesting
dirsearch to find configuration files:
Attacker Linux
Terminal Output
- We found a
.envfile! This typically stores environmental variables and credentials
.env file:
/dashboard/.env
- PostgreSQL database credentials:
dripmail_dba:2Qa2SsBkQvsc - Flask secret key:
GCqtvsJtexx5B7xHNVxVj0y2X0m10jq - This is valuable information for later exploitation
Attacker Linux
Terminal Output
- We can read the Flask application source code!
routes.py, we found the password reset functionality:
- This confirms the
dev-a3f1-01.drip.htbdomain we found earlier
Accessing the Dashboard
After resetting bcase’s password using the stolen reset token, we can log into the dashboard athttp://dev-a3f1-01.drip.htb:
Terminal Output
- We can see user information including IP addresses
- The
testuser has a different IP:172.16.20.1- suggesting an internal network
Exploiting SQLi in dev-a3f1-01.drip.htb
The dashboard has a search function that returns interesting error messages:Terminal Output
- The error reveals we’re dealing with PostgreSQL via SQLAlchemy
- The application uses
psycopg2for database connections
'bcase' (with quotes) returns results. This suggests SQL injection:
Attacker Linux
- This returns all users, confirming SQL injection
UNION appear to be filtered. Let’s enumerate the database manually using Stacked Queries:
SQL Injection Payload
- Tables found:
Users,Admins
SQL Injection Payload
- Columns:
id,username,password,email
SQL Injection Payload
Terminal Output
- We found password hashes for multiple users
ebelfordis particularly interesting as it appeared in the user list
PostgreSQL File Read and RCE
Since we have SQL injection in PostgreSQL, we can leverage powerful built-in functions. Let’s test file reading:SQL Injection Payload
Terminal Output
- File read works! We can see
bcaseandebelfordare system users
SQL Injection Payload
Terminal Output
COPY command can execute system commands, but it appears to be filtered by WAF. We can bypass this using obfuscation:
SQL Injection Payload
- This stores
C O P Yand the command into variablec, then executes it - The WAF cannot detect the keyword because it’s obfuscated using
CHR()functions
Attacker Linux
Terminal Output
- Success! We have a shell as the
postgresuser
Pivoting to ebelford
Enumerating the System
Let’s check the hosts file for network information:Terminal Output
- We’re on
172.16.20.3(drip.darkcorp.htb) - There’s a domain controller at
172.16.20.1(DC-01.darkcorp.htb) - This indicates an Active Directory environment
Terminal Output
- Confirmed: we’re on the
172.16.20.0/24network
Finding Credentials in Database Logs
Since we’re running as thepostgres user, we should check PostgreSQL logs for sensitive information. LinPEAS might not catch these:
Victim Linux
Terminal Output
- We found ebelford’s password hash being updated in the logs!
- Hash:
8bbd7f88841b4223ae63c8848969be86
Attacker Linux
Terminal Output
- Successfully cracked:
ThePlague61780
Alternative Path - PostgreSQL Backups
There’s also an alternative way to find credentials. Someone hinted that credentials exist in/var/backups/postgres:
Victim Linux
Terminal Output
- We found an encrypted GPG file
Victim Linux
- It requires a passphrase
Terminal Output
- Success! The backup decrypts
Terminal Output
- We found another user:
victor.rwith hashcac1c7b0e7008d67b6db40c03e76b9c0 - This is likely a Windows domain user
Attacker Linux
Terminal Output
- Successfully cracked:
victor1gustavo@#
SSH Access as ebelford
Let’s SSH as ebelford:Attacker Linux
Credentials
- Successfully authenticated!
Enumerating the Internal Network
Setting up for Lateral Movement
Since we need to access the internal172.16.20.0/24 network, we’ll set up Ligolo for pivoting.
First, download the Ligolo agent to the compromised host:
Victim Linux (ebelford)
Victim Linux (ebelford)
Attacker Linux
- Ligolo creates a tunnel allowing us to access the internal network directly
Attacker Linux
Credentials
- This creates a VPN-like tunnel to the internal network without needing to upload additional binaries
Network Discovery
Let’s scan the internal network for SMB hosts:Attacker Linux
Terminal Output
- DC-01: Domain Controller at
172.16.20.1(SMB signing enabled) - WEB-01: Web server at
172.16.20.2(SMB signing disabled - potential relay target!)
Attacker Linux
Terminal Output
- Success!
victor.ris a valid domain account
Attacker Linux
Terminal Output
- Multiple administrative accounts with
.admsuffix svc_acc- likely a service account
Attacker Linux
- No AS-REP roastable accounts found
Bloodhound Enumeration
Let’s run Bloodhound to map the Active Directory environment. Unfortunately, Ligolo has DNS resolution issues with Bloodhound, so we’ll use SSH dynamic port forwarding with proxychains instead. Setting up SSH dynamic port forwarding:Attacker Linux
Credentials
Attacker Linux
/etc/proxychains4.conf
- The
dnatline ensures traffic to10.10.11.54is routed to the actual DC at172.16.20.1
--dns-tcp flag:
Attacker Linux
taylor.b.admis a GPO manager and can PSRemotesvc_acchas DNSAdmin privileges
Enumerating SMB Shares
Attacker Linux
Terminal Output
- We have access to
CertEnroll- this suggests ADCS (Active Directory Certificate Services) is in use
Attacker Linux
Terminal Output
- ADCS is present but looks complex to exploit
Enumerating WEB-01
Let’s scan WEB-01 for additional services:Attacker Linux
Terminal Output
- Port 5000 is running IIS with NTLM authentication
- Port 5985 (WinRM) is open for PSRemoting
NTLM Relay Attack
Web Dashboard SSRF
Let’s try accessing port 5000 with NTLM authentication:Attacker Linux
- This works! The browser login wasn’t working due to Burp Proxy intercepting the NTLM authentication
- There’s a “Check Status” functionality that looks interesting
HTTP Request
HTTP Response
- The application performs health checks on arbitrary hosts!
- This is an SSRF vulnerability
Attacker Linux
Terminal Output
- Detailed error messages reveal this is a Python application using
urllib3 - When the application connects to an HTTP endpoint, it will authenticate using NTLM
- We can relay this authentication!
Relaying to Domain Controller
Since we’re on thedrip.darkcorp.htb host (172.16.20.3), we can make the application connect back to us and relay the authentication to the Domain Controller.
First, let’s update our hosts file on the DC:
Attacker Linux
/etc/hosts
ntlmrelayx with multiple targets:
targets.txt
Attacker Linux
- The
-wflag starts a web server to capture the authentication --output-filewill capture hashes for logging
Victim Linux
drip.darkcorp.htb (which we control via SSH), and from there relay to the DC:
Attacker Linux
Victim Linux (via SSH)
Attacker Linux
Attacker Linux
Attacker Linux
Attacker Linux
Terminal Output
- Success! We relayed
svc_acc’s authentication to the LDAP server - We now have an interactive LDAP shell as
svc_acc
Attacker Linux
Terminal Output
- We have an LDAP shell, but it’s limited in functionality
- The relay was successful, proving we can abuse the SSRF
Privilege Escalation
Abusing GPO as taylor.b.adm
Finding taylor.b.adm Credentials
From our Bloodhound analysis, we know thattaylor.b.adm is a GPO manager with PSRemote capabilities. Let’s try to find credentials for this account.
Since direct ADCS exploitation looks complex, let’s try password spraying:
Attacker Linux
Terminal Output
- Success! Credentials:
taylor.b.adm:!QAZzaq1
WinRM Access
Let’s connect via WinRM:Attacker Linux
- Successfully connected to the Domain Controller!
GPO Abuse
Sincetaylor.b.adm is a GPO manager, we can abuse Group Policy to escalate privileges. We’ll use pygpoabuse to create a scheduled task that adds a new admin user.
First, identify the GPO we can modify. From Bloodhound or by listing GPOs:
Victim Windows (DC-01)
Terminal Output
- The GPO ID is:
652CAE9A-4BB7-49F2-9E52-3361F33CE786
Attacker Linux
Terminal Output
- The tool created a scheduled task via GPO that will add a backdoor user
Victim Windows (DC-01)
Victim Windows (DC-01)
Terminal Output
- New user
johnhas been created! - Default credentials from pygpoabuse:
john:H4x00r123..
Attacker Linux
Terminal Output
- Confirmed!
johnhas administrative privileges
Dumping Domain Secrets
Now we can dump the domain secrets:Attacker Linux
Terminal Output
- Administrator NTLM hash:
fcb3ca5a19a1ccf2d14c13e8b64cde0f
Getting the Flags
User flag from WEB-01:Attacker Linux
Terminal Output
Attacker Linux
Victim Windows (DC-01)
Terminal Output
- Box complete!
Learning
1. CVE-2024-42009 - RoundCube XSS via Regex Desanitization
A Cross-Site Scripting vulnerability in Roundcube Webmail 1.6.7 allows attackers to steal emails by exploiting a regex pattern that removesbgcolor attributes. By crafting payloads like <body title="bgcolor=foo" name="bar onload=...">, the regex incorrectly removes bgcolor=foo", breaking the syntax and allowing JavaScript execution. This can be used to exfiltrate emails from targets who open malicious messages.
2. Always Enumerate All Domains Thoroughly
Don’t forget to add the box name as a domain in your hosts file (e.g.,darkcorp.htb in addition to drip.htb). Different domains may expose different applications and attack surfaces. Always perform both subdomain enumeration and directory busting on all discovered domains.
3. PostgreSQL Arbitrary File Read and RCE via SQL Injection
When you have SQL injection in PostgreSQL, you can leverage powerful built-in functions:pg_read_file('/path/to/file', offset, length)- Read arbitrary filespg_ls_dir('/path/')- List directory contentsCOPY (SELECT ...) TO PROGRAM 'command'- Execute system commands
COPY keyword, bypass it using character concatenation:
4. Check Database Logs and Backup Files When Running as Database User
When you compromise a database service account (likepostgres), always check:
- Database logs:
/var/log/postgresql/- May contain cleartext credentials from UPDATE/INSERT statements - Backup files:
/var/backups/postgres/- May contain GPG-encrypted database dumps - Configuration files: May contain passwords for decrypting backups
5. Pivoting Tools for Internal Networks - Ligolo, SSHuttle, and Proxychains
When you need to access internal networks through a compromised host, use Ligolo for efficient tunneling:/etc/proxychains4.conf:
dnat line is crucial for routing traffic to the correct internal host. Use proxychains4 to run tools through the tunnel.
6. NTLM Relay via SSRF
When you find an SSRF vulnerability in a Windows application that performs HTTP requests, the application may authenticate using NTLM. You can relay this authentication to other services:- Set up
impacket-ntlmrelayxtargeting LDAP or SMB on the Domain Controller - Use SSH port forwarding to make your relay server accessible from the internal network
- Trigger the SSRF to connect to your relay server
- Capture and relay the authentication to escalate privileges
7. GPO Abuse for Privilege Escalation
Users withWriteProperty, WriteDacl, or GenericAll permissions on Group Policy Objects can abuse GPOs to gain Domain Admin:
- Identify the target GPO ID from the SYSVOL path:
\\domain\SYSVOL\domain\POLICIES\{GPO-ID} - Use tools like
pygpoabuse.pyto add a scheduled task via GPO:
- Force a GPO update:
gpupdate /force - The tool creates a backdoor admin user (
john:H4x00r123..by default) - Use the new admin account to dump domain secrets

