Winnti: More than just Windows and Gates

May 15 · 7 min read

The Winnti malware family was first reported in 2013 by Kaspersky Lab¹. Since then, threat actors leveraging Winnti malware have victimized a diverse set of targets for varied motivations. While the name ‘Winnti’ in public reporting was previously used to signify a single actor, pronounced divergence in targeting and tradecraft between campaigns has led industry consensus to break up the tracking of the continued use of the Winnti malware under different actor clusters. The underlying hypothesis² is that the malware itself may be shared (or sold) across a small group of actors.

In April 2019, reports³ emerged of an intrusion involving Winnti⁴ malware at a German Pharmaceutical company. Following these reports, Chronicle researchers doubled down on efforts to try to unravel the various campaigns where Winnti was leveraged. Analysis of these larger convoluted clusters is ongoing. While reviewing a 2015 report⁵ of a Winnti intrusion at a Vietnamese gaming company, we identified a small cluster of Winnti⁶ samples designed specifically for Linux⁷. The following is a technical analysis of this variant.

Technical Analysis

As with other versions of Winnti, the core component of the malware doesn’t natively provide the operators with distinct functionality⁸. This component is primarily designed to handle communications and the deployment of modules directly from the command-and-control servers. During our analysis, we were unable to recover any active plugins. However, prior reporting⁹ suggests that the operators commonly deploy plugins for remote command execution, file exfiltration, and socks5 proxying on the infected host. We expect similar functionality to be leveraged via additional modules for Linux.

‘’ — the userland rootkit

The library used to hide Winnti’s system activity is a copy of the open-source userland rootkit Azazel¹⁰, with minor changes. When executed, it will register symbols for multiple commonly used functions, including: open(), rmdir(), and unlink(), and modify their returns to hide the malware’s operations. Below is a side-by-side comparison of the Azazel source code and the relevant function decompilation from ‘’.

Distinct changes to Azazel by the Winnti developers include the addition of a function named ‘Decrypt2’, which is used to decode an embedded configuration similar to the core implant. Unlike standard Azazel which is configured to hide network activity based on port ranges, the Winnti-modified version keeps a list of process identifiers and network connections associated with the malware’s activity. This modification likely serves to simplify the operator’s sample configuration process by not having to denote specific ports to hide.

Strings within this sample associated with the malware’s operations are encoded using a single-byte XOR encoding. The following is an example Python function to decode these strings.


Winnti Linux variant’s core functionality is within ‘libxselinux’. Upon execution, an embedded configuration is decoded from the data section using a simple XOR cipher. An example Python function to decode this configuration is shown below:

The decoded configuration is similar in structure to the version Kaspersky classifies as Winnti 2.0¹¹, as well as samples in the 2015 Novetta report¹². Embedded in this sample’s configuration three command-and-control server addresses and two additional strings we believe to be campaign designators. Winnti ver. 1, these values were designated as ‘tag’ and ‘group’. A sample decoded configuration is shown below:

Winnti Linux samples identified so far fall under three distinct campaign designators:

For context, embedded Winnti campaign designators have ranged from target names, geographic areas, industry, and profanity.

Interactions with control servers

This secondary communication channel may be used by operators when access to the hard-coded control servers is disrupted. Additionally, the operators could leverage this feature when infecting internet-facing devices in a targeted organization to allow them to reenter a network if evicted from internal hosts. This passive implant approach to network persistence has been previously observed with threat actors like Project Sauron and the Lamberts.

Initial technical information about this feature was shared by the Thyssenkrupp CERT in the form of an Nmap¹³ script¹⁴ that could be used to identify Winnti infections through network scanning. This script identifies infected hosts by first sending a custom hello packet, immediately followed by an encoded request for host information, and then parsing the response. The workflow of the script is diagrammed below:

The initial request, referred to as the helo/hello request in the Nmap script, is comprised of four DWORDs. The first three are generated by rand() and the fourth is computed based on the first and third. When received by a Winnti-infected host, it will validate the received packet and listen for a second inbound request containing tasking. A breakdown of this traffic is shown below.

This second request (Encoded Get System Information Request) is encoded using the same method as the custom TCP protocol used for communication with command-and-control servers, which uses a four-byte XOR encoding. Before acting on the request, Winnti will validate the third DWORD contains the magic value 0xABC18CBA before executing tasking.

While it may be possible to conduct broad scanning to identify infected systems, the results would likely only be the subset that are directly Internet accessible.


Additional Indicators


[1] However, Kaspersky researchers credited HBGary for prior analysis in 2010





[6]As in the malware, not a reference to an actor group

[7]PwC researchers were aware of the Winnti Linux variant, as revealed in Kris McConkey’s SAS 2019 talk, “Skeletons in the supply chain”.

[8] page 21

[9] page 21


[11] In the report Winnti: More than just a game




Chronicle Blog



Written by


Chronicle Blog