This post is also available in: English (英語)
概要
Cobalt Strikeは商用の脅威エミュレーションソフトウェアで、ネットワークに長期的にひそむアクターをエミュレートします。Beaconと呼ばれるこのアクターは外部チームサーバーと通信してコマンド&コントロール(C2)トラフィックを模倣します。汎用性が高く、レッドチームの正規ツールとしてよく利用されますが、脅威アクターの実際の攻撃でも広く使用されています。この汎用性の高さはCobalt Strike にそなわる多くの機能に起因しています。たとえばC2サーバーへ送信するメタデータを難読化するエンコード用のアルゴリズムなどがその例です。
前回のブログ「Cobalt Strike解析&チュートリアル: Malleable C2プロファイルでCobalt Strike検出が難しくなる理由」で、攻撃者またはレッド チームが HTTP トランザクションに対し、Malleable C2 プロファイル内でメタデータ エンコード インジケーターを定義できることを学びました。Cobalt Strike Beaconは、Phone Home通信 (C2サーバーへの連絡通信)時に、侵害システムに関する情報であるメタデータをCobalt Strike TeamServerに送信します。レッドチームや攻撃者は、このメタデータをどのようにエンコードし、HTTPリクエストで送信し、C2トラフィック通信を終了させるかを定義する必要があります。
本稿は、エンコードアルゴリズム、Cobalt Strikeフレームワークで使用されるエンコードタイプの定義と違い、実際に観測されている悪意のある攻撃について解説します。解説ではC2トラフィック通信中にエンコード用・デコード用のアルゴリズムがどのように機能するかを示すほか、なぜ汎用性が高いとCobalt Strikeがエミュレータとして有効で、従来型ファイアウォール対策の設計が難しくなってしまうのかについても示します。
関連する Unit 42 のトピック | Cobalt Strike, C2, Tutorials |
目次
メタデータのエンコード用アルゴリズム
Base64エンコードとデコード
Base64URLエンコードとデコード
NetBIOSエンコードとデコード
NetBIOSUエンコードとデコード
マスクエンコードとデコード
実際の攻撃事例
結論
IoC
追加リソース
メタデータのエンコード用アルゴリズム
Cobalt Strikeがサポートするエンコード方式は5つあります。RSAで暗号化したメタデータをエンコードすれば、ネットワークプロトコルでこの暗号化したバイナリデータを簡単に転送できるようになります。
Base64エンコードとデコード
Base64エンコードとデコードは標準的なRFC用アルゴリズム実装です。作者はBase64の文字集合になんら変更をくわえていません。データのエンコードとデコードに使用される文字の一覧は次のとおりです。
[ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' ]
MalleableプロファイルでのBase64アルゴリズムの使用について、実際の例をとりあげて理解しましょう。
1. プロファイルのメタデータ
Havex.profileは侵害システムに関するメタデータ情報をBase64エンコードで変換してから送信します。図2は、メタデータがBase64エンコードアルゴリズムでエンコードされ、その結果がCookieヘッダに配置される様子を示しています。
2. HTTP C2トラフィック
図3はこのプロファイルが生成したHTTP C2トラフィックです。ハイライト表示した部分が侵害システムに関するメタデータをBase64エンコードしたものです。
3. Base64デコード
- エンコードされたメタデータは何を使ってデコードしてもかまいません。私たちはPythonのBase64 ライブラリでデコードしました。図4はこのデータをデコードして16進数で表示するスクリプトのサンプルです。
- 以下はこのスクリプトでデコードしたデータで、侵害システムに関するRSA暗号化されたメタデータです。
"751990bee317e74e4f2aa6f13078ef22dd884e065b738f8373f49dee401a069d5dfd1d3e39e94cc637e21364e1fd71ab3322fb9c7a987fc6aa27dfab981f077e7ddc2f20aba8e9d841250adc4edd4d15082445869278f2bbcf66e145aa74152a22b85c9b6c5f15d69f7d8b3708b33deea7198683d6468bd0424f537617f759b5"
Base64URLエンコードとデコード
Base64URLはBase64エンコードアルゴリズムの変形版で、URLとファイル名を問題なく扱える文字集合をエンコードとデコードに使用します。以下がその文字集合です。
[ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' ]
標準Base64文字集合との違いは、変形版が「+」を「-」に、「/」を「_」に置き換えているところです。パディング文字の「=」はエンコードデータには含まれません。通常、URIではパーセントエンコードが行われるためです。
MalleableプロファイルでのBase64URLアルゴリズムの使用について、実際の例をとりあげて理解しましょう。
1. プロファイルのメタデータ
Cnnvideo_getonly.profileはメタデータ情報の変換にBase64URLエンコードを使います。なお、このプロファイルは正規のCNN HTTPトラフィックを模倣していることからその名がついていますが、当該組織とは無関係なので注意してください。さて、図5はBase64URLエンコードアルゴリズムでメタデータをエンコードし、パラメータgにデータをアペンドしたところを示しています。
2. HTTP C2トラフィック
図6はBeaconが生成するHTTP C2トラフィックを示したものです。パラメータの値は侵害システムに関するメタデータをBase64URLでエンコードしたものです。
3. Base64URLデコード
このデータのデコード方法はいくつかあります。
- 「+」を「-」に、「_」を「/」に置き換えてパディング文字の「=」を追加する。置換した文字列は標準Base64エンコードデータになるので任意のBase64デコードツールを使って暗号化メタデータを得られる。
- スクリプト言語に処理させる。図7にこのデータをデコードするPythonスクリプトのサンプルを示す。urlsafe_b64decode命令は文字を置き換えるだけでパディング文字は追加しないのでこのサンプルでは「=」を追加してBase64エンコードと互換の出力を得ている。パディング文字はもっと追加してもよい。Pythonはパディングが少なすぎる場合にのみエラーを返す。
- このスクリプトで出力されるRSAで暗号化されたメタデータは次のとおり。"60495dff002eddaa0c409aaaae0fda592810993ae0ae319c87d62b65c54d92447daf2c1bc84930c5d90ed3a023227e254d3a2c28763be372bb7444ef5719d5948b99d33ede3775f51c216bba97bc5fd4777e819517e89a737284c784bdc30b1d6b3b7debe2448c1dc28b00e3ac611fd5a8fd070502f3f7f672786f6b5787af51"
NetBIOSエンコードとデコード
NetBIOSエンコードはNetBIOSサービス名のエンコードに使用されます。Cobalt StrikeはC2通信で被害システムのメタデータを転送するさいこのアルゴリズムでエンコードしています。
NetBIOSのエンコードアルゴリズムは各バイトを2バイトのASCII文字で表現します。入力バイトの各4ビット(これを「ニブル」という)に2進数の右寄せ/ゼロ埋めを行い、それぞれを別のバイトとして扱います。その数値は次にASCII文字の「a」の値に加算され、結果として得られたバイトもそれぞれ別のバイトとして保存されます。エンコードに使用する文字集合は[a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p']です。
図8はエンコード処理の様子を示したものです。
MalleableプロファイルでのNetBIOSアルゴリズムの使用について、実際の例をとりあげて理解しましょう。
1. プロファイルのメタデータ
Ocsp.profileは被害システムのメタデータ変換にNetBIOSエンコードを使います。図9は、メタデータがNetBIOSエンコードアルゴリズムでエンコードされる様子を示しています。得られたデータはURIにアペンドされます。
2. HTTP C2トラフィック
図10はBeaconがOCSPプロファイルで生成するHTTPトラフィックを示したものです。
3. NetBIOSデコード
図11は、NetBIOSでエンコードされたメタデータをデコードするPythonの実装です。
スクリプトの出力は侵害システムに関するメタデータをRSAで暗号化したものです。"5725245edcb589b305e33e02da1cda208ed083bed8a1ae0b3a87da0f9d6ebe31025ab67c58572acb9757288cc2e78bea414249fa8cb0783485a1b5a3c0863501fc1c89c6ac59b7129c51cacbfa197cc64eea31ec8ac204cbcdbefaecf19762f9efcc56280f3e9b183c37f98f371f5e1c08b645524646d7010af4408f4ebb8a2f"
NetBIOSUエンコードとデコード
NetBIOSUは先のNetBIOSエンコードアルゴリズムを若干変更したもので、エンコードに使用する文字集合が異なっています。NetBIOSUの文字集合は、通常のNetBIOSアルゴリズムで使用される文字集合を大文字にしたもので、その内容は['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']です。
NetBIOSUのエンコード処理はNetBIOSのアルゴリズムと同じです。詳しくは、図8を参照してください。
MalleableプロファイルでのNetBIOSUアルゴリズムの使用について、実際の例をとりあげて理解しましょう。
1. プロファイルのメタデータ
Asprox.profileは被害システムのメタデータ変換にNetBIOSUエンコードを使います。図12は、メタデータがNetBIOSUエンコードアルゴリズムでエンコードされる様子を示しています。得られたデータはURIにアペンドされます。
2. HTTP C2トラフィック
図13は、Beaconがasproxプロファイルで生成するHTTPトラフィックを示したもので、ハイライトした箇所が被害システムに関するメタデータです。
3. NetBIOSUデコード
図14は、NetBIOSUでエンコードされたメタデータをデコードするPythonの実装です。
スクリプトの出力は侵害システムに関するメタデータをRSAで暗号化したものです。
"722676e535f86ffc29ba1cafb9856d98d1f697a83b0afc5bb143e2cf2242152a351081fb837192da3e3b2d9021fab75ce32677b6299a24d15e28db883adb36c5fe448d5eb47014f6d2e72eff389f0176efced60380450c87e2015a8c5de6aa90dc8f105683ac5fd96dc33d4d63da62818facda595910cf9aee10f36fe54d4a6a"
マスクエンコードとデコード
マスクエンコードアルゴリズムはMalleable C2プロファイルのほかのエンコードアルゴリズムに指定して組み合わせで使えます。その内容をTeamServerがロードしてC2通信として使うことができます。Beaconはランダムな4バイトをマスクのXORキーとして生成します。次に、生成したマスクキーで、暗号化した128バイトのメタデータをXORし、マスクキーと暗号化データをC2通信のためにTeamServerに送ります。例として randomized.profileの内容を順を追って説明します。
1. 図15はメタデータをマスクとBase64URLでエンコードしたプロファイルの一部を示しています。このプロファイルではURIとメタデータのエンコードアルゴリズムをマスクとBase64URLと定義しているので、エンコードされたメタデータはURIにアペンドされます。
2. HTTP C2トラフィック
図16は図15のプロファイルに基づくC2トラフィックなので、次の手順でエンコードデータを元に戻せます。
- キャプチャしたトラフィックから、全体のURIが/zChN7QMDhftv10Li9Cu-fm_T_3qDQawT-Z1GzNg1FWfAfSILT-u_rKLvXP-RE0ac-pxJTlGFCUIm4Aw9rGHPCIJVl0zNdCbM_G2VkYXJ5GGtVh8LWM4YLGZD9okLcFBc402j5zESK71HaR_owJb-AVBfFvAo8q0I2J74rmfGyIROygであることがわかります。
- 接頭辞の/zCを取り除きます。残りの値はBase64URLでエンコードされています。
hN7QMDhftv10Li9Cu-fm_T_3qDQawT-Z1GzNg1FWfAfSILT-u_rKLvXP-RE0ac-pxJTlGFCUIm4Aw9rGHPCIJVl0zNdCbM_G2VkYXJ5GGGtVh8S0LWMM4YLGZD9okLcFBc402j5zESK71HaR_owJb-AVBfFvAo8q0I2J74rmfGyIROyg
3. データのエンコードとデコード
- Base64URLのエンコードとデコード Base64URLエンコードされたデータ:
hN7QMDhftv10Li9Cu-fm_T_3qDQawT-Z1GzNg1FWfAfSILT-u_rKLvXP-RE0ac-pxJTlGFCUIm4Aw9rGHPCIJVl0zNdCbM_G2VkYXJ5GGGtVh8S0LWMM4YLGZD9okLcFBc402j5zESK71HaR_owJb-AVBfFvAo8q0I2J74rmfGyIROyg - Base64URLデコードされたデータ: 84ded030385fb6fd742e2f42bbe7e6fd3ff7a8341ac13f99d46ccd8351567c07d220b4febbfaca2ef5cff9113469cfa9c494e5185094226e00c3dac61cf088255974ccd7426ccfc6d959185c9e46186b5587c4b42d630ce182c6643f6890b70505ce34da3e731122bbd47691fe8c096fe01505f16f028f2ad08d89ef8ae67c6c8844eca0 図17に示したコードのように、PythonのBase64ライブラリを使ってBase64URLでエンコードしたデータをデコードすると、デコードされた16進データの長さは132で、最初の4バイト(84ded030)がマスクのXORキーです。残りの128バイトは、マスクのXORアルゴリズムでエンコードされたメタデータです。PythonコードでのBase64URLデコードを以下に示します。
- マスクのエンコードとデコード: マスクのキーは84ded030です。マスクエンコードしたデータは以下のようになります。385fb6fd742e2f42bbe7e6fd3ff7a8341ac13f99d46ccd8351567c07d220b4febbfaca2ef5cff9113469cfa9c494e5185094226e00c3dac61cf088255974ccd7426ccfc6d959185c9e46186b5587c4b42d630ce182c6643f6890b70505ce34da3e731122bbd47691fe8c096fe01505f16f028f2ad08d89ef8ae67c6c8844eca0マスクデコードしたデータ:
bc8166cdf0f0ff723f3936cdbb2978049e1fefa950b21db3d588ac3756fe64ce3f241a1e71112921b0b71f99404a3528d44af25e841d0af6982e5815ddaa1ce7c6b21ff65d87c86c1a98c85bd1591484a9bddcd10618b40fec4e67358110e4eabaadc1123f0aa6a17a52d95f64cbd5c1ebdc5f1a545359df0e38ac5c0c9a3c90図18のPythonコードでマスクエンコードしたデータをデコードすると、デコードされた16進データの長さは128バイトになります。この128バイトはRSAアルゴリズムで暗号化されたメタデータで、詳細はちかく公開予定のブログで解説します。
マスクデコードを行うPythonコード:
実際の攻撃事例
以下のセクションでは、実際にマルウェアによる使用が確認された、2つの異なる事例でのCobalt Strikeペイロードを紹介します。1つめの事例ではBase64エンコードが使われ、2つめの事例ではBase64URLエンコードが使われています。パロアルトネットワークスはAutoFocusシステムのUnit42.CobaltStrikeタグ以下で静的・動的分析によりこれらのペイロードを特定しました。
Base64エンコード
SHA256: 6b6413a059a9f12d849c007055685d981ddb0ff308d6e3c2638d197e6d3e8802
Base64URLエンコード
SHA256: f6e75c20ddcbe3bc09e1d803a8268a00bf5f7e66b7dbd221a36ed5ead079e093
結論
Cobalt Strikeは侵害後のアクターをエミュレートする強力なツールです。上記の5つのエンコードアルゴリズムは巧妙で、セキュリティ検出回避をねらって設計されています。セキュリティアプライアンス単体ではCobalt Strikeの攻撃を防げないので、ファイアウォール、サンドボックス、エンドポイント、さらにこれらすべての要素を統合してくれるソフトウェアのセキュリティソリューションを組み合わせて使うことが必要になります。
パロアルトネットワークスのお客様は、次の方法でこの種の攻撃から保護されています。
- 脅威防御シグネチャ86445と86446を含む次世代ファイアウォール(NGFW)は、デフォルトプロファイルのBase64メタデータエンコードを行うHTTP C2リクエストを識別します。
- NGFW用のセキュリティサブスクリプションWildFireとCortex XDRはCobalt Strike Beaconを識別・ブロックします。
- AutoFocusをお使いのお客様は次のタグを使用してこれらのアクティビティを追跡できます: CobaltStrike
IoC (侵害指標)
Cobalt Strike サンプル
- 6b6413a059a9f12d849c007055685d981ddb0ff308d6e3c2638d197e6d3e8802
- f6e75c20ddcbe3bc09e1d803a8268a00bf5f7e66b7dbd221a36ed5ead079e093
Cobalt Strike Beacon サンプル
- /n9Rd
- SHA256ハッシュ:
- fc95e7f4c8ec810646c16c8b6075b0b9e2cc686153cdad46e82d6cca099b19e7
- SHA256ハッシュ:
- /flas
- SHA-256ハッシュ:
- 11b8beaa53353f5f52607e994849c3086733dfa01cc57fea2dae42eb7a6ee972
- SHA-256ハッシュ:
Cobalt Strike TeamServerのIPアドレス
- 80.255.3[.]109
- 143.244.178[.]247
追加リソース
Cobalt Strike Training (Cobalt Strikeトレーニング)
Cobalt Strike Malleable C2 Profile (Cobalt Strike Malleable C2プロファイル)
Cobalt Strike解析&チュートリアル: Malleable C2プロファイルでCobalt Strike検出が難しくなる理由