Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
freebsd-dirent-info-leak-bugs — CVE-2020-25578 und CVE-2020-25579: Einige FreeBSD Info-Leak-Bugs, die ich 2020 gefunden habe. | Kitploit
Tools/GitHubGitHub/farazsth98/freebsd-dirent-info-leak-bugs
SpeicherforensikSchwachstellenanalyseExploitationInformationsbeschaffungBinäranalyse
GitHubfarazsth98/freebsd-dirent-info-leak-bugs

freebsd-dirent-info-leak-bugs

CVE-2020-25578 und CVE-2020-25579: Einige FreeBSD Info-Leak-Bugs, die ich 2020 gefunden habe.

Repository anzeigen

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
722vor 5 JahrenNoch nicht geprüft

Wie habe ich die Fehler gefunden?

  1. Zufällig entscheiden, die Dateisysteme in FreeBSD zu auditieren
  2. Einige Recherchen durchführen und feststellen, dass das standardmäßig verwendete Dateisystem eine Kombination aus FFS und UFS ist
  3. Einige Zeit damit verbringen, ufs_create zu auditieren und 0 Fehler finden
  4. Gehe hierhin und sieh dir die Commit-Historie der UFS-Dateisystemfunktionen an
  5. Diesen Commit entdecken, der Informationen betrifft, die durch Padding-Bytes in struct dirent-Objekten, die auf dem Stack allokiert werden, durchsickern
  6. Den Patch analysieren und feststellen, dass der Patch für msdosfs_readdir unvollständig ist. Sie haben eine Instanz des Fehlers gepatcht, aber nicht eine zweite.
  7. Ein PoC schreiben, um zu bestätigen, dass ich 3 Bytes aus dem Padding leaken kann. Dann anfangen, nach Varianten zu suchen.
  8. Die Varianten in mqueuefs, autofs, smbfs und tmpfs finden, die es mir erlauben, einen vollen 8-Byte-Zeiger zu leaken. PoC zur Bestätigung schreiben.

Ursprünglicher Fehler

Wie oben erwähnt, war der ursprüngliche Fehler, den ich fand, in msdosfs_readdir, während ich den Patch für den oben verlinkten Commit analysierte.

Der grundlegende Ablauf für den Aufruf von readdir auf FreeBSD ist wie folgt:

root@kitploit:~
#include <dirent.h>

int main(void) {
    struct dirent *dp;
    DIR *dirp;

    dirp = opendir("./somedir");
    dp = readdir(dirp);
}

Abhängig vom Dateisystem, in dem sich somedir befindet, könnte jede der vielen *_readdir-Funktionen im FreeBSD-Kernel aufgerufen werden.

Der obige Patch fügt eine Funktion namens dirent_terminate hinzu, die aufgerufen werden soll, bevor ein struct dirent-Objekt an den Userspace zurückgegeben wird (oft mit der Funktion uiomove). Diese Funktion setzt die Padding-Bytes sowie alle verbleibenden Bytes im d_name-Feld der Struktur auf Null. Die Definition von struct dirent ist hier.

Wenn wir uns den Patch ansehen, in Zeile 1562 sehen wir, dass dirent_terminate mit der Variable dirbuf als Argument aufgerufen wird. Danach wird uiomove aufgerufen, um den Inhalt von dirbuf zurück in den Userspace zu kopieren. Beachten Sie jedoch, dass diese Codezeilen innerhalb des Blocks dieser if-Anweisung liegen. Der Kommentar über dieser if-Anweisung erklärt, dass dieser Zweig nur genommen wird, wenn readdir auf dem Root des MSDOS-Dateisystems aufgerufen wird. Daher können wir diese if-Anweisung einfach überspringen, indem wir readdir in einem Unterverzeichnis jenseits des Root des Dateisystems aufrufen.

Weiter unten sehen wir einen weiteren Aufruf von uiomove in Zeile 1691. Wenn wir den Code jedoch genau lesen, stellen wir fest, dass dirent_terminate in diesem Fall nicht aufgerufen wird, was bedeutet, dass die Padding-Bytes nicht initialisiert bleiben. Leider wurde das d_name-Feld zu Beginn dieser Funktion hier auf Null gesetzt, sodass wir keinen größeren Leak erhalten können.

PoC

Zuerst hatte ich keinen USB-Stick, also musste ich einen Weg finden, ein MSDOS-Dateisystem zu mounten. Folgendes funktioniert:

root@kitploit:~
$ dd if=/dev/zero of=test.img bs=512 count=256000
$ sudo mdconfig -a -t vnode -f test.img
$ sudo newfs_msdos -s 131072000 /dev/md1 # My mdconfig returned md1
$ mkdir ./temp
$ sudo mount -t msdosfs /dev/md1 ./temp
$ mkdir ./temp/test_dir

Das PoC befindet sich in original_poc.c. Einfach mit clang kompilieren und aus demselben Verzeichnis wie die obigen Befehle ausführen, und Sie werden die durchgesickerten Bytes ausgegeben sehen.

Varianten

Ich begann, nach Varianten davon zu suchen. Ich glaube, ich habe einfach nach uiomove\(&.*, gegrept, was etwa 15-20 Ergebnisse lieferte, und habe sie alle von Hand überprüft. Leider existiert keine der Varianten standardmäßig in FreeBSD (die Dateisysteme müssen manuell aktiviert / in den Kernel kompiliert werden). Die Funktionen mit den Varianten sind wie folgt:

  1. mqfs_readdir
  2. tmpfs_dir_getdotdent
  3. tmpfs_dir_getdotdotdent
  4. smbfs_readvdir
  5. autofs_readdir_one

Der Fehler ist in all diesen Funktionen genau derselbe, daher werde ich nur mqfs_readdir behandeln.

  1. Zuerst wird ein struct dirent entry auf dem Stack allokiert
  2. Als nächstes wird dirent_terminate aufgerufen, um die Padding- und d_name-Felder der Struktur auf Null zu setzen
  3. Schließlich wird vfs_read_dirent aufgerufen. Diese Funktion ruft uiomove auf, um die Struktur in den Userspace zu kopieren

Bisher sieht alles gut aus, oder? Nicht unbedingt. Wir müssen sicherstellen, dass alle Felder der Struktur initialisiert sind. Wenn Sie den Code genau betrachten, sehen Sie, dass das Feld d_off nicht initialisiert bleibt. Der Typ dieses Feldes ist off_t, was im Wesentlichen ein int64_t ist. Wenn die Struktur in den Userspace kopiert wird, erhalten wir in diesem Feld nicht initialisierte Daten.

PoC

Dieses selbe PoC wird für alle Varianten funktionieren, Sie müssen es nur auf einem anderen Dateisystem ausführen. Für mqueuefs gehen Sie wie folgt vor (benötigt, dass mqueuefs zuerst aktiviert / in den Kernel kompiliert wurde):

root@kitploit:~
$ mkdir ./temp
$ sudo mount -t mqueuefs null ./temp

Das PoC selbst befindet sich in variants_poc.c. Einfach mit clang kompilieren und aus demselben Verzeichnis wie die obigen Befehle ausführen. Sie werden Kernel-Zeiger ausgegeben sehen (vermutlich ein Stack-Zeiger und ein Codebereichs-/Heap-Zeiger, ich habe nicht nachgeprüft).

Tool herunterladen