Ivanti Connect Secureの脆弱性を起点とした侵害で確認されたマルウェア

以前のJPCERT/CC Eyesで、Ivanti Connect Secureの脆弱性を利用して設置されたマルウェアSPAWNCHIMERADslogdRATについて紹介しましたが、JPCERT/CCでは、現在まで継続してIvanti Connect Secureの脆弱性を悪用する攻撃活動を確認しています。今回は、2024年12月から2025年7月現在までCVE-2025-0282CVE-2025-22457を悪用する攻撃者が使用した以下のマルウェア、ツール、攻撃者が組織内ネットワークに侵入した際に使用する攻撃手法について解説します。

  • MDifyLoaderとCobalt Strike Beacon
  • vshell
  • Fscan

MDifyLoaderとCobalt Strike Beacon

Cobalt Strikeの実行までの流れを図1に示します。初めに設定されたタスクなどから正規ファイルが動作し、ローダー(以下、MDifyLoaderという。)がDLLサイドローディングによって実行されます。MDifyLoaderは暗号化されたデータファイルを読み込み、Cobalt Strike Beaconをデコード後、メモリ上で実行します。

図1:MDifyLoaderによるCobalt Strikeの実行までの流れ


MDifyLoaderはオープンソースのlibPeConv[1]をもとに作成されたローダーです。データファイルの復号においてはRC4が使用され、RC4の鍵は実行ファイルのMD5ハッシュ値を使用します。この方法により実行ファイル、ローダー、データファイルの3つがそろっていないと動作しないため、分析を妨害する目的などが考えられます。なお、使用された正規ファイルにはJava RMI コンパイラのrmic.exepush_detect.exeなどが使用された事例を確認しています。

MDifyLoaderの各関数内においては、図2に示すようなジャンクコードが無数に挿入されていました。ジャンクコードは意味のほとんどない関数の呼び出しや変数の参照を組み合わせて挿入されており、相対アドレスの値がコード内に含まれる点や関数の返り値の値を参照するため、ジャンクコードを機械的に判別することが難しく、難読化解除を妨害する工夫が見受けられました。

図2:MDifyLoaderにおける難読化


通常、Cobalt Strike Beaconはコンフィグデータを検体内部に持っており、1バイトのXOR鍵を使用して実行時にデコードされ参照されますが、攻撃者が使用するCobalt Strike Beaconではコンフィグデータのデコード方式にRC4が使用され、そのRC4鍵は"google"としてBeacon内にハードコードされていました。その追加されたRC4のコードを図3に示します。また、設定されているコンフィグの要素数からCobalt StrikeのVersion 4.5であることを確認しています。なお、BeaconのNameフィールドにNewBeacon.dllと記載があり、攻撃者によって付けられた本Beaconの名称と考えられます。

図3:Cobalt Strike Beaconへ追加されたRC4関数


vshellの使用

vshellはGitHubで公開されていたGo言語で書かれたマルチプラットフォーム環境で動作するRATです(本ブログ執筆時点では、対象のGitHubレポジトリは公開されていません)。攻撃者は、Windows実行ファイルのvshell version 4.6.0を使用する事例を確認しています。使用されたvshellの特徴として実行時に中国語環境かどうかをチェックする機能が含まれており、そのコードの一部を図4に示します。攻撃者はvshellの実行に何度も失敗しており、そのたびに新しいvshellを設置、実行を試みた痕跡が確認されました。原因としては、内部テスト用に使用していた言語確認機能をそのまま使ってしまった可能性が考えられます。

図4:中国語環境かをチェックしているvshellのコードの一部


Fscan

Fscan[2]はオープンソースのGo言語で書かれたネットワークスキャンツールです。攻撃者はローダーを介してFscanを実行します。Fscan実行までの流れを図5に示します。Fscanの実行には正規のpython.exeが悪用されています。DLLサイドローディングで悪意のあるpython311.dllをロードさせ、エンコードされたFscanであるk.binを読み込み、デコード後、メモリ上で実行されます。なお、python311.dllはオープンソースのFilelessRemotePE[3]をもとに作成されており、Fscan本体の復号には内部にハードコードされている"99999999"を鍵としてRC4を使用し、デコードします。

