One of the top Internet threats today is drive-by download attacks which originate from exploits kits, hacked websites, spam campaigns and more. As browsers are the main tool for navigating the web, the main attack vectors are browser vulnerabilities, plugin and extension vulnerabilities, as well as some OS vulnerabilities.
A web page is constructed from static and dynamic components.
In our experience with exploit kit behavior, hacked websites, and web-based exploits, we find that malicious websites rely heavily on obfuscation to bypass signature-based protection products as well as making the researcher’s life a bit harder.
For example, the following screenshot is taken from a landing page of a known exploit kit:
As you can see, this is just a blob of data, not something with a lot of meaning initially. However, this data is decoded and de-obfuscated by the functions in the landing page code.
As we said above, if de-obfuscation is done through scripts, why not hook these script functions so we will be alerted when something interesting happens, such as dynamic addition of Java applet tags?
- Detect a web site that has been injected with malicious code.
- Detect exploit-kits.
- Identify new evasion techniques and new delivery methods.
- Intercept and react to specific patterns in the middle of the de-obfuscation process. We will not explain the specifics in this blog post, but it is an attempt to solve the problem of manipulating data inside an obfuscation/de-obfuscation chain.
- Detect common browser vulnerabilities.
- Not everything can be hooked easily; once again, this depends on the particular browser and its version.
Our chosen topology for the task looks like this:
We have a few available options. For example, we could use the console.log() function. However, this function works in Chrome but not in all versions of IE. The equivalent solution for IE is using the event manager, but that makes development and maintenance much harder.
Our other option is to use <img> tags, but we prefer the idea of adding a header to a new HTTP request and letting our proxy catch it.
To demonstrate one implementation of this idea, let’s take a look at our first goal: Detect a web site that has been injected with malicious code.
Usually, a benign website is hacked and the cybercriminal adds a piece of code to the website. This redirects the unsuspecting victim to a malicious server such as an exploit kit server.
Our experience shows that the redirection is usually carried out by de-obfuscating the data and dynamically creating an iframe element. The iframe may have suspicious attributes values such as hidden visibility.
An iframe object is a DOM element which eventually, after all mutations, must be added to the HTML document in a way that can be read by the browser’s HTML parser.
As a reference, let’s list some of the ways an element can be added to the HTML document:
- [DOM Element].appendChild([DOM Element])
- [DOM Element].replaceChild([DOM Element])
- [DOM Element].innerHTML = [string]
So… our first thought is: if we could see all the changes to an HTML document, we would know if an iframe was added dynamically. We could scan its attributes as well.
Without considering external libraries:
After choosing our method, we hooked the first three ways of adding elements: appendChild, replaceChild, and document.write.
The 4th method, using ‘innerHTML’, is a bit more tricky but the idea is to hook functions that are interesting, such as document.getElementById(), document.createElement(), etc. We then add the objects to the MutationObserver object or use Mutation Events and watch for changes.
For example, we want to hook the document.write() method and call a function after it finishes. We can use our function like this:
hook_function(document, ‘write’, null, callback)
As a side note, sometimes different functions need different hooking mechanisms. This depends on the browser and the browser version. For example, IE11 supports extending Node.prototype, but older versions of the browser don’t.
There’s not much to say about the logic. Everything is added eventually with an HTML element or a string; it sums up to traversing elements and checking their attributes and content or comparing strings.
We put all the logic to detect an iframe inside the callback function. Let’s see if that works.
Of course, we still need to check for false-positive rates. We may tweak the attributes, or maybe even use a blacklist of specific patterns. However, the example above is real: an infected website with a dynamic iframe eventually leads us to an infection chain.
Exploit-kits are systems that try to maximize their uptime by reducing their general signature, meaning they will expose as little of themselves as possible. This is why they employ different evasion techniques. For example, sometimes they will use known vulnerabilities to determine if the landing page runs on a virtual machine. At other times, they will try to load certain components to find out if there is some kind of protection system running. These are signs that raise suspicions and help identify malicious websites. Let’s tackle these two examples.
A known technique for determining if software is installed on a system using a vulnerability which affects a different version of IE is to abuse the res:// protocol. There are a few ways to do it, but by hooking dynamic creation of elements like <img> and <script>, we can send the content to a function that checks for the use of this vulnerability.
In the following screen shot, we see an exploit kit attempt to recognize if software such as Fiddler proxy, VirtualBox, VMware, etc are installed on the system. If they are present, the exploit kit will not continue its execution.
The second example of evasion on IE is when an exploit kit tries to instantiate an ActiveXObject of a specific product. ActiveXObjects can be wrapped with our own object. A simple method would be to use code like this:
The jsh_detect_activex_by_name method will take the name and check if a known ActiveX object is used when trying to evade a system.
Here the attacker tries to instantiate a Kaspersky virtual keyboard plugin to check if a Kaspersky product is installed.
Nuclear exploit kit uses a recent Flash vulnerability to attack victims. It uses the <object> tag to load a flash object. To bypass the signature-based protections, the tag is obfuscated and is only added during runtime.
The <object> tag loads the .swf file that triggers the vulnerability. It’s important to note that FlashVars are supplied to the movie as well. Exploit-kits sometimes use FlashVars to supply the payload download link or even the shellcode to the exploit.