SynAck targeted ransomware uses the Doppelgänging technique

The Process Doppelgänging technique was first presented in December 2017 at the BlackHat conference. Since the presentation several threat actors have started using this sophisticated technique in an attempt to bypass modern security solutions.
In April 2018, we spotted the first ransomware employing this bypass technique – SynAck ransomware. It should be noted that SynAck is not new – it has been known since at least September 2017 – but a recently discovered sample caught our attention after it was found to be using Process Doppelgänging. Here we present the results of our investigation of this new SynAck variant.
Anti-analysis and anti-detection techniques
Process Doppelgänging
SynAck ransomware uses this technique in an attempt to bypass modern security solutions. The main purpose of the technique is to use NTFS transactions to launch a malicious process from the transacted file so that the malicious process looks like a legitimate one.
Part of the procedure that implements Process Doppelgänging
Binary obfuscation
To complicate the malware analysts’ task, malware developers often use custom PE packers to protect the original code of the Trojan executable. Most packers of this type, however, are effortlessly unpacked to reveal the original unchanged Trojan PE file that’s suitable for analysis.
This, however, is not the case with SynAck. The Trojan executable is not packed; instead, it is thoroughly obfuscated prior to compilation. As a result, the task of reverse engineering is considerably more complicated with SynAck than it is with other recent ransomware strains.
The control flow of the Trojan executable is convoluted. Most of the CALLs are indirect, and the destination address is calculated by arithmetic operation from two DWORD constants.

All of the WinAPI function addresses are imported dynamically by parsing the exports of system DLLs and calculating a CRC32-based hash of the function name. This in itself is neither new nor particularly difficult to analyze. However, the developers of SynAck further complicated this approach by obscuring both the address of the procedure that retrieves the API function address, and the target hash value.
Let’s illustrate in detail how SynAck calls WinAPI functions. Consider the following piece of disassembly:

This code takes the DWORD located at 403b13, subtracts the constant 78f5ec4d, with the result 403ad0, and calls the procedure at this address.

This procedure pushes two constants (N1 = ffffffff877bbca1 and N2 = 2f399204) onto the stack and passes the execution to the procedure at 403680 which will calculate the result of N1 xor N2 = a8422ea5.
This value is the hash of the API function name that SynAck wants to call. The procedure 403680 will then find the address of this function by parsing the export tables of system DLLs, calculating the hash of each function name and comparing it to the value a8422ea5. When this API function address is found, SynAck will pass the execution to this address.
Notice that instead of a simple CALL in the image above it uses the instructions PUSH + RET which is another attempt to complicate analysis. The developers of SynAck use different instruction combinations instead of CALL when calling WinAPI functions:

push reg
retn
jmp reg
mov [rsp-var], reg
jmp qword ptr [rsp-var]

Deobfuscation
To counter these attempts by the malware developers, we created an IDAPython script that automatically parses the code, extracts the addresses of all intermediate procedures, extracts the constants and calculates the hashes of the WinAPI functions that the malware wants to import.
We then calculated the hash values of the functions exported from Windows system DLLs and matched them against the values required by SynAck. The result was a list showing which hash value corresponds to which API function.
Part of the list of API functions imported by SynAck and their hashes
Our script then uses this list to save comments in the IDA database to indicate which API is going to be called by the Trojan. Here is the code from the example above after deobfuscation.
Disassembly screen – note the comment with the target API function name
Hex-Rays decompilation screen – again, the API function names are recognized
Language check
At an early stage of execution the Trojan performs a check to find out whether it has been launched on a PC from a certain list of countries. To do this, it lists all the keyboard layouts installed on the victim’s PC and checks against a list hardcoded into the malware body. If it finds a match, SynAck sleeps for 300 seconds and then just calls ExitProcess to prevent encryption of files belonging to a victim from these countries.
Part of the procedure that stops the Trojan if the language check is not passed
Part of the procedure that checks the keyboard layouts on the infected PC
Directory name validation
Shortly after the language check, which can be considered fairly common among modern ransomware, SynAck performs a check on the directory where its executable is started from. If there’s an attempt to launch it from an ‘incorrect’ directory, the Trojan won’t proceed and will just exit instead. This measure has been added by the malware developers to counter automatic sandbox analysis.
As with API imports, the Trojan doesn’t store the strings it wants to check; instead it stores their hashes – a tactic that hinders efforts to find the original strings.
SynAck contains nine hashes; we have been able to brute-force two of them:

