DVWA靶场Brute Force (暴力破解) 漏洞low(低),medium(中等),high(高),impossible(不可能的)所有级别通关教程及代码审计

暴力破解

暴力破解是一种尝试通过穷尽所有可能的选项来获取密码、密钥或其他安全凭证的攻击方法。它是一种简单但通常无效率的破解技术,适用于密码强度较弱的环境或当攻击者没有其他信息可供利用时。暴力破解的基本原理是依次尝试所有可能的组合,直到找到正确的答案。

low

方法1

sql注入万能密码,输入admin' or '1'=1

方法2

随意输入,然后抓包

发送到爆破模块,添加变量并选择集束炸弹模式

在pyload设置里设置字典攻击,然后开始攻击即可

筛选长度查看,攻击成功

源码审计

php 复制代码
<?php

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

	// Get password
	$pass = $_GET[ 'password' ];
	$pass = md5( $pass );                      //明文md5算法不安全

	// Check the database
	$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";    //此处直接将用户输入的用户名和密码嵌入到 SQL 查询中,容易受到 SQL 注入攻击。攻击者可以通过输入特定的恶意字符串来操作数据库
	$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
		$html .= "<p>Welcome to the password protected area {$user}</p>";
		$html .= "<img src=\"{$avatar}\" />";
	}
	else {
		// Login failed
		$html .= "<pre><br />Username and/or password incorrect.</pre>";
	}

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

?>

medium

随意输入抓包并发送到爆破模块

添加变量选择集束炸弹模式攻击

pyload模块设置字典并攻击

攻击速度会比较慢,因为源码设置了每次登录后需要2秒才能再次登录,爆破成功

源码审计

php 复制代码
<?php

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

	// Sanitise password input
	$pass = $_GET[ 'password' ];
	$pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
	$pass = md5( $pass );                  //md5算法不安全

	// Check the database
	$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";    //代码使用 mysqli_real_escape_string 函数对用户输入进行清理,但仍然存在 SQL 注入的风险,因为 SQL 查询是通过字符串拼接的。
	$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
		$html .= "<p>Welcome to the password protected area {$user}</p>";
		$html .= "<img src=\"{$avatar}\" />";
	}
	else {
		// Login failed
		sleep( 2 );
		$html .= "<pre><br />Username and/or password incorrect.</pre>";
	}

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

?>

high

随意输入然后抓包,可以看到这里设置了token,token相当于一个房门的钥匙,没有它即使有账号密码也无法登录

选择交叉攻击,并且token也要设置变量

在设置里添加token,选中并添加

重定向选中总是

资源池设置最大并发请求为1,防止还没使用token就被刷掉

在设置里,攻击结果这取消勾选此选项

回到浏览器,刷新页面后找到token,复制下来

选中递归提取,并把刚复制的token复制进去

设置好字典后就可以攻击了

攻击成功

源码审计

php 复制代码
<?php

if( isset( $_GET[ 'Login' ] ) ) {
    // 检查 Anti-CSRF 令牌
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );  // 增加了一个 token 检测

    // 清理用户名输入
    $user = $_GET[ 'username' ];
    $user = stripslashes( $user );  // 去除字符串中的反斜杠(\)
    $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] 修复 mysql_escape_string() 调用!此代码无法工作。", E_USER_ERROR)) ? "" : ""));
    // 对字符串中的特殊字符(\x00,\n,\r,\',\",\x1a)进行转义

    // 清理密码输入
    $pass = $_GET[ 'password' ];
    $pass = stripslashes( $pass );
    $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] 修复 mysql_escape_string() 调用!此代码无法工作。", E_USER_ERROR)) ? "" : ""));
    $pass = md5( $pass );  // 将密码进行 MD5 哈希处理

    // 检查数据库
    $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 ) {
        // 获取用户详情
        $row    = mysqli_fetch_assoc( $result );
        $avatar = $row["avatar"];

        // 登录成功
        $html .= "<p>欢迎来到受密码保护的区域 {$user}</p>";
        $html .= "<img src=\"{$avatar}\" />";
    }
    else {
        // 登录失败
        sleep( rand( 0, 3 ) );  // 随机暂停 0 到 3 秒
        $html .= "<pre><br />用户名和/或密码不正确。</pre>";
    }

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

// 生成 Anti-CSRF 令牌
generateSessionToken();

?>

impossible

这是最高的难度,其中每次登录都由GET提交方式改为POST提交方式,同样加了token校验机制,还有就是他限制的登录的次数,如果登录失败3次,账户就会被锁定,需要等待15,然后才能重新尝试。

源码审计

php 复制代码
<?php

