ICShell 0.1 released

24. Juni 2015 | Von | Kategorie: Admin | StickyBit

Einleitung

icshell_logo

Die Steuerung von Industrieanlagen erfolgt heute mit speicherprogrammierbaren Steuerungen (SPS, engl. PLC). Diese Industrial Control Systems (ICS) werden von Firmen wie Siemens, Mitsubishi, Schneider oder General Electric hergestellt. Sie ähneln sich stark in ihren Aufgaben und ihrem Funktionsumfang. Der internationale Standard IEC 61131 definiert hierzu ein einheitliches Programmiermodell und legt Mindestanforderungen für die Elektronik fest. Diese Standardisierung ermöglicht eine herstellerübergreifende Vernetzung und bildet die Grundlage für die Industrie 4.0. Der gesamte Prozess von der individuellen Bestellung des Kunden, über eine flexible Produktion bis zur Auslieferung wird automatisiert. Ein wesentlicher Bestandteil ist die hochgradige Vernetzung mit Enterprise Resource Planning (ERP) und Machine Execution Systems (MES) mit Hilfe des TCP/IP-Protokolls. Diese Vernetzung setzt die Steuerungen neuen Bedrohungen aus und erhöht die Anforderungen an die IT-Sicherheit der PLCs .

Entwickler, Integratoren, Administratoren und Penetrationstester benötigen einfache Werkzeuge, um die Sicherheit der Steuerungen testen und Schwachstellen demonstrieren zu können.

Die ICShell stellt eine unabhängige und durch OpenSource offene Möglichkeit dar, die IT-Sicherheit der IEC 61131 kompatiblen Systeme zu bewerten. Neben standardisierten Kommunikationsprotokollen wie Profinet oder OPC existieren herstellerspezifische Protokolle, die z.B. für Konfiguration und Diagnose der Geräte eingesetzt werden. Die genaue Funktionsweise dieser Protokolle wird durch die Hersteller nicht veröffentlicht.. Das Ziel der ICShell ist es diese Protokolle zu verstehen und ein Werkzeug für Penetrationstester und Sicherheitsforscher zu entwickeln.

Download & Installation

Die aktuelle ICShell-Version steht unter https://code.opensource-security.de/brueggemann/icshell/ zum Download bereit. Nach dem Download entpacken Sie die Datei und wechseln in das neu erstellte Verzeichnis. Mit dem folgenden Befehl installieren Sie die ICShell auf Ihrem System:

$ python2.7 setup.py install

Nach der erfolgreichen Installation kann die ICShell mit dem Befehl

$ icshell

gestartet werden.

Kurze Einführung

Die ICShell ist komplett in Python realisiert. Sie verwendet den interaktiven Python-Interpreter als Benutzerschnittstelle. Dadurch stehen dem Benutzer nicht nur die ICS spezifischen Befehle sondern der gesamte Sprachumfang von Python zur Verfügung. Dies erlaubt eine flexible Kombination der verschiedenen Befehle.

 In [1]: a = 5 + 5
 In [2]: print a
 10

Geräte suchen

Um ein Netzwerk nach PLCs zu durchsuchen wird der Befehl ics_scan verwendet. Dieser benötigt die Angabe des zu untersuchenden Netzbereichs. Es werden Hostnamen, IP-Adressen und IP-Bereiche akzeptiert.

 In [1]: scan_result = ics_scan("192.168.155.0/24")
 Scanning: 256/256
 Found 3 devices.

Drei Geräte wurden gefunden. Das Ergebnis kann mit dem print Befehl angezeigt werden.

 In [2]: print scan_result
 Out[2]: Devices: 3
 +-------------------------------------------------------------------------------+
 | Name      | Host           | Port | Protocol          | Security problems?    |
 +-------------------------------------------------------------------------------+
 | S7300     | 192.168.155.40 | 102  | S7Comm            | UNKNOWN               |
 +-------------------------------------------------------------------------------+
 | S71200    | 192.168.155.50 | 102  | S7Comm            | UNKNOWN               |
 +-------------------------------------------------------------------------------+
 | FX3G/FX1N | 192.168.155.80 | 5556 | MelsoftConnection | UNKNOWN               |
 +---------------------------------------------------------------------  --------+

Verbindungen zu Geräten herstellen

In dem folgenden Beispiel wird eine Verbindung zu der Siemens S7-1200 aufgebaut, die im ersten Beispiel gefunden wurde.

 In [3]: plc = scan_result[1]
 In [4]: ics_connect(plc)

