📜 ⬆️ ⬇️

SQL injection. Check, hacking, protection

SQL injection is one of the most accessible ways to hack a site.
The essence of such injections is the injection of arbitrary SQL code into the data (transmitted via GET, POST requests or Cookie values). If the site is vulnerable and performs such injections, then in fact there is an opportunity to create from the database (most often it is MySQL) anything.

How to calculate a vulnerability that allows to introduce SQL injections?


Pretty easy. For example, there is a test site test.ru. The site displays a list of news, with the possibility of a detailed view. The address of the page with a detailed description of the news is as follows: test.ru/?detail=1 . Ie, through the GET request, the detail variable passes the value 1 (which is the identifier of the entry in the news tabica).

We change the GET request to ?detail=1' or ?detail=1" Next we try to send these requests to the server, that is, we go to test.ru/?detail=1 ' or to test.ru/?detail=1 ".

If an error occurs on entering these pages, then the site is vulnerable to SQL injections.
')
An example of an error that occurs when checking a vulnerability
image

Possible SQL injections (SQL deployments)
1) The simplest is to minimize the WHERE condition to a true result for any parameter values.
2) Attach to the query results of another query. This is done through the UNION operator.
3) Comment out part of the request.

Practice. Options for hacking a site with a vulnerability to SQL injection


So, we have the already mentioned site test.ru. The database stores 4 news, 3 of which are displayed. Permission to publish news depends on the public parameter (if the parameter contains the value 1, then the news is published).

List of permitted news
image

When accessing the page test.ru/?detail=4 , which should display the fourth news, an error appears - the news was not found.
In our case, the news exists, but it is prohibited for publication.
image

But since we already checked the site for vulnerability and it gave out a database error, then we try to sort out possible variants of requests.
In the address bar, plus (+) plays the role of a space, so do not be scared

I'm testing the following options:
test.ru/?detail=4+OR+1
test.ru/?detail=4+--
test.ru/?detail=4+UNION+SELECT+ * + FROM + news + WHERE + id = 4

As a result, luck smiled and two requests (first and third) returned us a detailed description of the fourth news.
image

Parse example from the inside


A block of code answers for receiving a detailed description of the news:
$detail_id=$_GET['detail'];
$zapros="SELECT * FROM `$table_news` WHERE `public`='1' AND `id`=$detail_id ORDER BY `position` DESC";


Not only does $ detail_id get the value without any processing, so the `id` = $ detail_id construct is crooked, it’s better to stick with` id` = '$ detail_id' (that is, write the comparison value in direct apostrophes).

Looking at the request received when accessing the page through test.ru/?detail=4+OR+1

SELECT * FROM `news` WHERE `public`='1' AND `id`=4 OR 1 ORDER BY `position` DESC


it is not entirely clear why the 4th news was displayed. The fact is that the query returned all the entries from the news table, sorted in descending order from above. And so our fourth news was the very first, and it also came out as detailed. Ie just a coincidence.

Parse the request generated when accessing through test.ru/?detail=4+UNION+SELECT+*+FROM+news+WHERE+id=4 test.ru/?detail=4+UNION+SELECT+*+FROM+news+WHERE+id=4 .

Here the name of the table with the news (in our case, this news) was taken as a logical search.
So, the query SELECT * FROM `news` WHERE `public`='1' AND `id`=4 UNION SELECT * FROM news WHERE id=4 ORDER BY `position` DESC . The zero result of the first part of the request (before UNION) was joined by the result of the second part (after UNION), which returned a detailed description of the 4th news.

Protection against SQL injections (SQL implementations)


Protection against hacking comes down to the basic rule of "trust but verify." You need to check everything - numbers, strings, dates, data in special formats.

Numbers

To check a variable for a numeric value, the function is_numeric (n); is used, which returns true if the parameter n is a number, and false otherwise.
You can also not check the value for a number, but manually override the type. Here is an example that overrides the $ id value obtained from $ _GET ['id_news'] to an integer type value (as an integer):
$id=(int)$_GET['id_news'];

Strings

Most hacking through SQL occur due to the presence of quotes, apostrophes, and other special characters in the rows. For this deactivation, you need to use the addslashes ($ str); function, which returns the string $ str with an added backslash (\) before each special character. This process is called adaptation.

$a=" ' ";
echo addslashes($a); // : \'


In addition, there are two functions created specifically for the adaptation of strings used in SQL expressions.
This is mysql_escape_string ($ str); and mysql_real_escape_string ($ str) ;.

The first one does not take into account the coding of the connection with the database and can be bypassed, but the second one takes it into account and is absolutely safe. mysql_real_escape_string ($ str); returns the string $ str with a backslash added to the following characters: \x00, \n, \r, \, ', " \x1a .

Magic quotes


Magic Quotes - The effect of automatically replacing quotes with backslash (\) and quotation marks during I / O operations. In some PHP configurations, this option is enabled, but not in some. In order to avoid double-shielding of characters and screen the data in a normal way through mysql_real_escape_string ($ str);, it is necessary to remove the automatically inserted backslashes (if magic quotes are included).

Checking the inclusion of magic quotes for data obtained from GET, POST or Cooks is organized via the get_magic_quotes_gpc(); function get_magic_quotes_gpc(); (returns 1 - if magic quotes are on, 0 - if disabled).

If magic quotes are included (that is, back slashes are added) and this happens more often, they should be removed. This is done through the stripslashes ($ str) function; (returns the string $ str without backslashes for quotes and direct apostrophes).

In conclusion, I cite the code with full string adaptation for writing to the database.

if(get_magic_quotes_gpc()==1)
{
$element_title=stripslashes(trim($_POST["element_title"]));
$element_text=stripslashes(trim($_POST["element_text"]));
$element_date=stripslashes(trim($_POST["element_date"]));
}
else
{
$element_title=trim($_POST["element_title"]);
$element_text=trim($_POST["element_text"]);
$element_date=trim($_POST["element_date"]);
}

$element_title=mysql_real_escape_string($element_title);
$element_text=mysql_real_escape_string($element_text);
$element_date=mysql_real_escape_string($element_date);


The article was prepared on the basis of practical skills for the protection of web systems. The theory is a good thing, but the practice is more important and most importantly it works.

Source: https://habr.com/ru/post/130826/


All Articles