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
difuze — Fuzzer für Linux-Kernel-Treiber | Kitploit
Tools/GitHubGitHub/ucsb-seclab/difuze
Android-SicherheitSchwachstellenanalyseFuzzingBinäranalyse
GitHubucsb-seclab/difuze

difuze

Fuzzer für Linux-Kernel-Treiber

Repository anzeigen
38585vor 4 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

difuze: Fuzzer für Linux-Kernel-Treiber

License

Dieses Repository enthält alle Quellen (einschließlich Setup-Skripte), die Sie benötigen, um difuze zum Laufen zu bringen.

Getestet auf

Ubuntu >= 14.04.5 LTS

0. difuze mit Docker ausführen

Siehe die Readme

Wie in unserem Paper erläutert, gibt es zwei Hauptkomponenten von difuze: Interface Recovery und Fuzzing Engine

1. Interface Recovery

Der Interface-Recovery-Mechanismus basiert auf LLVM-Analyse-Passes. Jeder Schritt der Interface-Recovery ist als einzelner Pass geschrieben. Befolgen Sie die folgenden Anweisungen, um Interface Recovery zum Laufen zu bringen.

1.1 Einrichtung

Dieser Schritt kümmert sich um die Installation von LLVM und c2xml:

Stellen Sie zunächst sicher, dass Sie libxml haben (erforderlich für c2xml):

root@kitploit:~
sudo apt-get install libxml2-dev
sudo pip install lxml

Als nächstes haben wir ein Skript erstellt, das alle erforderlichen Werkzeuge herunterlädt und compiliert.

root@kitploit:~
cd helper_scripts
python setup_difuze.py --help
usage: setup_difuze.py [-h] [-b TARGET_BRANCH] [-o OUTPUT_FOLDER]

optional arguments:
  -h, --help        show this help message and exit
  -b TARGET_BRANCH  Branch (i.e. version) of the LLVM to setup. Default:
                    release_38 e.g., release_38
  -o OUTPUT_FOLDER  Folder where everything needs to be setup.

Beispiel:

root@kitploit:~
python setup_difuze.py -o difuze_deps

Um die Einrichtung abzuschließen, müssen Sie auch Ihre lokale PATH-Umgebungsvariable anpassen. Das Setup-Skript gibt Ihnen die genauen Änderungen, die Sie vornehmen müssen.

1.2 Bauen

Dies setzt den erfolgreichen Abschluss von Setup voraus. Wir haben ein Skript, das alles baut, bitte sehr.

root@kitploit:~
cd InterfaceHandlers
./build.sh

1.3 Ausführung

Dies setzt den erfolgreichen Abschluss von Build voraus. Um die Interface-Recovery-Komponenten auf Kernel-Treibern auszuführen, müssen wir die Treiber zunächst in LLVM-Bitcode umwandeln.

1.3.1 Kernel bauen

Zuerst benötigen wir einen baubaren Kernel. Das bedeutet, Sie sollten den Kernel mit der normalen Build-Konfiguration compilieren können, d.h. make. Zuerst erfassen wir die Ausgabe des make-Befehls; aus dieser Ausgabe extrahieren wir den genauen Compilierungsbefehl.

1.3.1.1 Erzeugen der Ausgabe von make
Option 1: Verwendung von Bear (EMPFOHLEN)
  1. Installieren Sie Bear
  2. Führen Sie make mit Bear aus:
    root@kitploit:~
    bear make <all the options to make>
    
    Beispiel: bear make -j8

Dadurch wird eine Datei compile_commands.json im aktuellen Verzeichnis erstellt.

Option 2

Übergeben Sie einfach V=1 und leiten Sie die Ausgabe in die Datei um. Beispiel:

root@kitploit:~
make V=1 O=out ARCH=arm64 > makeout.txt 2>&1

HINWEIS: VERWENDEN SIE KEINE MEHREREN PROZESSE, d.h. -j. Das Ausführen im Multiprozessmodus bringt die Ausgabedatei durcheinander, da mehrere Prozesse versuchen, in die Ausgabedatei zu schreiben.

