
mTLS上でx509証明書を使用するプロトタイプのマルウェアC2チャネル
まず、なぜこれをオープンソースにするのか?
MITRE ATT&CKは、窃取された証明書または自己署名証明書についてのみ言及しており、NDR(私が知る限り)は、発行元CAが誰であるか以外のx509証明書の内容にはほとんど注意を払っていません。一般に、x509証明書は信頼され、ファイアウォールを難なく通過することを許されています。しかし、本質的には、他のファイルと同様に、悪意のあるペイロードを簡単に含むことができる単なるファイルです。私たちが当然のこととして受け入れてきた暗号化プロセスの中核的構成要素であるため、私たちはx509証明書を信頼し、無視しています。このプロジェクトの主な目的は、私たちが信頼するに至ったセキュリティインジケータのクラスに対する認識を高め、その悪意のある使用を検出するために使用できる方法を強調することです。
私は常に、脅威アクターがC2通信の一部としてx509証明書を使用したことがあるかどうか疑問に思っていました。ネットワークトラフィックを暗号化するためではなく、実際にC2通信をx509証明書に埋め込むためです。このようなものを実環境で5年間探した後、ついにそれが可能かどうかを確かめるために自分でコードを書くことにしました...そして、可能でした。
HTTPS/TLSを介して送信されるすべての暗号化メッセージは、x509証明書の転送によって可能になっています。TLSハンドシェイク(下図)を確立するとき、4番目のステップでサーバーはx509証明書をクライアントに送信します。クライアントは証明書を検証し、サーバーがサポートする暗号化アルゴリズムを比較し、以降のすべての通信で使用するアルゴリズムを選択します。

この図が示すように、これはサーバーからクライアントへのx509証明書の一方向の転送にすぎません。クライアントがサーバーに応答を返す手段がないため、これはC2通信には適していません。せいぜい、一方向のデータ転送メカニズムとしてのみ使用できます(下記の先行技術セクションを参照)。
しかし、相互TLS認証(mTLS)と呼ばれる別のタイプのTLSセッションがあります。これは、クライアントとサーバーの両方がx509証明書を交換して相互に認証する方式です。

上の図が示すように、相互認証中は、認証のためにサーバーのx509証明書がクライアントに送信され、次に認証のためにクライアントのx509証明書がサーバーに送信されます。このアーティファクトの交換は、C2サーバー用の双方向通信チャネルを作成する機会を表しています。
サーバー証明書とクライアント証明書は基盤となるSSLライブラリによって交換されるため、クライアントがサーバーの証明書からメッセージを取り出し、コマンドを実行し、応答証明書を生成するという一連の処理を単一のmTLS接続内で行う機会はありません。つまり、C2チャネルは、リクエストと応答の交換が2つの異なる相互TLS接続を介して行われるように設計する必要があります。いわば、疑似半二重伝送モードのようなものです。

リクエスト/レスポンスプロセスは次のステップに従います:
これを動作させたとき、私は自分が創造的で大したことをやったとかなり誇らしく思っていました。
その後、私はこのJason Reavesによる2018年のBSidesトークに出くわしました。彼はTLSを介したx509証明書を使用するマルウェアバイナリドロッパーを作成した人物です。1年後、JasonはmTLSを使用した完全な双方向通信チャネルを詳述したこの論文を公開しました。
mTLSでは、クライアントとサーバーの両方の証明書が同じCA証明書によって署名されている必要があります。そのため、最初のステップは、独自のCA秘密鍵/証明書ペアを生成することです。
ルートCA秘密鍵を作成します:
openssl genrsa -des3 -out hmCA.key 2048
注:パスフレーズは、あなたの秘密鍵を入手した誰かが独自のルート証明書を生成することを防ぎます。
ルートCA証明書を作成します
openssl req -x509 -new -nodes -key hmCA.key -sha256 -days 1825 -out hmCA.pem
生成された鍵ファイルと証明書ファイルをcerts/ca_certsフォルダーにコピーします。このプロジェクトにはデモ用の鍵/証明書ペアが同梱されているので、必要なければこのステップをスキップできます。
クライアントを起動します:
python client.py
サーバーを起動します:
python server.py
ネットワークログでそれを検出する方法も詳述せずに、潜在的に悪意のあるものをリリースしたくはありません。
この種のTLSパターンの検出は簡単だと思うかもしれませんが、それほど単純ではありません。このC2チャネルの主な兆候の1つは、その半二重方式の通信です。サーバーとクライアントの間で完全なリクエスト/応答を完了するには、2つの相互認証フローが必要です。そして、サーバーがクライアントにさまざまなコマンドを送信するため、これが複数回発生します。
つまり、以下を探す必要があります:
これは文句なしの検出ルールのセットのように思えますが、前に言ったように、それほど簡単ではありません。同様のmTLSトラフィックパターンを持つ一連のエンタープライズサービスもあることが判明しています。その中には以下が含まれます:
これらのいくつかは資産/デバイス管理サービスであると思われるため、理論的には、すべてのデバイスを巡回するたびに同じセットの証明書を送信しているはずです。N時間ごとに繰り返される複数のmTLSセッションのセットがあるかどうかを確認し、2つの異なるmTLSセッションのセット間で証明書ハッシュが一致するか、ほぼ一致するかを確認できます。また、各mTLSセッションでクライアント証明書が異なる一方で、すべてのセッションで同じサーバー証明書が使用されている可能性も確認してください。
SSLインスペクションは、この種のC2通信チャネルを潜在的にブロックする1つの方法です。SSLインスペクションサーバーは、クライアント証明書の認証に必要な悪意のあるCA証明書を持っていないためです。