Malware Identified in Attacks Exploiting Ivanti Connect Secure Vulnerabilities
JPCERT/CC Eyes previously introduced the malware SPAWNCHIMERA and DslogdRAT, which were deployed by exploiting vulnerabilities in Ivanti Connect Secure. At JPCERT/CC, we have continued to observe active exploitation of these vulnerabilities. In this report, we explain the following malware, tools, and penetration tactics used by attackers leveraging CVE-2025-0282 and CVE-2025-22457 in attacks observed from December 2024 to the present, July 2025.
- MDifyLoader and Cobalt Strike Beacon
- vshell
- Fscan
MDifyLoader and Cobalt Strike Beacon
Figure 1 illustrates the execution flow of Cobalt Strike. It starts with the activation of a legitimate file, triggered by a pre-configured task. This executes a loader (hereafter referred to as MDifyLoader) through DLL side-loading. MDifyLoader then loads an encrypted data file, decodes Cobalt Strike Beacon, and runs it on memory.
MDifyLoader is a loader created based on the open-source project libPeConv [1]. It uses RC4 for decrypting data files, and its key derives from the MD5 hash value of executable files. As this method requires three items, the executable file, the loader, and the data file, for execution, it is likely that the attackers intended to obstruct analysis using this method. In addition, it is confirmed that legitimate files such as the Java RMI compiler rmic.exe and push_detect.exe had been used.
As shown in Figure 2, a number of junk code were inserted in each function of MDifyLoader. These junk code consists of meaningless function calls and variable references. Because the junk code includes relative address values and refer to function return values, automated identification is difficult. This suggests that the attackers intended to hinder deobfuscations.
Typically, Cobalt Strike Beacon contains config data embedded within the sample, which is decoded using a one-byte XOR key when executed. However, the attackers in this case employed RC4 for configuration data decryption. The RC4 key was hardcoded as "google" within the Beacon. Figure 3 shows the additional RC4 code. Based on the number of config elements, this Beacon has been identified as Version 4.5 of Cobalt Strike. Furthermore, the Beacon’s Name field says "NewBeacon.dll", likely indicating a custom name assigned by the attackers.
Using vshell
vshell is a multi-platform RAT written in Go language and previously published on GitHub (the repository is no longer publicly available at the time of this publication). Attackers have been observed using the Windows executable vshell version version 4.6.0. The used vshell has a function to check whether the system language is set to Chinese. A portion of the code is shown in Figure 4. The attackers repeatedly failed to execute vshell, and it was confirmed that each time they had installed a new version and attempted execution again. This behavior suggests that the language-checking function, likely intended for internal testing, was left enabled during deployment.
Fscan
Fscan [2] is an open-source network scanning tool written in Go language. Attackers execute it through a loader. The execution flow is shown in Figure 5. A legitimate python.exe is used to execute Fscan. A malicious python311.dll is loaded through DLL side-loading, which loads an encoded Fscan k.bin and runs it on memory after decoding. The python311.dll was developed based on the open-source tool FilelessRemotePE [3]. For decoding the main body of Fscan, it uses RC4 with a hardcoded key "99999999".
Attackers’ behavior after initial access to internal network
This section explains the attackers’ methods for lateral movement, establishing persistence, and evading detection, after they penetrated the target organization’s internal network.
Lateral movement
After gaining access to the internal network, the attackers attempted to obtain credentials by conducting brute-force attacks against AD servers. They also performed network scans on internal systems and conducted brute-force attacks on FTP, MSSQL, and SSH servers. Additionally, they exploited the SMB vulnerability MS17-010 to compromise unpatched hosts. Using credentials obtained through these activities, the attackers laterally moved to other systems through RDP and SMB, deploying malware across the network.
Persistence
The attackers created new domain accounts and added them to existing groups, allowing them to retain access even if previously acquired credentials were revoked. These accounts blend in with normal operations, enabling long-term access to the internal network. Additionally, the attackers registered their malware as a service or a task scheduler to maintain persistence, ensuring it would run at system startup or upon specific event triggers.
Defense evasion
The malware used in Windows environment is considered to be executed through a loader using a legitimate file, which is likely intended to evade detection and monitoring by security products. The loader for Fscan, which is created based on FilelessRemotePE, includes an ETW bypass to ntdll.dll, a feature that derives from FilelessRemotePE. This suggests that the attackers intended to bypass EDR and other detections mechanisms.
In Closing
These attacks have persisted since December 2024 and are expected to remain active, particularly those aimed at VPN devices like Ivanti Connect Secure. For further details, including malware hash values, C2, and Cobalt Strike and vshell config information, please refer to the appendices.
Yuma Masubuchi, Kota Kino, Tomoya Kamei (Translated by Takumi Nakano)
参考情報
[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
Table 1: ATT&CK Mapping of the Attack Activities
Tactic | Technique ID | Technique Name | Content |
---|---|---|---|
Initial Access | T1133 | External Remote Services | Exploit a vulnerability in the VPN device to gain access |
Execution | T1053.005 | Scheduled Task/Job: Scheduled Task | Execute malware through a scheduled task |
T1136.002 | Create Account: Domain Account | Create a new domain account for persistence | |
T1098 | Account Manipulation | Add the created accounts to each group to ensure continued access | |
T1543.003 | Create or Modify System Process: Windows Service | Register malware as a Windows service to enable automatic execution | |
T1053.005 | Scheduled Task | Use task scheduler to re-execute the malware periodically or with specific trigger conditions | |
Privilege Escalation | T1543.003 | Create or Modify System Process: Windows Service | Register malware as a Windows service to enable automatic execution |
Defense Evasion | T1036 | Masquerading | Disguise malware as a legitimate file or name to conceal anomaly |
T1070.004 | File Deletion | Delete used malware and tools to cover traces of the attack | |
T1140 | Deobfuscate/Decode Files or Information | Use obfuscation and decryption techniques in each loader | |
T1562.001 | Impair Defenses: Disable or Modify Tools | Use Fscan loader to patch ntdll.dll to disable ETW | |
Credential Access | T1110.001 | Password Guessing | Perform a brute-force attack on AD servers, FTP, MSSQL, and SSH to obtain credentials |
Discovery | T1087 | Account Discovery | Collect account information |
Lateral Movement | T1210 | Exploitation for Lateral Movement | Exploit the SMB vulnerability MS17-010 to move laterally to other hosts |
T1021.001 | Remote Services: Remote Desktop Protocol | Use obtained credentials to move laterally via RDP | |
T1021.002 | Remote Services: SMB/Windows Admin Shares | Expand compromise via SMB share | |
Command and Control | T1573 | Encrypted Channel | Encrypt C2 communications using TLS or custom encryption protocols |
Appendix B:Malware
表2: Malware
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:C2
- 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:Config Information
- vshell config
{"server":"proxy.objectlook[.]com:80","type":"ws","vkey":"safeshell","proxy":"http[:]//10.71.30[.]140:8080","salt":"safeshell","l":false,"e":false}
- Cobalt Strike config
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 config
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