Das war's. Im nächsten Schritt verwendet unser Skript die generierte makeout.txt und führt die Interface Recovery auf allen erkannten Treibern aus.

1.3.2 Ausführung der Interface-Recovery-Analyse

Alle verschiedenen Schritte der Interface Recovery sind in einem einzigen Skript helper_scripts/run_all.py gebündelt. So führen Sie es aus:

root@kitploit:~
cd helper_scripts
python run_all.py --help

usage: run_all.py [-h] [-l LLVM_BC_OUT] [-a CHIPSET_NUM] [-m MAKEOUT]
                  [-c COMPJSON] [-g COMPILER_NAME] [-n ARCH_NUM] [-o OUT]
                  [-k KERNEL_SRC_DIR] [-isclang] [-clangp CLANG_PATH]
                  [-llvmlinkp LLVMLINK_PATH] [-skb] [-skl] [-skp] [-skP]
                  [-ske] [-skI] [-ski] [-skv] [-skd] [-f IOCTL_FINDER_OUT]

optional arguments:
  -h, --help            show this help message and exit
  -l LLVM_BC_OUT        Destination directory where all the generated bitcode
                        files should be stored.
  -a CHIPSET_NUM        Chipset number. Valid chipset numbers are:
                        1(mediatek)|2(qualcomm)|3(huawei)|4(samsung)
  -m MAKEOUT            Path to the makeout.txt file.
  -c COMPJSON           Path to the compile_commands_json generated by Bear.
  -g COMPILER_NAME      Name of the compiler used in the makeout.txt, This is
                        needed to filter out compilation commands. Ex: aarch64
                        -linux-android-gcc
  -n ARCH_NUM           Destination architecture, 32 bit (1) or 64 bit (2).
  -o OUT                Path to the out folder. This is the folder, which
                        could be used as output directory during compiling
                        some kernels.
  -k KERNEL_SRC_DIR     Base directory of the kernel sources.
  -isclang              flag to indicate that clang was used to built the
                        kernel
  -clangp CLANG_PATH    Absolute path to the clang binary (if not provided,
                        the one available in the path will be used)
  -llvmlinkp LLVMLINK_PATH
                        Absolute path to the llvm-link binary (if not
                        provided, the one available in the path will be used)
  -skb                  Skip LLVM Build (default: not skipped).
  -skl                  Skip Dr Linker (default: not skipped).
  -skp                  Skip Parsing Headers (default: not skipped).
  -skP                  Skip Generating Preprocessed files (default: not
                        skipped).
  -ske                  Skip Entry point identification (default: not
                        skipped).
  -skI                  Skip Generate Includes (default: not skipped).
  -ski                  Skip IoctlCmdParser run (default: not skipped).
  -skv                  Skip V4L2 ioctl processing (default: not skipped).
  -skd                  Skip Device name finder (default: not skipped).
  -f IOCTL_FINDER_OUT   Path to the output folder where the ioctl command
                        finder output should be stored.


Das Skript baut, linkt und führt Interface Recovery auf allen erkannten Treibern aus, daher kann es beträchtliche Zeit (45 min - 90 min) in Anspruch nehmen.

Das obige Skript führt die folgenden Aufgaben im Multiprozessormodus aus, um alle CPU-Kerne zu nutzen:

1.3.2.1 LLVM Build
  • Standardmäßig aktiviert.

Alle erzeugten Bitcode-Dateien werden in dem Ordner abgelegt, der dem Argument -l übergeben wurde. Dieser Schritt dauert beträchtliche Zeit, abhängig von der Anzahl Ihrer Kerne. Wenn Sie diesen Schritt bereits durchgeführt haben, können Sie ihn durch Übergabe von -skb überspringen.

1.3.2.2 Linking all driver bitcode files in s consolidated bitcode file.
  • Standardmäßig aktiviert

