The Tale of Double JavaScript Obfuscated Scam
Overview
The phishing landscape is constantly evolving. Over the years, it has evolved into a more scalable threat, with an overwhelming amount of campaigns being launched daily. Phishing also changed when criminals started adding more capabilities and features to their toolkits, which make the phishing websites long lived and difficult to detect.
Our previous publications show a variety of techniques being used by criminals to try to evade detection. Those techniques include blacklisting unwanted visitors such as search engines and security scanners and random generation of phishing web page content and URLs. The point behind all of this evasion development is to keep the phishing attack hidden. The longer the scam lives, the more effective it is.
In this blog, we'll take a deep dive into a different type of evasive technique called JavaScript obfuscation, which is being used in many types of scams such as phishing and Magecart attacks, and follow a unique example of double obfuscation and encryption recently observed in an active phishing scam.
7 pieces of obfuscated code
In order to better understand the obfuscated JavaScript code, we've broken it into seven sections as presented in Figure 1. These sections will be referenced from this point forward.
Payload
The page code contains two payload arrays, flagged as sections one (1) and four (4) in the image. These arrays contain the encrypted content of the final page to be rendered, the decoded JavaScript function that is responsible for decryption of the first payload, and the JavaScript code keywords such as "push" and "shift" that will be used by other functions on the original page.
The second payload contains both encoded chunks of the page content and references one of the values in the first payload. This referencing makes the process of understanding the code functionality, and debugging it, harder to do.
Anonymous Javascript functions
The page also contains two anonymous JavaScript functions. An anonymous function is a JavaScript function that will be executed as the page being rendered, without the need to call and execute it explicitly.
The first JavaScript function, seen in section number two (2) on Figure 1, will reshuffle the order of the first payload. The second JavaScript function, section number four (4) on Figure 1, will loop 229 times without doing any changes to the second payload.
Anonymous code being executed, and more specifically code that is not essential to the rendering or functionality of the page, is considered as dead code. It was added to make it harder for the phishing source code to be understood and debugged.
Retrieve payload data
JavaScript functions, flagged as sections three (3) and six (6), in Figure 1 are responsible for retrieving the payload items by referencing to the location on the payload array. These functions add more complexity to the executed code; while both are identical in functionality and structure, they use different obfuscated hexadecimal patterns for variable names.
Code execution
Section seven (7) Figure 1 contains two lines of code responsible for execution of JavaScript functionality. Each line is wrapped by decoding (unescape()) and execution (eval()) functions, which will take the post processed payload, decode it, and execute it.
The first line of code will result in a JavaScript function named "j9b53a9832", which is rendered after being retrieved from one of the encoded payload values, as seen in Figure 3. This function, once executed, will be responsible for getting encrypted payload and split it based on the given 8-digit number to key and encrypted page content. The encrypted page content will be padded with a 6-digit number and afterwards each character of the encrypted page content will be XORed by using the extracted key.
This decrypting JavaScript function has been spotted in active attacks many times in the past, using different function names, padding, and separator values. As it is being decoded and obfuscated inside the original page content, it can't be detected easily without rendering and debugging the page itself.
The second execution line, once running, executes the code as appears in Figure 4. It becomes a document.write JavaScript function, which will render the decrypted content of the page after decrypting "j9b53a9832" that was running on the encrypted page payload.
Finally, the page being rendered is a standard fake forgotten password phishing page using a well-known brand's familiarity. The sole purpose of this page is to steal victim credentials.
Summary
The use of JavaScript to obfuscate scams does not come as a surprise as Javascript enables criminals to create slim HTML pages that create the content seen by victims only once being rendered by their browser. On top of that, JavaScript, as a language, can also be used in a polymorphic way to create different versions of the same source code that perform exactly the same but look different. The need to render obfuscated and polymorphic code creates a challenge from a defensive point of view, as it requires more computational resources and advanced detection capabilities.
The examples in this blog are just the tip of the iceberg, as more complex techniques, including huge chunks of embedded dead code and anti-debugging, are constantly being used in the wild.
The ability to analyze, encrypt, and remove the obfuscation on such pages is not impossible but requires time and resources. The task is compounded, however, by the overwhelming amount of phishing and Magecart campaigns being introduced daily, resulting in many of these scams slipping under the radar.
The use of JavaScript to create encrypted and obfuscated content on phishing and other malicious websites is not new. However, the example shown in this blog presents a level of sophistication that makes the detection of such malicious code harder. As criminals move to adopt advanced obfuscation techniques, defenders need to adopt layered defensive approaches that can detect, isolate, and block such threats in the future.