
IPMI stuff from DARPA work
Ich habe ein wenig Software geschrieben, um IPMI zu erkunden; hier sind einige der Ergebnisse. Ich dachte mir, ich mache den üblichen Kreislauf aus Erkennen, Datensammeln und Auditieren. Jede dieser Aufgaben erwies sich als ziemlich interessantes Problem für sich – zumindest für mich.
Die Papiere und Dinge von http://fish2.com/ipmi
Hier ist ein kleines Perl-Programm, das versucht, einen Account auf einer entfernten BMC zu erraten, seinen Hash zu extrahieren und dann zu versuchen, sein (HMAC-gehashtes) Passwort zu knacken. Ich habe dazu für die Neugierigen ein wenig aufgeschrieben. Stark kommentiert, könnte es von Nutzen sein.
Die IPMI-Spezifikation besagt, dass man den Cipher eines entfernten Systems ohne jede Authentifizierung abrufen kann, aber mir ist kein Werkzeug bekannt, das dies tatsächlich tut (sie alle erfordern eine Authentifizierung, obwohl man natürlich die rohen Hex-Bytes eingeben könnte, wenn man wollte!). Also habe ich dieses kleine Programm geschrieben, um genau das zu tun; es versucht weitgehend, der Ausgabe von ipmitool zu folgen; dabei glaube ich, einen Fehler in diesem Werkzeug gefunden zu haben (in der letzten Zeile senden manchmal Systeme ein paar Datenmüll, der offenbar fehlinterpretiert wird), aber wer weiß, ich habe nicht genug Systeme zum Testen. Wie auch immer... ipmi-get-ciphers.py.
Wenn schon sonst nichts, ist es nützlich, um Cipher0-Systeme zu erkennen (Hinweis - das weist lediglich auf Ciphers hin, die unterstützt werden - es bedeutet nicht, dass sie tatsächlich aktiviert sind), aber es gibt da draußen interessante Dinge.
Zwei Programme hier, eines ist ein einfacher Python- Fernprober (ich beginne, Perl zu hassen, das sage ich euch) und ein zweites, das Hilfsprogramme von FreeIPMI nutzt, um Konfigurationsdaten mit Anmeldeinformationen abzugreifen.
Ein kleines Python-Programm (über 50 % Inline-Kommentare, 2,5 KB gzip-komprimiert), das ein einzelnes Paket an eine BMC sendet und die Antwort auswertet. Was kann man mit nur einem einzigen Paket anfangen, mag man fragen? Zehn und mehr verschiedene Sicherheitstests für IPMI, zunächst einmal. Nun, für den Anfang und für das Ende ist es eben nur ein Paket :) Es erfordert Python, eine BMC und einen offenen Pfad zum UDP-Port 623. Die Verwendung ist einfach „ipmi-get-auth.py target“.
ipmi-get-auth.py /
Eine sehr kleine Beschreibung
Ins Extreme getrieben ... nun, hier ist eine Art Mega-Version von dem Obigen, die es für alle Kanäle, alle Privilegien, alle ... nun, ihr wisst schon. Für die Monomanischen (lest die Kommentare oder den Beitrag, den ich darüber geschrieben habe, um zu sehen, warum es tut, was es tut!)
mega_chan.py /
Mega mega mega ... chan chan chan...
Und hier ist ein einfaches Programm, um ein Get-Device-ID-Paket (siehe S. 250 der IPMI-v2-Spezifikation) an ein System zu senden. Das sollte theoretisch ohne Authentifizierung funktionieren. In einer kleinen Umfrage, die ich durchgeführt habe, antworteten etwa 90 % der Systeme darauf (wenn auch nicht alle mit gültigen Informationen!) Man kann mitunter den Hersteller und andere Informationen erhalten, wie Modellnummern und Ähnliches, aber interessanter ist es, tatsächlich eine eindeutige ID zu bekommen - traditionell etwas, das über das Netz nur schwer zu erlangen ist.
get-ipmi-guid.py /
Geräte-ID abrufen
Supermicro hatte einige Probleme mit der Offenlegung von Passwortdateien durch ihre BMC - siehe zum Beispiel diesen und andere Berichte:
a-penetration-testers-guide-to-ipmi
Um dieses Skript zu verwenden, einfach Folgendes eingeben:
dump_SM.py password_file
Funktioniert bei mir, ohne Gewähr, Garantie usw.
Nun, wenn man mit UDP-Port 623 kommunizieren kann, ist es ziemlich einfach herauszufinden, ob ein entferntes System IPMI ausführt. Außerhalb eines Rechenzentrums blockieren die meisten Leute jedoch UDP. Und selbst wenn sie es nicht tun ... UDP-Scans sind etwa so langsam, wie man es sich nur vorstellen kann. Daher verwende ich derzeit zwei grundlegende Methoden, die sich das ehrwürdige Nmap und ipmiping (aus den FreeIPMI-GNU-Werkzeugen) zunutze machen. Das Einfachste ist:
</p> <p>
Da Nmap beim Scannen großer Netzwerke weitaus effizienter ist
als ipmiping, wird diese Methode nur verwendet, wenn Nmap sagt, dass ein Host
UDP 623 offen hat.
</p> <p>
Ob zum Guten oder Schlechten - dieser Port ist oft blockiert, sodass ein Großteil der
Zeit andere Methoden mit höherer Wahrscheinlichkeit beiläufig herausfinden, ob
IPMI läuft oder nicht.
</p> <p>
Die Ports werden nach ihrer Aussagekraft gewichtet und danach, ob
Nmap sie als offen, gefiltert oder in anderen Zuständen einstuft.
</p> <p>
Nmap kann auch die Banner der Dienste anzeigen, mit denen eine Verbindung besteht. Ich verwende
reguläre Ausdrücke, um nach Zielen zu suchen - zum Beispiel sind die Zeichenfolgen
„iLO“ und „DRAC“ gute Indikatoren dafür, dass ein System möglicherweise
HPs Integrated Lights Out service, kurz iLO, ausführt.
</p> <p>
<strong>Hinweis:</strong> Derzeit verwende ich NICHT die Broadcast-
Ping-Methode (eine sehr schnelle Möglichkeit, das eigene Subnetz zu durchpflügen);
ich habe einfach keine Daten über deren Effektivität;
obwohl sie sehr schnell ist, wenn sie funktioniert, hatte ich nicht das Gefühl, dass sie
die Kontrolle und Zuverlässigkeit beliebiger Scans ermöglicht.
Zwei meiner drei Systeme (Dell und HP) antworteten auf einen
RMCP-Ping. Keines antwortete auf einen Broadcast-Ping von idiscover
(ipmiutil discover). Alle jedoch antworteten auf mein weiter unten
beschriebenes Python-Audit-Tool.
</p> <p>
Unglücklicherweise (natürlich!) kommt das Gespenst der Kommunikation und
Netzwerke ins Spiel - nmap liefert eine Reihe verschiedener Gründe
dafür, warum ein Port offen ist oder nicht (offen, geschlossen, gefiltert usw.)
Eine weitere Tabelle enthält einen Satz Gewichtungen, die einem offenen Port
mehr Punkte geben als einem „open|filtered“-Treffer (wie Nmap es nennen würde).
Die Interpretation von nmap und die Gewichtung sind etwas frustrierend,
aber c'est la vie.
</p> <p>
Nimm alle Gewichtungen, summiere alle Punkte, und du hast einen IPMI-
Gewissheitsgrad. Bei Ad-hoc-Tests habe ich festgestellt, dass 15 Punkte oder
mehr starke Indikatoren dafür sind, dass das System IPMI ausführt.
</p> <p>
Derzeit habe ich verschiedene Schwellenwerte (nein, möglicherweise, wahrscheinlich,
ja). In Tests - ohne bekannten Zugang zu anderen Servern als meinen eigenen -
scheint es einigermaßen gut zu funktionieren. Das heißt,
die Dinge, die ich für verdächtig halte, und mein oben beschriebenes grundlegendes Denkmodell
lassen tatsächlich bestimmte Server nach oben aufsteigen und
lassen zufällige Hosts in Ruhe. Es gibt jedoch einige echte Probleme mit
Fehlalarmen - viele Firewalls scheinen nmap zu suggerieren, dass
auf jedem Port etwas lauscht (ich habe darüber nachgedacht, ein oder zwei seltene
Ports einzustreuen - wenn zum Beispiel auf Port 1 und 31313 etwas lauscht,
dann lauscht dort wahrscheinlich nicht *wirklich* etwas!)
</p> <p>
Aber das soll nicht das letzte Wort zu diesem Thema sein. Es sollte
ziemlich einfach sein, brauchbare Daten über IPMI-Banner zu sammeln; meine
Vermutung ist, dass dies bei weitem der beste Weg wäre, um schnell große
Mengen von Systemen zu scannen.
Hier sind vier Perl-Programme, um das oben Genannte umzusetzen; eines scannt, eines interpretiert, und die anderen beiden werden für die Gewichtung verwendet. Es ist ein Forschungs- oder Proof-of-Concept-Werkzeug, kein Produktionsscanner, aber es erzeugt dennoch brauchbare Ausgaben.
ERFORDERLICH: Nmap Version 6.
Die Verwendung ist ziemlich einfach, wenn auch ein wenig eigenwillig. Sollte als root ausgeführt werden. Ausführlich (-v) für viele Ausgaben.
Der Scan erzeugt ein Paar Ergebnisdateien, die den Zielnamen entsprechen (Schrägstriche werden in Unterstriche umgewandelt.) Führe einfach den Nachbearbeiter auf ihnen aus; eine umgekehrte numerische Sortierung bringt sie in eine interessantere Reihenfolge. Alles über 10 würde ich als verdächtig bezeichnen, während bei mehr als 20 ziemlich sicher IPMI läuft.# standard run: ./ipmi_scan.pl -A -v -O yes 192.168.0.0/24 # fast ./ipmi_scan.pl -tcp -v 192.168.0.0/24 # kitchen sink ./ipmi_scan.pl -A -v -O high 192.168.0.0/24
In diesem Fall habe ich das Kürzel-Flag (-t) verwendet, um die Ausgabe auf das absolute Minimum zu reduzieren.
./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
In den obigen Ergebnissen führen die ersten 3 Systeme tatsächlich IPMI aus, aber nur der HP teilte Nmap mit, dass UDP-Port 623 offen sei - mein Dell und mein Supermicro lieferten die mehrdeutigere Antwort „open|filtered“, die ziemlich häufig ein Fehlalarm ist, bäh. Vielleicht ist es besser, einfach die Zähne zusammenzubeißen und den IPMI-Ping parallel zum Scanner durchzuführen (oder ein NSE zu schreiben, das es in Nmap richtig macht.)
Hier sind ein paar kleine Python-Programme, die - unter Verwendung von FreeIPMI-Werkzeugen - (a) die grundlegende IPMI/BMC-Konfiguration eines Servers einsaugen und (b) eine kleine Sicherheitsprüfung der Ergebnisse durchführen.
Weil ich ... nun, eigentlich ohne guten Grund. Eines ist in python3 und das andere in python2. Ich schätze, ich teste eure Bereitschaft. Die Programme sind ziemlich stark kommentiert, besonders ipmifreely.py, also schau dort für weitere Details nach, was vor sich geht. Erfordert simplejson und ConfigParser, vielleicht noch einiges mehr.
IHR MÜSST FreeIPMI installiert haben, was zum Zeitpunkt dieses Schreibens Mac- und Windows-Nutzern die Chance nimmt, eine coole JSON-Datei von einem Server zu saugen. Und ihr solltet wirklich, wirklich eine aktuelle Version haben. Sagt nicht, ich hätte euch nicht gewarnt. Aber das Leben geht weiter.
Die Datenerfassung erfolgt über ein Python-Programm (I-check.py), das gültige Anmeldeinformationen benötigt, um Daten zu erhalten. Es konvertiert die Ergebnisse in JSON, das wiederum vom Audit-Tool (ipmifreely.py) geprüft werden kann. Es gibt eine Beispielrichtlinie in „IPMI-policy.ini“, in der ich einige Werte zum Testen hinterlegt habe.
| I-check.py - holt IPMI-Konfigurationsdaten |
Beispielverwendung:
# this grabs the configuration stuff; here I'm using it on an HP iLO 3 server # the output is redirected to a file $ ./ipmifreely.py -v -u admin -p admin 192.168.0.46 > hp.json # This takes the JSON file and looks for issues $ ./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
Ihr könnt euch einige IPMI-Sicherheits-Best-Practices ansehen, um mehr darüber zu erfahren, was zu prüfen ist und was ich aus Sicherheitssicht für gute Maßnahmen halte.
| ipmi_scan.pl - grundlegender IPMI-Scanner, verwendet Nmap und, falls verfügbar, ipmitool |
| ipmi_scan-Manpage - Manpage für das Obige |
| post_ipmi_scan.pl - analysiert die Ausgabe des Obigen und gibt einige gewichtete Ergebnisse aus |
| j_vendor.pl - Einige grundlegende Herstellerdaten ... welche verwenden welche Ports? |
| j_weights.pl - Einige grundlegende Herstellergewichtungen für das Obige |
| ipmifreely.py - analysiert die Ausgabe des Obigen und gibt einige Ergebnisse aus |
| IPMI-policy.ini - IPMI-Richtliniendatei |