0x05f9053d == hash(“output”)
0x2cd2f8e2 == hash(“plugins”)

In the process we found a lot of collisions (gibberish strings that give the same hash value as the meaningful ones).
Cryptographic scheme
Like other ransomware, SynAck uses a combination of symmetric and asymmetric encryption algorithms. At the core of the SynAck algorithm lies the hybrid ECIES scheme. It is composed of ‘building blocks’ which interact with each other: ENC (symmetric encryption algorithm), KDF (key derivation function), and MAC (message authentication code). The ECIES scheme can be implemented using different building blocks. To calculate a key for the symmetric algorithm ENC, this scheme employs the ECDH protocol (Diffie-Hellman over a chosen elliptic curve).
The developers of this Trojan chose the following implementation:
ENC: XOR
KDF: PBKDF2-SHA1 with one iteration
MAC: HMAC-SHA1
ECDH curve: standard NIST elliptic curve secp192r1
ECIES-XOR-HMAC-SHA1
This is the function that implements the ECIES scheme in the SynAck sample.
Input: plaintext, input_public_key
Output: ciphertext, ecies_public_key, MAC
The Trojan generates a pair of asymmetric keys: ecies_private_key and ecies_public_key;
Using the generated ecies_private_key and input_public_key the Trojan calculates the shared secret according to the Diffie-Hellman protocol on an elliptic curve:

ecies_shared_secret = ECDH(ecies_private_key, input_public_key)

Using the PBKDF2-SHA1 function with one iteration, the Trojan derives two byte arrays, key_enc and key_mac, from ecies_shared_secret. The size of key_enc is equal to the size of the plaintext;
The plaintext is XORed byte to byte with the key_enc;
The Trojan calculates the MAC (message authentication code) of the obtained ciphertext using the algorithm HMAC-SHA1 with key_mac as the key.
Initialization
At the first step the Trojan generates a pair of private and public keys: the private key (session_private_key) is a 192-bit random number and the public key (session_public_key) is a point on the standard NIST elliptic curve secp192r1.
Then the Trojan gathers some unique information such as computer and user names, OS version info, unique infection ID, session private key and some random data and encrypts it using a randomly generated 256-bit AES key. The encrypted data is saved as the encrypted_unique_data buffer.
To encrypt the AES key, the Trojan uses the ECIES-XOR-HMAC-SHA1 function (see description above; hereafter referred to as the ECIES function). SynAck passes the AES key as the plaintext parameter and the hardcoded cybercriminal’s master_public_key as input_public_key. The field encrypted_aes_key contains the ciphertext returned by the function, public_key_n is the ECIES public key and message_authentication_code is the MAC.
At the next step the Trojan forms the structure cipher_info.

struct cipher_info
{
uint8_t encrypted_unique_data[240];
uint8_t public_key_n[49];
uint8_t encrypted_aes_key[44];
uint8_t message_authentication_code[20];
};

It is shown in the image below.
Encrypted initialization information
This data is then encoded in base64 and written into the ransom note.
Ransom note
As we can see, the criminals ask the victim to include this encoded text in their message.
File encryption
The content of each file is encrypted by the AES-256-ECB algorithm with a randomly generated key. After encryption, the Trojan forms a structure containing information such as the encryption label 0xA4EF5C91, the used AES key, encrypted chunk size and the original file name. This information can be represented as a structure:

struct encryption_info
{
uint32_t label = 0xA4EF5C91;
uint8_t aes_key[32];
uint32_t encrypted_chunk_size;
uint32_t reserved;
uint8_t original_name_buffer[522];
};

The Trojan then calls the ECIES function and passes the encryption_info structure as the plaintext and the previously generated session_public_key as the input_public_key. The result returned by this function is saved into a structure which we dubbed file_service_structure. The field encrypted_file_info contains the ciphertext returned by the function, ecc_file_key_public is the ECIES public key and message_authentication_code is the MAC.

struct file_service_structure
{
uint8_t ecc_file_key_public[49];
encryption_info encrypted_file_info;
uint8_t message_authentication_code[20];
};

