Das BICsuite Run Program Teil 6: Sicherheitsüberlegungen und Fazit

Obwohl das Run Programm an sich ein leistungsstarkes Feature ist, ist es nicht ohne Risiken. Code-Injection ist hier das passende Stichwort. Stellen Sie sich vor, ein ausgeführtes Programm wie das folgende wurde konfiguriert:

run program = /bin/bash -c "ls -l $DIRSPEC"

DIRSPEC ist in diesem Fall ein Parameter vom Typ Parameter. Das bedeutet, dass, wenn jemand über Operating Rechte für diesen Job verfügt, diese Person in der Lage ist, den Inhalt des DIRSPEC-Parameters zu ändern. Daher wäre es überhaupt kein Problem, den Wert von „/tmp“ in ”/tmp; cat /etc/passwd” zu ändern. Plötzlich wird der Inhalt der Datei /etc/passwd nach stdout kopiert und ist für jeden lesbar, der die Protokolldatei des Jobs lesen kann. Natürlich können auch andere, gefährlichere Befehle hinzugefügt werden, im Grunde sogar ganze Skripte.

Um solche Einbruchsversuche zu verhindern, ist es entscheidend, die Parameter als Typ Konstante statt Parameter zu definieren. Der Typ Import ist auch in Ordnung, solange er einen Parameter vom Typ Konstante importiert. Parameter, die auf Ordner-, Bereichs- oder Ressourcenebene definiert sind, können ebenfalls als sicher angesehen werden. Ressourcenparameter von Jobs können geändert werden, wenn es sich um eine synchronisierende Ressource handelt und der Job sie mit einer exklusiven Sperre zuweist. Theoretisch kann ein indirekter Angriff konstruiert werden, indem der Wert auf etwas Offensives gesetzt wird.

Es ist natürlich nicht immer möglich, solche Angriffe auszuschließen. Deshalb ist es in solchen Fällen wichtig, den Inhalt eines Parameters zu testen. In unserem Beispiel muss der Inhalt von DIRSPEC getestet werden, ob er auf eine vorhandene Datei oder ein Verzeichnis verweist. Nehmen wir für unser Beispiel an, dass DIRSPEC ein importierter Parameter aus einem anderen Bereich ist, wo er als Parameter vom Typ Parameter definiert wurde.

Indem das Programm so geändert wurde:

run program = /bin/bash -c "$MY_LS_SCRIPT"

Mit der Konstante MY_LS_SCRIPT, die etwa diesen Inhalt hat:

BICSUITE_PRAGMA_VPFX:&
X="&DIRSPEC"
if [ -e "$X" ]; then
    ls -l "$X";
else
    echo "File ’$X’ not found or invalid";
    exit 1;
fi;

haben wir unseren ls Befehl so geändert, dass einfache Attacken nicht mehr so einfach funktionieren.

Aber wir sind noch weit von der Sicherheit entfernt. Die problematische Anweisung ist nun die Zuweisung des Wertes von DIRSPEC an die Shell-Variable X. Wir müssen uns bewusst machen, dass die Variablenersetzung durch das Scheduling System erfolgt, bevor das Bash-Skript an die Shell übergeben wird. Wenn wir also unseren Job wie oben beschrieben ändern, würde das immer noch ausreichen, um den Wert von DIRSPEC auf etwas wie /tmp"; cat "/etc/passwd zu setzen. Die Zuweisung des Parameterwerts an X bewirkt, dass die Shell ausgeführt wird.

X="/tmp"; cat "/etc/passwd"

Die Inhalte der etc/passwd Datei würden immer noch nach stdout kopiert werden.

Es lohnt sich, dies etwas genauer zu analysieren. Wir haben eine Befehlszeile, die geändert wird (Scheduler-Variablen/-Parameter werden aufgelöst), während der Job für die Ausführung vorbereitet wird. Zu diesem Zeitpunkt können Parameter noch nicht überprüft werden. Aber nach dem Ersetzen gibt es keine Möglichkeit, Originalcode von neu hinzugefügtem Code zu unterscheiden.

Vergleichen wir die Shell als Befehlsinterpreter mit einer Skriptsprache, z.B. Python oder Perl werden wir feststellen, dass die Sicherheitsprobleme plötzlich stark reduziert sind. Um dies zu zeigen, verwenden wir ein Python-Dienstprogramm, das nichts weiter als ls -l macht und ein Argument verwendet, um zu erfahren, welches Verzeichnis aufgelistet werden soll.

Das Python-Skript könnte so aussehen:

import os
import sys
accperm = {0 : ’---’, 1 : ’--x’, 2 : ’-w-’, 3 : ’-wx ’,
           4 : ’r--’, 5 : ’r-x’, 6 : ’rw -’, 7 : ’rwx ’ }
def print_details (f):
    stats = os. stat (f)
    print str (f) + ’\t’ + accperm [( stats . st_mode /64)%8] + \
                           accperm [( stats . st_mode /8)%8] + \
                           accperm [( stats . st_mode %8)] + \
                    ’\t’ + str ( stats . st_size /1024) + ’K’
    return
my_path = ’/ tmp ’
if len ( sys . argv ) > 1:
    my_path = sys. argv [1]
os. chdir ( my_path )
files = os. listdir ( my_path )
for f in files :
    print_details (f)

Auch mit begrenzten Python-Kenntnissen ist es offensichtlich, dass das Skript die Dateien in /tmp auflistet, wenn keine Argumente angegeben sind, andernfalls listet es die Dateien des angegebenen Verzeichnisses auf (sofern vorhanden).

Bei Verwendung in einer BICsuite-Umgebung könnte das Ausführungsprogramm so aussehen:

run program = /usr/bin/python -c "$PYTHONLS" "$DIRTOLIST"

PYTHONLS ist ein Parameter (Konstante), der das obige Skript bereitstellt, und DIRTOLIST ist ein Parameter, der das zu verarbeitende Verzeichnis angibt.

Im Falle der Verwendung der Bash würde dies die Türen für die Codeinjektion weit offen lassen. Aber in unserem Python-Beispiel ist das gar nicht so einfach, wenn überhaupt möglich. Der Parameter PYTHONLS ist eine Konstante und kann nicht missbraucht werden. Der andere Parameter DISTOLIST kann manipuliert werden. Das ist jedoch nicht so einfach, auch wenn wir keinen Code geschrieben haben, um den Wert von außen zu überprüfen. Der Parameter wird als Argument von os.chdir() verwendet und es ist sehr wahrscheinlich, dass diese Standard-Python-Funktion ihr Argument einfach an den zugrunde liegenden Systemaufruf weitergibt. Der zugrunde liegende Systemaufruf findet wahrscheinlich kein Verzeichnis mit dem (manipulierten) Wert von DIRTOLIST und schlägt fehl, genau wie der Aufruf von os.listfiles(). In diesem Fall müssen Sie nur etwas Fehlerverarbeitungscode hinzufügen, und das Skript kann als sicher angesehen werden.

Fazit

Das Fazit dieses Beitrags ist, dass BICsuite leistungsstarke Funktionen bietet, die es ermöglichen, Skripte im Scheduling Server zu speichern und auszuführen.

Werden modifizierbare Parameter in Kombination mit einer Shell als Befehlsinterpreter verwendet, ist es aufgrund der Beschaffenheit von Shells unmöglich oder zumindest schwierig, Code-Injection-Angriffe zu verhindern. Daher müssen entweder solche Jobs gestrichen werden, oder es muss gewährleistet sein, dass nur hochprivilegierte Personen solche Jobs abgeben und / oder ausführen können.

Werden andere Kommando Interpreter eingesetzt, ist die Situation deutlich entspannter und die Sicherheit kann mit mäßigem Aufwand gewährleistet werden.


Teil 1: Einführung und einfache Anwendung

Teil 2: Fortgeschrittene Anwendung

Teil 3: Backticks

Teil 4: Andere Interpreter

Teil 5: Umgehung von Einschränkungen

Teil 6: Sicherheitsüberlegungen und Fazit