Kafka Connect 4.3.1 — высокий уровень — остаточный classpath Windows FileStream — неавторизованное чтение/запись файлов
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · kafka-connect-filestream-win
Apache Kafka Connect 4.3.1 (26b251a) - Apache Software Foundation
KAFKA-13748 убрал FileStream из Unix Connect CLASSPATH, чтобы неаутентифицированный REST не мог открывать локальные файлы. В Windows-лаунчере это исключение так и не появилось. В tarball по-прежнему connect-file попадает в libs/. kafka-run-class.bat объединяет все jar-файлы оттуда.
Неаутентифицированный POST /connectors на worker'е, запущенном под Windows, читает и дописывает файлы, доступные UID процесса Connect.
| ID | CVE пока нет |
| CWE | CWE-552, CWE-1188 |
| CVSS | High: 9.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N |
| Продукт | Apache Kafka Connect |
| Затронуто | 4.3.1 (26b251a); Windows bin/windows/kafka-run-class.bat. Unix .sh уже исключает connect-file. |
| Аутентификация | неаутентифицированный Connect REST (по умолчанию listeners=http://:8083, без rest.extension.classes) |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1 |
Направьте браузер или curl на Connect REST на worker'е, запущенном с поставляемыми Windows .bat-файлами. Создайте источник FileStream. Worker откроет любой путь, который вы укажете в file, и отправит байты в топик Kafka. Создайте приёмник FileStream. Worker создаст или допишет любой путь, который вы укажете в file. Никакого allowlist нет.
Unix-лаунчер уже отбрасывает connect-file.*.jar. Тот же JSON против стандартного connect-distributed.sh даёт 400: неизвестный коннектор. Стандартный Docker-образ apache/kafka — это Linux-брокер. Этот остаток — Windows CLASSPATH.
Сначала я прочитал список CVE Kafka: JAAS Jndi/Ldap, allowlist URL OAUTHBEARER, DefaultJwtValidator, ConfigProvider, публичный JIRA по FileStream. В Unix kafka-run-class.sh всё ещё есть исключение:
regex="(-(test|test-sources|src|scaladoc|javadoc)\.jar|jar.asc|connect-file.*\.jar)$"
cc_pkg также не включает file. Затем я открыл Windows-версию:
for %%p in (api runtime file json tools) do (
for %%i in ("%BASE_DIR%\connect\%%p\build\libs\connect-%%p*.jar") do (
call :concat "%%i"
)
)
rem Classpath addition for release
for %%i in ("%BASE_DIR%\libs\*") do (
call :concat "%%i"
)
build.gradle по-прежнему копирует connect-file в libs/. В документации сказано, что FileStream не входит в CLASSPATH по умолчанию. Это утверждение верно для .sh.
Doyensec описали этот класс в 2022 году. KAFKA-13748 / PR 11908 было исправлением для Unix. .bat так и не обновили.
Уже зафиксированные ошибочные пути: Wine; выполнение .bat на macOS; рассмотрение plugin.path как дыры (он пуст на обоих worker'ах); утверждение, что Linux Docker — это данный баг; восприятие 201 на Unix как SUCCESS. Театр: reverse shell. Оракул — это 400 на Unix плюс строка-свидетель в файле приёмника.
cd lab
./run.sh
Unix REST 127.0.0.1:18083 — это стандартный connect-distributed.sh. Windows-симуляция 127.0.0.1:18084 — это нефильтрованный libs/*, цикл libs\* из релизного .bat. Не Wine. Брокер — apache/kafka:4.3.1 в сети compose. Привяжите его к loopback.
unix-filestream=absent unix-post=400
win-filestream=present win-source=201 win-sink=201 pwned=yes
SUCCESS kafka-connect-filestream-win ... KAFKA-CONNECT-FILESTREAM-WIN-WITNESS
Добавьте в kafka-run-class.bat то же исключение connect-file, которое уже есть в .sh. Уберите file из цикла for %%p in (api runtime file json tools) в gradle-from-source. Продолжайте поставлять jar для тех, кто намеренно задаёт plugin.path.
26b251a451ce941d3d7a55e6487bcb7f16b5ad48)bin/windows/kafka-run-class.bat · bin/kafka-run-class.shFileStreamSourceTask.java · FileStreamSinkTask.java