SlideShare a Scribd company logo
1 of 10
Download to read offline
ファジング(Fuzzing)を実践、プロジェクト適用する人向けの資料です。
ファジングでOSS・3rdPartyのバグを見つけよう
1. ファジングとは 1
1.1 ファジングツール 1
1.1.1 ファズ 1
1.1.2 ファジングツール 1
1.2 ファジングの効果 2
1.3 ファジングの課題 2
2. 代表的なファジングツール 2
3. ファジング実践 3
3.1 AFL 3
3.1.1 環境構築 3
3.1.2 ファジング 3
3.1.3 結果確認 5
3.2 OSS-Fuzz 7
3.2.1 環境構築 7
新規プロジェクトをOSS-Fuzzに統合する 7
ローカル環境でお試し 8
参考文献 9
あとがき 10
1. ファジングとは
 検査対象のソフトに様々なデータ(Fuzz)を入力し、その挙動を確認することで​バグや脆弱性を検出するブラックボックステス
ト​の一つである。
 ファジングでは例えば、ソフトやコンポーネントに極端に長い文字列や通常用いないような制御コードを入力し挙動を観察す
る。その結果、予期しない異常動作、再起動等が発生した場合に何らかの問題がある可能性が高いと判断できる。
1.1 ファジングツール
1.1.1 ファズ
ファズとは試験対象のソフトに入力する「問題を引き起こしそうなデータ」である。ファズはファジング対象によって様々なもの
がある。例えば、サーバー向けの場合はパケット、画像処理ソフト向けの場合は画像になる。
1.1.2 ファジングツール
 ファジングはツールを用いて行うことが一般的である。ファジングツール(ファザーとも言う)は主に3つの機能を備えてい
る。​「①ファズの生成」、「②ファズの入力」、「③ファジング対象の挙動確認」である。ファジングツールでは①~③を自動的
に繰り返し行うことでバグを検出する。
1
1.2 ファジングの効果
● バグの低減
 設計者、テスト設計者が想定しえないようなテストケースによるバグを発見できる可能性がある。例えば、文字列の入
力を想定しているところに、制御コード等を入力することでバグを発見できる可能性がある。
● テストの自動化・効率化による工数削減
 一般的にファジングツールは人の操作を必要としないため、楽にバグを検出できる。また、同じような入力を想定した
ソフトに対してファズを流用することが容易なため、テストの工数削減にもなる。
1.3 ファジングの課題
● テストの完了判定が難しい
総当り的に無限にファズを生成することもできるため、何をもってファジングを完了とするかの判定が難しい。
● 工数、費用の増加
新規プロセスを導入することになるのでそれなりに増える。
2. 代表的なファジングツール
 様々なものがある。ツールによってファズの生成方法や動作が異なり、とても奥が深い分野である。
 有名どころはAFL、libFuzzerである。
 OSS-Fuzzは各種ファジングの統合サービスである。
 ファジングツールは試験対象のソフト特性や、開発環境、ファジングのベンチマーク結果、バグ検出実績等をもとに選択する。
 後ほど使い慣れているAFL、OSS Fuzzの使い方を紹介する。
名前 特徴 URL
libFuzzer テスト対象のライブラリに対してコードカバレッジを最大
化するようなファズを遺伝的アルゴリズムで生成して入力
する。AFLと互換性があり、ファジングの結果を引き継い
だりできる。
LLVM(Clang)に組み込まれている。
https://llvm.org/docs/LibF
uzzer.html
American Fuzzy Lop
(AFL)
テスト対象のコンパイル時に計測用のコードを埋め込み、
全てのルートを遷移、網羅するような動作をする。
AFLのアルゴリズムを改善した拡張ツールも多い。
(例:MOpt)
・AFL
http://lcamtuf.coredump.cx
/afl/
・MOpf-AFL
https://github.com/puppet-
meteor/MOpt-AFL
Honggfuzz セキュリティ志向のフィードバック駆動形の遺伝的アルゴ
リズムを採用している。
OpenSSH、OpenSSL等のセキュリティ系ツールに強い。
https://honggfuzz.dev/
Eclipser テスト対象がバイナリ形式(ELF)。グレーボックステスト
という内部構造を把握した上で入力データを決定する手法
https://github.com/SoftSec
-KAIST/Eclipser
2
を用いている。AFL等もグレーボックステスト。
OSS-Fuzz 様々なファジングツールを統合てスケーラブルにファジン
グテストできるファジング基盤。
https://github.com/google/
oss-fuzz
FuzzBench ファジングツールを評価するサービス。 https://github.com/google/
fuzzbench
・ベンチマーク結果の例
https://www.fuzzbench.com/
reports/sample/index.html
3. ファジング実践
 普段OSSや自社ソフトのバグ探しに使っているファジングツールの紹介する。
3.1 AFL
 AFLにはC/C++以外の言語対応版、可視化ツール等様々な派生品がある[文献4]。
 ここでは無印のAFLを使用したファジングを実践する。派製品も大体同じ手順で使える。
 AFLでは①テストケースを作成/変更、②ターゲットアプリに入力、③実行、④記録をすることを⑤繰り返す。