Eine manuelle Definition des Gerätes ist ebenfalls möglich.

 In [3]: plc = PLC_S71200()
 In [4]: plc.host = "192.168.155.40"
 In [5]: ics_connect(plc)

Geräte identifizieren

Die ics_identify Funktion identifiziert unbekannte Hersteller oder Produkte..

 In [3]: plc = PLC_GENERIC()
 In [4]: plc.host = "192.168.155.40"
 In [5]: identified_plc = ics_identify(plc, protocol_list=[ProtocolS7Comm])

Geräte analysieren

Die Analyse-Funktion sammelt alle sicherheitsrelevanten Informationen. Zum jetzigen Zeitpunkt wird ausschliesslich die Firmware-Version ermittelt.

 In [5]: ics_analyze(plc)
 Out[5]:
 +--------------------------->
 | S7300:
 +--------------------------->
 | Model: S7300Generic
 +--------------------------->
 | Host: 192.168.155.40
 | Port: 102
 | Protocol: S7Comm
 +--------------------------->
 | Local tsap: 0x02 0x02
 | Remote tsap: 0x02 0x02
 +--------------------------->
 | OrderNo.: 6ES7 315-2AF03-0AB0
 | Firmware: 1.2.0
 | Module version: 0.1
 | Hardware version: 0.1
 +--------------------------->
 | Security issues: UNKNOWN
 +--------------------------->

Mit Variablen arbeiten

Intern speichern die PLCs ihre Zustände in Prozessvariablen. Alle PLCs erlauben von Aussen den Zugriff auf diese Prozessvariablen. Meist ist dieser Zugriff ohne Authentifizierung und Autorisierung möglich. Entsprechend IEC-611311 erfolgt der Zugriff auf eine Variable über eine Adresse und eine Area. Die Area bestimmt den Geltungsbereich der Variable (z.B. physikalische Ausgänge). Die Adresse wählt ein Element auf dem Bereich aus. Das nachfolgende Beispiel definiert eine Prozessvariable für den ersten physikalischen Ausgang.

 In [6]: output0 = VarBool()
 In [7]: output0.address = 0x0
 In [8]: output0.area = IEC61131_AREA_NAMES.Output

Der aktuelle Wert der Variable kann mit dem Befehl ics_getvar aus dem PLC gelesen werden.

BULB01 In [9]: ics_getvar(plc, output0)
 Out[9]:
 +--------------------------->
 | VarBool:
 +--------------------------->
 | Address: 0x0
 | Area: Output
 +--------------------------->
 | Value: False
 +--------------------------->

Der erste Ausgang ist False bzw. 0V. Eine Pegelveränderung kann durch setzen der Variable erreicht werden.

 In [14]: output0.value = TrueBULB02
 In [16]: ics_setvar(plc, output0)
 Out[16]:
 +--------------------------->
 | VarBool:
 +--------------------------->
 | Address: 0x0
 | Area: Output
 +--------------------------->
 | Value: True
 +--------------------------->

Exploiting

Die ICShell bietet auch die Möglichkeit spezifische Angriffe in einfachen Python-Plugins zu realisieren. Diese Expoits können dann mit der Funktion ics_exploit ausgeführt werden.

In [17]: ics_exploit(plc, EXPLOIT_S71200_HTTPS_POST_DEFECT())

 

Post to Twitter Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to Ping.fm Post to Reddit

Tags: | | | | |

2 Kommentare
Hinterlasse einen Kommentar »

  1. Hallo,

    ich bin zufällig auf den Mitschnitt ihres PLC-Blaster Vortrages beim 32c3 aufmerksam geworden, nach etwas suchen habe ich nun diese Anleitung hier gefunden – mit einem Kontaktformular.
    Ich finde das sehr interessant was sie machen.
    Ich habe vor einigen Jahren auch mal die Idee gehabt die Kommunikation zwischen SPS und Programmiergerät (bei S5) und den Siemens-Bus (alte S7) auszuwerten.
    Trotz guter Konntakte in einen Hack-Space kam das Projekt leider nicht zustande.

    Ich würde gerne mehr über Ihre SPS Projekte erfahren.
    Grüße Jochen

  2. Hallo Herr Sing,

    im Moment haben wir noch nicht mehr Code veröffentlicht. Am besten verfolgen Sie aber das GIT.
    Bei spezifischen Fragen sollten wir telefonieren oder direkten E-Mail-Austausch betreiben.

    Gruß,

    Ralf

Schreibe einen Kommentar

Fühle dich ermuntert einen Kommentar, Anmerkungen, Hinweise oder deine Ideen zum Thema zu hinterlassen. Wir freuen uns über deine Rückmeldung.