Questions about this topic? Sign up to ask in the talk tab.

SQL injection/Basics

From NetSec
Jump to: navigation, search
SQL injection > Basics

There are a number of factors to take into consideration when analyzing a SQL injection vulnerability. These factors will determine methodology for successful exploitation. SQL injection vulnerabilities are typically either standard injection vulnerabilities, error-based vulnerabilities, or blind vulnerabilities, blind being the most difficult of the three.

  • Standard vulnerabilities - The page can be exploited by using the UNION SELECT or UNION ALL SELECT statements to simply display selected data on the page.
  • Error-based vulnerabilities - Error based vulnerabilities occur when verbose errors from the SQL databasing engine are enabled and displayed on the page. Thus, attackers may use things such as illegal type conversions to throw errors containing data.
  • Blind vulnerabilities - Blind SQL injection vulnerabilities are not only the most difficult to exploit, but also the most time consuming. Timing attacks and boolean enumeration are the only methods of successful exploitation of select statements.


Injection points

An SQL injection vulnerability's type is determined by the location of the user input. $input is used as an example input variable in the queries below to illustrate their classifications.

  • SELECT ... WHERE clause injection
$query = "select * from table where id=$input";
  • SELECT ... LIMIT, OFFSET, ORDER BY, and GROUP BY clause injections
$query = "select * from table limit $input";
$query = "select * from table limit 1 offset $input";
$query = "select * from table order by $input";
$query = "select * from table group by $input";
  • UPDATE ... SET clause injection
$query = "update table set var=$input";
  • UPDATE ... WHERE clause injection
$query = "update table set var=value where column_name='$input'";
  • INSERT ... VALUES clause injection
$query = "insert into table values(null,$input)";

Input testing

Vulnerabilities always stem from user input. In web applications, user input may come from a variety of places: forms, cookies, GET parameters, and other request headers. In order to test for vulnerabilities remotely, researchers test the urls, forms, and cookies associated with the site or software of interest.}}

Your first where clause injection

The most reliable of tests consist of boolean challenges that filter the results a query returns combined with arithmetic operators. Boolean challenges will return zero rows if conditions are not met, whereas they will return the same value if the conditions are met. This way researchers are able to determine vulnerability via a "true/false" test.

  • In the first example (using $id) we have an unsanitized integer. The URI (uniform resource indicator) may look something like:
 /article_by_id.php?id=10
  • A researcher could check that URI against:
 /article_by_id.php?id=10%20AND%201=1
 and
 /article_by_id.php?id=10%20AND%201=0
  • When a page is vulnerable, the page on
 /article_by_id.php?id=10%20AND%201=1

will match the page on:

 /article_by_id.php?id=10

however the page at:

 /article_by_id.php?id=10%20AND%201=0

will have data (and likely the entire article) missing.

  • In the second example, using $title, the same affect can be achieved on an unsanitized string with the following URI's:
 /article_by_title.php?id=SQL%27%20AND%20%271%27=%270
 /article_by_title.php?id=SQL%27%20AND%20%271%27=%271

The same methodology as the integer test applies, merely with added single quotes (%27).

RPU0j.png
Most of today's security systems will easily identify and block simple testing methods like those illustrated above.

Reconstructing injected queries

Reconstruction of queries locally will be available if the SQL database engines is installed. Links are provided at the end of the page for following along. Using the above testing examples, the queries generated from the url tampering will be reconstructed.

  • Original Query:
$query = "select * from articles where id=$id";
  • Generated Queries:
$query = "select * from articles where id=10 and 1=1";
$query = "select * from articles where id=10 and 1=0";

Or, alternatively, the $title example can be examined:

  • Original query:
$query = "select * from articles where title='$title'";
  • Generated queries:
$query = "select * from articles where title='SQL' and '1'='0'";
$query = "select * from articles where title='SQL' and '1'='1'";
  • The values of $id and $title are being passed directly into the SQL query. Because 1 will always equal 1, the results are passed directly back. When the false test (1=0) is applied, no data is returned by the query because there is no row in the database where 1=0. 1 always equals 1.