現在、完全に書き直しています。まずは標準入力からの入力のみを受け付ける対話型Linuxアプリに焦点を当てます。ShellphishのDrillerとFuzzer機能を利用しようと試みています。
autoPwnの現状では、これが限定的な形で動作します。単にautoPwn ./binaryを実行し、Startオプションを選択してください。
依存関係の問題が多いため、autoPwnを動かす最も簡単な方法はDockerビルドを使用することです。--security-optおよび--cap-addオプションは削除しても構いませんが、一部のファジング機能が動作しなくなる可能性があります。
$ sudo docker pull bannsec/autoPwn
$ sudo docker run -it -v $PWD:/mount --security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix/ bannsec/autopwn
Dockerビルド内では、すべての準備が整っています。以下のようにツールを起動するだけです。
$ autoPwn ./file
autoPwnは、ファジング用にプロジェクトのソースをコンパイルする作業を簡単にすることを目指しています。そのためにautoPwnCompileが作成されました。ソースコードを指定し、オプションを与えるだけで、ファジング可能な実行ファイルが出力されます。
usage: autoPwnCompile [-h] [--file FILE] [--ASAN | --MSAN] [--UBSAN]
[--fuzzer FUZZER]
Compile source to binaries for use in autoPwn.
optional arguments:
-h, --help show this help message and exit
--file FILE Single file to compile.
--ASAN Enable ASAN (default off)
--MSAN Enable MSAN (default off)
--UBSAN Enable UBSAN (default off)
--fuzzer FUZZER (optional) What fuzzer to compile for. Options are:
['AFL']. Default is AFL.
以下はautoPwnの旧バージョンの内容です。
autoPwnという名前は大げさですが、実際はシンプルなスクリプトです。ファジングやafl-fuzzを扱っていると、同じ作業を何度も繰り返していることに気付きました。そこで、以下のことを実現するスクリプトを作成したいと考えました。
現在までに、スクリプトは1〜5を達成しています。パート6はまだ推測段階で、現在開発を試みています。angrシンボリック実行エンジンを利用して、可能な初期パスを作成する予定です。それが実現すれば、スクリプトは理論的に単純なファジングタスクを完全に自動化できるでしょう。
最近のTUCTFチャレンジ「WoO2」を見てみましょう。必ずしも必要なエクスプロイトを見つけられるわけではありませんが、autoPwnがどのようにパス発見を簡略化できるかを示しています。
以下はプログラムの基本的な実行例です。
$ ./e67eb287f23011a40ef5bd5c2ad2f48ca97834cf
Welcome! I don't think we're in Kansas anymore.
We're about to head off on an adventure!
Select some animals you want to bring along.
Menu Options:
1: Bring a lion
2: Bring a tiger
3: Bring a bear
4: Delete Animal
5: Exit
Enter your choice:
1
Choose the type of lion you want:
1: Congo Lion
2: Barbary Lion
1
Enter name of lion:
Test
Menu Options:
1: Bring a lion
2: Bring a tiger
3: Bring a bear
4: Delete Animal
5: Exit
Enter your choice:
5
シンプルな入力テストケースを作成しましょう。
$ cat in/1
1
1
Test
5
これで簡単にファザーを起動できます。
$ autoPwn
Setting up fuzz configuration
Target Binary (full or relative path): e67eb287f23011a40ef5bd5c2ad2f48ca97834cf
Command line args:
Number of cores (default: 8):
Test Case Dir (default: 'in/'):
Test Case Dir (default: 'out/'):
Max memory (default: 200): 4096
Starting fuzz
autoPwn> s
status check tool for afl-fuzz by <[email protected]>
Individual fuzzers
==================
>>> SESSION007 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION000 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION002 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION006 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION004 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION001 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION005 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
>>> SESSION003 (0 days, 0 hrs) <<<
cycle 1, lifetime speed 1 execs/sec, path 0/1 (0%)
pending 1/1, coverage 0.15%, no crashes yet
Summary stats
=============
Fuzzers alive : 8
Total run time : 0 days, 0 hours
Total execs : 0 million
Cumulative speed : 8 execs/sec
Pending paths : 8 faves, 8 total
Pending per fuzzer : 1 faves, 1 total (on average)
Crashes found : 0 locally unique
autoPwn> h
autoPwn
s == fuzzer (s)tatus
e == collect (e)xploits
a == collect (a)ll paths
m == (m)inimize corpus
q == (q)uit
つまり、ここでスクリプトはデフォルト値(利用可能なコア数の決定を含む)を作成しました。QEMUで実行するために追加のメモリが必要だったため、デフォルト値を1つ変更しました。autoPwnは設定ファイルを作成し、それをafl-utils(https://github.com/rc0r/afl-utils)に渡しました。設定ファイルではCPUアフィニティも設定し、ファジングがデフォルトで最適になるようにしました。
この時点で、コンピュータはファジングを続けています。しかし、ファジングの重要な側面の1つはコーパスの最小化です。そこで、autoPwnはafl-fuzzインスタンスを監視し、一連の突然変異が完了したタイミングを検出します。その時点でファジングを停止し(最適ではありませんが、今のところは問題ありません)、コーパスを最小化し、その後ファジングを再開します。この作業はすべて人間の介入なしに行われるため、設定して放置できます。
ある時点で、aflがどのようなパスを見つけたかを確認したくなるでしょう。「a」コマンドを実行すると、autoPwnは既知のすべてのパスをコピーし、コーパスを最小化し、さらに各ケースを最小化して出力ディレクトリに提供します。