
Dufflebagは、公開されたElastic Block Storage(EBS)スナップショットを検索し、誤って残された秘密情報を見つけ出すツールです。あちこちに転がっているパスワードや秘密情報には驚かされるかもしれません!
このツールはElastic Beanstalk(「EB」、EBSと混同しないでください)アプリケーションとして構成されており、自分のマシンで実行しようとしても絶対に動作しません。
Dufflebagには多くの可動部品があります。実際にEBSボリュームを読み取るのはかなり簡単ではありません。AWS環境内で、スナップショットをクローンし、スナップショットからボリュームを作成し、ボリュームをアタッチし、マウントするなどが必要です。そのため、Elastic Beanstalkアプリとして作られており、自動的に好きなだけスケールアップ・ダウンでき、使い終わったら全体を簡単に解体できます。
AWSコンソールを監視して、何かが暴走して請求がかさんでいないか確認してください。あらゆる不測の事態を想定し、エラーハンドリングを提供しようと努めましたが…注意はしましたよ!
ロール aws-elasticbeanstalk-ec2-role にいくつかの追加のAWS IAM権限を追加する必要があります。または、これらの権限を持つ新しいロールを作成し、EBがそのロールを使用するように設定することもできますが、少し手間がかかります。いずれにせよ、以下を追加する必要があります:
コアアプリケーションはGoで書かれているため、Golangコンパイラが必要です。しかし、EBアプリケーションは実際には.zipファイルにビルドされます(それがEBの仕組みです)。そのため、makefileがzipを出力します。
自分のリージョンを確認してください。Dufflebagは一度に1つのAWSリージョンでのみ動作します。すべてのリージョンを検索したい場合は、その数のインスタンスをデプロイする必要があります。リージョンを変更するには、ソースコードファイル region.go の内容を変更します。
依存関係をインストール:Ubuntu 18.04 x64:
sudo apt install make golang-go git
go get -u github.com/aws/aws-sdk-go
go get -u github.com/deckarep/golang-set
go get -u github.com/lib/pq
go get -u lukechampine.com/blake3
make
これで、プロジェクトのルートディレクトリに dufflebag.zip ファイルが表示されるはずです。
dufflebag で始まるようにするだけです。S3バケット名はグローバルに一意でなければならないため、何らかのギブリッシュのようなサフィックスを付ける必要があるでしょう。AWSコンソールに移動し、Elastic Beanstalkメニューオプションを見つけてください。CLIからも実行可能ですが、この説明ではコンソールを使用します。Actions -> Create Environment を選択します。

次のウィンドウで Worker environment を選択し、Select をクリックします。

次のウィンドウで、Platform に Preconfigured -> Go を選択します。

Application Code で Upload your Code を選択します。

Upload ボタンをクリックし、先ほどビルドした dufflebag.zip を選択します。

最後に、Create Environment をクリックして開始します。
AWSがすべてのものを作成して開始するまで数分かかります。作成されると、Dufflebagはすぐに起動します。他に何もする必要はありません。
この環境が稼働したら、安全弁を外してもう一度試すことができます。デフォルトでは、Dufflebagは20個のEBSスナップショットのみを検索します(最初の試行で暴走しないようにするためです)。検索範囲をリージョン全体に広げるには、populate.go に移動し、以下のコード行を削除して再ビルドしてください:
//#####################################################################
//#### Safety Valve ####
//#### Remove this line of code below to search all of your region ####
//#####################################################################
snapshots = snapshots_result.Snapshots[0:20]
DufflebagがElastic Beanstalkアプリとして設計されている理由の1つは、プログラムを自動的に簡単にスケールアップまたはスケールダウンできることです。デフォルトでは1つのインスタンスで実行され、かなり遅くなります。しかし、少しパワーアップしたい場合は、Elastic Beanstalkのオートスケーリングを調整してください。そのための全オプションはこのドキュメントの範囲外ですので、皆さんで試していただくことにします。しかし実際には、シンプルなCPU使用率トリガーがかなりうまく機能することがわかりました。
上記の環境設定時に、Configure more options ボタン(Create environment を押す代わりに)の下にオプションがあります。その後 Scaling をクリックします。

Dufflebagは、興味深いファイルを先ほど作成したS3バケットにコピーします。(厳密には、Dufflebagは名前が「dufflebag」で始まる最初のS3バケットを使用します。)
S3バケットでファイルが1つずつ届くのを確認できます。ファイル名は次のようになります:
originalfilename_blake3sum_volumeid
すべてが順調に進んでいる場合、ログを読む必要はありません。しかし、万一に備えて、Elastic Beanstalkはアプリが実行中にログファイルに書き込むことを許可しており、これらは Logs タブに移動することでキャプチャできます。その後 Request Logs と Last 100 Lines をクリックします。これにより、最新のDufflebagログのバッチが取得されます。Download ボタンをクリックして読みます。このファイルには多くのシステムログが含まれていますが、Dufflebagの部分は上部の /var/log/web-1.log にあります。
完全なログ履歴を表示するには、Last 100 Lines の代わりに Full Logs を選択します。(デフォルトではEBはログをかなり積極的にローテーションすることに注意してください)
さらに、環境のSQSキューを見ることで全体的な進捗を把握できます。Elastic Beanstalkワーカー環境はSQSを使用してワークフローを管理します。Dufflebagのキュー内の各メッセージは、処理すべきEBSボリュームを表します:

Messages Available 列は、まだ処理されていないボリュームの数を示します。Messages in Flight 列は、現在処理中のボリュームの数を示します。
Dufflebagは、「興味深い」と思われるものを検索するようにプログラムされています。秘密鍵、パスワード、AWSキーなどです。しかし、自分に固有のものを検索したい場合はどうでしょうか?例えば、bank.comで働いていて、bank.comに言及しているものがあるかどうかを確認したい場合などです。
そのためには、Dufflebagのコードに少し変更を加える必要がありますが、それほど多くはありません。心配しないでください!検索対象のロジックは inspector.go で行われています。pilfer() 関数はファイルを検査するゴルーチンです。最初は少し難しそうに見えるかもしれませんが、ここで何をしているかを説明します(そして、難しくなく変更する方法も)。
ファイル名ブラックリスト:
blacklist_exact)blacklist_contains)blacklist_prefix)これらの3つのリストの中身を変更するだけで、検索ロジックを簡単に変更できます。ただし、一般的にはこれらのブラックリストはそのままにしておくことをお勧めします。これらのブラックリストは、多くのファイルシステムに存在する退屈なファイルをカバーし、DufflebagがAWS上のすべてのファイルを詳細に検査する必要を防ぐために設計されています。探している機密データがそれらのファイルにある可能性はありますが…おそらくありません。
ファイル名ホワイトリスト:
IsSensitiveFileName() 関数は、機密ファイル名を見つける正規表現に対してファイル名をチェックします(例:/etc/shadow、bash_historyなど)。ファイル内容:
checkContentsRegex() 関数は、一連の正規表現に対してファイル内容をチェックします(ファイル入力引数は行単位なので、この関数への入力はファイルの1行であり、ファイル全体ではありません)。したがって、組織に関連するキーワードを探すには、checkContentsRegex() 内の正規表現を変更するだけです。