Introduction
When a machine has only port 80 opened, your most trusted vulnerability scanner cannot return anything useful, and you know that the admin always patch his server, we have to turn to web hacking. SQL injection is one of type of web hacking that require nothing but port 80 and it might just work even if the admin is patch-happy. It attacks on the web application (like ASP, JSP, PHP, CGI, etc) itself rather than on the web server or services running in the OS.
This article does not introduce anything new, SQL injection has been widely written and used in the wild. I wrote the article because i would like to document some of users to test the server SQL injection security and i hope that it may be of some use to others. You may find a trick or two but please check out the RageZone Rulez!
SQL injection.
One of the most common problems with security in web applications is SQL injection. To begin with I will present this comic for you:
The comic clearly illustrates the problems with SQL injection. If you do not get it, do not worry, you will in just a moment.
SQL injections work by injecting SQL into the queries you have already written in your script. Often you will pass some sort of variable data to your queries; this data might be influenced by user input. In the above comment we might imagine that the school had a query that looks something like this:
view plaincopy to clipboard
The above snippet works. As long as users input data that conforms to an expected format. Now, the mother in the comic did not provide expected data, rather she injected an entire additional query into the existing query. Let's take a look at how the query looks when we enter the string given by the mother:
view plaincopy to clipboard
(Note: PHP does not support stacking queries with all DBMSs. MySQL in particular)
As you probably know, a semi-colon ends a query and most times it is actually required, but PHP just adds it automatically if you omit it. Therefore, by closing the string and finishing the query by entering the closing parenthesis and a semi-colon we will be able to add an additional query that drops the student table. The two hyphens at the end make whatever comes after it a comment, so whatever remaining characters that might have been in the original query will simply be ignored.
It should not take too much brain power to figure out why this is a bad thing. Malicious users will basically be able to execute any kind of queries they would like to. This can be done for various purposes. It could be retrieving confidential information or destroying your data just to name a few.
3.1. Protecting your script from SQL injections
Fortunately, protecting yourself from SQL injections is rather easy. It is just a matter of calling a single function which make data safe for use in a query. How you should do this depends on which PHP extension you are using. Many people use the regular mysql extension, so let us start with that one. That particular extension has a function called mysql_real_escape_string(). Let us take a look at how that one works with a simple example that illustrates its usage:
view plaincopy to clipboard
As you see, doing it is incredibly easy yet many people fail to do this and only find out when it is too late. Other extensions support something called prepared statements. An example of a such extension is PDO (PHP Data Objects). Let us take a look at how that works:
view plaincopy to clipboard
If you have many fields you need to use in your query then it might be a little difficult remembering the order of all these different question marks which act as place holders for the data. An alternate syntax is using named parameters. In our case it would look like this:
view plaincopy to clipboard
Obviously, in our case this would not have any benefits, but as I said, if you have many parameters then you might find that more useful. There can be other reasons why using prepared statements would be useful, but I will leave that to research for yourself.
The mysqli (MySQL improved) extension has support for prepared statements as well, so if you are using that then check out its documentation to see the syntax.
The golden rule regarding this is that nothing is to be trusted and all data should be escaped.
Additionally, I mentioned earlier that users should not get information from error messages. Not only is it irrelevant, but it may also be information that may aid people with malicious purposes. You may sometimes be told that you should add or die(mysql_error()) to the end of your query calls to functions like mysql_query(). However, you should not do that. By doing that you are no longer using PHP's error and exception handling functionality and you remove the opportunity to control whether errors should be displayed or not. In my opinion the best solution would be to use PHP's exceptions. If you do not want to do that then at least do something like or trigger_error('Query failed: '. mysql_error()). By doing that you are utilizing PHP's built-in functionality and you will be able to use the methods discussed under Error Reporting. Moreover, ending script execution with die() is simply bad practice. You will not be able to give the user a proper error page and you will not be able to do any cleaning up for the rest of the script.
Source: phpfreaks.com
How do you test if it is vulnerable?
Oky i made a littel test for your sql!
How is work?
Simple!
Go to web page => Register new Account => Add account info!
BUT! BUT in e-mail add this code:
Then click: Create New Account!
If your web is not secured in 5---10 seconds your SQL will sleep!SQL SHOTDOWN!
Or you can do same sh*t to: web page =>Lost Password=> Add account info! in e-mail add this code:
For example view images:
BEFORE:
AFTER:
Credits: hackalin , HurryPoker
How to avoid SQL Injection?
Filter out character like single quote, double quote, slash, back slash, semi colon, extended character like NULL, carry return, new line, etc, in all strings from:
- Input from users
- Parameters from URL
- Values from cookie
For numeric value, convert it to an integer before parsing it into SQL statement. Or using ISNUMERIC to make sure it is an integer.
Change "Startup and run SQL Server" using low privilege user in SQL Server Security tab.
Delete stored procedures that you are not using like:
master..Xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask
The information has been provided: HurryPoker
When a machine has only port 80 opened, your most trusted vulnerability scanner cannot return anything useful, and you know that the admin always patch his server, we have to turn to web hacking. SQL injection is one of type of web hacking that require nothing but port 80 and it might just work even if the admin is patch-happy. It attacks on the web application (like ASP, JSP, PHP, CGI, etc) itself rather than on the web server or services running in the OS.
This article does not introduce anything new, SQL injection has been widely written and used in the wild. I wrote the article because i would like to document some of users to test the server SQL injection security and i hope that it may be of some use to others. You may find a trick or two but please check out the RageZone Rulez!
SQL injection.
One of the most common problems with security in web applications is SQL injection. To begin with I will present this comic for you:
The comic clearly illustrates the problems with SQL injection. If you do not get it, do not worry, you will in just a moment.
SQL injections work by injecting SQL into the queries you have already written in your script. Often you will pass some sort of variable data to your queries; this data might be influenced by user input. In the above comment we might imagine that the school had a query that looks something like this:
view plaincopy to clipboard
Code:
1. $sql = "INSERT INTO Students (name) VALUES ('{$_POST['student_name']}')";
$sql = "INSERT INTO Students (name) VALUES ('{$_POST['student_name']}')";
view plaincopy to clipboard
Code:
1. INSERT INTO students (name) VALUES ('Robert'); DROP TABLE Students;--')
INSERT INTO students (name) VALUES ('Robert'); DROP TABLE Students;--')
(Note: PHP does not support stacking queries with all DBMSs. MySQL in particular)
As you probably know, a semi-colon ends a query and most times it is actually required, but PHP just adds it automatically if you omit it. Therefore, by closing the string and finishing the query by entering the closing parenthesis and a semi-colon we will be able to add an additional query that drops the student table. The two hyphens at the end make whatever comes after it a comment, so whatever remaining characters that might have been in the original query will simply be ignored.
It should not take too much brain power to figure out why this is a bad thing. Malicious users will basically be able to execute any kind of queries they would like to. This can be done for various purposes. It could be retrieving confidential information or destroying your data just to name a few.
3.1. Protecting your script from SQL injections
Fortunately, protecting yourself from SQL injections is rather easy. It is just a matter of calling a single function which make data safe for use in a query. How you should do this depends on which PHP extension you are using. Many people use the regular mysql extension, so let us start with that one. That particular extension has a function called mysql_real_escape_string(). Let us take a look at how that one works with a simple example that illustrates its usage:
view plaincopy to clipboard
Code:
1. <?php
2. $db = mysql_connect('localhost', 'username', 'password');
3. mysql_select_db('school', $db);
4.
5. $studentName = mysql_real_escape_string($_POST['student_name'], $db);
6.
7. $queryResult = mysql_query("INSERT INTO Students (name) VALUE ('{$studentName}')");
8.
9. if ($queryResult) {
10. echo 'Success.';
11. }
12. else {
13. echo 'Insertion failed. Please try again.';
14. }
15. ?>
<?php $db = mysql_connect('localhost', 'username', 'password'); mysql_select_db('school', $db); $studentName = mysql_real_escape_string($_POST['student_name'], $db); $queryResult = mysql_query("INSERT INTO Students (name) VALUE ('{$studentName}')"); if ($queryResult) { echo 'Success.'; } else { echo 'Insertion failed. Please try again.'; } ?>
view plaincopy to clipboard
Code:
1. <?php
2. $db = new PDO('mysql:host=localhost;dbname=school', 'username', 'password');
3.
4. $stmt = $db->prepare('INSERT INTO Students (name) VALUES (?)');
5.
6. try {
7. $stmt->execute(array($_POST['student_name']));
8. echo 'Success.';
9. }
10. catch(PDOException $e) {
11. echo 'Insertion failed. Please try again.';
12. }
13. ?>
<?php $db = new PDO('mysql:host=localhost;dbname=school', 'username', 'password'); $stmt = $db->prepare('INSERT INTO Students (name) VALUES (?)'); try { $stmt->execute(array($_POST['student_name'])); echo 'Success.'; } catch(PDOException $e) { echo 'Insertion failed. Please try again.'; } ?>
If you have many fields you need to use in your query then it might be a little difficult remembering the order of all these different question marks which act as place holders for the data. An alternate syntax is using named parameters. In our case it would look like this:
view plaincopy to clipboard
Code:
1. <?php
2. $db = new PDO('mysql:host=localhost;dbname=school', 'username', 'password');
3.
4. $stmt = $db->prepare('INSERT INTO Students (name) VALUES (:name)');
5.
6. try {
7. $stmt->execute(array('name' => $_POST['student_name']));
8. echo 'Success.';
9. }
10. catch(PDOException $e) {
11. echo 'Insertion failed. Please try again.';
12. }
13. ?>
<?php $db = new PDO('mysql:host=localhost;dbname=school', 'username', 'password'); $stmt = $db->prepare('INSERT INTO Students (name) VALUES (:name)'); try { $stmt->execute(array('name' => $_POST['student_name'])); echo 'Success.'; } catch(PDOException $e) { echo 'Insertion failed. Please try again.'; } ?>
Obviously, in our case this would not have any benefits, but as I said, if you have many parameters then you might find that more useful. There can be other reasons why using prepared statements would be useful, but I will leave that to research for yourself.
The mysqli (MySQL improved) extension has support for prepared statements as well, so if you are using that then check out its documentation to see the syntax.
The golden rule regarding this is that nothing is to be trusted and all data should be escaped.
Additionally, I mentioned earlier that users should not get information from error messages. Not only is it irrelevant, but it may also be information that may aid people with malicious purposes. You may sometimes be told that you should add or die(mysql_error()) to the end of your query calls to functions like mysql_query(). However, you should not do that. By doing that you are no longer using PHP's error and exception handling functionality and you remove the opportunity to control whether errors should be displayed or not. In my opinion the best solution would be to use PHP's exceptions. If you do not want to do that then at least do something like or trigger_error('Query failed: '. mysql_error()). By doing that you are utilizing PHP's built-in functionality and you will be able to use the methods discussed under Error Reporting. Moreover, ending script execution with die() is simply bad practice. You will not be able to give the user a proper error page and you will not be able to do any cleaning up for the rest of the script.
Source: phpfreaks.com
How do you test if it is vulnerable?
Oky i made a littel test for your sql!
How is work?
Simple!
Go to web page => Register new Account => Add account info!
BUT! BUT in e-mail add this code:
Code:
'';shutdown;--
If your web is not secured in 5---10 seconds your SQL will sleep!SQL SHOTDOWN!
Or you can do same sh*t to: web page =>Lost Password=> Add account info! in e-mail add this code:
Code:
'';shutdown;--
BEFORE:
AFTER:
Credits: hackalin , HurryPoker
How to avoid SQL Injection?
Filter out character like single quote, double quote, slash, back slash, semi colon, extended character like NULL, carry return, new line, etc, in all strings from:
- Input from users
- Parameters from URL
- Values from cookie
For numeric value, convert it to an integer before parsing it into SQL statement. Or using ISNUMERIC to make sure it is an integer.
Change "Startup and run SQL Server" using low privilege user in SQL Server Security tab.
Delete stored procedures that you are not using like:
master..Xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask
The information has been provided: HurryPoker
Last edited: