
他のホストの複数の視点からネットワークの可視性を強化する
軍事用語でCornerShotは、兵士が角の先を覗き見(そして場合によっては射撃も)できるようにする武器であり、自らを危険にさらす必要がありません。 同様に、CornerShotパッケージを使用すると、リモートホストのネットワークアクセスを、そのホスト上で特別な権限を持つことなく確認できます。
CornerShotを使用すると、キャリアにネットワークアクセスできるソースが、キャリアとターゲットの間で特定のポートpに対するネットワークアクセスがあるかどうかを判断できます。
たとえば、レッドチームが「侵害済み」のソースホストAから、ホストAがアクセスできないターゲットホストXへ伝播しようとしているとします。 もしホストBを経由して伝播すると、その時点で初めて、ホストBとXの間にネットワークアクセスがないことがわかります。
CornerShotを使用することで、チームはホストCが実際にターゲットXにアクセスできることを発見できるため、ターゲットXへの伝播は最初にホストCを経由する必要があります。
+-----+ +-----+ +-----+
| | | | filtered | |
| A +--------> B +----X--->(p) X |
| | | | | |
+-----+ +-----+ +-(p)-+
source carrier target
+ ^
| |
| +-----+ |
| | | open |
+---------->+ C +-------------+
| |
+-----+
nmapと同様に、CornerShotはポートの状態をopen、closed、filtered、unknown(判断できない場合)に区別します。
次のデモは、2つのキャリアホスト172.0.1.12と172.0.1.13に対してCornerShotを実行し、それらが192.168.200.1へのネットワークアクセスを持っているかどうかを判断する様子を示しています。

詳細はこちらをご覧ください。
ネットワーク内のあるホストBがホストCにアクセスできるかどうかを識別するという一見単純なタスクには、多数のネットワークセンサー、デバイスエージェントの展開、または多数のファイアウォールルール、ルーター構成、ホストポリシーの収集が必要になる場合があります。
CornerShotは、1つ(またはごく少数)のエージェントを使用してネットワーク内の他のホストにクエリを実行し、リモートホストへのアクセスを判別することで、このプロセスを簡素化できます。
BloodHoundを使用してネットワーク内の特権昇格パスを検出して軽減するセキュリティチームは、BloodHoundによって検出された数百万の論理パスにしばしば苦労します。
ShotHoundは、CornerShotとBloodHoundを統合したツールであり、ネットワークアクセスによってサポートされる実用的なパスを発見します。
CornerShotはパッケージとして、またはスタンドアロンモジュールとして使用できます。唯一の要件はPython 3とimpacketパッケージです。
pip install cornershot
基本的な使用法には、有効なドメインユーザーの資格情報、完全修飾ドメイン名(FQDN)、キャリアIP、およびターゲットIPが必要です。
python -m cornershot <user> <password> <domain> <carrier> <target>
キャリアの範囲をターゲットの範囲に対してスキャンするには、サブネットまたはIP範囲をカンマ区切りのリストで使用できます。
python -m cornershot <user> <password> <domain> 192.168.1.10-192.168.1.20 192.168.5.0/24,192.168.6.0/24
デフォルトでは、CornerShotは次のポートをスキャンしようとします:135, 445, 3389, 5985, 5986。ユーザーはカンマ区切りのポートとポート範囲のリストを指定できます。
python -m cornershot -tp 22,8080,45000-45005 <user> <password> <domain> <carrier> <target>
コード内では、有効なドメインユーザーのユーザー名、パスワード、およびドメイン名を指定してCornerShotオブジェクトをインスタンス化する必要があります。 キャリア、ターゲット、ポートの追加はadd_shotsメソッドで行います。準備ができたらopen_fireメソッドを呼び出すと、必要なポートに基づいて関連するRPC呼び出しのみが実行されます。
from cornershot import CornerShot
cs = CornerShot("username", "password", "fqdn")
cs.add_shots(carriers=["192.168.1.1"],targets=["192.168.1.2","192.168.1.3"])
results = cs.open_fire()
open_fireの結果は、キャリアをキーとする辞書です。各キャリアにはさらにターゲットのキーがあり、各ターゲットにはポートとそれぞれの状態を示す辞書が含まれます。 結果の形式例:
{'carrier_1':
{'target_1':
{135: 'unknown', 445: 'filtered', 3389: 'filtered', 5986: 'filtered', 5985: 'filtered'},
'target_2':
{135: 'unknown', 445: 'open', 5985: 'unknown', 5986: 'filtered', 3389: 'open'}
},
'carrier_2':
{'target_1':
{3389: 'filtered', 135: 'filtered', 5985: 'filtered', 445: 'filtered', 5986: 'unknown'},
'target_2':
{5985: 'filtered', 5986: 'filtered', 445: 'filtered', 135: 'filtered', 3389: 'open'}
}
}
CornerShotは、Microsoftのさまざまなサービスで使用される、十分に文書化された標準のリモートプロシージャコール(RPC)メソッドに依存しています。 ドメイン内の認証されたアカウントのみを必要とするメソッドを使用することで、CornerShotはキャリアホストからターゲットへのネットワークトラフィックをトリガーできます。
CornerShotは、RPC呼び出しにかかった時間と、各RPCメソッドの異なるエラーコードを測定することで、リモートのポート状態を判別できます。
読者は、Lee Christensenによって発見された"printer bug"をご存知かもしれません。これはバグと呼ばれていますが、プリントサービスの十分に文書化された動作であり、認証されたユーザーであれば誰でも、RpcRemoteFindFirstPrinterChangeNotificationExメソッドを使用して、リモートサーバーを任意のマシンに認証させることができます。
CornerShotは、いくつかのMicrosoftプロトコルから以下のRPCメソッドを利用します(将来的なバージョンで実装予定のメソッドは他にも多数あります):
プロトコル自体の実装は、素晴らしいimpacketパッケージを介して実現されています。
このメソッドは、printerNameをパラメータとして受け取ります。 printerNameは、ローカルファイル、リモートファイル、またはWebプリンターへのパスにすることができます。WEB_PRINT_SERVER形式に準拠した名前を指定することで、任意のリモートポートにクエリを実行できます。 リモートホストとポートへのHTTPトラフィックをトリガーするWebプリントサーバー名の例は次のとおりです:"http://<target_ip>:<target_port>/printers/ppp/.printer"。
このメソッドを利用するには、2段階のアプローチが必要です。まず、リモートホストのレジストリキーを開き、有効なハンドルを取得します。次に、このハンドルのバックアップをリモートファイルに保存しようとします。 BaseRegSaveKeyメソッドは、レジストリのバックアップを保存できるファイルパスを受け取り、ポート445(およびバックアップとして135)を介してターゲットへのSMBトラフィックをトリガーします。 CornerShotが開くレジストリキーはHKEY_CURRENT_USERで、これはほとんどのクライアントホストでデフォルトで読み取り可能です。
この関数は、Windowsイベントをファイルパスにバックアップしようとします。このファイルパスはリモートにすることができ、その場合、サービスはリモートホストとパスにアクセスしようとします。
EVENメソッドと同様ですが、このメソッドはWindowsイベントプロトコルの別のバージョンを利用し、TCP経由で直接実行されます。SMBポートを開く必要はありません。
CornerShotは、RPCメソッドまたは基盤となるトランスポートから受信したタイミング要因とエラーメッセージに基づいて、リモートポートの状態を推定します。 さまざまなWindowsホストとさまざまなRPCプロトコルで実験を行った結果、ほとんどのネットワーク環境で機能することが証明された3つの異なるタイミングしきい値を導き出しました。 これらのしきい値は、次の図で最もよく示されています。
+ + +
| | |
unknown | open / closed | filtered | open
/ | | |
open | | |
| | |
+-------------+------------------+-----------------+--------------+
0 0.5 20 40 Seconds
MIN FILTERED UPPER
MINしきい値は0.5秒です。このしきい値を下回る応答は、基盤となるRPCメソッドまたはトランスポートのエラーか、ターゲットホストから応答が受信された可能性があります。
FILTEREDしきい値(20秒)を下回る応答は、メソッドに対して受信したエラーメッセージの種類に応じて、オープンポートまたはクローズドポートのいずれかを示している可能性があります。
FILTEREDしきい値とUPPERしきい値(40秒)の間の応答は、テストされたすべてのメソッドでフィルタリングされたポートを示しています(今のところ...)。UPPER制限を超えるリクエストは、長時間のオープンTCP接続を示しています。
CornerShotを異なるOSバージョンや構成に対して実行すると、異なる結果が得られます。すべてのWindowsバージョンが同じ名前付きパイプを持っているわけではなく、同じRPCメソッドでクエリされた場合も同じように動作するとは限りません。 ほとんどのWindows OOTBはSMBやその他のRPCサービスをネットワーク上に公開しませんが、大規模な環境ではこれらのポートが開いており、ほとんどのアセットがアクセス可能である傾向があることが経験から示されています。
次の表は、適切なポートがキャリアホストからアクセス可能であり、ホストの構成が変更されていない場合の、さまざまなRPCプロトコルのデフォルトのサポートを示しています。
* クライアントマシンでWebclientサービスが実行されている場合、追加のポートをスキャンできます。現在、CornerShotはこのオプションをサポートしていません。
** RPRNプロトコルはサーバーホストでサポートされていますが、リモートWebプリンターを開くことは機能しません(そのため、ANYターゲットポートをスキャンできません)。回避策が見つかるまで 😉
追加のRPCショットやその他のコントリビューションを歓迎します!
すべてのRPCメソッドは*/shots*の下に実装され、BaseRPCShotという抽象クラスから継承しています。 /exampleフォルダは、カスタムRPCショットを作成してコードで使用する方法を示しています。
CornerShotはApache 2.0ライセンスの下でリリースされています。詳細については、LICENSEをご覧ください。
ご連絡をお待ちしております! このパッケージに関するバグ、パッチ、提案については、[email protected]までご連絡ください。
| OS | サポートされるRPCプロトコル | 必要なキャリアのオープンポート | スキャン可能なターゲットポート |
|---|
| Windows 7 | EVEN,EVEN6 | 445 / 135 & even6 tcp port | 445* |
| Windows 8 | EVEN,EVEN6 | 445 / 135 & even6 tcp port | 445* |
| Windows 10 | EVEN,EVEN6,RPRN | 445 / 135 & even6 tcp port | ANY |
| Server 2008 | EVEN,EVEN6,RRP,RPRN** | 445 / 135 & even6 tcp port | 445 |
| Server 2012 | EVEN,EVEN6,RRP,RPRN** | 445 / 135 & even6 tcp port | 445 |
| Server 2016 | EVEN,EVEN6,RRP,RPRN** | 445 / 135 & even6 tcp port | 445 |
| Server 2019 | EVEN,EVEN6,RRP,RPRN** | 445 / 135 & even6 tcp port | 445 |