
E2E暗号化によるマルチホップttyセッションまたはポートシェル + TCP/UDPポートフォワーディング
このプロジェクトは、姉妹プロジェクトである crash と同様、私の検閲対策ツールセットの一部であり、敵対的な検閲環境において完全に機能する暗号化シェルや TCP/UDP 転送をセットアップすることができます。また、フォレンジックにおいて、UART や adb を介して他の手段がない場合にデバイスからデータをダンプするのにも役立ちます。
Pi への UART 接続を介して転送された DNS ルックアップと SSH セッション
PSC は、シェルセッションをエンドツーエンドで暗号化し、シングルまたはマルチホップで、基盤となるトランスポートに依存しません。ただし、トランスポートが信頼性があり、改変やフィルタリングなしに Base64 エンコードされたデータを送受信できることが条件です。エンドツーエンドの pty(例えばポートシェル内で受け取るもの)に加えて、OpenSSH の -L パラメータと同様に、TCP および UDP 接続を転送できます。これは透過的に動作し、開始地点でローカルに IP アドレスを割り当てる必要はありません。これにより、フォレンジック担当者やペネトレーションテスターは、例えば以下の方法でネットワーク接続を作成できます:
adbd が TCP 転送をサポートしていない場合の adb shell セッションあなたのシェルセッションの中に、リモートピアが実際に ppp をサポートしていなくても、目に見えない ppp セッションがあると想像してみてください。
Linux、Android、OSX、Windows、FreeBSD、NetBSD、そして(おそらく)OpenBSD 上で動作します。
PSC は SOCKS4 および SOCKS5 プロキシもサポートしており、ポートシェルやモデムダイヤルアップ経由でリモートから実際の Web ブラウジングセッションを行うことができます。
Makefile の先頭で定義されている事前共有鍵を反映するように Makefile を編集します。
その後、Linux および OSX では make と入力するだけです。
BSD では GNU make をインストールし、代わりに gmake を実行する必要があります。
Windows では cygwin をインストールし、適切な gcc, gcc-g++, make および git パッケージを選択する必要があります。
Linux では、PSC は Unix98 疑似端末を使用し、他のシステムでは POSIX pty を使用しますが、それは透過的に扱われるはずです。ずっと昔、特定の理由で 4.4BSD pty と SunOS サポートを追加したことがあるので、Solaris でもビルドできるかもしれません(できないかもしれません)。
誇り高きスポンサー:
シンプルかつ明快です。ローカルマシンで pscl を実行し、リモートサイト から 特定のアドレスに転送したい TCP または UDP ポートを指定します。例:
linux:~ > ./pscl -T 1234:[192.168.0.254]:22 -U 1234:[8.8.8.8]:53
PortShellCrypter [pscl] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: set up local TCP port 1234 to proxy to 192.168.0.254:22 @ remote.
pscl: set up local UDP port 1234 to proxy to 8.8.8.8:53 @ remote.
pscl: Waiting for [pscr] session to appear ...
linux:~ >
[ UART / SSH / ... login to remote side ... ]
リモートサイト(最後のホップ)でシェルセッションを使用している場合、それがポートシェル、SSH、コンソールログインなどであっても、pscr を実行します:
linux:~ > ./pscr
PortShellCrypter [pscr] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: Seen STARTTLS sequence, enabling crypto.
linux:~ >
pscr を実行すると、両端で暗号ハンドシェイクが確立され、既存のセッション上に透過的な追加プロトコルがレイヤーされます。その後、ローカルマシンの 127.0.0.1:1234 に接続することで、TCP 経由で 192.168.0.254:22 に到達したり、UDP 経由で 8.8.8.8 リゾルバに到達したりできます。これは [IPv6] アドレスでも機能します(リモートサイトが IPv6 接続を持っている場合)。実際、ローカル側では常に 127.0.0.1 に接続するため、IPv4 ソフトウェアを IPv6 に変換するためにも使用できます。
複数の -T および -U パラメータを渡すことができます。セッションがすでにエンドツーエンドで暗号化されているかどうかを見失った場合は、ローカルの pscl プロセスに SIGUSR1 を送信すると、その状態が表示されます。
PSC は、リモート SSH シェルから tor を使用したい場合にも役立ちます。その場合、socks5 および DNS ポートをリモートホストの 127.0.0.1 アドレスに転送できます。SSH は UDP パケットを転送しないため、通常は tor ノード経由で解決するために 2 つの socat コネクタなどを使用します。PSC には、UDP データグラムの境界を維持できるという利点がありますが、SSH -L 経由の socat ではデータグラムの境界が壊れ、不正な DNS 要求が生成される可能性があります。
セッションは Makefile で選択した PSK の aes_256_ctr で暗号化されます。この暗号スキームは変更可能ですが、AAD または OAD データを追加するとパケットサイズが大きくなり、インタラクティブセッションや Base64 エンコーディングのため、入力された文字ごとにより多くのデータが送信されることになります。
UART セッションは screen を使用して使用できますが、例えば minicom は使用できません。minicom はステータス行を持つ非表示のウィンドウを作成し、フィルタのように動作して PSC のプロトコルを破壊するためです。PSC はフィルタリングを検出しようとし、ある程度のデータ改変には対応できますが、状況によっては復旧できない場合があります。tmux も同様です。PSC と一緒に、受信データを過度に操作/処理する pty ハンドラを重ねないようにしてください。
PSC が pty 上で実行するシェルを認識するために、pscl と pscr の両方で SHELL 環境変数を設定する必要があります。多くの環境では SHELL はデフォルトで設定されていますが、設定されていない場合は、SHELL=/bin/bash pscl のように実行する必要があります。
pscl は SOCKS4 (-4 port) および SOCKS5 (-5 port) を介した TCP 接続の転送もサポートしています。これにより、ポートシェルセッションからリモートネットワークをブラウズできるようになり、ペンテスト中に他の接続を開く必要がなくなります。-N を pscl に渡すと、リモート側で DNS 名前解決が有効になり、chrome でも使用できるようになります。ただし、プライバシーの問題があります。ブラウザは起動時に制御できない一連の DNS 名を解決しようとするためです。また、リモート側の DNS 設定が壊れている場合、DNS 応答パケットが欠落すると、シェルが数秒間ブロックされる可能性があります。移植可能で埋め込み可能な優れた非同期リゾルバ関数がないため、単一スレッドで getaddrinfo() に依存する必要がありました。その代償として、DNS 問題が存在する場合に数秒間のブロッキングが発生する可能性があります。そのため、名前解決は明示的に有効にする必要があります。ただし、pscr は DNS ルックアップキャッシュを使用してこの潜在的な問題を最小限に抑えようとするため、ほとんどの状況では問題なく動作するはずです。-X IP-address(最初の引数である必要があります)を渡すと、ローカルプロキシを 127.0.0.1 以外のアドレスにバインドできるため、ローカルネットワークでプロキシを共有できます。
psc の機能により、リモートデバイスに pscr バイナリをインストールできない場合でも、TCP 接続やバイナリデータブロブを複数のホップを経由してリモートデバイスとの間で転送できます。これは、デバイスからアーティファクトをダウンロードする他の手段がない場合(例えば UART 接続された電話機など)や、フォレンジック目的でファイルシステムに触れずに接続を転送して証拠を破壊しないようにする場合、またはルートファイルシステムが読み取り専用でマウントされていてツールセットをアップロードできない場合に非常に役立ちます。
これは非常に優れた機能で、TCP 接続がローカルの tty からリモートボックスにホップするのを、リモートに何もインストールせずに確認できます。
これは、ローカルの pty パンクロックと、pscl に渡すバウンスコマンド(pscr を実行せずにリモートシェルにドロップされる)と、ローカル側でデータをフィルタリングして処理するステートエンジンの魔法によってのみ機能します。通常、これにはまず実際のコマンドを発行する前にリモート pty を raw モードに設定し、-B に渡すその他の詳細が必要です。引数は次の部分に分割されます:
: で続く)、例:1234:。stty -echo raw または python -c "import tty;tty.setraw(0)"(引用符に注意。-B も引用符で囲む必要があります)、または同様のもの。pscl にデータ送信を開始するよう指示し、stty が実際に実行されてからコマンドが開始されるまでの競合を回避します。例えば echo GO が最適です。nc 127.0.0.1 22 を使用してローカルポート 1234 をリモートの SSH サーバーにバウンスします。pscl が tty 状態をリセットできます。echo FIN で十分です。推奨します。そうしないと、コマンドの終了を認識するのに問題が生じる可能性があります。; で区切られ、括弧で囲まれます。例:
TCP 接続を転送したい場合、この例ではデバイスに stty と nc がインストールされている必要がありますが、理論的には同等の機能を持つ他のものでも構いません。
ローカルセッションを開始します:
./pscl -B '1234:[stty -echo raw;echo GO;nc example.com 22;echo FIN]'
これにより、ローカルでポート 1234 に接続すると、リモートデバイスに stty -echo raw;echo GO;nc example.com 22;echo FIN コマンドが発行され、その後は双方向でデータを転送し、デバイスの tty 速度(デフォルトは 115200)を超えないようにレート制限を行います。
pscl セッションが開始されたら、UART、ssh -e none ... などでリモートデバイスに接続し、リモートシェルを取得したら、ローカルでも次のように入力します:
ssh [email protected] -p 1234 これにより、ローカルボックスからリモートデバイスを経由して example.com 宛先に SSH 接続をバウンスします。もちろん pscr を使用する方が推奨されます。-B は一度に 1 つの接続しかバウンスできません(ただし、複数の転送のために複数の -B コマンドを渡すことは可能です)。また、TCP セッション後、pty が raw -echo モードのままになるとシェルがハングする可能性があります。最終的なリモートピアも接続を閉じるかどうかに依存します。接続が完了したことを示す pscl 通知が表示され、プロンプトが表示された場合は、reset して新しい接続を開始できるようにする必要があります。データ転送中は、pscl に 7 ビット ASCII の < および > 通知が表示されます。これらはデバッグと進行状況検出のためのローカルなものです。
リモートサイトへの接続は 8 ビットクリーンである必要があることに注意してください。つまり、ssh、telnet、UART、その他のチャネルは(pscr を使用する場合とは異なり)エスケープシーケンスを処理してはなりません。ssh 接続の場合、pscl セッションで ssh -e none を使用する必要があります。
次に、バイナリファイル転送の例を示します。rfile はリモートファイル、lfile はローカルファイルを表します。
リモートファイルをドロップするセッションをローカルで開始する場合:
./pscl -B '1234:[stty -echo raw;echo GO;dd of=rfile.bin bs=1 count=7350;echo FIN]'
ここでは、リモート側が期待するデータ量を指定する必要があります。cat>... のように指定しないと、転送完了後にセッションがハングします(cat は入力を無限に待機するため)。dd count=... を使用すると、クリーンに終了し、FIN マーカーで通知されます。
次に、必要に応じて ssh などを使用して、開始した pscl セッション内からリモートデバイスにシェルを取得します。別のローカルターミナルで:
dd if=lfile.bin|nc 127.0.0.1 1234
これにより、pscl のローカルポート 1234 に接続し、リモート側のダンプコマンドをトリガーして、ローカルの lfile.bin のバイナリデータをリモートの rfile.bin に転送します。レート制限のため、これには時間がかかる可能性があり、転送が完了したかどうかは psc の進行状況画面のみを信頼 してください。ローカルの dd ...|nc ... コマンドはローカルステータスのみを表示し、ローカル TCP バッファによりファイル全体をミリ秒単位で消費する可能性がありますが、実際のファイル転送は pty を通じて行われています。Ctrl-C を押すのは、pscl 画面で完了を示すか、FIN 終了マーカーが dd ...|nc ... セッションにエコーバックされた場合のみにしてください。
同様に、フォレンジック目的でリモートデバイスからローカルボックスにバイナリデータを転送する同様のコマンドを使用できます。ローカルセッションの開始:
./pscl -B '1234:[stty -echo raw;echo GO;dd if=rfile.bin]' または
./pscl -B '1234:[stty -echo raw;echo GO;cat rfile.bin]'
次に、ssh でリモートデバイスに接続してシェルを取得し、再度ローカルで:
nc 127.0.0.1 1234|dd of=lfile.bin bs=1 count=7350
これでサイズ 7350 の rfile.bin を取得し、ローカルファイル lfile.bin にコピーします。
デバイスで stty -echo raw が利用できない場合は、python -c "import tty;tty.setraw(0)" のようなものでも機能します。バウンスコマンドを使用する場合は、リモートデバイスに tty(単なるポートシェルではなく)が必要であることに注意してください。raw モードを設定する stty コマンドには実際の tty が必要です。
psc がシリアル接続を介して実行される場合、ビット損失が発生するとすべてが台無しになる可能性があります。ハードウェアフロー制御なしで実行すると、特に バウンスコマンド を使用している場合、デバイスがデータを送信しているときにスロットリングが行われないため、ビット損失や接続のハングが発生する可能性があります。デバイスへのデータダンプは、このデータが pscl のレート制限を通過するため、よりうまく機能します。
ただし、デバイスで pscr やハードウェアフロー制御を使用できない状況で、私にとってうまくいったヒントをいくつか示します。これは UART を使用する場合にのみ適用されます。これは潜在的に信頼性の低いトランスポートチャネルであるためです。
pscr を使用すると、デバイスから送信されるデータのレート制限を設定できます。デバイスへの方向は常にレート制限されているため、バウンスコマンドを使用してクロスコンパイルした pscr バイナリをデバイスにダンプし、それを使用して双方向のレート制限セッションを開始できます。tio -o 1 または -o 2 を使用して、送信出力バイト間に遅延を追加します。38400 を優先します)。-DRESPECT_UART_BUFSIZE=4096 で psc をコンパイルします。ただし、これによりセッションが非常に遅くなります。contrib フォルダ内には、エスケープ文字の処理を無効にする tio-noprefix パッチもありますが、このパッチは古いバージョンにのみ必要です。上流ですでに受け入れられ統合されているためです。UART を使用する場合は tio を使用することを強くお勧めします。
tio を介してバウンスコマンドを使用する場合、~/.tioconfig ファイルに以下を追加する必要があります:
[default]
prefix-ctrl-key = none
これにより、ESC 処理が無効になり、8 ビットクリーンなチャネルが提供されます。
SIGUSR1 を pscl に送信すると、セッションが暗号化されているかどうかが表示されます。リモートの pscr がローカル部分にそれを通知する手段なしに終了または終了した場合、pscl は暗号化モードのままになり、ハングします。その場合は、SIGUSR2 を送信して平文モードに強制リセットし、新しいセッションを開始できます。
バージョン 0.64 以降、psc はスクリプティングソケットをサポートしているため、ファイルの取得/配置やペーストバッファのリモートコンソールへのダンプに screen は不要になりました。代わりに、ローカルセッションを次のように開始します:
~ > ./pscl -S ~/psc.script_sock
その後は以前と同じように使用できます。何かを「ペースト」する必要がある場合は、次のようにします:
~ > ./pscsh -S ~/psc.script_sock -f script_/helloworld
これにより、script_/helloworld の内容がコンソールに「タイプ」されます。スクリプティング中は、pscl の標準入力がブロックされ、注入された入力がタイピングと混ざりません。pscsh で -S を省略すると、~/psc.script_sock が自動的に使用されます。安全のため、スクリプトは script_ プレフィックスで始まる必要があります。
さらに、pscr には、埋め込み CR 文字を含むファイルの base64 エンコード/デコード機能が追加されました。これは uuencode -m と互換性があります。