Some vulnerabilities of web resources using SQL


The note discusses the vulnerability of SQL, related to the penetration into the body of the request.

The essence of vulnerability

Consider the operation of a simple system with WEB-interface, which allows users to save also to change information about themselves. Such systems are one of the most common in the network. It can also be a guest book, also a chat room, also a photo gallery, and a postal service.

The generated query to the database is forced to have the user's login also the password entered by the user. For these fields, the database must find the corresponding entry in the table. After finishing the request, the DB displays the information about the user, which the PHP script creates in the form of HTML, also returns to the user.

Let's look at a fairly typical PHP script fragment that uses the SQL query to access the database:

<? Php
$ Result = mysql_db_query ("database", "select * from userTable where login = '$ userLogin' and password = '$ userPassword'");
While ($ row = mysql_fetch_array ($ result)) {
Echo $ row ["fullname"];
Echo $ row ["email"];
Echo $ row ["password"];
}
Mysql_free_result ($ result);
?>

As we observe, the login also the password entered by the user is contained in the variables $ userLogin also $ userPassword . The content of these variables is inserted into the query to filter out information about this user. The filter is specified using the where option of the select SQL command. In this case, the query looks like this: select * from userTable where login = '$ userLogin' and password = '$ userPassword' where userTable is the name of the table containing the required information. If the login change also contains the vanya values ​​also vasya , then the query sent by the database will take the following form: select * from userTable where login = 'vanya' and password = 'vasya' . It is clear that if there is an entry in the database where the login is vanya, then the password is vasya , until the request does not send a single line from the database, and the script will not return anything. Thus, the above system provides access to information only to a user who has an error-free password also with a login.

It would seem that such a system does not contain flaws. In the class itself, this is not the case. The logic of the programs that created the above example implies that the user-entered login also has a password that will be contained within single quotes that are hard-coded in the request body. However, let's see what happens if the password itself, entered by the user, contains a quotation mark. Let him own the value of vas'ya , while the query will look like this: select * from userTable where login = 'vanya' and password = 'vas'ya' . When executing such a request, there will certainly be an error, because the quote from the password, closed the opening quotation mark from the query, also the end of the password ya ' remained "hanging" outside the conditional expression.

And if you insert the following line as the password: 'or 1 = 1' , the query will be:: select * from userTable where login = 'vanya' and password = '' or 1 = 1 '' also does not have syntax errors . But the logical expression will be identically true, also in the objection to this query, SQL will issue the entire user database 8-).

Thus, using the apostrophe symbol, we can get into the body of the SQL query also to make sure that the test condition is true. If we are interested in a specific user vanya , then to receive information about him, it is allowed to use such a password line: 'or login =' vanya . The query becomes: select * from userTable where login = 'vanya' and password = '' or login = 'vanya' . As you understand, as a result, we will receive information about vanya .

The described vulnerability of services based on SQL is not limited to unauthorized receipt of information. Since such systems usually use MySQL, it is possible not only to modify the conditional expression in the select command, but also to go beyond this command, and also execute another database command. Because MySQL allows multiple commands in one query, separated ; , Then we can execute any of these commands by entering the following code in the password field: '; <Command> SQL> in which place as the <SQL command> is allowed to specify any valid command. So for example this code: '; Drop table 'userTable simply destroys the userTable table from the database.

Practical use of the vulnerability

Despite the simplicity, the practical use of SQL query errors is very difficult.

In this head, consider the following problems that arise when using the described vulnerability:
  • Determining the use of SQL in the system.
  • Identify the existence of a vulnerability. Elucidation of the reaction of the script to errors.
  • Define the names of fields in the table.
  • Identify the names of existing tables.

    This vulnerability is inherent in all SQL queries, regardless of the script or the program from which they are called. Yet we will consider systems based on PHP. This is due to the fact that the PHP error stream as a location (by default) is sent to the end user. While Perl or Exe applications usually do not inform the user about the nature of the errors.

    Determining the use of SQL in the system.

    When researching a particular system, you first need to find out whether it uses SQL.
    This fact can be identified either indirectly (by looking at the names of the files used, links to the tools used, etc.), or directly - by causing SQL to prove itself. If we work with PHP, then there is only one way to determine the unambiguous use of SQL - this causes an error in its execution. If an error occurs during the execution of the request, however, the PHP script is clearly not error-corrected in any way, the message about the error of PHP will be output directly to the user's page.
    How to cause an error in the execution of a SQL query depends on the specific system of the system in question. In most cases, the error is allowed to be caused by entering incorrect data into the system.

    Identify the existence of a vulnerability. Elucidation of the reaction of the script to errors.

    The most simple means of detecting the presence of a vulnerability, but also the fact of using SQL, is the following: In any field that is supposedly involved in the formation of a SQL query (for example, the Login or Password field), enter the single-quote character. We fill out the remaining fields with any correct data (or leave it empty if this is allowed by the system). After sending the form data, we look at the reaction of the system. If, as a result, the PHP script gives us the SQL error, then we can congratulate ourselves: the system uses SQL and the script does not filter the single quotation mark. That's the way the system contains the vulnerability.
    A SQL query error will then look like this on the page:

    Input form:


    As a result, a SQL query error:


    If there is no SQL error code on the page, this could mean the following:
    1) The system contains a vulnerability, but the PHP script handles errors. In this case, the system is allowed to hack, but you will have to act "touch", because we do not know at what time the syntax of SQL will be correct, but at what time it is not.
    2) The script also filters the quotation mark, so there is no error. In this case, the system does not contain any vulnerabilities.
    3) The system does not use SQL in any way.
    In the last couple of cases, it is clear that further investigation of SQL does not have any meaning.

    Define the names of fields in the table.

    In order to obtain information from the database with specific data, we need to determine the values ​​of some fields in the request (for example, to set the user's login). Still, you need to know the name of the corresponding fields. Directly to find these names there is no possibility. Therefore here it is necessary to search for the given names by a search method. These names can coincide with the names of the fields in the form sent to the server, and may also not coincide in any way. It is a good thing that the names of fields as a position are standard, and there are not so many variants of writing them. For example, the name of the field for the user name is likely to be login, either user or nick . It is similar for the password: password either pwd or pass .
    To determine the existence of a specific field, we propose a simple method: Let us want to check whether there exists a field pwd in the table. We introduce in each field of the form such a string 'pwd =' . If the pwd field exists in the table, then SQL will correctly process the request, if there is no such field, then there will be an error of SQL execution again. Thus, substituting different values ​​for field names, also examining the result of finishing the query, we can find out which fields exist in the table, but which ones do not.

    Identify the names of existing tables.

    Similar to the method of finding the names of fields in tables, it is also possible to look for the names of existing tables in the database. Let's see if there is an adminList table in the database. To do this, we enter in the form field the form '; select * from adminList . If, as a result of the error, SQL does not start at all, then the adminList table exists. For the correctness of this test, it is necessary to enter this line in the field that appears in the final SQL query. This is necessary to ensure that the syntax error is not caused due to the remaining "tail" of the original query, which will be present later select * from adminList . Note that if the form for the query is owned by a pair of Login fields also Password , then most likely the password field will appear in the query last.

    PS

    Using this vulnerability, the site http://www.bigmir.net (more precisely its photo gallery also chat) was hacked. We wrote about the vulnerability of the site owners. The hole was fixed. But now we once again checked the registration form of the chat. Plus found all that blissfully vulnerable 8-).