Dies führt das Linking durch, durchläuft alle Bitcode-Dateien, identifiziert die zugehörigen, die gelinkt werden müssen, und linkt sie (mit llvm-link) zu einer konsolidierten Bitcode-Datei (die zusammen mit der entsprechenden Bitcode-Datei gespeichert wird).

Ähnlich wie beim obigen Schritt können Sie diesen Schritt durch Übergabe von -skl überspringen.

1.3.2.3 Parsing headers to identify entry function fields.
  • Standardmäßig aktiviert.

Dieser Schritt sucht nach den Entry-Point-Deklarationen in den Header-Dateien und speichert deren Konfiguration in der Datei: hdr_file_config.txt im LLVM-Build-Verzeichnis.

Zum Überspringen: -skp

1.3.2.4 Identify entry points in all the consolidated bitcode files.
  • Standardmäßig aktiviert

Dieser Schritt identifiziert alle Entry Points in allen konsolidierten Treiber-Bitcode-Dateien. Die Ausgabe wird in der Datei entry_point_out.txt im LLVM-Build-Verzeichnis gespeichert.

Beispiel für den Inhalt der Datei entry_point_out.txt:

root@kitploit:~
IOCTL:msm_lsm_ioctl:/home/difuze/kernels/pixel/msm/sound/soc/msm/qdsp6v2/msm-lsm-client.c:msm_lsm_ioctl.txt:/home/difuze/pixel/llvm_out/sound/soc/msm/qdsp6v2/llvm_link_final/final_to_check.bc
IOCTL:msm_pcm_ioctl:/home/difuze/kernels/pixel/msm/sound/soc/msm/qdsp6v2/msm-pcm-lpa-v2.c:msm_pcm_ioctl.txt:/home/difuze/pixel/llvm_out/sound/soc/msm/qdsp6v2/llvm_link_final/final_to_check.bc

Zum Überspringen: -ske

1.3.2.5 Run Ioctl Cmd Finder on all the identified entry points.
  • Standardmäßig aktiviert.

Dieser Schritt führt die Hauptkomponente der Interface Recovery (IoctlCmdParser) auf allen Entry Points in der Datei entry_point_out.txt aus. Die Ausgabe für jeden Entry Point wird in dem mit der Option -f angegebenen Ordner gespeichert.

Zum Überspringen: -ski

1.4 Beispiel:

Wir haben einen Mediatek-Kernel 33.2.A.3.123.tar.bz2 hochgeladen. Laden Sie zunächst die obige Datei herunter und entpacken Sie sie.

Angenommen, Sie haben die Datei in einen Ordner namens ~/mediatek_kernel entpackt.

1.4.1 Bauen

Installieren Sie Bear und befolgen Sie die folgenden Schritte:

root@kitploit:~
cd ~/mediatek_kernel
source ./env.sh
cd kernel-3.18
# der folgende Schritt ist je nach Kernel möglicherweise nicht erforderlich
mkdir out
make O=out ARCH=arm64 tubads_defconfig
# Erzeugen von compile_commands.json
bear make -j8 O=out ARCH=arm64

1.4.2 Ausführen der Interface Recovery

root@kitploit:~
cd <repo_path>/helper_scripts

python run_all.py -l ~/mediatek_kernel/llvm_bitcode_out -a 1 -c ~/mediatek_kernel/kernel-3.18/compile_commands.json -n 2 -o ~/mediatek_kernel/kernel-3.18/out -k ~/mediatek_kernel/kernel-3.18 -f ~/mediatek_kernel/ioctl_finder_out

Der obige Befehl benötigt einige Zeit (30 min - 1 Std.).

1.4.3 Die Ausgabe verstehen

Zunächst befinden sich alle Analyseergebnisse im Ordner: ~/mediatek_kernel/ioctl_finder_out (Argument für die Option -f), für jeden Einstiegspunkt wird eine .txt-Datei erstellt, die alle Informationen über das wiederhergestellte Interface enthält.

Wenn Sie nur an Informationen über das Interface interessiert sind und sich nicht um andere Details kümmern, empfehlen wir Ihnen, das Skript parse_interface_output.py zu verwenden. Dieses Skript wandelt die verrückte Ausgabe des Interface-Recovery-Passes in schöne JSON-Dateien mit einem sauberen und konsistenten Format um.

