Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
difuze — Linuxカーネルドライバ用ファザー | Kitploit
ツール/GitHubGitHub/ucsb-seclab/difuze
Androidセキュリティ脆弱性分析ファジングバイナリ解析
GitHubucsb-seclab/difuze

difuze

Linuxカーネルドライバ用ファザー

リポジトリを見る
385854年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

difuze: Linuxカーネルドライバ用ファザー

License

このリポジトリには、difuze をセットアップして実行するために必要なすべてのソース(セットアップスクリプトを含む)が含まれています。

テスト済み環境

Ubuntu >= 14.04.5 LTS

0. Dockerからdifuzeを実行する

詳細はreadmeを参照してください。

論文で説明されているように、difuze には2つの主要コンポーネントがあります:インターフェース回復 とファジングエンジン です。

1. インターフェース回復

インターフェース回復メカニズムはLLVM解析パスに基づいています。インターフェース回復の各ステップは個別のパスとして書かれています。以下の手順に従って、インターフェース回復 をセットアップしてください。

1.1 セットアップ

このステップでは、LLVM と c2xml をインストールします:

まず、libxml がインストールされていることを確認してください(c2xml に必要です):

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

次に、必要なツールをすべてダウンロードしてビルドする単一のスクリプトを作成しました。

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.

例:

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

セットアップを完了するには、ローカルの PATH 環境変数の変更も必要です。セットアップスクリプトは必要な変更内容を正確に教えてくれます。

1.2 ビルド

これはセットアップの正常な完了に依存します。 すべてをビルドする単一のスクリプトがあります。どうぞご利用ください。

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

1.3 実行

これはビルドの正常な完了に依存します。 インターフェース回復コンポーネントをカーネルドライバで実行するには、まずドライバをLLVMビットコードに変換する必要があります。

1.3.1 カーネルのビルド

まず、ビルド可能なカーネルが必要です。つまり、通常のビルドセットアップ(make)を使ってカーネルをコンパイルできる必要があります。 最初に make コマンドの出力を取得し、その出力から正確なコンパイルコマンドを抽出します。

1.3.1.1 makeの出力を生成
オプション1: Bearを使用(推奨)
  1. Bear をインストールします。
  2. Bear を使用して make を実行します:
    root@kitploit:~
    bear make <make へのすべてのオプション>
    
    例: bear make -j8

これにより、カレントディレクトリに compile_commands.json ファイルが生成されます。

オプション2

単に V=1 を渡して出力をファイルにリダイレクトします。 例:

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

注意: 複数プロセス(-j)を使用しないでください。マルチプロセッシングモードで実行すると、複数のプロセスが出力ファイルに書き込もうとするため、出力ファイルが乱れます。

以上です。次のステップでは、スクリプトが生成された makeout.txt を取得し、認識されたすべてのドライバに対してインターフェース回復を実行します。

1.3.2 インターフェース回復解析の実行

インターフェース回復のさまざまなステップは、すべて単一のスクリプト helper_scripts/run_all.py にまとめられています。 実行方法:

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.


このスクリプトは、認識されたすべてのドライバに対してインターフェース回復をビルド、リンク、実行するため、かなりの時間(45分~90分) を要する可能性があります。

上記のスクリプトは、すべてのCPUコアを活用するためにマルチプロセッサモードで以下のタスクを実行します:

1.3.2.1 LLVMビルド
  • デフォルトで有効。

生成されたすべてのビットコードファイルは、-l 引数で指定されたフォルダに配置されます。 このステップは、コア数によってかなりの時間がかかります。 したがって、このステップを既に実行している場合は、-skb を渡してスキップできます。

1.3.2.2 すべてのドライバビットコードファイルを統合ビットコードファイルにリンク
  • デフォルトで有効。

これはリンクを実行し、すべてのビットコードファイルを調べて、リンクする必要がある関連ビットコードファイルを特定し、それらを(llvm-link を使用して)統合ビットコードファイル(対応するビットコードファイルと並べて保存されます)にリンクします。

