Analysis of the ShadowHammer backdoor

On March 25, Kim Zetter published an astonishing story describing a supply-chain attack against ASUS which was run between June and November 2018. The ASUS Live Update software was backdoored in order to attack a very specific group of targets. The campaign, named ShadowHammer, was discovered and investigated by Kaspersky Lab, which will present the full details during SAS2019.

NOTE: as of yet Kaspersky has only published a single sample of the backdoor (hash: aa15eb28292321b586c27d8401703494), so the analysis and the considerations presented in this post are specific to that. Once more samples come out it may become necessary to perform some adjustments.

The backdoored setup.exe

The ASUS software is distributed as a zip archive containing 3 files, setup.exe and two versions of 409.msi. The backdoor resides in the first one. The malicious code is executed just before the program exits.

VM directory

The call to execute_backdoor overwrites a call to a legitimate function just before the execution of ExitProcess.

execute_backdoor is straightforward. First, it allocates a region of memory with read, write and execution permissions. It then retrieves the encrypted shellcode data using hardcoded offsets and decrypts it in the allocated memory. Finally, it calls the entrypoint of the shellcode, once again with a hardcoded offset.

VM directory

It is worth noting that the two functions used to execute the malicious shellcode, execute_backdoor and decrypt, are both located at the end of the .text section of the executable. This indicates that they were added directly to the legitimate compiled file, rather than during compilation.

The shellcode

The shellcode starts by dynamically loading the DLLs it needs and then retrieves the addresses of the required exported functions. The most interesting ones are iphlpapi.dll, used to retrieve the MAC addresses of the machine, and wininet.dll, for the communication with the C&C.

The next step is to get the MAC addresses of all the interfaces. To obtain this information, the shellcode uses the API function GetAdaptersAddresses. To avoid revealing the targeted addresses, the authors of the backdoor stored their MD5 hashes. In order to correctly check the correspondence, for each interface of the machine, the shellcode computes the MD5 hash of the MAC address.

VM directory

We can now look at how the backdoor checks if the retrieved MAC addresses match any of the targeted ones. The data of each target is stored in the following data structure:

struct mac_data {
    DWORD type;
    BYTE md5_hash1[0x10];
    DWORD sep1;
    BYTE md5_hash2[0x10];
    DWORD sep2;

sep1 and sep2 are always 0. type can be either 1 or 2. If type is 1, in order to match this target the machine just needs to have a MAC address with an MD5 equal to md5_hash1; md5_hash2 is filled with 0. Instead, if type is 2, both md5_hash1 and md5_hash2 have an actual value and they both must be found in the MAC addresses of the machine.
In the example below, we can see type in red, md5_hash1 in blue and md5_hash2 in green.

VM directory

As mentioned by Vitaly Kamluk from Kaspersky Lab, the complete list of targets is scattered among different samples of the backdoor. This specific sample contains 18 of them.

Target identified

If the MAC addresses match one of those in the target list, the shellcode contacts the C&C with the following URL


followed by the hex encode of the matched md5_hash1.

Using the WININET APIs, the shellcode of the second stage is downloaded and saved in another memory region with read, write, execute permission. Finally it is executed.

Not a target

If instead the current machine is not a target, the shellcode performs one final action. It creates a file named idx.ini in the folder of the current user, where it stores a date a week after the current one. The purpose of this file is unclear.

VM directory

At least for this sample, the backdoor does not perform any malicious activity on machines that are not targeted. There is no form of persistence, so the people behind ShadowHammer cannot reobtain execution unless the setup.exe file is run again by a user.

List of target data

type: 2

type: 1

type: 1

type: 1

type: 2

type: 1

type: 1

type: 1

type: 2

type: 1

type: 2

type: 1

type: 1

type: 1

type: 2

type: 1

type: 2

type: 1

Read More

whack-a-proc: catch hidden executables as they are injected

Nowadays it is fairly common for malware authors to use some form of process injection. The real malicious PE file (dll or exe) is hidden beneath one or more layers of wrappers which try to execute it as stealthly as possible, for example by injecting it in a seemingly harmless process. There is a wide variety of techniques to achieve process injection (check out this nice summary). For malware analysts the external layers of protection are just a nuance, and the most interesting code is in the final executable that is injected, so getting to it as quickly as possible is a primary goal. That is why I wanted to automate as much as possible the extraction procedure, for which I built a tool called whack-a-proc.


The idea behind whack-a-proc is fairly simple: we let the external layer decrypt/unpack its payload and inject it in a target process, and then just before its execution, we dump it from the process memory. This is actually one of the most common approaches used during manual analysis.
whack-a-proc is built on top of two components:

  • APIhooklib - a library I have developed that allows to set inline hooks before and after the execution of target functions.
  • pe-sieve - a powerful scanning tool created by hasherezade, which analyzes the memory of a target process in order fo find suspicious implants, such as rogue loaded modules, shellcode or hooks.

As an example we can take the case of process hollowing:

