DVWA靶场-暴力破解

DVWA是一个适合新手锻炼的靶机,是由PHP/MySQL组成的 Web应用程序,帮助大家了解web应用的攻击手段

DVWA大致能分成以下几个模块,包含了OWASP Top 10大主流漏洞环境。

Brute Force——暴力破解
Command Injection——命令注入
CSRF——跨站请求伪造
File Inclusion——文件包含
File Upload——文件上传漏洞
Insecure CAPTCHA——不安全的验证
SQL Injection——sql注入
SQL Injection(Blind)——sql注入(盲注)
Weak Session IDs——不安全的SessionID
XSS(DOM)——DOM型XSS  
XSS(Reflected)——反射型XSS
XSS(Stored)——存储型XSS
CSP Bypass ——绕过内容安全策略
JavaScript——JS攻击

本文所用dvwa版本为2.3

GitHub - digininja/DVWA: Damn Vulnerable Web Application (DVWA)

可以自行通过phpstudy搭建以供练习

DVWA Security分为四个等级,low,medium,high,impossible,不同的安全等级对应了不同的漏洞等级。
1.low-最低安全等级,无任何安全措施,通过简单毫无安全性的编码展示了安全漏洞。
2.medium-中等安全等级,有安全措施的保护,但是安全性并不强。
3.high-高等安全等级,有安全措施保护,是中等安全等级的加深,这个等级下的安全漏洞可能不允许相同程度的攻击。
4.impossible-最高(不可能)安全等级,存在相当强的安全保护措施,这个级别应能防止所有的漏洞,主要用于比较不同等级下的源代码。

开此篇文章的主要目的是为了对代码进行分析,查看其应对攻击的方法及绕过手法

进入暴力破解的界面,有点基础的都知道,在bp中通过字典,导入用户名和密码进行爆破,这样的操作大家见多了,再写没啥意思,想看的可以去pikachu靶场的暴力破解去了解具体操作,本文主要结合代码进行分析

pikachu靶场-暴力破解-CSDN博客

low等级
<?phpif( isset( $_GET[ 'Login' ] ) ) {    // Get username$user = $_GET[ 'username' ];    //通过get方式获取username// Get password$pass = $_GET[ 'password' ];    //通过get方式获取password$pass = md5( $pass );            //收到密码后进行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 ) {//mysqli_num_rows()函数是一个用于获取查询结果中行数的mysqli扩展函数。它接受一个查询结果对象作为参数,并返回该结果集中的行数。通常用于检查查询结果是否包含了符合条件的记录,以便在代码中进行相应的处理。// 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);
}?>

以上是一个简单的PHP登录验证功能。当用户提交登录表单时,通过GET方法获取用户名和密码,然后将密码进行MD5加密。接着查询数据库,检查用户名和加密后的密码是否匹配数据库中的记录。如果匹配成功,则显示用户的欢迎信息和头像;如果匹配失败,则显示错误信息。

无任何防护,直接进行暴力破解即可

medium等级
<?phpif( 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 );// 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$html .= "<p>Welcome to the password protected area {$user}</p>";$html .= "<img src=\"{$avatar}\" />";}else {// Login failedsleep( 2 );$html .= "<pre><br />Username and/or password incorrect.</pre>";}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}?>

相比于low的代码,这里获取到username和password后,有一段转义的代码

	$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)) ? "" : ""));

这行代码是对用户输入的用户名进行转义处理,以防止SQL注入攻击。具体来说,它使用了mysqli_real_escape_string()函数对用户输入的用户名进行转义,确保特殊字符在SQL语句中不会被误解为SQL语句的一部分,从而保护数据库安全。

加了这个转义只是对sql注入进行防范,对暴力破解还是没有起到效果

high等级
<?phpif( isset( $_GET[ 'Login' ] ) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );// Sanitise username input$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] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Sanitise password input$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] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));$pass = md5( $pass );// Check 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$html .= "<p>Welcome to the password protected area {$user}</p>";$html .= "<img src=\"{$avatar}\" />";}else {// Login failedsleep( rand( 0, 3 ) );$html .= "<pre><br />Username and/or password incorrect.</pre>";}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}// Generate Anti-CSRF token
generateSessionToken();?>