図5:Fscanの実行までの流れ


組織内ネットワークに侵入後の攻撃活動

以降では組織内ネットワークに侵入した攻撃者が使用した横展開方法や永続化、防衛回避手法などについて解説します。

横展開(Lateral Movement)

攻撃者は内部ネットワークへの侵入後、ADサーバーに対してブルートフォース攻撃などを行い認証情報の取得を試みます。また、内部ネットワークに対しネットワークスキャンを行いFTPサーバーやMSSQLサーバー、SSHサーバーに対してもブルートフォース攻撃を行います。さらに、SMBの脆弱性であるMS17-010を悪用して、脆弱性が未修整のホストに侵入します。これらの活動により取得した資格情報などを用いてRDPやSMBを経由して他のシステムへ横展開し、マルウェアを設置します。

永続化(Persistence)

攻撃者は新たなドメインアカウントを作成し、これを既存の各グループに登録することで取得していた認証情報が失効した場合でも再侵入することが可能なアカウントを確保しました。このようなアカウントは、通常の運用と見分けがつきにくく、長期間にわたり内部ネットワークへのアクセスを維持することが可能となります。加えて、マルウェアの永続化方法として、攻撃者はマルウェアをサービスやタスクスケジューラとして登録することで、システム起動時や特定のイベントトリガーにおいてマルウェアが実行されるよう設定しました。

防衛回避(Defense Evasion)

Windows環境において使用されるマルウェアは正規ファイルを使ったローダーを介して実行することでセキュリティ製品による検知や監視の回避を狙っていると考えられます。なお、FilelessRemotePEをもとに作成されているFscanのローダーには、FilelessRemotePEの機能であるNtdll.dllへのETW Bypass機能があるため、EDRなどの検知回避を狙っていると考えられます。

おわりに

これらの攻撃は2024年12月から現在まで続いており、Ivanti Connect SecureなどのVPN機器を狙った攻撃は今後も継続して行われることが予想されます。なお、Appendixにマルウェアのハッシュ値、通信先、Cobalt Strikeのコンフィグ、vshellのコンフィグなどをそれぞれ記載していますのでご確認ください。

インシデントレスポンスグループ 増渕 維摩、喜野 孝太、亀井 智矢

参考情報

[1] libPeConv
https://github.com/hasherezade/libpeconv

[2] Fscan
https://github.com/shadow1ng/Fscan

[3] FilelessRemotePE
https://github.com/ASkyeye/FilelessRemotePE

Appendix A:MITRE ATT&CK

表1: 攻撃活動におけるATT&CKマッピング

戦術(Tactic) テクニックID テクニック名 内容
Initial Access T1133 External Remote Services VPN機器の脆弱性を悪用して侵入
Execution T1053.005 Scheduled Task/Job: Scheduled Task スケジュールタスク経由でマルウェアを実行
T1136.002 Create Account: Domain Account 永続化のために新たなドメインアカウントを作成
T1098 Account Manipulation 作成したアカウントを各グループに追加し、持続的なアクセスを確保
T1543.003 Create or Modify System Process: Windows Service マルウェアをWindowsサービスとして登録し、自動実行の設定
T1053.005 Scheduled Task タスクスケジューラを用いてマルウェアを定期的またはトリガー条件で再実行させる
Privilege Escalation T1543.003 Create or Modify System Process: Windows Service マルウェアをWindowsサービスとして登録し、自動実行の設定
Defense Evasion T1036 Masquerading マルウェアを正規のファイルや名称に偽装し、異常な挙動を隠蔽
T1070.004 File Deletion 攻撃の痕跡を隠すために、使用したマルウェアやツールを削除
T1140 Deobfuscate/Decode Files or Information 各ローダーによる難読化や復号テクニックの使用
T1562.001 Impair Defenses: Disable or Modify Tools Fscanのローダーによるntd.dllへのパッチによるETWの無効化
Credential Access T1110.001 Password Guessing ADサーバーやFTP、MSSQL、SSHに対してブルートフォース攻撃を実施し、認証情報を取得
Discovery T1087 Account Discovery アカウント情報を収集
Lateral Movement T1210 Exploitation for Lateral Movement SMBのMS17-010脆弱性を悪用して、他のホストに横展開を実施
T1021.001 Remote Services: Remote Desktop Protocol 取得した資格情報を用いてRDP経由で他ホストへ横展開
T1021.002 Remote Services: SMB/Windows Admin Shares SMB共有を通じて侵害を拡大
Command and Control T1573 Encrypted Channel TLSやカスタム暗号化プロトコルを利用し、C2通信を暗号化

