Slide 1

Slide 1 text

ファジングツールAFLが ターゲットに入力を送る方法 MsY(@py65criz) 1

Slide 2

Slide 2 text

まえおき ソースコード:https://github.com/msymt/afl-fuzz-to-target ● ファジングツールは、AFL(American Fuzzy Lop)を前提とする ● 主にLinuxのプロセスやファイルディスクリプタ(fd)に関する話 ● AFLが分かる人向け: forkserverは今回考慮しない 2

Slide 3

Slide 3 text

ファジング ● 自動テスト手法の1種 ● テスト対象のシステムに対して大量のデータを入力し、バグを検出する手法 入力値の生成 テスト対象の システム 入力値の送信 システムの状態の監視 送信 応答 ターゲット 図:ipa, ファジング活用の手引き , p6, 図 2.1-1をもとに作成 3

Slide 4

Slide 4 text

ファジング ● 自動テスト手法の1種 ● テスト対象のシステムに対して大量のデータを入力し、バグを検出する手法 入力値の生成 テスト対象の システム 入力値の送信 システムの状態の監視 送信 ここどうなってんの? -> 抽出してみよう 応答 図:ipa, ファジング活用の手引き , p6, 図 2.1-1をもとに作成 4

Slide 5

Slide 5 text

ファイルディスクリプタ(file descriptor, fd) 5 ● システムコールopen(2)の使用時、 そのファイルを示す非負整数のfdを返す ● 予約番号 ○ 0: 標準入力 ○ 1: 標準出力 ○ 2: 標準エラー出力 ● ファイルへの読み書きや位置決めは、fdを使用 プロセス fd:1(標準出力) fd:2(標準エラー出力) fd:0(標準入力) プロセス fd:3 ファイルA int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); 例:ファイルAを読みモードで開いた

Slide 6

Slide 6 text

構成要素 ● afl-fuzz: ファジングツールAFLのメインから書き込み部分を抽出 ● .cur_input: ファズ(入力値)の書き込み先のファイル ● target: テスト対象のプログラム ○ プログラムの内容:標準入力から受け取った文字列をファイルに書き込む 6

Slide 7

Slide 7 text

ワークフロー 1. afl-fuzzを起動 2. afl-fuzz:用意したファズ(入力値)を.cur_inputに書き込む 3. afl-fuzz:子プロセスを生成 4. afl-fuzz(子プロセス):ターゲットプログラム(target)を起動 a. target:標準入力から文字列を受取 b. target:受け取った文字列をファイルに書き込み、終了 5. afl-fuzz: 子プロセスの終了を待機 7

Slide 8

Slide 8 text

子プロセス afl-fuzz(親プロセス) target .cur_inputにファズを 書き込む .cur_inputの 読み書き位置を 先頭に戻す 子プロセスを生成 子プロセスの終了を待機 標準入力のfd(0)を .cur_inputのfdで上書き 標準入力の受取・コー ド実行 targetの起動 終了 lseek dup2 execv .cur_inputを開く ワークフロー fd = open(O_RDWR) 8

Slide 9

Slide 9 text

子プロセス afl-fuzz(親プロセス) target .cur_inputにファズを 書き込む .cur_inputの 読み書き位置を 先頭に戻す 子プロセスを生成 子プロセスの終了を待機 標準入力のfd(0)を .cur_inputのfdで上書き 標準入力の受取・コー ド実行 targetの起動 終了 lseek dup2 execv .cur_inputを開く ワークフロー fd = open(O_RDWR) 9

Slide 10

Slide 10 text

子プロセス afl-fuzz(親プロセス) target .cur_inputにファズを 書き込む .cur_inputの 読み書き位置を 先頭に戻す 子プロセスを生成 子プロセスの終了を待機 標準入力のfd(0)を .cur_inputのfdで上書き 標準入力の受取・コー ド実行 targetの起動 終了 lseek dup2 execv .cur_inputを開く ワークフロー fd = open(O_RDWR) 10 execv後も有効

Slide 11

Slide 11 text

子プロセス afl-fuzz(親プロセス) target .cur_inputにファズを 書き込む .cur_inputの 読み書き位置を 先頭に戻す 子プロセスを生成 子プロセスの終了を待機 標準入力のfd(0)を .cur_inputのfdで上書き 標準入力の受取・コー ド実行 targetの起動 終了 lseek dup2 execv .cur_inputを開く ワークフロー fd = open(O_RDWR) 11 .cur_inputを 読み込む

Slide 12

Slide 12 text

子プロセス afl-fuzz(親プロセス) target .cur_inputにファズを 書き込む .cur_inputの 読み書き位置を 先頭に戻す 子プロセスを生成 子プロセスの終了を待機 標準入力のfd(0)を .cur_inputのfdで上書き 標準入力の受取・コー ド実行 targetの起動 終了 lseek dup2 execv .cur_inputを開く ワークフロー(プログラム) fd = open(O_RDWR) 12

Slide 13

Slide 13 text

子プロセス afl-fuzz(親プロセス) target .cur_inputにファズを 書き込む .cur_inputの 読み書き位置を 先頭に戻す 子プロセスを生成 子プロセスの終了を待機 標準入力のfd(0)を .cur_inputのfdで上書き 標準入力の受取・コー ド実行 targetの起動 終了 lseek dup2 execv .cur_inputを開く ワークフロー(プログラム) fd = open(O_RDWR) 13

Slide 14

Slide 14 text

afl-fuzz ワークフロー(図版) out_fd 14 out_fd = open(O_RDWR,…) により生成 .cur_input

Slide 15

Slide 15 text

afl-fuzz ワークフロー(図版) out_fd 15 forkによりfdは継承 .cur_input 子プロセス (target) out_fd 子プロセス (target) out_fd int dup2(int oldfd, int newfd); ファイルディスクリプタ oldfd を newfd でも使えるようにする

Slide 16

Slide 16 text

afl-fuzz ワークフロー(図版) out_fd 16 dup2(out_fd, 0); .cur_input 子プロセス (target) out_fd 子プロセス (target) fd:0(標準入力) out_fd target.c int dup2(int oldfd, int newfd); ファイルディスクリプタ oldfd を newfd でも使えるようにする

Slide 17

Slide 17 text

afl-fuzz ワークフロー(図版) out_fd 17 .cur_input 子プロセス (target) out_fd 子プロセス (target) fd:0(標準入力) out_fd target.c int dup2(int oldfd, int newfd); ファイルディスクリプタ oldfd を newfd でも使えるようにする “Hello, World!” をファズとする

Slide 18

Slide 18 text

afl-fuzz ワークフロー(図版) out_fd 18 .cur_input 子プロセス (target) out_fd 子プロセス (target) fd:0(標準入力) out_fd target.c int dup2(int oldfd, int newfd); ファイルディスクリプタ oldfd を newfd でも使えるようにする “Hello, World!” をファズとする out.txtに “Hello, World!” が渡る

Slide 19

Slide 19 text

実行結果 ファズ(入力値) targetに渡せた 19

Slide 20

Slide 20 text

抽出した感想・今後 20 ● 学部のシステムプログラミングの復習になり、勉強になった ● afl-fuzzのソースコード多すぎ・マクロ多すぎで辛い 今後 ● forkserverありの場合も図解していきたい ○ 確かafl-fuzz(親)とforkserver(子)とターゲット(孫)間を今回のように dup2によって渡していたような。。。

Slide 21

Slide 21 text

参考文献 21 ● ipa, ファジング活用の手引き, https://www.ipa.go.jp/files/000057652.pdfZ ● 冨永 和人, 権藤 克彦, 例解UNIX/Linuxプログラミング教室: システムコールを使 いこなすための12講 ● 田浦健次朗, ファイルディスクリプタと擬似ファイル 副題: Unix的な考え方(全てが ファイル), https://www.eidos.ic.i.u-tokyo.ac.jp/~tau/lecture/operating_systems/slides/pdf/ 07_everything_is_file.pdf