if( isset( $_POST[ 'Login' ] ) && isset ($_POST['username']) && isset ($_POST['password']) ) {
    // 检查 Anti-CSRF 令牌
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // 清理用户名输入
    $user = $_POST[ 'username' ];
    $user = stripslashes( $user ); // 去除字符串中的反斜杠(\)
    $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] 修复 mysql_escape_string() 调用!此代码无法工作。", E_USER_ERROR)) ? "" : ""));

    // 清理密码输入
    $pass = $_POST[ 'password' ];
    $pass = stripslashes( $pass );
    $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] 修复 mysql_escape_string() 调用!此代码无法工作。", E_USER_ERROR)) ? "" : ""));
    $pass = md5( $pass ); // 将密码进行 MD5 哈希处理

    // 默认值
    $total_failed_login = 3; // 允许失败登录的最大次数
    $lockout_time       = 15; // 锁定时间(分钟)
    $account_locked     = false; // 账户是否被锁定

    // 检查数据库(检查用户信息)
    $data = $db->prepare( 'SELECT failed_login, last_login FROM users WHERE user = (:user) LIMIT 1;' );
    $data->bindParam( ':user', $user, PDO::PARAM_STR );
    $data->execute();
    $row = $data->fetch();

    // 检查用户是否被锁定
    if( ( $data->rowCount() == 1 ) && ( $row[ 'failed_login' ] >= $total_failed_login ) ) {
        // 用户被锁定
        //$html .= "<pre><br />此账户因登录错误过多而被锁定。</pre>";

        // 计算用户何时可以再次登录
        $last_login = strtotime( $row[ 'last_login' ] );
        $timeout    = $last_login + ($lockout_time * 60);
        $timenow    = time();

        /*
        print "最后一次登录时间是: " . date ("h:i:s", $last_login) . "<br />";
        print "当前时间是: " . date ("h:i:s", $timenow) . "<br />";
        print "超时时间是: " . date ("h:i:s", $timeout) . "<br />";
        */

        // 检查是否经过足够的时间,如果没有,则锁定账户
        if( $timenow < $timeout ) {
            $account_locked = true;
            // print "账户已锁定<br />";
        }
    }

    // 检查数据库(如果用户名与密码匹配)
    $data = $db->prepare( 'SELECT * FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
    $data->bindParam( ':user', $user, PDO::PARAM_STR);
    $data->bindParam( ':password', $pass, PDO::PARAM_STR );
    $data->execute();
    $row = $data->fetch();

    // 如果登录有效
    if( ( $data->rowCount() == 1 ) && ( $account_locked == false ) ) {
        // 获取用户详情
        $avatar       = $row[ 'avatar' ];
        $failed_login = $row[ 'failed_login' ];
        $last_login   = $row[ 'last_login' ];

        // 登录成功
        $html .= "<p>欢迎来到受密码保护的区域 <em>{$user}</em></p>";
        $html .= "<img src=\"{$avatar}\" />";

        // 自上次登录以来,账户是否被锁定?
        if( $failed_login >= $total_failed_login ) {
            $html .= "<p><em>警告</em>: 可能有人正在暴力破解您的账户。</p>";
            $html .= "<p>登录尝试次数: <em>{$failed_login}</em>。<br />上一次登录尝试是在: <em>{$last_login}</em>.</p>";
        }

        // 重置错误登录计数
        $data = $db->prepare( 'UPDATE users SET failed_login = "0" WHERE user = (:user) LIMIT 1;' );
        $data->bindParam( ':user', $user, PDO::PARAM_STR );
        $data->execute();
    } else {
        // 登录失败
        sleep( rand( 2, 4 ) ); // 随机暂停2到4秒

        // 给用户一些反馈
        $html .= "<pre><br />用户名和/或密码不正确.<br /><br/>或者,账户因登录失败次数过多而被锁定.<br />如果是这种情况,<em>请在 {$lockout_time} 分钟后再试</em>.</pre>";

        // 更新错误登录计数
        $data = $db->prepare( 'UPDATE users SET failed_login = (failed_login + 1) WHERE user = (:user) LIMIT 1;' );
        $data->bindParam( ':user', $user, PDO::PARAM_STR );
        $data->execute();
    }

    // 设置最后登录时间
    $data = $db->prepare( 'UPDATE users SET last_login = now() WHERE user = (:user) LIMIT 1;' );
    $data->bindParam( ':user', $user, PDO::PARAM_STR );
    $data->execute();
}

// 生成 Anti-CSRF 令牌
generateSessionToken();
?>

设置了防爆破模式,同时采用了更为安全的PDO(PHP Data Object)机制防御sql注入,这是因为不能使用PDO扩展本身执行任何数据库操作,而sql注入的关键就是通过破坏sql语句结构执行恶意的sql命令。

相关推荐
SRC_BLUE_1724 分钟前
攻防世界 - Misc - Level 1 | Banmabanma
网络安全·ctf
开源网安5 小时前
开源网安携手重庆人文科技学院开展软件安全实训,赋能新时代西部大开发
安全·网络安全·软件安全·培训
轨迹H9 小时前
DVWA靶场Open HTTP Redirect (重定向) 漏洞所有级别通关教程及源码审计
网络协议·渗透测试·dvwa·重定向·web漏洞
XLYcmy10 小时前
分布式练手:Client
c++·windows·分布式·网络安全·操作系统·c·实验源码
XLYcmy13 小时前
分布式练手:Server
c++·windows·分布式·网络安全·操作系统·c·实验源码
ccc_9wy15 小时前
HackMyVM-Again靶机的测试报告
网络安全·php代码审计·hackmyvm靶场·again靶机·capabilities提权·修改linux文件权限·setcap
xcLeigh16 小时前
网络安全 | 信息安全管理体系(ISMS)认证与实施
网络安全·认证·管理体系
网络安全筑盾者-燕子18 小时前
【入门级】零基础小白入门挖漏洞看——漏洞扫描工具大全
网络·计算机网络·网络安全·漏洞·挖漏洞·漏洞工具
H轨迹H20 小时前
DVWA靶场Insecure CAPTCHA(不安全验证)漏洞所有级别通关教程及源码审计
网络安全·渗透测试·dvwa·web漏洞