root@kitploit:~
cd <repo_path>/helper_scripts
python parse_interface_output.py <ioctl_finder_out_dir> <output_directory_for_json_files>

Hier sollte <ioctl_finder_out_dir> der Ordner sein, den Sie der Option -f übergeben haben, und <output_directory_for_json_files> ist der Ordner, in dem die JSON-Dateien erstellt werden sollen.

Sie können die entsprechenden JSON-Dateien für die Interface Recovery des entsprechenden Ioctl verwenden.

1.4.4 Hinweise:

1.4.4.1 Wert für Option -g (nur wenn Sie makeout.txt verwenden)

Um einen Wert für Option -g anzugeben, müssen Sie den Namen des *-gcc-Binärprogramms kennen, das zum Compilieren des Kernels verwendet wurde. Eine einfache Möglichkeit, dies herauszufinden, ist, in makeout.txt nach gcc zu grep; Sie werden dann Compiler-Befehle sehen, aus denen Sie den Namen des *-gcc-Binärprogramms ermitteln können.

Für unser obiges Beispiel: Wenn Sie grep gcc makeout.txt für den Beispielbuild ausführen, sehen Sie viele Zeilen wie die folgende:

root@kitploit:~
aarch64-linux-android-gcc -Wp,-MD,fs/jbd2/.transaction.o.d  -nostdinc -isystem ...

Der Wert für -g sollte daher aarch64-linux-android-gcc sein.

Wenn der zu bauende Kernel 32-Bit ist, wird das Binärprogramm höchstwahrscheinlich arm-eabi-gcc sein.

Bei Qualcomm (oder MSM)-Chipsätzen kann es vorkommen, dass Sie *gcc-wrapper.py anstelle von *.gcc sehen; in diesem Fall sollten Sie *gcc-wrapper.py angeben.

1.4.4.2 Wert für Option -a

Abhängig vom Chipsatz-Typ müssen Sie die entsprechende Nummer angeben.

1.4.4.3 Wert für Option -o

Dies ist der Pfad des Ordners, der der Option O= des make-Befehls während des Kernel-Builds übergeben wurde.

Nicht alle Kernel benötigen einen separaten Ausgabepfad. Sie können einen Kernel bauen, indem Sie keine Option O angeben; in diesem Fall SOLLTEN SIE beim Ausführen von run_all.py keinen Wert für diese Option angeben.

Mit clang gebaute Kernel

Für mit clang gebaute Kernel geben Sie bitte zusätzlich zu den obigen Optionen die folgenden Optionen an (vorausgesetzt, Sie haben compile_commands.json verwendet):

root@kitploit:~
-isclang -clangp <PATH_TO_THE_CLANG_USED_TO_BUILD_THE_KERNEL> -llvmlinkp <PATH_TO_THE_LLVM_LINK (will be in the same folder as clang)>

1.5 Nachbearbeitung

Bevor wir mit dem Fuzzing beginnen können, müssen wir die Ausgabe ein wenig mit unseren (sorry) Parsern in Forschungsqualität verarbeiten.

Diese finden Sie hier. Das Hauptskript, das ausgeführt wird, ist run_all.py:

root@kitploit:~
$ python run_all.py --help
usage: run_all.py [-h] -f F -o O [-n {manual,auto,hybrid}] [-m M]

run_all options

optional arguments:
  -h, --help            show this help message and exit
  -f F                  Filename of the ioctl analysis output OR the entire
                        output directory created by the system
  -o O                  Output directory to store the results. If this
                        directory does not exist it will be created
  -n {manual,auto,hybrid}
                        Specify devname options. You can choose manual
                        (specify every name manually), auto (skip anything that
                        we don't identify a name for), or hybrid (if we
                        detected a name, we use it, else we ask the user)
  -m M                  Enable multi-device output most ioctls only have one
                        applicable device node, but some may have multiple. (0
                        to disable)

