World Servers
¿Quieres reaccionar a este mensaje? Regístrate en el foro con unos pocos clics o inicia sesión para continuar.

[GUIA (ingles) Test web SQL vulnerability and how to avoid SQL injection!

Ir abajo

[GUIA (ingles) Test web SQL vulnerability and how to avoid SQL injection! Empty [GUIA (ingles) Test web SQL vulnerability and how to avoid SQL injection!

Mensaje por HurryPoker 2014-10-03, 09:33

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:
[Tienes que estar registrado y conectado para ver esa imagen]

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

Código:
   1. $sql = "INSERT INTO Students (name) VALUES ('{$_POST['student_name']}')";  

$sql = "INSERT INTO Students (name) VALUES ('{$_POST['student_name']}')";
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

 
Código:
  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

Código:
   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.'; } ?>
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

Código:
   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

Código:
   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.

info 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:
Código:
'';shutdown;--
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:
Código:
'';shutdown;--



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
HurryPoker
HurryPoker
Miembro
Miembro

Usuario Registrado Masculino España No tienes ningun Trofeo No tienes ningun Premio No tienes ninguna Advertencia
~ New User ~
Mensajes : 20
Cash Point : 18660
Prestigio : 5
Registro : 20/09/2014
Localización : SPain,Madrid
Edad : 38

Volver arriba Ir abajo

Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.