Copyright: The development of this document is funded by Higher Education of Academy. Permission is granted to copy, distribute and /or modify this document under a license compliant with the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/. SQL Injection BLOSSOM Manchester Metropolitan University (Funded by Higher Education Academy) l.han@mmu.ac.uk
1. Learning Objectives This lab aims to understand SQL injection. 2. Preparation 1) Under Linux environment 2) Files that you will need from /home/user/blossomfiles/sqlinjection: 'sqlinjection.php' 3) Some documents that you may need to refer to: 3. Tasks 'Virtual-MachineGuide.pdf' Linux-Guide.pdf BLOSSOM-UserGuide.pdf Setup & Installation: Start a single virtual machine as you have done with previous exercises (see Virtual Machine Guide) # kvm -cdrom /var/tmp/blossomfiles/blossom-0.98.iso -m 512 -net nic,macaddr=52:54:00:12:34:57 -net vde -name node-one Set the extension for mysql in PHP to 'mysql.so' using the following commands, and then restart the apache2 server: # gedit /etc/php5/apache2/php.ini > extension=mysql.so # /etc/init.d/apache2 restart
Task 1 MYSQL 1.1 Nearly all databases that you see in use on websites are provided by either MYSQL(*nix systems) or SQL Server(Microsoft). In these labs we will be using MYSQL. Unlike other database software you may already be familiar with, such as Microsoft Access, it's very easy to access the databases through a variety of programming languages. Like most websites, we will be accessing the MYSQL databases through PHP, a server side language. Typically, the routine for accessing a MYSQL database is as follows: 1) Connect to the MYSQL backend, using the address, password and user 2) Select the correct database 3) Assemble a MYSQL query (or command) 4) Query the database, checking the query is valid. 5) Read the results if required. 1.2 The SQL query syntax is very easy to learn, below are some examples that you can adapt for use in the lab. SELECT * from ANIMALS; The above displays the entire table `ANIMALS' SELECT * from ANIMALS WHERE animal=`chicken'; Displays all data about chickens from table, `ANIMALS' SELECT animal from ANIMALS WHERE name=`dave'; Returns a list of animals called Dave You can also write data into a table using the following SQL commands as examples: INSERT INTO ANIMALS (id, name, animal, favcrisps) VALUES (1, "Jim", "cow", "Salt and Vinegar"); Inserts data into table ANIMALS about Jim the cow
INSERT INTO ANIMALS (id, animal, favcrisps, name) VALUES (1, "Chicken", "Doesn't Like Crisps", "Dave"), (2, "Pig", "Bacon", "Sam"), (3, "Dog", "Ready Salted", "Lauren"); Inserts multiple rows of data, in the given order Rows can be altered using commands similar to the following command too: UPDATE ANIMALS SET name=`percy' WHERE animal='pig'; Renames all pigs Percy The above commands should be sufficient for this exercise, more commands can be found in the MYSQL reference manual at http://dev.mysql.com/doc/refman/5.0/en/ 1.3 We now need to create the basic tables that will be used for this task. Start mysql and create a table using the following commands: #mysql -u root -p # mypass > CREATE DATABASE users; > USE users; > CREATE TABLE people (id int NOT NULL AUTO_INCREMENT, PRIMARY KEY(id), name varchar(15), email varchar(20)); > INSERT INTO people(id,name,email) VALUES (1,'Betty','bo@illumati.com'), (2,'Jamie','jh@something.com'); This will provide us with enough data to perform some basic SQL Injections. Task 2 SQL Injection 2.1 Due to the nature of the MYSQL syntax, it is possible to extend the intended command to perform other commands. Below is a simple example of SQL injection implemented through a PHP page: <?php //sweetstock.php //This PHP page returns the number of items in stock for given sweet //Connect to the mysql database mysql_connect(`localhost', `root', `mypass');
//Select database sweets mysql_select_db(`sweets'); //Get sweet name from url $name = $_GET[`sweet']; //Construct a mysql query $cmd = sprintf("select stock FROM stock WHERE sweet='%s'", $name); //mysql returns an array of results $result = mysql_query("$cmd"); //Open the result array with this while loop //Keep echoing the first column of the result until none left while($row = mysql_fetch_array($result)){ echo "$row[0]"; }?> When the above PHP page is called with 'http://insecuresweetshop.com/sweetstock.php?sweet='milkbottles', the website will return the number of milkbottles in stock. The MYSQL command is assembled to be: SELECT stock FROM stock WHERE sweet=`milkbottles' However, if we access the following URL, 'http://insecuresweetshop.com/php?sweet=milkbottles'or'1'='1' The query will become: SELECT stock FROM stock WHERE sweet='milkbottles' OR '1' = '1' Which is always TRUE. The program will output all stock for all sweets; we have performed an SQL Injection. By injecting the URL, we have obtained information from a MYSQL database that we shouldn't have. This may not seem like much, but in some cases it's possible to completely escape the command, changing tables and accessing other information. There are hundreds of examples of SQL injection being used in just this way to obtain people's personal information. 2.2 Now we can look at an SQL Injection for ourselves. Move the file that you downloaded earlier called 'sqlinjection.php' into a directory under /var/www/: # mkdir /var/www/sql # cp sqlinjection.php /var/www/sql
Open up a browser and navigate to 'http://localhost/sql/sqlinjection.php'. We should be confronted with a few messages stating the success of the connection, the basis of the query being used in this example, and a message telling us that the query is not valid due to the fact that not data has been read in to the PHP page. Using the browser, type the following in to the URL address bar: > http://localhost/sql/sqlinjection.php?name=betty This should then display the ID number attached to the name Betty, and it should because this is how the page is meant to function; however, due to the fact that the code is vulnerable to an SQL Injection, we can input the following URL in to the browser in order to obtain more information: > http://localhost/sql/sqlinjection.php?name=' OR email='bo@illumati.com This will display the ID number attached to the email 'bo@illumati.com'. We have managed to enter the rest of the query in to the address bar due to the code's vulnerabilities. Even though this is a very simple example, it's quite easy to understand the potential of an SQL Injection. Try to input a URL into the browser that will output the ID number for every single row from the table. HINT: Refer back to the milkbottles example in task 2.1. 2.3 We should have developed quite an understanding of how an SQL Injection is performed, so we will now take a brief look in to how we can prevent them. Open up the source code for 'sqlinjection.php' and look at it, you should be able to make sense of what's happening at each bit of code. Take a look at the commented out line which when uncommented will apply the method 'mysql_real_escape_string()' to the variable '$user' and then store it in '$validuser'. After uncommenting this line, change the variable '$user' on the next line to '$validuser'. This will remove certain special characters such as apostrophes, quotation marks or new line characters by prepending them with backslashes, which should render the query as invalid. This is known as Input Validation and it is something that should be done whenever trying to prevent SQL code from potential injections. Try using one of the URLs we used earlier and take note of the difference.