Skip to content
Scripts and rulesets for analysing the Winnti malware
Python YARA
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
yara initial commit Jul 24, 2019
.gitignore update Readme Jul 24, 2019 initial commit Jul 24, 2019 add script Jul 24, 2019
requirements.txt add script Jul 24, 2019

Winnti analysis

For a number of years now, a group of professional hackers has been busy spying on businesses all over the world: Winnti. It is believed to be a digital mercenary group controlled by China. For the first time, in a joint investigation, German public broadcasters BR and NDR are shedding light on how the hackers operate and how widespread they are.

Read the full article on hackers for hire, conducting industrial espionage, here:


The search for affected company networks is mostly build around so-called campaign identifiers. In some instances, Winnti operators wrote the names of their targets directly into the malware, obfuscated with a rolling XOR cipher. In a first step, we tried to verify the information we were provided with, using a (not very good) python script. We then used yara rules to hunt for Winnti samples. The yara rules we used are included in this repo, hopefully they prove useful to other researchers.

Another way of finding networks with Winnti infections is this Nmap script by the Thyssenkrupp CERT.


An execellent script for extracting the configuration details from a Winnti sample was written by Moritz Contag. He thankfully allowed us to share it. Here is how to use it:


The script requires lief in version 0.9 to be installed and thus is currently tied to Python 2.7. The dependency can be installed running pip on the command line:

pip2 install -r requirements.txt


To extract the configuration of multiple Winnti samples, simply pass the directory to the script. The script will also recurse into subdirectory and blindly try to parse each file it encounters.

The script does not try to identify Winnti samples and might produce incoherent output if the sample looks too different. Currently, it tries to parse configuration information stored in the executable's overlay as well as inline configurations indicated by a special marker. Further, it also tries to repair broken or "encrypted" files before processing them.

It is recommended to name the samples according to their, e.g., SHA-256 hash for better identification.

To scan a directory called samples, simply invoke the script as follows:

$ python2 ./samples


./9c3415507b38694d65262e28f73c3fade5038e455b83d41060f024403c26c9ee: Parsed configuration (overlay).

- Size:    0x50E
- Type:    exe 
- Configuration:

	+0x000:  ""
	+0x304:  "1"
	+0x324:  "shinetsu"
	+0x356:  4B A0 D6 05 
	+0x3C2:  "HpInsightEx.dll"
	+0x3E2:  "kb25489.dat"
	+0x402:  "HPSupportService"
	+0x442:  "HP Insight Extension Support"
	+0x50A:  A9 A1 A5 A6 


./585fa6bbc8bc9dbd8821a0855432c911cf828e834ec86e27546b46652afbfa5e: Parsed configuration (overlay).

- Size:    0x048
- Type:    dll exe 
- Exports: #3

- Configuration:

	+0x000:  "DEHENSV533-IIS"
	+0x020:  ""
	+0x044:  99 DE DF E0 


  • Moritz Contag for writing the great script and allowing us to share it
  • Silas Cutler who helped us a great deal to corroborate our findings


BR Data is a data-driven investigative unit at the German public broadcaster Bayerischer Rundfunk. We are a team of journalists, developers and data scientist. We specialize in data- and document-driven research and interactive storytelling.

Please send us your questions and feedback:

You can’t perform that action at this time.