  1. The injector process creates a new suspended process with a harmless image (for example svchost.exe).
  2. It then unmaps the original image from the process memory and replaces it with the malicious PE file.
  3. Finally it resumes the main thread of the target process.

The new process appears to be a normal svchost.exe from the outside, while it is actually executing malicious code.

whack-a-proc puts itself in between point 2 and 3 by hooking a set of low level system APIs in order to scan the target process before its execution is resumed.

VM directory

Lets see a couple of examples with real malware samples.

Practical cases


Sample: 2a550956263a22991c34f076f3160b49

Kronos is an infamous banking trojan which first appeared in 2014. The sample we will look at is from 2017. This malware uses the already mentioned technique of process hollowing. If we take a look at the report of Hybrid Analysis, we can see that it creates a new process of itself, and then a new svchost process.

VM directory

In this case the ability of whack-a-proc to monitor subprocesses as well becomes handy. Here it is in action:

VM directory

In each folder pe-sieve writes the suspicious PE file if has found, together with a JSON report. In the first subprocess (2328) an executable of 290 KB is injected. Instead in the second one (3120) we get two different PE files. The first is the same as the previous, meaning that it is injected also in the svchost process; the second one, of only 21 KB, is actually the real svchost.exe image, which is still in the process memory because the malware does not bother unmapping it.


Sample: 5e6764534b3a1e4d3abacc4810b6985d

Osiris is a newer version of Kronos that uses a more advanced injection technique known as process doppelganging. This technique makes use of transactions, a feature of NTFS that allows to group together a set of actions on the file system, and if any of those actions fails, a complete rollback occurs. The injector process creates a new transaction, inside of which it creates a new file containing the malicious payload. It then maps the file inside the target process and finally rolls back the transaction. In this way it appears as if the file has never existed, even though its content is still inside the process memory.

VM directory

In this case we can see that the malware creates a new wermgr.exe process (3752) and it injects its payload in it. Once again the malicious second stage is dumped from memory.

About the project

At the moment whack-a-proc supports only the x86 architecture.
Binaries are available here.
If you want to check out the source code, you can find it on GitHub.

Read More

A hook to rule them all: Flare-On 5 - challenge 9

Flare-On is one of the most challenging CTFs of the year when it comes to reverse engineering. In this post I will present an approach to solve level 9 based on hooking program functions with the aid of my library APIhooklib. This will not be a complete solution, the focus will be on the decryption of the VB script, which I consider the hardest part to tackle in this challenge. For a full walkthrough I recommend the one posted by the Flare team itself (link).

Read More

Quick analysis of the Sepsis ransomware

This quick analysis presents the main features and elements regarding the ransomware Septis. I will not explain exactly how it was cracked, because nobody wants to help a ransomware author to fix his vile creation. There are, however, enough elements to guide any further analysis by curious minds to reach the core of its vulnerability.

Read More

Deobfuscation of Bitpaymer API calls

In the plethora of bad ransomware that infests the internet these days, sometimes a “gem” stands out. This is the case of Bitpaymer. It targets companies, with ad-hoc samples for each victim, and it requires ransoms way above the average “spray-and-pray” ransomware. To attack such high-profile targets, it uses a set of features that you rarely find in ransomware: the use of ADSs, multiple layers of encryption and packing, and an elaborated system to hide calls to the Windows API. The focus of this post is the latter.

Read More

API call inspection with APIhooklib

Windows API hooks are among the best friends of infosec people. For example, bad guys use them for stealing information or hiding their files/processes; on the other hand they are found in security tools to detect malicious behaviors.

Read More

Write-up: solution to a RE crackme

CTFs and challenges mainly based on reverse engineering are a bit uncommon, so when I find one I am always happy to devote some time to try and solve it. This write-up will be on the crackme created by hasherezade. To make the reading more spicy I decided to explain my thought process while going through the challenge, instead of writing a plain (boring) solution.

Read More

Getting your hands on the "micro kernel" of NotPetya

As everyone in the infosec community, I wanted to get my hands on the latest malware case, the infamous NotPetya, EternalPetya, WhateveryouwantPetya. Let me start with a disclamer: I am completely out the naming debate, but for the sake of my mental health I will call it NotPetya from now on. There are already a lot of in-depth technical analysis of this malware, so I do not want to waste time writing down things that you can find elsewhere. As an example I’ll leave here the links to a couple of interesting reads on the topic:

Read More

Need a malware? No problem, I'll put it on pastebin

We can find many different means for malwares to spread: just to name a couple, the evergreen of email spam, with that nasty invoice.pdf.exe attachment, or some Viagra malvertising leading to an Exploit Kit. But malware authors also look for more “unusual” ways to move around their products. A very interesting one is pastebin, the well-known service to quickly distribute chunks of text online. The idea of monitoring pastebin comes from sudosev, who proposed to look for Base64 encodings of Windows executables (i.e. PE files) among the content that goes through pastebin. To achieve this goal he used used pastemonitor: the name is self-explanatory, this service stores pastes and allows the user to look for specific strings or regular expressions. sev perfomed the analysis manually, so I decided to take his very good idea and automatize it.

Read More

When monkeys create ransomwares

2016 has been a year full of ransomwares, and the trend doesn’t seem to change in the new year. Many “sophisticated” pieces of malware have been developed, from Locky, to Cerber, to the more recent Spora. But in the wild sometimes strange examples of wannabe-ransomware can appear, as the one we will look at here. Actually I’m writing this post just to make some fun of this script-kiddie masterpiece, so do not expect any obscure technique or advanced feature presented here.

Read More