Qadars is a banking Trojan with advanced capabilities aimed at monetary theft from online bank accounts through man-in-the-browser style attacks, including a mobile-based component to help circumvent banking apps with two-factor authentication by hijacking out-of-band SMS authentication codes.
The Qadars banking Trojan first surfaced in 2013 targeting France and Netherlands. Whilst the first activity was reported then, new variants have gradually been seen targeting more countries with more recent activity affecting as many as 18 banks in the UK in the latter half of 2016.
While much analysis has been published in the past, we had not encountered any publicly available code for analysis of the command and control channel it uses. The analysis below is based on the “ad69e780446a076c3aceccd39424cac6227905351e8263ec04d991a8dc5a454e” sample downloaded, which is publicly available from this forum.
Figure 1: Screenshot of sample availability
On infection, this sample attempts to contact the C2 server by resolving four hardcoded domain names, as opposed to using Domain Generation Algorithms that are often favored by some malware families. Examples of some of the C2 domains observed in use by several samples of Qadars analyzed are given below:
AES128 Client Key
The C2 request packet is AES128-encrypted with the 0x20 bytes MD5 hash of the client-key. The client-key, in turn, is a 9-character string randomly selected using upper and lower case characters from the English alphabet. The code block to generate the client-key is shown below, where the block is looped for nine iterations to randomly select a character in each iteration.
Figure 2: Generation of the 9-character AES128 Client-Key
The C2 response packet is also AES128-encrypted with a server-key generated in a similar manner by the malware. The server-key is also embedded in the request packet. Therefore, the malware would have knowledge of the server-key to decrypt the response. In contrast, as the client-key is generated randomly by the malware itself, the C2 server would not have prior knowledge of the client-key required to decrypt the request. As evident, since both keys are generated randomly, it is likely that the server also maintained a database of blobs to figure out the client-key and decrypt the request.
Brute-forcing for client-key
To transmit the C2 request securely, the client-key is also encrypted and prepended to the request message. The client-key is encrypted in 2-character sets, in this format.
Encryption of AES128 Client-Key
As an example, the Client-Key “AABBCCDDE” is encrypted into 5 sets of blobs, with the last character padded with NULL. Each blob is prepended with a WORD value for the blob-size in DWORD. In turn, these 5 sets of blobs are prepended with a DWORD value for the total blobs-size.
Earlier reversing efforts have also identified sub_000072A0 to be the routine responsible for encrypting each 2-character client-key into blobs. Therefore, to retrieve the client-key from the blobs, further reversing could be performed or it would be possible to brute-force the client key using in-memory fuzzing.
In-memory fuzzing is a technique to fuzz a target function by taking a snapshot of the process at function entrance, input random values, execute the function, observe for crashes, restore the snapshot at function exit, redirect execution back to function entrance and repeat. A more detailed explanation of the approach is available here.
In this case, to brute-force the Qadars client-key a database of blobs would be built from the output of sub_000072A0 after specifying 2-character permutations of the character set. Subsequently, the client-key could be obtained by matching the blobs in the database, and appending the characters together.
The approach of using in-memory brute-forcing is inefficient for use in real-time decryption - in this case it originally took 50 minutes using Immunity Debugger. However, because the encryption is not dependent on any dynamic variable, the blobs database could be created offline once and then re-used as a lookup table in future.
Qadars Network Decryption Tool: “qadars_decryptor_public.py”
Based on the results of this analysis, we decided to release a tool to decrypt Qadars network traffic. Essentially the qadars_decryptor_public.py tool is a Qadars network packet parser with the following functionality:
- Specify a PCAP file as an argument
- Parses the specified PCAP for DNS queries to known Qadars C2 domain names
- Identifies and reassembles C2 request and response packets
- Base64-decodes the C2 request
- Obtains the client-key in C2 request using the hash database
- Decrypts the C2 request for the server-key and message body
- Decrypts the corresponding server response
In step 2, the list of known Qadars C2 domain names in this tool is initialized to those mentioned in the “C2 Domains” section. Users could expand this list by appending to the “self.c2_domains_list” variable.
As an example, the sample Qadars PCAP file available on malware-traffic produces the following output: