Shell Command Injection – Wie fremder Text in das Terminal gelangt
Fortsetzung der Lücke
Nun würden erfahrene Programmierer einwenden, dass es üblich ist, Dateinamen und Pfade zu »quoten«, also in Anführungszeichen zu setzen, um damit ggf. bösartigen Text zwischen Hochkommata »einzusperren«, sodass dieser nicht mehr ausgeführt wird. Jedoch lässt sich das mitunter umgehen, wenn der umgebende Text, in den die Ausgabe von quote()
eingefügt werden soll, bereits Hochkommata enthält, z.B.:
import mailcap, os try: from shlex import quote except ImportError: from pipes import quote d=mailcap.getcaps() DATEINAME=quote(";ls;#.txt") cmd,m=mailcap.findmatch(d, "text/plain", filename=DATEINAME) os.system(cmd)
In diesem Fall wird nicht das Programm zum Öffnen einer mp4-Datei gesucht, sondern für eine Textdatei. Sofern MailCap als Kommando less '%s'
zum Anzeigen einer Textdatei findet, führt dies in cmd
zu folgendem Inhalt:
> print cmd less '';ls;#.txt''
Das führt nun trotz – oder gerade wegen – der Verwendung von quote()
unerwünschterweise dazu, dass das aktuelle Verzeichnis mit ls
auflistet wird, nachdem die sinnfreie Textausgabe von less «
mit der Taste »Q« beendet wurde.
Zu hoffen bleibt, dass kein Mailprogramm das Pythonmodul MailCap in der zuvor dargestellten Weise verwendet.
Fazit
Es gibt ein paar Tipps, die man befolgen sollte, damit Angreifer nicht eine Lücke im eigenen Code ausnutzen können:
- Niemals »blind« Text zusammenkopieren und ohne vorherige Prüfung an die Shell übergeben.
- Ausführen von Shell-Befehlen aus den beiden Python-Modulen
os
undcommands
vermeiden. - Wenn Shell-Befehle notwendig sind, dann diese mit
subprocess.Popen()
ausführen. Dieses Python-Modul ist resistenter gegen Injektionen. - Der Befehl
quote()
kann bei unsachgemäßem Gebrauch ungewollt Beihilfe zum Ausbruch aus dem Gefängnis der Hochkommata leisten. - Alle Texte, die von einem Angreifer erreichbar sind, gegebenenfalls temporär vor Benutzung eines Shell-Befehls durch harmlose Texte austauschen, um diese erst nach der Shell-Operation wieder durch den ursprünglichen Text zu ersetzen.
- Auch vermeintlich sicheren Standard-Pythonmodulen sollte man keineswegs uneingeschränktes Vertrauen entgegenbringen.
Das in dem Artikel demonstrierte Problem mit dem Standard-Pythonmodul MailCap wurde bereits gemeldet, zu dem es auch einen Workaround gibt.
Auf Launchpad findet man eine Liste derjenigen Programme, die für Shell Command Injection anfällig sind.
Autoreninformation
Bernd Dietzel (Webseite) ist 2010 dank freiesMagazin zur Programmiersprache Python gekommen und programmiert seitdem in Python, z.B. Demos für seinen YouTube-Kanal.
Dieser Artikel ist in freiesMagazin 10/2015 (ISSN 1867-7991) erschienen. Veröffentlichung mit freundlicher Genehmigung.