3.1.1 環境構築
● ローカルマシン
# wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz
# tar -zxvf afl-latest.tgz
# cd afl-2*
# make
# make install
● Docker
https://hub.docker.com/r/moflow/afl-tools
3.1.2 ファジング
● 試験対象ソフトのソースコードがある場合
コンパイラをafl-gccに変更するだけ。
3
● 試験対象がライブラリの場合
試験対象のライブラリをラップするテストハーネスから間接的に試験する。
● ソースコードがない場合
afl-QEMU上でバイナリを実行する。
● 試験対象ソフトが複数の引数を必要とする場合
ファズを分割する or 一つの引数を試験対象にして他を固定値にする。
ファズの分割が若干複雑なため、後者がおすすめ。
(参考)ファズの分割
https://github.com/google/fuzzing/blob/master/docs/split-inputs.md
マルチスレッドやマスター/スレーブによる並列実行も可能。
試験対象のソースコードがあり、実行形式の場合の基本的な手順を以下に示す。
ビルドして
# CC=/usr/local/bin/afl-gcc CFLAGS="AFL_HARDEN=1” ./configure --disable-shared
# make clean all
ファジングする。コマンドライン引数やファイルを入力に指定することもできる。
# afl-fuzz -i testcase_dir -o findings_dir /path/to/program [...params...]
# afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@
testcase_dirには適当なテストケース(遺伝的アルゴリズムのシード)を入れておく。
「echo -n '' > testcase_dir/hoge」 でも問題は無いが、適切なシードを入れておいたほうがよい。
シードの例は「afl-2.52b/testcases」にある。
testcases/
├── archives
│ ├── common
│ └── exotic
├── images
├── multimedia
├── others
│ ├── js
│ │ └── small_script.js
│ │ if (1==1) eval('1');
│ ├── sql
│ │ └── simple_queries.sql
│ │ create table t1(one smallint);
│ │ insert into t1 values(1);
│ │ select * from t1;
│ ├── text
│ └── xml
│ └── small_document.xml
└── README.testcases
例)dhclientのファジングをする。
# /home/hasegawa/dhcp/dhcp-4.3.6/client
# mkdir test_in
# echo -n 'hoge' > test_in/hello
# CC=/usr/local/bin/afl-gcc CFLAGS="AFL_HARDEN=1” ./configure --disable-shared
# make clean all
4
# afl-fuzz -i test_in -o test_out ./dhclient
 途中経過の画面を以下に示す。
 全部終わるのに数日以上かかるため下記がある程度増えたら止める。
進捗状況:favored paths(重要なパス)やexec speed(消化スピード)、fuzzing strategy yields
バグ状況:crashed、hang
 各項目の詳細はREADME参照。
3.1.3 結果確認
プロットして結果を確認して全体像を見る。
# afl-plot test_out/ plot/
5
クラッシュ解析ツールを使う。
# cp afl-***/experimental/crash_triage/triage_crashes.sh .
# ./triage_crashes.sh test_out/ dhclient
NGになった出力を確認する。
この例だと特殊文字でハングしているようです。
# cd test_out/
# ls -1
id:000000,src:000000,op:arith8,pos:1,val:+14
id:000001,src:000000,op:arith8,pos:1,val:+25
id:000002,src:000000,op:arith8,pos:2,val:-25
id:000003,src:000000,op:arith8,pos:2,val:+26
# cat “id:000003,src:000000,op:arith8,pos:2,val:+26”
ho�eroot
# hexdump “id:000003,src:000000,op:arith8,pos:2,val:+26”
0000000 6f68 6581
0000004
# cat “id:000003,src:000000,op:arith8,pos:2,val:+26” | ./dhclient
 ⇒事象再現
6
3.2 OSS-Fuzz
 代表的なファザーであるlibFuzzer、AFLおよび分散ファジングツールであるClusterFuzzを統合したファジング環境であ
る。
 OSS-Fuzzの使用方法には、オープンソースプロジェクトとして新規プロジェクトをOSS-Fuzzに統合する方法と、ローカルで
OSS-Fuzzを使用する方法がある。
 前者はOSS-Fuzz Prjにホームページアドレス、メールアドレス、言語等を記載したyamlファイル、ビルドシェル、
Dockerfileをプルリクエストする。オープンソースのファジングをしたい場合にはおすすめの方法。
 後者はOSS-Fuzz Prjにプルリクエストする前のお試しという位置づけ。
以下は現在OSS-Fuzzに登録されているプロジェクト一覧である。 
https://github.com/google/oss-fuzz/tree/master/projects
3.2.1 環境構築
● 新規プロジェクトをOSS-Fuzzに統合する
    他のプロジェクトを参考にすればOK。
    ​https://github.com/google/oss-fuzz/tree/master/projects