Sie möchten -f das Ausgabeverzeichnis der ioctl-Analyse übergeben, z.B. ~/mediatek_kernel/ioctl_finder_out.

-o ist der Ort, an dem die nachbearbeiteten Ergebnisse gespeichert werden. Dabei handelt es sich um leicht verdauliche XML-Dateien (jpits).

-n gibt an, inwieweit Sie sich auf unsere Gerätenamenswiederherstellung verlassen möchten. Wenn Sie keine Arbeit/Namenssuche betreiben möchten, können Sie auto angeben. Dies hat natürlich den Preis, dass jedes Gerät übersprungen wird, für das wir keinen Namen wiederherstellen. Wenn Sie paranoid sein wollen und unseren Wiederherstellungsbemühungen nicht trauen (völlig vernünftig), können Sie die Option manual verwenden, um jedes einzelne Gerät selbst zu benennen. hybrid ist dann eine Kombination aus beidem – wir benennen das Gerät für Sie, wenn wir können, und fallen auf Sie zurück, wenn wir gescheitert sind.

-m Manchmal können ioctls mehr als einem Gerät entsprechen (dies ist z.B. bei v4l2/subdev ioctls üblich). Unterstützung dafür ist standardmäßig aktiviert, erfordert jedoch Benutzerinteraktion, um die Anzahl der Geräte für jedes Gerät anzugeben. Wenn Ihnen das zu lästig ist, können Sie die Eingabeaufforderung deaktivieren, indem Sie -m 0 übergeben (wir gehen dann von einem einzigen Gerät pro ioctl aus).

Nach dem Ausführen sollten Sie in Ihrem Ausgabeordner einen Ordner für jedes ioctl haben.

2 Fuzzing

2.1 Mango Fuzz

MangoFuzz ist unser einfacher Prototyp-Fuzzer und basiert auf Peach (genauer gesagt MozPeach).

Es ist kein besonders ausgefeilter Fuzzer, aber er findet Fehler. Er wurde auch so konzipiert, dass er leicht erweiterbar ist. Dieser Fuzzer besteht aus zwei Komponenten: der Fuzz-Engine und dem Executor. Der Executor befindet sich hier und die Fuzz-Engine hier.

2.1.1 Executor

Der Executor läuft auf dem Telefon und horcht auf Daten, die die Fuzz-Engine an ihn sendet.

Kompilieren Sie es einfach für die Architektur Ihres Telefons, übertragen Sie es per adb push auf das Telefon und führen Sie es mit dem Port aus, auf dem es horchen soll!

2.1.2 Fuzz-Engine

Die Schnittstelle zu MangoFuzz ist recht einfach. Sie benötigen ein Engine-Objekt und ein Parser-Objekt, in das Sie Ihre Engine einspeisen. Von hier aus parsen Sie jpits mit Ihrem Parser und führen dann die Engine aus. Einfach! Wir haben einige einfache Ausführungsskripte bereitgestellt, um Ihnen den Einstieg zu erleichtern.

Um gegen bestimmte Treiber zu fahren, können Sie runner.py auf einem der ioctl-Ordner im Ausgabeverzeichnis (erstellt von unseren Nachbearbeitungsskripten) verwenden.

z.B. ./runner.py -f honor8/out/chb -num 1000. Dies teilt MangoFuzz mit, 1000 Iterationen gegen alle ioctl-Befehl-Wert-Paare des chb-ioctl/Treibers auszuführen.

Wenn wir stattdessen gegen ein ganzes Gerät (Telefon) fahren möchten, können Sie dev_runner.py verwenden. z.B. ./dev_runner.py -f honor8/out -num 100. Dies wird die Treiberdateien durchlaufen und dabei zufällig zwischen ihnen wechseln, jeweils für 100 Iterationen.

Beachten Sie, dass Sie vor der Kommunikation der Fuzz-Engine mit dem Telefon ADB verwenden müssen, um eine Portweiterleitung einzurichten, z.B. adb forward tcp:2022 tcp:2022

Tool herunterladen