Kafka Connect 4.3.1 - Alta - Resíduo de classpath do Windows FileStream - leitura/escrita de arquivos sem autenticação
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 removeu o FileStream do CLASSPATH do Connect no Unix para que o REST não autenticado não pudesse abrir arquivos locais. O launcher do Windows nunca recebeu essa exclusão. O tarball ainda inclui connect-file em libs/. O kafka-run-class.bat concatena todos os jars que estão lá.
POST /connectors não autenticado em um worker iniciado no Windows lê e anexa arquivos que o UID do Connect pode acessar.
| ID | sem CVE ainda |
| CWE | CWE-552, CWE-1188 |
| CVSS | Alto: 9.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N |
| Produto | Apache Kafka Connect |
| Afetado | 4.3.1 (26b251a); Windows bin/windows/kafka-run-class.bat. O .sh do Unix já exclui connect-file. |
| Autenticação | Connect REST não autenticado (padrão listeners=http://:8083, sem rest.extension.classes) |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1 |
Aponte um navegador ou curl para o Connect REST em um worker iniciado com os arquivos .bat do Windows fornecidos. Crie um source FileStream. O worker abre qualquer caminho que você colocar em file e produz os bytes em um tópico Kafka. Crie um sink FileStream. O worker cria ou anexa qualquer caminho que você colocar em file. Não há allowlist.
O launcher do Unix já descarta connect-file.*.jar. O mesmo JSON contra o connect-distributed.sh padrão resulta em 400: conector desconhecido. O Docker padrão apache/kafka é o broker Linux. Esse resquício é o CLASSPATH do Windows.
Li primeiro a lista de CVEs do Kafka: JAAS Jndi/Ldap, allowlist de URL do OAUTHBEARER, DefaultJwtValidator, ConfigProvider, o JIRA público do FileStream. O kafka-run-class.sh do Unix ainda tem a exclusão:
regex="(-(test|test-sources|src|scaladoc|javadoc)\.jar|jar.asc|connect-file.*\.jar)$"
cc_pkg também omite file. Então abri a cópia do 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"
)
O build.gradle ainda copia connect-file para libs/. A documentação diz que o FileStream não está no CLASSPATH padrão. Essa frase é verdadeira para o .sh.
A Doyensec escreveu sobre essa classe em 2022. KAFKA-13748 / PR 11908 foi a correção para Unix. O .bat nunca foi atualizado.
Caminhos errados já registrados: Wine; executar o .bat no macOS; tratar plugin.path como a falha (ele está vazio em ambos os workers); afirmar que o Docker Linux é esse bug; tomar um 201 no Unix como SUCCESS. Teatro: um reverse shell. O oráculo é o 400 no Unix mais uma linha testemunha no arquivo sink.
cd lab
./run.sh
O REST do Unix 127.0.0.1:18083 é o connect-distributed.sh padrão. O Windows-sim 127.0.0.1:18084 é o libs/* sem filtro, o loop libs\* do .bat de release. Não é Wine. O broker é apache/kafka:4.3.1 na rede do compose. Vincule-o ao 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
Dê ao kafka-run-class.bat a mesma exclusão de connect-file que o .sh já tem. Remova file do loop for %%p in (api runtime file json tools) do gradle-from-source. Continue distribuindo o jar para quem define plugin.path de propósito.
26b251a451ce941d3d7a55e6487bcb7f16b5ad48)bin/windows/kafka-run-class.bat · bin/kafka-run-class.shFileStreamSourceTask.java · FileStreamSinkTask.java