上記のステップと同様に、-skl を渡してこのステップをスキップできます。

1.3.2.3 ヘッダーを解析してエントリ関数フィールドを特定
  • デフォルトで有効。

このステップでは、ヘッダーファイル内のエントリポイント宣言を探し、その構成を LLVM ビルドディレクトリの hdr_file_config.txt ファイルに保存します。

スキップするには: -skp

1.3.2.4 すべての統合ビットコードファイル内のエントリポイントを特定
  • デフォルトで有効。

このステップでは、すべてのドライバ統合ビットコードファイルにわたってすべてのエントリポイントを特定します。 出力は LLVM ビルドディレクトリの entry_point_out.txt ファイルに保存されます。

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

スキップするには: -ske

1.3.2.5 特定されたすべてのエントリポイントに対してIoctl Cmd Finderを実行
  • デフォルトで有効。

このステップでは、主要なインターフェース回復コンポーネント(IoctlCmdParser)を entry_point_out.txt ファイル内のすべてのエントリポイントに対して実行します。各エントリポイントの出力は、-f オプションで指定されたフォルダに保存されます。

スキップするには: -ski

1.4 例:

ここで、カーネルソースがある時点からインターフェース回復結果を得るまでの例を示します。

mediatek カーネル 33.2.A.3.123.tar.bz2 をアップロードしています。 まず、上記のファイルをダウンロードして展開してください。

展開したファイルが ~/mediatek_kernel というフォルダにあると仮定します。

1.4.1 ビルド

Bear をインストールし、以下の手順に従ってください:

root@kitploit:~
cd ~/mediatek_kernel
source ./env.sh
cd kernel-3.18
# 以下の手順はカーネルによっては不要な場合があります
mkdir out
make O=out ARCH=arm64 tubads_defconfig
# compile_commands.json を生成
bear make -j8 O=out ARCH=arm64

1.4.2 インターフェース回復の実行

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

上記のコマンドはかなり時間(30分~1時間) がかかります。

1.4.3 出力の理解

まず、すべての解析結果はフォルダ ~/mediatek_kernel/ioctl_finder_out (-f オプションに指定した引数) に格納されます。各エントリポイントに対して .txt ファイルが作成され、回復されたインターフェースに関するすべての情報が含まれます。

インターフェースのみの情報に興味があり、他のことは気にしない場合は、parse_interface_output.py スクリプトを使用することをお勧めします。このスクリプトは、インターフェース回復パスの複雑な出力を、クリーンで一貫性のある形式のJSONファイルに変換します。

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

ここで、<ioctl_finder_out_dir> は -f オプションに指定したフォルダと同じで、<output_directory_for_json_files> はJSONファイルを作成するフォルダです。

対応するioctlのインターフェース回復には、対応するJSONファイルを使用できます。

1.4.4 注意点:

1.4.4.1 オプション -g の値(makeout.txtを使用する場合のみ)

-g オプションの値を指定するには、カーネルのコンパイルに使用された *-gcc バイナリの名前を知る必要があります。 簡単な確認方法は、makeout.txt 内で gcc を grep することです。コンパイラコマンドが表示され、そこから *-gcc バイナリ名がわかります。

上記の例では、grep gcc makeout.txt を実行すると、以下のような行が多数表示されます:

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

したがって、-g の値は aarch64-linux-android-gcc であるべきです。

ビルドするカーネルが32ビットの場合、バイナリはおそらく arm-eabi-gcc になります。

Qualcomm(またはmsm)チップセットの場合、*.gcc の代わりに *gcc-wrapper.py が表示されることがあり、その場合は *gcc-wrapper.py を指定する必要があります。

1.4.4.2 オプション -a の値

チップセットの種類に応じて、対応する番号を指定する必要があります。

1.4.4.3 オプション -o の値

これは、カーネルビルド時に make コマンドの O= オプションに指定したフォルダのパスです。

すべてのカーネルが個別の出力パスを必要とするわけではありません。O オプションを指定せずにカーネルをビルドすることもできます。その場合、run_all.py の実行時にそのオプションに値を指定してはいけません。

clangを使用してビルドされたカーネル

clang を使用してビルドされたカーネルの場合、上記のオプションに加えて、以下のオプションを指定してください(compile_commands.json を使用した場合):

root@kitploit:~
-isclang -clangp <カーネルのビルドに使用したCLANGへのパス> -llvmlinkp <LLVMリンクへのパス(clangと同じフォルダにあります)>

1.5 後処理

ファジングを開始する前に、研究品質の(すみません)パーサーを使って出力を少し処理する必要があります。

これらのパーサーはこちらにあります。実行するメインスクリプトは 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)

-f には、ioctl解析の出力ディレクトリ(例: ~/mediatek_kernel/ioctl_finder_out)を指定します。

-o は後処理結果を保存する場所です。これらは解析しやすいXMLファイル(jpits)になります。

-n は、デバイス名の回復にどの程度依存するかをシステムに指定します。 作業/名前探索を全く行いたくない場合は、auto を指定できます。 ただし、当然ながら名前を回復できなかったデバイスはすべてスキップされます。回復の努力を一切信頼したくない場合(それは十分合理的です)は、manual オプションを使用してすべてのデバイスに自分で名前を付けることができます。 hybrid はその両方の組み合わせです。可能な場合は自動でデバイス名を付け、失敗した場合はユーザーに問い合わせます。

-m 時には、ioctl が複数のデバイスに対応することがあります(これは v4l2/subdev ioctl などでよく見られます)。この機能はデフォルトで有効ですが、デバイスごとにデバイス数を指定するためのユーザー操作が必要です。これが煩わしい場合は、-m 0 を渡してプロンプトを無効にできます(各 ioctl に対して単一のデバイスを想定します)。

実行後、出力フォルダには各 ioctl のフォルダが作成されます。

2 ファジング

2.1 MangoFuzz

MangoFuzz はシンプルなプロトタイプファザーで、Peach(具体的には MozPeach)をベースにしています。 特に洗練されたファザーではありませんが、バグを見つけます。 また、拡張が容易になるように設計されています。 このファザーには2つのコンポーネントがあります。ファズエンジンとエグゼキュータです。 エグゼキュータはこちら、ファズエンジンはこちらにあります。

2.1.1 エグゼキュータ

エグゼキュータはスマートフォン上で実行され、ファズエンジンが送信するデータを待ち受けます。

スマートフォンのアーキテクチャに合わせてコンパイルし、adb push でスマートフォンに転送し、待受ポートを指定して実行するだけです。

2.1.2 ファズエンジン

MangoFuzz とのインターフェースは非常にシンプルです。Engine オブジェクトと Parser オブジェクトが必要で、エンジンにパーサーを渡します。 その後、パーサーで jpit を解析し、エンジンを実行します。簡単です! 開始するためのシンプルな実行スクリプトをいくつか用意しています。

特定のドライバに対して実行するには、出力ディレクトリ(後処理スクリプトで作成)内の ioctl フォルダの1つに対して runner.py を使用できます。

例: ./runner.py -f honor8/out/chb -num 1000。これは、chb ioctl/ドライバに関連するすべての ioctl コマンド値ペアに対して1000回の反復で MangoFuzz を実行します。

代わりにデバイス(スマートフォン)全体に対して実行する場合は、dev_runner.py を使用できます。例: ./dev_runner.py -f honor8/out -num 100。 これは、ドライバファイルをループし、ランダムに切り替えながら各ファイルに対して100回の反復を実行します。

ファズエンジンがスマートフォンと通信する前に、ADB を使用してポート転送を設定する必要があることに注意してください。例: adb forward tcp:2022 tcp:2022

ツールをダウンロード