Video Screencast Help
Symantec to Separate Into Two Focused, Industry-Leading Technology Companies. Learn more.
Security Response

Inside Trojan.Clampi: Enhanced Logging

Created: 20 Oct 2009 15:40:27 GMT • Updated: 23 Jan 2014 18:31:59 GMT
Nicolas Falliere's picture
0 0 Votes
Login to vote

This chapter in our Clampi saga brings us back to the malware’s logging facility. As we saw before, one of Clampi’s modules, codenamed LOGGER, is responsible for logging outgoing information going to a determined list of URLs – stored in a data file as CRCs.

One problem arises with banking sites that preprocess the user’s personal information before sending it over HTTPS—it’s done using client-side JavaScript.  For instance, a hash of the input PIN number could be sent instead of the PIN number itself. This mechanism adds an extra layer of security, preventing malware from sniffing network traffic at one end of the SSL tunnel. But still, it’s only covering one end. It’s more secure than no encryption, but still not great. At least two methods exist to get around this:

  • Setting up a keylogger using either software (driver/user-mode hooks) or hardware (wire-tapping). This is the generic approach.
  • Grabbing the user information before it gets processed. This is non-generic, Web site-specific approach.

The Clampi gang decided to go with the second method and created another module named “LOGGEREXT” (which obviously stands for ‘Logger Extended’).

This module is replacing JavaScript stubs inside targeted Web pages. The replacement code is similar to Win32 hooks—they are called instead of other JavaScript functions, do some processing, and then call the original function.

The target pages, the original JavaScript stubs, and the replacement ones are stored in a separate data file, loaded by the LOGGEREXT module in its address space.

After reverse-engineering, guessing, and correlating elements with what we found out when analyzing the LOGGER module, we were able to figure out the data file’s file format. Here’s an entry:

offset=498, id=35, flags=83, count=1
  type=3, len=17, crc=C1008A17
  HTML entries:
    blk00: '</BODY>'
    blk01: '<script type="text/javascript">\r\n (…)</body>'
    blk10: '</body>'
    blk11: '<script type="text/javascript">\r\n (…)</body>'

As for the LOGGER module, each entry contains one or more URL’s CRC and length, as well as a type. HTML blocks may follow, containing the original HTML code and what it should be replaced with. The example above has two HTML entries: they indicate that the tags </body> or </BODY> should be replaced by a <script> stub, followed by the closing </body> for coherence.

This replacement will occur when the user browses a URL whose type 3 length and CRC are 17 and 0xC1008A17, respectively. Note that using type 3 CRCs means any part of the URL’s top section can be matched. The preceding “.” is not required.

Let’s examine the injected code carefully:


A JavaScript routine newfff() is injected and called. This routine first saves the original address of the routine doEncryption(), which belongs to the original Web page. We may safely assume this routine is responsible for encrypting or hashing the user’s PIN and password. It then replaces doEncryption with a routine of its own. The new doEncryption does three things:

  1. It retrieves the “idPassPhrase” element, if found. It creates a hidden HTML <input> tag, names it “idPassPhrase_2”, and then attaches it to the DOM.
  2. It does the same thing for the “Password” element.
  3. It then calls the original doEncryption(), saved in the global variable doEncryption2.

When the data is sent to the server, the POST (or GET) fields will include two additional fields, ‘idPassPhrase_2’ and ‘Password_2’, containing the passphrase and password before encryption. Et voila!

The current data file that LOGGEREXT uses contains exactly 78 entries. It’s worth noting that only 25% of them have HTML replacement stubs, which is fairly strange.

The amount of HTML code it contains is pretty impressive. The authors analyzed about 15 Web sites carefully enough to determine where additional JavaScript stubs should be injected and when the module should be called.

One last thing to mention: the list appears to be old, as some URLs contained in the HTML stubs have outdated version numbers. For instance, for a well-known UK bank, a (partial) match is done on the "PC_7_1_5L9_cam10To30Form" substring. We found the page that’s intended to be hooked, but it now contains the value "PC_7_2_5PF_cam10To30Form".

The next blog will discuss the two remaining modules. Stay tuned!

Next: Inside Trojan.Clampi: Network Modules
Previous: Inside Trojan.Clampi: Stealing Your Information