这一等级开始,登录设置了token

选中这个checktoken函数,跳转到这个函数

// Token functions --
function checkToken( $user_token, $session_token, $returnURL ) {  # Validate the given (CSRF) tokenglobal $_DVWA;if (in_array("disable_authentication", $_DVWA) && $_DVWA['disable_authentication']) {return true;}if( $user_token !== $session_token || !isset( $session_token ) ) {dvwaMessagePush( 'CSRF token is incorrect' );dvwaRedirect( $returnURL );}
}

跟进到checkToken方法,设置了三个参数,如果user_token不等于session_token或者session_token为空,调用dvwaRedirect方法。

function dvwaRedirect( $pLocation ) {session_commit();header( "Location: {$pLocation}" );exit;
}

这段代码定义了一个名为dvwaRedirect()的函数,用于实现页面重定向的功能。函数接受一个参数$pLocation,即要重定向到的目标位置。

在函数内部,首先调用session_commit()函数来提交并保存当前会话的所有数据。然后通过header()函数设置HTTP响应头,将浏览器重定向到指定的目标位置。最后使用exit函数来终止脚本的执行,确保页面重定向的立即生效。

这个函数通常用于在应用程序中需要进行页面跳转的情况,如登录成功后跳转到用户首页,或者在某些条件下需要跳转到其他页面。通过调用这个函数,可以实现简单的页面重定向功能。

可以看到这个提交界面多了一串user_token,并且每次刷新都重新生成,pikachu靶场的那篇文章有演示在前端发现token怎么进行爆破操作

从medium等级开始,登录失败就会延时,提高了暴力破解的成本

impossiable等级
<?phpif( isset( $_POST[ 'Login' ] ) && isset ($_POST['username']) && isset ($_POST['password']) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );// Sanitise username input$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] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Sanitise password input$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] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));$pass = md5( $pass );// Default values$total_failed_login = 3;$lockout_time       = 15;$account_locked     = false;// Check the database (Check user information)$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();// Check to see if the user has been locked out.if( ( $data->rowCount() == 1 ) && ( $row[ 'failed_login' ] >= $total_failed_login ) )  {// User locked out.  Note, using this method would allow for user enumeration!//$html .= "<pre><br />This account has been locked due to too many incorrect logins.</pre>";// Calculate when the user would be allowed to login again$last_login = strtotime( $row[ 'last_login' ] );$timeout    = $last_login + ($lockout_time * 60);$timenow    = time();/*print "The last login was: " . date ("h:i:s", $last_login) . "<br />";print "The timenow is: " . date ("h:i:s", $timenow) . "<br />";print "The timeout is: " . date ("h:i:s", $timeout) . "<br />";*/// Check to see if enough time has passed, if it hasn't locked the accountif( $timenow < $timeout ) {$account_locked = true;// print "The account is locked<br />";}}// Check the database (if username matches the password)$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 its a valid login...if( ( $data->rowCount() == 1 ) && ( $account_locked == false ) ) {// Get users details$avatar       = $row[ 'avatar' ];$failed_login = $row[ 'failed_login' ];$last_login   = $row[ 'last_login' ];// Login successful$html .= "<p>Welcome to the password protected area <em>{$user}</em></p>";$html .= "<img src=\"{$avatar}\" />";// Had the account been locked out since last login?if( $failed_login >= $total_failed_login ) {$html .= "<p><em>Warning</em>: Someone might of been brute forcing your account.</p>";$html .= "<p>Number of login attempts: <em>{$failed_login}</em>.<br />Last login attempt was at: <em>{$last_login}</em>.</p>";}// Reset bad login count$data = $db->prepare( 'UPDATE users SET failed_login = "0" WHERE user = (:user) LIMIT 1;' );$data->bindParam( ':user', $user, PDO::PARAM_STR );$data->execute();} else {// Login failedsleep( rand( 2, 4 ) );// Give the user some feedback$html .= "<pre><br />Username and/or password incorrect.<br /><br/>Alternative, the account has been locked because of too many failed logins.<br />If this is the case, <em>please try again in {$lockout_time} minutes</em>.</pre>";// Update bad login count$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();}// Set the last login time$data = $db->prepare( 'UPDATE users SET last_login = now() WHERE user = (:user) LIMIT 1;' );$data->bindParam( ':user', $user, PDO::PARAM_STR );$data->execute();
}// Generate Anti-CSRF token
generateSessionToken();?>

这是最高难度的代码,它主要采取了以下几种措施来防止暴力破解

POST方式获取用户名密码

设置token

对sql语句进行转义

PDO预编译

设置登录次数,超过次数进行锁定

登录失败后延时

 一般来说,这种情况进行爆破是不可能的了,或者说成本过高

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/741220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SublimeText4 安装

Sublime Text 可以编写html&#xff0c;css&#xff0c;js&#xff0c;php等等&#xff0c;是一个轻量、简洁、高效、跨平台的编辑器。 图1&#xff1a;SublimeText官网 Sublime Text具有漂亮的用户界面和强大的功能&#xff0c;例如代码缩略图&#xff0c;Python的插件&#…

Java的编程之旅41——字符流

目录 1.字符流的简介 2.字符的编码与解码 3.字符流读写操作 1.字符流写入 2.字符流复制文件 4.FileWriter&FileReader 5.缓冲区高效读写 6.序列化与反序列化 1.字符流的简介 在Java中&#xff0c;字符流是用于处理字符数据的输入输出流。它是以字符为单位进行处理&a…

读取txt文件并统计每行最长的单词以及长度

读取txt文件并统计每行最长的单词以及长度 题目 在 D:\\documant.txt 文本中,文件中有若干行英文文本,每行英文文本中有若干个单词&#xff0c;每个单词不会跨行出现每行至多包含100个字符,要求编写一个程序,处理文件,分析各行中的单词,找到每行中的最长单词&#xff0c;分别…

群晖docker安装sql server

安装步骤 开启群晖 SSH&#xff0c;通过 SSH 工具连接到群晖&#xff0c;运行下面的命令拉取mssql 2019 镜像 sudo docker pull mcr.microsoft.com/mssql/server:2019-latest然后在 docker 中就可以看到该镜像&#xff1a; 在群晖 docker 共享文件夹中创建 mssql2009 文件夹 …

ABAP - cl_gui_alv_grid cl_salv_table的各种处理

这篇文章主要是记录一下cl_gui_alv_grid 和 cl_salv_table 两种方式的ALV的字段&#xff0c;事件等的处理 举例&#xff0c;下面这个是用一个screen&#xff0c;显示2个ALV&#xff1b;上面这一个是用alv grid的&#xff1b;下面那一个是用salv去实现的 alv grid 主要涉及&am…

神舟通用-神通MPP

1、国产MPP 神通MPP是以多年大型通用数据库领域的研发实力为基础&#xff0c;集深厚的航天信息化建设经验&#xff0c;集成多项先进技术&#xff0c;为满足航天、政府、金融、电信等行业的海量数据分析统计应用需求而打造的分布式数据库软件&#xff0c;具有负载衡、在线扩展、…

基于ssm的志愿者招募系统的设计与实现(程序+文档+数据库)

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一、研究背景…

nginx有几种启动方式

Nginx 通常可以以两种主要的方式启动&#xff1a;作为前台进程运行或作为守护进程&#xff08;后台&#xff09;运行。 前台运行&#xff1a; 当Nginx以前台模式运行时&#xff0c;它会在命令行保持活动状态&#xff0c;所有的日志输出都会直接显示在命令行上。这种模式通常用于…

Redis底层数据结构之List

文章目录 1. Redis 6的list源码分析1. Redis 7的list源码分析 1. Redis 6的list源码分析 首先我们查看一下redis 6关于list的相关配置&#xff1a; config get list*可以看见redis 6的quicklist底层使用的数据结构是ziplist list-compress-depth&#xff1a;表示一个quicklis…