1. プロジェクト名/project.yaml を作成する。
homepage: ホームページ 例)"http://www.hogehoge.com/"
language: 言語 例)c++, c
primary_contact: 報告先のメールアドレス 例) "xxx@xx.xx"
auto_ccs:
- CCのメールアドレス 例) "xxx@xx.xx"
fuzzing_engines:
- ファジングに使用するエンジン 例)libfuzzer
sanitizers:
- サニタイズの種別 例)address or undefined
2. プロジェクト名/Dockerfile を作成する。
例)Dockerfileの例
7
FROM gcr.io/oss-fuzz-base/base-builder #clangツールチェーンを使用するベースイメージ
MAINTAINER xxxxx@yyyy.jp #代表者
RUN set -e; 
apt-get update && 
apt-get -y --no-install-recommends install libicu-dev 
apt-utils git curl wget unzip tar; 
apt-get -y clean #依存関係をインストール
# Get *your* source code here. #必要なソースをチェックアウト
RUN git clone --depth 1 --single-branch --branch master
https://github.com/xxx/yyy.git
WORKDIR yyyy #build.shのカレントディレクトリ
COPY build.sh $SRC/ #build.shのコピー
3. プロジェクト名/build.sh を作成する。
ファジング対象をビルドするスクリプト。build.shはDockerfileからビルドされたイメージ内で実行される。
#!/bin/bash -eu
./configure
make clean
make -j$(nproc) all
cp a.out $OUT/ #アーティファクトを格納するディレクトリ。バイナリやファズのシード等もここに入れる。
● ローカル環境でお試し
“infra/helper.py”を使ってローカル環境でOSS-Fuzzできる。
GCP、JenkinsやClusterFuzzと統合しないでOSS-Fuzzだけ使うイメージ。
#cloneして、自分のプロジェクトをprojectに追加(例:libxml2をファジングする)
8
#git clone https://github.com/google/oss-fuzz.git
# cp -rf /home/hasegawa/libxml2 oss-fuzz/project
# cd oss-fuzz
# PROJECT_NAME=libxml2
#Dockerビルドして
# python infra/helper.py build_image $PROJECT_NAME
# python infra/helper.py build_fuzzers --sanitizer address --sanitizer coverage
$PROJECT_NAME
#ファザーの実行
# python infra/helper.py run_fuzzer $PROJECT_NAME libxml2_xml_read_memory_fuzzer
#カバレッジのチェック(-sanitizerにcoverageを設定している場合)
python infra/helper.py coverage $PROJECT_NAME libxml2_xml_read_memory_fuzzer
参考文献
文献1 Google, Google Security Blog
https://security.googleblog.com/2019/02/open-sourcing-clusterfuzz.html
文献2 IPA, 脆弱性対策:ファジング
https://www.ipa.go.jp/security/vuln/fuzzing.html
文献3 IPA, 製品の品質を確保する「セキュリティテスト」に関するレポート
https://www.ipa.go.jp/files/000009390.pdf
文献4 Google, Fuzzing
https://github.com/google/fuzzing/tree/master/docs
9
あとがき
 今後3rd Party製ソフトやOSSを使用する機会が増えていくと思います。
 その際、開発・運用ライフサイクルにファジングを取り入れることでバグ・脆弱性を効率よく検出していきましょう!
 ↓情報安全確保支援士(RISS)007417として情報セキュリティ普及活動、セキュリティコンサルタントに従事しています。
  セキュリティに関することは何でもご相談ください。
 第007417号
10

More Related Content

More from Tetsuya Hasegawa

More from Tetsuya Hasegawa (20)

RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。
 
3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要
 
RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料
 
SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)
SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)
SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)
 
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
 
RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料
 
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
 
RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料
 
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
 
MCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモMCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモ
 
RFC5996(IKEv2)第2版
RFC5996(IKEv2)第2版RFC5996(IKEv2)第2版
RFC5996(IKEv2)第2版
 
面白いセキュリティツール
面白いセキュリティツール面白いセキュリティツール
面白いセキュリティツール
 
3GPP TS 38.300-100まとめ
3GPP TS 38.300-100まとめ3GPP TS 38.300-100まとめ
3GPP TS 38.300-100まとめ
 
Infer:人工知能を使った静的コードチェック
Infer:人工知能を使った静的コードチェックInfer:人工知能を使った静的コードチェック
Infer:人工知能を使った静的コードチェック
 
3GPP TR23.711-e00まとめ
3GPP TR23.711-e00まとめ3GPP TR23.711-e00まとめ
3GPP TR23.711-e00まとめ
 
3GPP TR38.801-e00まとめ
3GPP TR38.801-e00まとめ3GPP TR38.801-e00まとめ
3GPP TR38.801-e00まとめ
 
Web applicationpenetrationtest その5
Web applicationpenetrationtest その5Web applicationpenetrationtest その5
Web applicationpenetrationtest その5
 
Web applicationpenetrationtest その4
Web applicationpenetrationtest その4Web applicationpenetrationtest その4
Web applicationpenetrationtest その4
 
Web applicationpenetrationtest その3
Web applicationpenetrationtest その3Web applicationpenetrationtest その3
Web applicationpenetrationtest その3
 
Web applicationpenetrationtest その2
Web applicationpenetrationtest その2Web applicationpenetrationtest その2
Web applicationpenetrationtest その2
 

ファジングでOSS、3rdPartyのバグを見つけよう