Appendix B:マルウェア

表2: マルウェア

Malware Filename SHA256 Hash
Python(Legitimate) python.exe 0cbf71efa09ec4ce62d95c1448553314728ed5850720c8ad40352bfbb39be99a
Fscan Loader python311.dll 699290a753f35ae3f05a7ea1984d95f6e6f21971a146714fca5708896e5e6218
Fscan k.bin cff2afc651a9cba84a11a4e275cc9ec49e29af5fd968352d40aeee07fb00445e
Java RMI Compiler(Legitimate) rmic.exe a747be292339eae693b7c26cac0d33851cba31140fd0883371cc8de978583dbe
push_detect(Legitimate) push_detect.exe f12250a43926dba46dcfb6145b7f1a524c0eead82bd1a8682307d1f2f1f1e66f
MDifyLoader jli.dll 45ecb7b23b328ab762d8519e69738a20eb0cd5618a10abb2c57a9c72582aa7e7
MDifyLoader Microsoft.WindowsAppRuntime.Bootstrap.dll 9e91862b585fc4d213e9aaadd571435c1a007d326bd9b07b72dbecb77d1a27ac
Cobalt Strike version 4.5 update.dat 09087fc4f8c261a810479bb574b0ecbf8173d4a8365a73113025bd506b95e3d7
Cobalt Strike version 4.5 config.ini 1652ab693512cd4f26cc73e253b5b9b0e342ac70aa767524264fef08706d0e69
vshell ws_windows_amd2.exe 48f3915fb8d8ad39dc5267894a950efc863bcc660f1654187b3d77a302fd040f
vshell ws_windows_amd64.exe 54350d677174269b4dc25b0ccfb0029d6aeac5abbbc8d39eb880c9fd95691125
vshell ws.exe 85f9819118af284e6b00ce49fb0c85ff0c0b9d7a0589e1bb56a275ed91314965

Appendix C:通信先

  • 172.237.6[.]207:80
  • proxy.objectlook[.]com:80
  • api.openedr.eu[.]org:443
  • community.openedr.eu[.]org:443
  • query.datasophos[.]com:443

Appendix D:各コンフィグ情報

  • vshellのコンフィグ
{"server":"proxy.objectlook[.]com:80","type":"ws","vkey":"safeshell","proxy":"http[:]//10.71.30[.]140:8080","salt":"safeshell","l":false,"e":false}
  • Cobalt Strikeのコンフィグ
BeaconType                       - HTTPS
Port                             - 443
SleepTime                        - 97352
MaxGetSize                       - 2105202
Jitter                           - 48
MaxDNS                           - Not Found
PublicKey_MD5                    - e880c4268fb48aebc5510e02f49d3bce
C2Server                         - api.openedr.eu[.]org,/avatar/js/flashdetect.min.js,community.openedr.eu[.]org,/avatar/js/utm5.min.js
UserAgent                        - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
HttpPostUri                      - /Destroy/stylesheets/color_definitions_base
Malleable_C2_Instructions        - Remove 2025 bytes from the end
                                   Remove 6017 bytes from the beginning
                                   NetBIOS decode 'a'
                                   XOR mask w/ random key
HttpGet_Metadata                 - ConstHeaders
                                    Accept: application/json, application/xml, text/html
                                    Accept-Language: zh-hk
                                    Accept-Encoding: br, compress
                                   Metadata
                                    mask
                                    base64url
                                    prepend "secure_id_4427KV8TXLHDJ9YJAM5XRIXHI12="
                                    header "Cookie"