This structure is written to the end of the encrypted file. This results in an encrypted file having the following structure:

struct encrypted_file
{
uint8_t encrypted_data[file_size – file_size % AES_BLOCK_SIZE];
uint8_t original_trailer[file_size % AES_BLOCK_SIZE];
uint64_t encryption_label = 0x65CE3D204A93A12F;
uint32_t infection_id;
uint32_t service_structure_size;
file_service_structure service_info;
};

The encrypted file structure is shown in the image below.
Encrypted file structure
After encryption the files will have randomly generated extensions.
Directory after encryption
Other features
Termination of processes and services
Prior to file encryption, SynAck enumerates all running processes and all services and checks the hashes of their names against two lists of hardcoded hash values (several hundred combined). If it finds a match, the Trojan will attempt to kill the process (using the TerminateProcess API function) or to stop the service (using ControlService with the parameter SERVICE_CONTROL_STOP).
To find out which processes it wants to terminate and which services to stop, we brute-forced the hashes from the Trojan body. Below are some of the results.
Processes
Services
Hash
Name
Hash
Name
0x9a130164
dns.exe
0x11216a38
vss
0xf79b0775
lua.exe
0xe3f1f130
mysql
0x6475ad3c
mmc.exe
0xc82cea8d
qbvss
0xe107acf0
php.exe
0xebcd4079
sesvc
0xf7f811c4
vds.exe
0xf3d0e358
vmvss
0xcf96a066
lync.exe
0x31c3fbb6
wmsvc
0x167f833f
nssm.exe
0x716f1a42
w3svc
0x255c7041
ssms.exe
0xa6332453
memtas
0xbdcc75a9
w3wp.exe
0x82953a7a
mepocs
0x410de6a4
excel.exe

0x9197b633
httpd.exe

0x83ddb55a
ilsvc.exe

0xb27761ed
javaw.exe

0xfd8b9308
melsc.exe

0xa105f60b
memis.exe

0x10e94bcc
memta.exe

0xb8de9e34
mepoc.exe

0xeaa98593
monad.exe

0x67181e9b
mqsvc.exe

0xd6863409
msoia.exe

0x5fcab0fe
named.exe

0x7d171368
qbw32.exe

0x7216db84
skype.exe

0xd2f6ce06
steam.exe

0x68906b65
store.exe

0x6d6daa28
vksts.exe

0x33cc148e
vssvc.exe

0x26731ae9
conime.exe

0x76384ffe
fdhost.exe

0x8cc08bd7
mepopc.exe

0x2e883bd5
metray.exe

0xd1b5c8df
mysqld.exe

0xd2831c37
python.exe

0xf7dc2e4e
srvany.exe

0x8a37ebfa
tabtip.exe

As we can see, SynAck seeks to stop programs related to virtual machines, office applications, script interpreters, database applications, backup systems, gaming applications and so on. It might be doing this to grant itself access to valuable files that could have been otherwise used by the running processes.
Clearing the event logs
To impede possible forensic analysis of an infected machine, SynAck clears the event logs stored by the system. To do so, it uses two approaches. For Windows versions prior to Vista, it enumerates the registry key SYSTEMCurrentControlSetServicesEventLog and uses OpenEventLog/ClearEventLog API functions. For more modern Windows versions, it uses the functions from EvtOpenChannelEnum/EvtNextChannelPath/EvtClearLog and from Wevtapi.dll.
Ransom note on logon screen
SynAck is also capable of adding a custom text to the Windows logon screen. It does this by modifying the LegalNoticeCaption and LegalNoticeText keys in the registry. As a result, before the user signs in to their account, Windows shows a message from the cybercriminals.
Windows logon screen with ransom text
Attack statistics
We have currently only observed several attacks in the USA, Kuwait, Germany, and Iran. This leads us to believe that this is targeted ransomware.
Detection verdicts
Trojan-Ransom.Win32.Agent.abwa
Trojan-Ransom.Win32.Agent.abwb
PDM:Trojan.Win32.Generic
IoCs
0x6F772EB660BC05FC26DF86C98CA49ABC
0x911D5905CBE1DD462F171B7167CD15B9
Click here for best antivirus and antispyware software

Powered by WPeMatico