Friday, 29 September 2017

Dreambot Targeting Bulgarian Users

Recently, in a spam campaign targeted towards Bulgarian users, malicious JavaScript based Dreambot downloader was sent inside an archive file. The theme of the emails was related to "Notification of changes to Regulation for NRA" as shown in Figure 1.

Figure 1

NRA is the National Revenue Agency in Bulgaria (in Bulgarian it is: Национална агенция за приходите).

The JavaScript file had multiple layers of obfuscation and it was particularly interesting to deobfuscate this JavaScript because conventional methods of deobfuscation would not work here.

The conventional methods of deobfuscation include replacing eval() with WScript.Echo(), simple hex or base64 string decoding.

Usually, conventional methods of deobfuscation used by Analysts include modifying the JavaScript so that it prints the deobfuscated output which can be further analyzed.

However, an interesting technique used in the JavaScript in this case was Function Length based Obfuscation.

What is Function Length based Obfuscation?

The main function which is used to perform the malicious activities is obfuscated. It uses the Length of the Function Body as a parameter for decryption. As a result of this, any modifications made to the JavaScript will prevent the data to be decrypted properly.

Layer 1 of the JavaScript is shown in Figure 2. It can be deobfuscated easily by replacing eval() with WScript.Echo().

Figure 2

Layer 2 JavaScript is shown in Figure 3. This layer uses the Function Length based Obfuscation technique which doesn't allow the conventional methods of analysis to work.

Figure 3

After careful inspection of the code, we can see that the long encoded string is passed for decoding to function, KNOY8I(). However, if we try to echo the return value of this function to get the decoded string, it won't work because inside the function, KNOY8I() it uses the length of the function, C47RAD() as a decoding parameter.

The following line of code will replace all instances of the characters, "\(| |    |\n|\r|;|}|{|\)" from the function body of C47RAD(). Then it calculates the length of the function body and splits it into an array as shown below:

var FW29WS=C47RAD[YM8N2P[1]]()[YM8N2P[0]](/\(| |    |\n|\r|;|}|{|\)/)[YM8N2P[2]]("")[YM8N2P[3]][YM8N2P[1]]()[YM8N2P[0]]("")

In our case, the length of the function body is 5686 bytes. So, the array, FW29WS[] is set to [5,6,8,6].

Later on in the code, the length of the function body is used as shown below to decode the string passed to this function:


How do we decode this JavaScript?

The best way to perform deobfuscation in this case is by debugging the script and stepping through the code. cscript and wscript on Windows provide a method to perform JIT debugging. You need to invoke your script as shown below:

cscript.exe <script_name.js> //X

This will prompt us to choose the Debugger. We will use MS Visual Studio debugger and step through the code. We are specifically interested to know the return value of the function: KNOY8I(). So, we can set a Watch on the variable: YM8N2P() which will store the return value.

YM8N2P is an array as shown below:

[0]           "i0,R1(ESrL)|yO6DpTebGlfB.xj84otHIa/Am9gchu-n2Q5q:s?W d"
[1]           ""            String
[2]           "split"    String
[3]           "length"                String
[4]           "charAt"               String
[5]           "Type"   String
[6]           "Charset"              String
[7]           "Open"  String
[8]           "WriteText"         String
[9]           "SaveToFile"        String
[10]         "Close"  String
[11]         "GetSpecialFolder"            String
[12]         "push"   String
[13]         "setTimeouts"     String
[14]         "open"   String
[15]         "send"   String
[16]         "Sleep"  String
[17]         "responseText"   String
[18]         "indexOf"              String
[19]         "Status" String
[20]         "substr" String
[21]         "fromCharCode" String
[22]         "apply"  String
[23]         "Run"     String
[24]         "echo"   String
[25]         "Quit"    String

The first member of this array is a long encoded string which is used to construct important keywords and parameters in the JavaScript. As an example:

var G612GW=new ActiveXObject(WV7D7I[35]+WV7D7I[15]+WV7D7I[13]+WV7D7I[15]+WV7D7I[23]+WV7D7I[24]+WV7D7I[7]+WV7D7I[30]+WV7D7I[8]+WV7D7I[18]+WV7D7I[33]+WV7D7I[36]);

Here, WV7D7I corresponds to an array of characters of the encoded string in YM8N2P[0]

So, we can decode the above string as shown below:

var t = "i0,R1(ESrL)|yO6DpTebGlfB.xj84otHIa/Am9gchu-n2Q5q:s?W d"
var WV7D7I = t["split"]("")


The decoded string is as shown in Figure 4.

Figure 4

In this way, we can decode all the strings and the deobfuscated script is as shown in Figure 5.

Figure 5

Steps performed by the JavaScript:

1. It downloads the encrypted binary (refer Figure 6) from the URL:<counter>. Here, counter is a variable which is incremented in a loop till the time, JavaScript receives the response from the Server. Between each attempt, the JavaScript sleeps for 1 second.
2. Once it receives the response, it checks the response for the marker: "|||"
3. If the marker is found, then it splits the response into 2 parts using the marker. The resulting content is sent to the decryption routine.
4. The decrypted content is a binary which is dropped in the path: %temp%\62ea.exe
5. It is then executed using WScript.Shell["Run"]
6. After execution, a message box is displayed with the message: "Runtime Error 0x48940 (.QBT) Library not located on the system, please use x64 system." This message is only for social engineering purpose.

Figure 6

MD5 hash of the Dropped Binary: 37fb9dd68c86deeb44b672a84a8e25bf

The dropped binary is Dreambot with functionality to communicate through TOR and this is evident from the following Registry Keys it creates post execution:



 The TOR client is fetched encrypted from the URL:

No comments:

Post a Comment