
pip3 install frelatage
世界が待ち望んだPythonファザー
インストール | 仕組み | 機能 | Frelatageの使い方 | 設定
Frelatageは、カバレッジベースのPythonファジングライブラリで、Pythonコードをファジングするために使用できます。Frelatageの開発は、AFL/AFL++、Atheris、PythonFuzzなど、さまざまなファザーから着想を得ています。このプロジェクトの主な目的は、これらのファザーの優れた機能を活用し、それらを一つの新しいツールにまとめて、Pythonアプリケーションを効率的にファジングすることです。
免責事項: このプロジェクトはアルファ段階であり、まだ多くの予期しない動作を引き起こす可能性があります。現時点では、Frelatageを本番環境で使用すべきではありません。
pip3 install frelatage
開発者向けに推奨。frelatageリポジトリのメインブランチを自動的にクローンし、ソースからインストールします。
# Frelatageリポジトリを自動的にクローンし、Frelatageをソースからインストール
bash <(wget -q https://raw.githubusercontent.com/Rog3rSm1th/Frelatage/main/scripts/autoinstall.sh -O -)
Frelatageの設計の背後にある考え方は、遺伝的アルゴリズムを使用して、可能な限り多くのコードをカバーする突然変異を生成することです。ファジングサイクルの機能は、次の図で大まかに要約できます。
graph TB
m1(突然変異 1) --> |入力| function(ファジング対象関数)
m2(突然変異 2) --> |入力| function(ファジング対象関数)
mplus(突然変異 ...) --> |入力| function(ファジング対象関数)
mn(突然変異 n) --> |入力| function(ファジング対象関数)
function --> generate_reports(レポート生成)
generate_reports --> rank_reports(レポートランク付け)
rank_reports --> select(最良のレポートn件を選択)
select --> |突然変異| nm1(突然変異 1) & nm2(突然変異 2) & nmplus(突然変異 ...) & nmn(突然変異 n)
subgraph サイクル内の突然変異
direction LR
m1
m2
mplus
mn
end
subgraph 次のサイクルの突然変異
direction LR
nm1
nm2
nmplus
nmn
end
style function fill:#5388e8,stroke:white,stroke-width:4px
Frelatageでは、ファイルを入力として関数に渡してファジングできます。
import frelatage
import my_vulnerable_library
def MyFunctionFuzz(data):
my_vulnerable_library.parse(data)
input = frelatage.Input(value="initial_value")
f = frelatage.Fuzzer(MyFunctionFuzz, [[input]])
f.fuzz()
Frelatageでは、ファイルタイプの入力パラメータをファジングできます。これらのファイルの値を初期化するには、入力フォルダ(デフォルトでは./in)にファイルを作成する必要があります。
ファジングに使用するファイルの値を初期化したい場合は、次のように実行します:
echo "initial value" > ./in/input.txt
そしてファザーを実行します:
import frelatage
import my_vulnerable_library
def MyFunctionFuzz(data):
my_vulnerable_library.load_file(data)
input = frelatage.Input(file=True, value="input.txt")
f = frelatage.Fuzzer(MyFunctionFuzz, [[input]])
f.fuzz()
import frelatage
import my_vulnerable_library
input = frelatage.Input(file=True, value="input.txt")
@frelatage.instrument([[input]])
def MyFunctionFuzz_1(data):
my_vulnerable_library.load_file(data)
@frelatage.instrument([[input]])
def MyFunctionFuzz_1(data):
my_vulnerable_library.load_file_but_different(data)
# 以下同様
# インストゥルメントされたメソッドを順番にファジングします
frelatage.Fuzzer.fuzz_all()
複数のファイルを一度にコーパスに読み込む必要がある場合(大きなコーパスを使用する場合に便利)、Frelatageの組み込み関数load_corpusを使用できます。この関数は入力のリストを返します。
load_corpus(directory: str, file_extensions: list) -> list[Input]
./、./images["jpeg", "gif"]、["pdf"]import frelatage
import my_vulnerable_library
def MyFunctionFuzz(data):
my_vulnerable_library.load_file(data)
my_vulnerable_library.load_file(data2)
# ./in ディレクトリ内のすべてのファイルを読み込む
corpus_1 = frelatage.load_corpus(directory="./")
# ./in/images サブディレクトリ内のすべての .gif/.jpeg ファイルを読み込む
corpus_2 = frelatage.load_corpus(directory="./images", file_extension=["gif", "jpeg"])
f = frelatage.Fuzzer(MyFunctionFuzz, [corpus_1, corpus_2])
f.fuzz()
ここにある1つ以上の辞書を、辞書専用ディレクトリ(デフォルトでは./dict)にコピーします。
差分ファジングは、人気のあるソフトウェアテスト手法で、複数のライブラリ/プログラムに同じ入力を与え、その動作の違いを観察することでバグを検出しようとします。Frelatageを使用した差分ファジングの使用例は、jsonライブラリとujsonライブラリを使用したここにあります。
ファザーとコーパスの詳細な例は、examples ディレクトリにあります。
各クラッシュレポートは、出力フォルダ(デフォルトでは./out)内に、id:<crash ID>,err:<error type>,err_pos:<error>,err_file:<error file>という名前のフォルダに保存されます。
レポートディレクトリの構成は次のとおりです:
├── out
│ ├── id:<クラッシュID>,err:<エラータイプ>,err_file:<エラーファイル>,err_pos:<エラー位置>
│ ├── message
│ ├── input
│ ├── 0
│ ├── <入力ファイル1>
│ ├── ...
│ ├── ...
各クラッシュレポートには、エラーメッセージを含むmessageファイルが含まれています。
各カバレッジ増加レポートは、カバレッジフォルダ(デフォルトでは./cov)内に、coverage_<ID>という名前のフォルダに保存されます。レポートディレクトリの構成は、クラッシュレポートディレクトリと同じ形式です。
関数に渡された入力は、pickleモジュールを使用してシリアル化された後、<report_folder>/inputファイルに保存されます。そのため、ファイルの内容を読み取るには、逆シリアル化する必要があります。この操作は、frelatage-reportコマンドで実行できます。
$ frelatage-report input
Frelatageを設定する方法は2つあります:
設定例:
export FRELATAGE_DICTIONARY_ENABLE=1 &&
export FRELATAGE_SAVE_NEW_COVERAGE=1 &&
export FRELATAGE_TIMEOUT_DELAY=2 &&
export FRELATAGE_INPUT_FILE_TMP_DIR="/tmp/frelatage" &&
export FRELATAGE_INPUT_MAX_LEN=4096 &&
export FRELATAGE_MAX_THREADS=8 &&
export FRELATAGE_MAX_STAGES=1000000 &&
export FRELATAGE_MAX_CYCLES_WITHOUT_NEW_PATHS=5000 &&
export FRELATAGE_INPUT_DIR="./in" &&
export FRELATAGE_DICTIONARY_DIR="./dict" &&
python3 fuzzer.py
import frelatage
def myfunction(input1_string, input2_int):
pass
input1 = frelatage.Input(value="initial_value")
input2 = frelatage.Input(value=2)
f = frelatage.Fuzzer(
# ファジングしたいメソッド
method=myfunction,
# コーパス
corpus=[[input1], [input2]],
# スレッド数
threads_count=8,
# 考慮する例外
exceptions_whitelist=(OSError),
# 考慮しない例外
exceptions_blacklist=(),
# エラーレポートを保存するディレクトリ
output_directory="./out",
# カバレッジ増加レポートを保存するディレクトリ
coverage_directory="./cov",
# サイレントモードの有効/無効
silent=False,
# 無限ファジングの有効/無効
infinite_fuzz=False
)
f.fuzz()
他の多くの計算負荷の高いタスクと同様に、ファジングはハードウェアやOSに負担をかける可能性があることにご注意ください。具体的には:
CPUは高温になり、適切な冷却が必要です。ほとんどの場合、冷却が不十分だったり適切に動作しなくなったりすると、CPU速度は自動的に制限されます。ただし、特にあまり適していないハードウェア(ラップトップ、スマートフォンなど)でファジングを行う場合、何かが故障する可能性がまったくないわけではありません。
対象プログラムは、ギガバイト単位のメモリを異常に消費したり、ジャンクファイルでディスク容量をいっぱいにする可能性があります。Frelatageは基本的なメモリ制限を強制しようとしますが、起こり得るすべての事故を防ぐことはできません。つまり、データ損失のリスクが許容されないシステムでファジングを行うべきではありません。
ファジングには、ファイルシステムに対する数十億回の読み取りと書き込みが含まれます。最新のシステムでは、通常これらは大量にキャッシュされ、結果としてかなり控えめな「物理的な」I/Oになりますが、この方程式を変える可能性のある要因は多数あります。潜在的な問題を監視するのはあなたの責任です。非常に大きなI/Oがあると、多くのHDDやSSDの寿命が短くなる可能性があります。
LinuxでディスクI/Oを監視する良い方法は、iostatコマンドです:
$ iostat -d 3 -x -k [...オプションのディスクID...]
私はRog3rSm1th、21歳のフランス人で、コンピュータとサイバーセキュリティに情熱を注いでいます。ツール(OSINT、ファジングなど)の開発や、CTF/ウォーゲームに参加するのが好きです。私と私のプロジェクトについてもっと知りたい場合は、こちらをクリックしてください。
➜ あなたのプロジェクト(プログラミング、サイバーセキュリティなど)のために私を雇いたい場合は、[email protected]までご連絡いただき、一緒にあなたのニーズを評価しましょう。
何か意見、提案、バグ報告、またはFrelatageを使用してバグを発見した場合は、[email protected]またはTwitter @Rog3rSm1thまでご連絡ください。
| 環境変数 | 説明 | 可能な値 | デフォルト値 |
|---|
| FRELATAGE_DICTIONARY_ENABLE | 辞書要素に基づく突然変異の使用を有効にする | 1 で有効、0 で無効 | 1 |
| FRELATAGE_SAVE_NEW_COVERAGE | 新しいカバレッジ入力を保存して後で再利用する | 1 で有効、0 で無効 | 1 |
| FRELATAGE_TIMEOUT_DELAY | 関数がTimeoutErrorを返すまでの遅延時間(秒) | 1 - infinity | 2 |
| FRELATAGE_INPUT_FILE_TMP_DIR | 入力ファイルが保存される一時フォルダ | 絶対パス(例:/tmp/custom_dir) | /tmp/frelatage |
| FRELATAGE_INPUT_MAX_LEN | 入力変数の最大サイズ(バイト) | 4 - infinity | 4094 |
| FRELATAGE_MAX_THREADS | 同時スレッドの最大数 | 8 - infinity | 8 |
| FRELATAGE_MAX_STAGES | ファジング対象関数の最大ステージ数 | 1 - infinity | 1000000 |
| FRELATAGE_MAX_CYCLES_WITHOUT_NEW_PATHS | 新しいパスが見つからずに次のステージに進むまでのサイクル数 | 10 - infinity | 5000 |
| FRELATAGE_INPUT_DIR | 初期入力ファイルを含むディレクトリ。ファジングファイルへの相対パスである必要があります | フォルダへの相対パス(例:./in) | ./in |
| FRELATAGE_DICTIONARY_DIR | 辞書のデフォルトディレクトリ。ファジングファイルへの相対パスである必要があります | フォルダへの相対パス(例:./dict) | ./dict |
| FRELATAGE_DEBUG_MODE | デバッグモードを有効にする(Frelatageがクラッシュしたときにエラーを表示) | 1 で有効、0 で無効 | 1 |