HttpPost_Metadata                - ConstHeaders
                                    Accept: text/html, application/json, image/*
                                    Accept-Language: ar-ma
                                    Accept-Encoding: gzip, *
                                   SessionId
                                    mask
                                    base64url
                                    parameter "_SFUYPJNK"
                                   Output
                                    mask
                                    netbiosu
                                    print
PipeName                         - Not Found
DNS_Idle                         - Not Found
DNS_Sleep                        - Not Found
SSH_Host                         - Not Found
SSH_Port                         - Not Found
SSH_Username                     - Not Found
SSH_Password_Plaintext           - Not Found
SSH_Password_Pubkey              - Not Found
SSH_Banner                       - 
HttpGet_Verb                     - GET
HttpPost_Verb                    - POST
HttpPostChunk                    - 0
Spawnto_x86                      - %windir%\syswow64\svchost.exe -k wksvc
Spawnto_x64                      - %windir%\sysnative\SearchProtocolHost.exe
CryptoScheme                     - 0
Proxy_Config                     - Not Found
Proxy_User                       - Not Found
Proxy_Password                   - Not Found
Proxy_Behavior                   - Use IE settings
Watermark_Hash                   - MYhXSMGVvcr7PtOTMdABvA==
Watermark                        - 666666
bStageCleanup                    - True
bCFGCaution                      - False
KillDate                         - 0
bProcInject_StartRWX             - False
bProcInject_UseRWX               - False
bProcInject_MinAllocSize         - 6771
ProcInject_PrependAppend_x86     - b'\x90\x90\x90f\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1fD\x00\x00PXf\x90PX\x0f\x1f\x00\x0f\x1fD\x00\x00f\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x00PXPX\x0f\x1f\x80\x00\x00\x00\x00f\x90\x0f\x1f\x00\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x84\x00\x00\x00\x00\x00'
                                   b'f\x0f\x1fD\x00\x00\x0f\x1f\x80\x00\x00\x00\x00\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x00\x90\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x80\x00\x00\x00\x00f\x0f\x1f\x84\x00\x00\x00\x00\x00'
ProcInject_PrependAppend_x64     - b'\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x80\x00\x00\x00\x00f\x90PX\x0f\x1f@\x00\x0f\x1f\x80\x00\x00\x00\x00\x0f\x1f@\x00f\x0f\x1f\x84\x00\x00\x00\x00\x00f\x0f\x1f\x84\x00\x00\x00\x00\x00\x90PX\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f@\x00f\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x00\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f@\x00f\x0f\x1fD\x00\x00f\x0f\x1f\x84\x00\x00\x00\x00\x00'
                                   b'\x90\x0f\x1f\x00PX\x90PX\x0f\x1f@\x00f\x0f\x1f\x84\x00\x00\x00\x00\x00PX\x0f\x1f\x84\x00\x00\x00\x00\x00f\x90PX\x0f\x1fD\x00\x00\x0f\x1fD\x00\x00'
ProcInject_Execute               - ntdll:RtlUserThreadStart
                                   CreateThread
                                   NtQueueApcThread-s
                                   CreateRemoteThread
                                   RtlCreateUserThread
ProcInject_AllocationMethod      - NtMapViewOfSection
bUsesCookies                     - True
HostHeader                       - 
headersToRemove                  - Not Found
DNS_Beaconing                    - Not Found
DNS_get_TypeA                    - Not Found
DNS_get_TypeAAAA                 - Not Found
DNS_get_TypeTXT                  - Not Found
DNS_put_metadata                 - Not Found
DNS_put_output                   - Not Found
DNS_resolver                     - Not Found
DNS_strategy                     - failover
DNS_strategy_rotate_seconds      - -1
DNS_strategy_fail_x              - 100
DNS_strategy_fail_seconds        - -1
Retry_Max_Attempts               - 0
Retry_Increase_Attempts          - 0
Retry_Duration                   - 0
  • Cobalt Strikeのコンフィグ
BeaconType                       - HTTPS
Port                             - 443
SleepTime                        - 92318
MaxGetSize                       - 1408170
Jitter                           - 48
MaxDNS                           - Not Found
PublicKey_MD5                    - 492cdc5bc3d8cc5e6440a0da246f6684
C2Server                         - query.datasophos[.]com,/Enable/v5.10/VPGH7WQQPR
UserAgent                        - Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
HttpPostUri                      - /Enable/v8.20/STE7U5WILZII
Malleable_C2_Instructions        - Remove 7449 bytes from the end
                                   Remove 2614 bytes from the beginning
                                   Base64 URL-safe decode
                                   XOR mask w/ random key
HttpGet_Metadata                 - ConstHeaders
                                        Accept: application/xml, application/xhtml+xml, image/*
                                        Accept-Language: fr-lu
                                        Accept-Encoding: gzip, br
                                   Metadata
                                        mask
                                        netbios
                                        prepend "affiliate_id_69W8Y3G469RVG2W2="
                                        header "Cookie"
HttpPost_Metadata                - ConstHeaders
                                        Accept: application/xhtml+xml, image/*, text/html
                                        Accept-Language: zh-tw
                                        Accept-Encoding: compress, gzip
                                   SessionId
                                        mask
                                        netbios
                                        parameter "_TXLXHKQC"
                                   Output
                                        mask
                                        netbiosu
                                        print
PipeName                         - Not Found
DNS_Idle                         - Not Found
DNS_Sleep                        - Not Found
SSH_Host                         - Not Found
SSH_Port                         - Not Found
SSH_Username                     - Not Found
SSH_Password_Plaintext           - Not Found
SSH_Password_Pubkey              - Not Found
SSH_Banner                       -
HttpGet_Verb                     - GET
HttpPost_Verb                    - POST
HttpPostChunk                    - 0
Spawnto_x86                      - %windir%\syswow64\w32tm.exe
Spawnto_x64                      - %windir%\sysnative\WUAUCLT.exe
CryptoScheme                     - 0
Proxy_Config                     - Not Found
Proxy_User                       - Not Found
Proxy_Password                   - Not Found
Proxy_Behavior                   - Use IE settings
Watermark_Hash                   - MYhXSMGVvcr7PtOTMdABvA==
Watermark                        - 666666
bStageCleanup                    - True
bCFGCaution                      - False
KillDate                         - 0
bProcInject_StartRWX             - False
bProcInject_UseRWX               - False
bProcInject_MinAllocSize         - 6344
ProcInject_PrependAppend_x86     - b'PX\x0f\x1f\x84\x00\x00\x00\x00\x00f\x0f\x1fD\x00\x00PXf\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x80\x00\x00\x00\x00\x0f\x1f\x84\x00\x00\x00\x00\x00\x90f\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x80\x00\x00\x00\x00\x90\x90\x90\x0f\x1f\x80\x00\x00\x00\x00\x90'
                                   b'f\x0f\x1fD\x00\x00\x0f\x1f@\x00\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f@\x00'
ProcInject_PrependAppend_x64     - b'\x0f\x1f\x00\x90PX\x0f\x1f\x80\x00\x00\x00\x00f\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x00\x0f\x1f\x80\x00\x00\x00\x00\x0f\x1f\x00\x90\x90'
                                   b'\x0f\x1f\x00PXf\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1fD\x00\x00f\x0f\x1fD\x00\x00'
ProcInject_Execute               - ntdll:RtlUserThreadStart
                                   CreateThread
                                   NtQueueApcThread-s
                                   CreateRemoteThread
                                   RtlCreateUserThread
ProcInject_AllocationMethod      - VirtualAllocEx
bUsesCookies                     - True
HostHeader                       -
headersToRemove                  - Not Found
DNS_Beaconing                    - Not Found
DNS_get_TypeA                    - Not Found
DNS_get_TypeAAAA                 - Not Found
DNS_get_TypeTXT                  - Not Found
DNS_put_metadata                 - Not Found
DNS_put_output                   - Not Found
DNS_resolver                     - Not Found
DNS_strategy                     - round-robin
DNS_strategy_rotate_seconds      - -1
DNS_strategy_fail_x              - -1
DNS_strategy_fail_seconds        - -1
Retry_Max_Attempts               - 0
Retry_Increase_Attempts          - 0
Retry_Duration                   - 0
≪ 前へ
トップに戻る