
Roba IPMI dal lavoro DARPA
Ho scritto alcuni software per esplorare IPMI; ecco alcuni dei risultati. Ho pensato di fare il solito ciclo di rilevamento, acquisizione dati e audit. Ognuno di questi si è rivelato un problema piuttosto interessante di per sé, almeno per me.
BTW/FYI - Ho rilasciato un nuovo strumento per esplorare IPMI - https://github.com/zenfish/zipmi - così come una serie di ricette/immagini/etc. di Qemu per eseguire BMC come sistemi virtuali sotto Qemu su https://github.com/zenfish/zbmc.
I documenti e le cose da http://fish2.com/ipmi
Ecco un piccolo programma Perl che tenta di indovinare un account su un BMC remoto, estrarne l'hash, e poi provare a craccare la sua password (hashata con HMAC). Ho scritto un piccolo articolo su questo per i curiosi. Pesantemente commentato, potrebbe essere utile.
La specifica IPMI dice che puoi ottenere i cipher di un sistema remoto senza alcuna autenticazione, ma non sono a conoscenza di alcuno strumento che lo faccia davvero (tutti richiedono autenticazione, anche se ovviamente potresti inserire i byte hex grezzi se volessi!) Quindi ho scritto questo piccolo programma per farlo; per lo più cerca di seguire l'output di ipmitool; nel farlo credo di aver trovato un bug in quell'utilità (nell'ultima riga a volte i sistemi emettono della spazzatura che sembra essere interpretata male), ma chi lo sa, non ho abbastanza sistemi per testarlo. Comunque... ipmi-get-ciphers.py.
Se non altro, utile per individuare sistemi Cipher0 (nota - questo indica semplicemente i cipher supportati - non significa che siano effettivamente attivi), ma ci sono cose interessanti in giro.
Due programmi qui, uno è un semplice prober remoto in Python (sto iniziando a odiare Perl, ve lo dico io) e un secondo che usa le utilità di FreeIPMI per recuperare dati di configurazione con credenziali.
Un piccolo programma Python (oltre il 50% di commenti inline, 2.5k gzip'd) che invia un singolo pacchetto a un BMC e riflette sulla risposta. Cosa puoi fare con un solo pacchetto, uno potrebbe chiedere? 10+ diversi test di sicurezza per IPMI, tanto per cominciare. Beh, tanto per cominciare e per finire, è solo un pacchetto :) Richiede Python, un BMC e un percorso aperto verso la porta UDP 623 per funzionare. L'uso è semplicemente "ipmi-get-auth.py target".
ipmi-get-auth.py /
Una descrizione molto breve
Portando questo agli estremi... beh, ecco una specie di versione mega di quanto sopra che lo fa per tutti i canali, tutti i privilegi, tutti... beh, avete capito. Per i monomaniaci (leggete i commenti o il post che ho scritto al riguardo per capire perché fa quello che fa!)
mega_chan.py /
Mega mega mega ... chan chan chan...
Ed ecco un semplice programma per inviare un pacchetto Get Device ID (vedi p250 della specifica IPMI v 2) a un sistema. Questo dovrebbe, in teoria, funzionare senza autenticazione. In una piccola indagine che ho condotto, circa il 90% dei sistemi ha risposto a questo (anche se non tutti con informazioni valide!) A volte puoi ottenere il vendor e altre informazioni, come numeri di modello e simili, ma la cosa più interessante è ottenere un ID univoco, tradizionalmente una cosa difficile da ottenere via rete.
get-ipmi-guid.py /
Get Device ID
Supermicro ha avuto alcuni problemi con la divulgazione dei file di password dai loro BMC - per esempio, vedi questo e altri articoli:
a-penetration-testers-guide-to-ipmi
Per usare questo script basta dire:
dump_SM.py password_file
Funziona per me, nessuna garanzia implicita, garantita, ecc.
Beh, se puoi parlare con la porta UDP 623, è abbastanza semplice scoprire se un sistema remoto sta eseguendo IPMI. A meno che tu non sia dentro un data center, comunque, la maggior parte delle persone blocca UDP. E anche se non lo fanno... la scansione UDP è lenta quanto si possa immaginare. Quindi attualmente sto usando due metodi di base, sfruttando il venerabile Nmap e ipmiping (dagli strumenti GNU FreeIPMI.) La cosa più semplice da fare è:
</p> <p>
Poiché Nmap è molto più efficiente nella scansione di reti su larga scala
rispetto a ipmiping, questo metodo viene usato solo se Nmap dice che un host
ha la porta UDP 623 aperta.
</p> <p>
Nel bene e nel male questa porta è spesso bloccata, quindi molte
volte altri metodi hanno più probabilità di scoprire indirettamente se
IPMI è in esecuzione o no.
</p> <p>
Le porte sono pesate in base alla loro capacità indicativa e al fatto che
Nmap le trovi aperte, filtrate o in altri stati.
</p> <p>
Nmap può anche mostrare i banner dei servizi a cui si connette. Uso
espressioni regolari per cercare i target - per esempio le stringhe
"iLO" e "DRAC" sono buoni indicatori che un sistema potrebbe eseguire
il servizio Integrated Lights Out di HP, o iLO.
</p> <p>
<strong>Nota:</strong> Attualmente NON uso il metodo del
ping broadcast (un modo molto rapido per attraversare la sottorete in cui
ti trovi); semplicemente non ho dati sull'efficacia
di questo; anche se molto veloce quando funziona, non mi sembrava che
permettesse il controllo e l'affidabilità delle scansioni arbitrarie.
Due dei miei tre sistemi (Dell e HP) hanno risposto a un
ping RMCP. Nessuno ha risposto a un ping broadcast di idiscover
(ipmiutil discover.) Tutti, comunque, hanno risposto al mio
strumento di audit Python qui sotto.
</p> <p>
Sfortunatamente (ovviamente!) lo spettro delle comunicazioni e delle
reti entra in gioco - nmap dà un sacco di motivi diversi
sul perché una porta è aperta o no (open, closed, filtered, ecc.)
Un'altra tabella ha un insieme di pesi che dà più punti a
una porta aperta che a un risultato "open|filtered" (come direbbe Nmap).
Interpretare nmap e pesare è un po' frustrante,
ma c'est la vie.
</p> <p>
Prendi tutti i pesi, somma tutti i punti e hai un livello di certezza
IPMI. Ho scoperto in test ad hoc che 15 punti o
più sono forti indicatori che il sistema sta eseguendo IPMI.
</p> <p>
Attualmente ho varie soglie (no, forse, probabilmente,
sì.) Nei test - senza avere accesso noto ad altri server
oltre ai miei - sembra funzionare ragionevolmente bene. Cioè,
le cose che ritengo sospette e il mio modello di pensiero di base
di cui sopra fa effettivamente emergere certi server in cima e
lascia in pace gli host casuali. Ci sono però alcuni veri problemi con
i falsi positivi - molti firewall sembrano far credere a nmap che
ci sia qualcosa su qualsiasi porta (ho pensato di inserire una porta rara
o due (se ascolti qualcosa come la porta 1 e 31313,
per esempio, probabilmente non la stai *davvero* ascoltando!)
</p> <p>
Ma questo non vuole essere l'ultima parola sull'argomento. Dovrebbe
essere abbastanza semplice ottenere dei dati decenti sui banner IPMI, la mia
ipotesi è che sarebbe di gran lunga il modo migliore per scansionare rapidamente grandi
quantità di sistemi.
Ecco quattro pezzi di Perl per implementare quanto sopra; uno scansiona, uno interpreta, e gli altri due sono usati per la pesatura. È uno strumento di ricerca o una prova di concetto, non uno scanner di produzione, ma produce comunque un output ragionevole.
REQUISITO: Nmap versione 6.
L'uso è abbastanza semplice, anche se un po' strano. Dovrebbe essere eseguito come root. Verbose (-v) per molto output.
La scansione creerà una coppia di file di risultati che corrispondono ai nomi dei target (le barre sono convertite in underscore.) Basta eseguire il post-processore su di essi; passarli attraverso un ordinamento numerico inverso li mette in un ordine più interessante. Qualsiasi cosa sopra 10 la definirei sospetta, mentre maggiore di 20 è abbastanza certo che stia eseguendo IPMI.# esecuzione standard: ./ipmi_scan.pl -A -v -O yes 192.168.0.0/24 # veloce ./ipmi_scan.pl -tcp -v 192.168.0.0/24 # tutto incluso ./ipmi_scan.pl -A -v -O high 192.168.0.0/24
In questo caso ho usato il flag terse (-t) per ridurre l'output al minimo indispensabile.
./post_ipmi_scan.pl -t 192.168.0.0_24|sort -rn 96.3 192.168.0.69 16.25 192.168.0.46 10.8 192.168.0.23 7.33 192.168.0.202 5.4 192.168.0.189 5.4 192.168.0.179 1.7 192.168.0.9 1.23 192.168.0.1 1.1 192.168.0.8 0.9 192.168.0.251 0.63 192.168.0.55 0.43 silent/192.168.0.250 0.2 pi.fish2.com/192.168.0.14 0.2 fierce.fish2.com/192.168.0.6 0.2 192.168.0.88 0.01 192.168.0.16
Nei risultati sopra i primi 3 sistemi stanno effettivamente eseguendo IPMI, ma solo l'HP ha detto a Nmap che la porta UDP 623 era aperta - il mio Dell e Supermicro hanno restituito la risposta più ambigua "open|filtered", che è abbastanza comunemente un falso allarme, bleah. Forse è meglio semplicemente rassegnarsi e fare il ping IPMI in parallelo con lo scanner (o scrivere un NSE per farlo correttamente in Nmap.)
Ecco un paio di piccoli programmi Python che - usando gli strumenti FreeIPMI - (a) assorbono la configurazione di base IPMI/BMC di un server e (b) fanno un piccolo controllo di sicurezza sui risultati.
Perché io... beh, nessuna buona ragione, in realtà. Uno è in python3 e l' altro in python2. Immagino che stia testando la vostra prontezza. I programmi sono abbastanza pesantemente commentati, specialmente ipmifreely.py, quindi controllate quello per più dettagli su cosa succede. Richiede simplejson e ConfigParser, forse qualcosa in più.
DEVI avere FreeIPMI installato, che, al momento della scrittura, elimina le possibilità di Mac e Windows di scaricare un bel file JSON da un server. E dovresti davvero, davvero avere una versione recente. Non dire che non ti avevo avvisato. Ma la vita continua.
L'acquisizione dei dati è fatta tramite un programma Python (I-check.py) che richiede credenziali valide per ottenere i dati. Converte i risultati in JSON, che a sua volta può essere controllato dallo strumento di audit (ipmifreely.py.) C'è una policy di esempio in "IPMI-policy.ini", dove ho messo alcuni valori per i test.
| I-check.py - recupera i dati di configurazione IPMI |
Esempio di utilizzo:
# questo recupera le cose di configurazione; qui lo sto usando su un server HP iLO 3 # l'output è reindirizzato a un file $ ./ipmifreely.py -v -u admin -p admin 192.168.0.46 > hp.json # Questo prende il file JSON e cerca problemi $ ./I-check.py drac.json ./I-check.py hp.json Host: 192.168.0.46 [bmc-config] Serial_Channel Non_Volatile_Enable_Pef_Alerting = No [bmc-config] Serial_Channel Volatile_Enable_Pef_Alerting = No [bmc-config] Serial_Channel Volatile_Enable_Per_Message_Auth = No [bmc-config] Serial_Channel Non_Volatile_Enable_Per_Message_Auth = No [bmc-config] Lan_Conf_Security_Keys K_G = 0x0000000000000000000000000000000000000000 [bmc-config] SOL_Conf Force_SOL_Payload_Authentication = No [bmc-config] SOL_Conf Force_SOL_Payload_Encryption = No [bmc-config] Lan_Conf_Auth Callback_Enable_Auth_Type_None = Yes [bmc-config] Lan_Conf_Auth Operator_Enable_Auth_Type_None = Yes [bmc-config] Lan_Conf_Auth OEM_Enable_Auth_Type_None = Yes [bmc-config] Lan_Conf_Auth Admin_Enable_Auth_Type_None = Yes [bmc-config] Lan_Conf_Auth User_Enable_Auth_Type_None = Yes [bmc-config] Rmcpplus_Conf_Privilege Maximum_Privilege_Cipher_Suite_Id_1 = OEM_Proprietary [bmc-config] Rmcpplus_Conf_Privilege Maximum_Privilege_Cipher_Suite_Id_0 = OEM_Proprietary [bmc-config] Rmcpplus_Conf_Privilege Maximum_Privilege_Cipher_Suite_Id_2 = OEM_Proprietary [pef-config] Community_String Community_String = public [pef-config] PEF_Conf Enable_PEF_Event_Messages = No
Puoi dare un'occhiata ad alcune Best Practice di Sicurezza IPMI per maggiori informazioni su cosa controllare, cose che considero buone da fare, dal punto di vista della sicurezza.
| ipmi_scan.pl - scanner IPMI di base, usa Nmap e, se disponibile, ipmitool |
| pagina man di ipmi_scan - pagina man per quanto sopra |
| post_ipmi_scan.pl - analizza l'output di quanto sopra, produce alcuni risultati pesati |
| j_vendor.pl - Alcuni dati di base sui vendor... quali porte usano? |
| j_weights.pl - Alcuni pesi di base dei vendor per quanto sopra |
| ipmifreely.py - analizza l'output di quanto sopra, produce alcuni risultati |
| IPMI-policy.ini - file di policy IPMI |