【力扣hot100】刷题笔记Day25

前言 这几天搞工作处理数据真是类似我也&#xff0c;还被老板打电话push压力有点大的&#xff0c;还好搞的差不多了&#xff0c;明天再汇报&#xff0c;赶紧偷闲再刷几道题&#xff08;可恶&#xff0c;被打破连更记录了&#xff09;这几天刷的是动态规划&#xff0c;由于很成…

Node携手MongoDB探险旅行⛏️

Node携手MongoDB探险旅行⛏️ 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2; 文章简单学习总结&#xff1a;如有错误 大佬 &#x1f449;点. 本篇不适合纯新手&#xff0c;因为本人已经使用很多数据库&#xff0c;很多数据库概念…就不会进行解释&#xff…

presto / trino plugin(自定义UDF函数)开发指南

方案1:自定义udf插件开发 1. Presto插件机制 presto不能像hive那样配置自定义的udf,而是采用插件机制实现。Presto 的插件(Plugin)机制,是 Presto 能够整合多种数据源的核心。通过实现不同的 Plugin,Presto 允许用户在不同类型的数据源之间进行 JOIN 等计算。Presto 内部的…

10、设计模式之外观模式(Facade)

一、什么是外观模式 这个大家一定是经常使用的&#xff0c;外观模式&#xff08;门面模式&#xff09;是一种结构型设计模式。它提供一个统一的接口&#xff0c;用于访问子系统中的一组接口&#xff0c;隐藏了系统的复杂性。最简单的应用就是&#xff0c;当controller层的逻辑处…

C#实现二分查找算法

C#实现二分查找算法 以下是一个使用 C# 实现的二分查找算法示例&#xff1a; using System;class Program {static int BinarySearch(int[] arr, int target){int low 0;int high arr.Length - 1;while (low < high){int mid (low high) / 2;// 如果目标值等于中间元素…

doris安装(docker方式)

背景 doris有两个进程 fe,处理用户请求,查询,元数据管理,节点管理be,数据存储,查询计划执行 架构图如下: 参考:https://doris.apache.org/zh-CN/docs/get-starting/what-is-apache-doris 1、定义docker-compose文件 version: 3 services:docker-fe:image: "apac…

MySQL数据库自动备份(Linux操作系统)

方式一 参考&#xff1a;https://blog.csdn.net/qq_48157004/article/details/126683610?spm1001.2014.3001.5506 1.MySQL备份脚本 在/home/backups/下建立.sh文件&#xff0c;文件名称 mysql_backup.sh ,内容如下 #!/bin/bash #备份路径 BACKUP/home/backups/mysqlBackup…

参考线平滑 - FemPosDeviation算法

FemPosDeviation参考线平滑方法是离散点平滑方法 参考文章&#xff1a; &#xff08;1&#xff09;参考线平滑-FemPosDeviation-OSQP &#xff08;2&#xff09;Planning基础库——散点曲线平滑 &#xff08;3&#xff09;参考线平滑-FemPosDeviation-SQP &#xff08;4&#x…

ICCV 2023 | NeRF-Det

NeRF-Det: Learning Geometry-Aware Volumetric Representation for Multi-View 3D Object Detection 介绍 本文介绍了一种新颖的方法&#xff0c;用于仅使用RGB图像作为输入进行室内3D目标检测。作者提出了利用神经辐射场&#xff08;NeRF&#xff09;来显式估计3D几何形状&…

OCP Java17 SE Developers 复习题09

答案 A, E. For the first scenario, the answer needs to implement List because the scenario allows duplicates, narrowing it down to options A and D. Option A is a better answer than option D because LinkedList is both a List and a Queue, and you just nee…

代码随想录 贪心算法-难度题目-其他题目

目录 53.最大子数组和 134.加油站 968.监控二叉树 53.最大子数组和 53. 最大子数组和 中等 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个…