
自由戦闘モード: オープンソースのハッキングハーネス
FFM は、レッドチームエンゲージメントのポストエクスプロイテーションフェーズで使用できるハッキングハーネスです。このツールのアイデアは、@thegrugq による 2007 年のカンファレンス から着想を得ています。
SSTIC 2018 で発表され(動画)、付随するスライド資料は この URL で入手可能です。この種のツールに詳しくない場合は、ハッキングハーネスの目的を理解するためにそれらを一読することを強くお勧めします。すべてのコメントはスライドに含まれています。
このプロジェクトは GPL v3 ライセンス の条件の下で配布されています。
主要なドキュメントはこの README と commands/ 以下のコマンドモジュールにあります。上記の SSTIC の講演リンクは、ハーネスの使い方に関する最良の高レベルの背景情報です。追加のウォークスルー資料は以下で入手できます。
ice-wzl はプロジェクトの歴史を通じてコマンド、ドキュメント、リファクタリングに貢献しました。docker の使用を強く推奨します。Dockerfile を利用することで、発生する可能性のあるエラーを大幅に削減できます。Docker がインストールされていることを確認してください。git clone https://github.com/JusticeRage/FFM.git
cd /FFM
docker build Docker_Install/ -t ffm:ffm
docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/ffm ffm fb6dd17e3b91 9 minutes ago 614 MB
docker.io/library/ubuntu 22.04 3b418d7b466a 2 weeks ago 80.3 MB
#run your new container and drop into a /bin/bash prompt as root
docker run -it --entrypoint /bin/bash -u 0 fb6dd17e3b91
root と neo の passwd を設定します。su neo で準備完了です。 git clone https://github.com/JusticeRage/FFM.git
cd /FFM
pip install -r requirements.txt
ハッキングハーネスの目的は、ポストエクスプロイテーションフェーズ中の一般的なタスクを自動化するヘルパーとして機能することに加え、ユーザーが犯す可能性のあるミスから保護することです。
これはシェルの計装(インストルメンテーション)です。./ffm.py を実行して有効にし、すぐに作業を開始できます。コマンドは commands/ 以下の小さなモジュールに分割されており、commands/command_manager.py が発見と登録を処理します。主なグループは enumeration, help, stealth, transfer, execution です。
知っておくべきコマンドが 2 つあります。
!list と入力すると、ハーネスが提供するすべてのコマンドが表示されます。!list tags と入力すると、コマンドを分類できるさまざまなタグが表示されます。!list tags
List of commands available:
enumeration
execution
help
stealth
transfer
!list enumeration(または他のタグ)と入力すると、そのカテゴリに該当するコマンドが表示されます。!list enumeration
List of commands available:
!backup-hunter: Hunts for backup files
!info: Returns CPU(s), Architecture, Memory, and Kernel Verison for the current machine.
!log: Toggles logging the harness' input and output to a file.
!mtime: Returns files modified in the last X minutes
!os: Prints the distribution of the current machine.
!db-hunter: Hunts for .sqlite, .sqlite3, and .db files
!sshkeys: Hunts for Private and Public SSH keys on the current machine.
!suid: Finds SUID, SGID binaries on the current machine.
--snip--
SHIFT+TAB と入力すると、ローカルマシンでタブ補完が実行されます。これは、リモートコンピュータに SSH 接続しているが、自分のマシンにあるファイルを参照する必要がある場合に便利です。このハッキングハーネスは、以下で説明するいくつかの機能を提供します。説明に合わせて、ツールの設計哲学も紹介されます。FFM に実装されているすべてのコマンドが自分に合うとは限りません。誰でもやり方は異なり、ハーネスを自分の特定のニーズに合わせて調整するには、コードの一部を変更したり、いくつかのプラグインを書いたりする必要があるでしょう。この作業を可能な限り簡単にするために多くの努力が払われています。
!os は非常にシンプルなコマンドで、cat /etc/*release* を実行して現在のマシンが実行している OS を表示します。おそらく最も価値があるのは、ハッキングハーネスのコンテキストでは、マシンの境界を越えて機能するエイリアスを定義できることを示すデモンストレーションとしてでしょう。任意のコンピュータに SSH 接続し、!os と入力するとコマンドが実行されます。列挙コマンドは commands/enumeration_commands.py に、ヘルプコマンドは commands/help_commands.py に、ステルス関連のコマンドは commands/stealth_commands.py、commands/notty_sudo.py、commands/log_control.py に分散して存在します。!backup-hunter バックアップファイルを探します。!info 現在のマシンの CPU、アーキテクチャ、メモリ、カーネルバージョンを返します。!log ハーネスの入力と出力をファイルに記録するかどうかを切り替えます。commands/log_control.py に実装されています。!mtime 直近 X 分間に変更されたファイルを返します。例: は、ローカルマシン上で(閲覧権限がある)直近 5 分間に変更されたすべてのファイルを取得します。!download [remote file] [local path] リモートマシンからファイルを取得し、端末経由でローカルにコピーします。このコマンドはもう少し複雑で、より厳格なエラーチェックが必要ですが、読み始めるのに適した別のコマンドです。commands/download_file.py にあります。正常に機能するには、リモートマシンに xxd または od が必要です。!download-dir [remote directory] [local destination] リモートディレクトリの tar アーカイブを端末経由でストリーミングし、リモートファイルシステムに触れずにローカルで展開します。commands/download_directory.py にあります。リモートマシンに tar と base64 が必要で、利用可能な場合は gzip も使用します。!upload [local file] [remote path] 上記のコマンドとまったく同じように機能しますが、ローカルファイルをリモートマシンに置きます。commands/upload_file.py にあります。!sh [local script] ローカルマシンのシェルスクリプトをメモリ上で実行します。commands/remote_script.py にあります。!py [local script] ローカルの Python スクリプトをリモートマシン上で実行し、完全にメモリ上で実行します。commands/remote_script.py にあります。使用したいスクリプトについては、私の別のリポジトリをチェックしてください。このコマンドは << を使用した複数行構文を使用するため、それをサポートしていない疑似シェル(Weevely が良い例です)では、このコマンドが大きく壊れます。!py3 [local script] 同じことを python3 が利用可能なシステムに対して行います。同じモジュール commands/remote_script.py を使用します。!elf [local script] リモートマシン上の利用可能な互換性のある Python インタプリタを使用して、ローカルマシンの実行ファイルをメモリ上で実行します。commands/remote_elf.py にあります。!pty TTY を生成します。これは通常、フォレンジック証拠を残す傾向があるため避けたいところですが、一部のコマンド(sudo)やエクスプロイトは TTY 内で実行する必要があるため、便宜上提供されています。生成されるとすぐに UNSET HISTFILE HISTFILESIZE HISTSIZE PROMPT_COMMAND が渡され、export TERM=xterm も設定されます。!sudo TTY なしで sudo を呼び出します。commands/notty_sudo.py にあります。プラグインは ffm.conf を編集することでさらに設定できます。
概念的には、上記のコマンドはシェルに転送される bash を生成するために使用されます。これらはシェルの出力をキャプチャし、返された内容に基づいて追加の指示を生成することで、より複雑な操作を実行できます。プロセッサは少し異なり、ユーザーと基盤となる bash プロセスの間を循環するデータを書き換えるために使用されます。任意のプロセッサをコマンドとして書き直すことは可能ですが、両者を分離しておく方がよりクリーンに思えました。入力プロセッサは、ユーザーが ENTER キーを押したときに入力された内容に対して動作し、出力プロセッサはシェルによって返された任意の出力を変更できます。
processors/ssh_command_line.py にあります。これは、SSH コマンドに -T オプションが欠けている場合に追加するだけのものです。プロセッサの作成に興味がある場合は、そのシンプルなコードをぜひ確認してください。processors/assert_torify.py には、ネットワーキングコマンド(ssh、nc)のブラックリストが含まれており、torify などのツールを介してプロキシされていないように見える場合にそれらをブロックします。ハーネスは、コマンドがローカルマシンで実行されているように見える場合にのみユーザーに通知するように最善を尽くします。もちろん、これは自宅の IP アドレスが漏洩するのを防ぐ唯一の防護手段であるべきではありません。processors/sample_output_processor.py は非常にシンプルな出力プロセッサで、「password」という単語が出現するたびに赤色でハイライト表示します。これはかなり役に立たないため、フレームワークでは有効になっていませんが、より洗練されたことを行いたい場合の出発点として使用できます。CTRL+R はまだ実装されておらず、私たちは皆、それを切に懐かしんでいます。
さらに問題なのは、フレームワークが時々ハングすることです。99% のケースでは、起動したコマンドの実行が完了したことを検出できない場合に発生します。通常、これはログインしているマシンのコマンドプロンプトを認識できなかったことを意味します。その場合、ファイル ffm.py の先頭にある正規表現を改善するか、ssh -T で同じマシンにログインしてみてください(そうすれば問題のあるプロンプトはなくなります)。デフォルトでは、FFM は 5 分後にコマンドの出力を読み取りを試みるのを諦めます(一部のプラグインは異なるタイムアウトを実装している場合があります)。そのため、フレームワークがハングした場合は、エラーメッセージが表示されるまで待つ必要があります(ただし、基盤となるプロセスがまだ実行中の場合は、コマンドを入力できない可能性があります)。
このツールについてほぼすべてをカバーしたと思います。繰り返しになりますが、これは私が通常リリースするものとは少し異なり、ほとんどの人が自分にとって価値のあるものにするために修正する必要があるでしょう。
まだ書かれていないプラグインがたくさんあるので、FFM に加えた改良点があればぜひ共有してください。バグだけでなく、何かをしようとして方法がわからない場合も、遠慮なく issue を開いてください。それによって皆のためのドキュメントを改善できます。
!mtime 5!db-hunter .sqlite、.sqlite3、.db ファイルおよびその他のデータベースファイルを探します。!sshkeys 現在のマシン上の秘密鍵と公開鍵の SSH キーを探します。!suid 現在のマシン上の SUID、SGID バイナリを見つけます。!strange-dirs ユーザー指定のパスから開始して、ホスト上の奇妙なディレクトリをチェックします。!sudo-version 脆弱な sudo バージョンをチェックします。!vm デバイスが仮想マシンかどうかをチェックします。