DVWA靶场-SQL Injection (Blind)SQL注入盲注

2024-03-20 05:36

本文主要是介绍DVWA靶场-SQL Injection (Blind)SQL注入盲注,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概念

SQL Injection(Blind),即SQL盲注;

注入:可以查看到详细内容;

盲注:目标只会回复是或不是,没有详细内容;

盲注,与一般注入的区别在于,一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示页面上获取执行结果,甚至连注入语句是否执行都无从得知,因此盲注的难度要比一般注入高。

类型

基于布尔值的盲注;

基于时间的盲注;

基于报错的盲注;

基于布尔值的盲注

基于布尔型SQL盲注即在SQL注入过程中,应用程序仅仅返回True(页面)和False(页面)。 这时,我们无法根据应用程序的返回页面得到我们需要的数据库信息。但是可以通过构造逻辑判断(比较大小)来得到我们需要的信息。 

常用函数

if()
功能:条件判断。
语法格式:if(expr1,expr2,expr3):expr1为true则返回expr2,expr1为false则返回expr3。
注:仅MySQL支持if(expr1,expr2,expr3)。

left()
功能:截取具有指定长度的字符串的左边部分。
语法格式:left(str,length),如果str或length参数为NULL,则返回NULL值。
参数说明
str:要提取子串的字符串。
length:正整数,指定将从左边返回的字符数。length为0或为负,则LEFT返回一个空字符串
length大于str字符串的长度,则leftO返回整个str字符串。

length()
功能:返回字符串的长度,以字节为单位。
语法格式:length(str)

substr()、substring()
功能:从指定的位置开始,截取字符串指定长度的子串。
语法格式:substr(str,pos)或substr(str,pos,len),substring(str,pos)substring(str,pos,len)
参数说明
str:要提取子串的字符串。
pos:提取子串的开始位置
len:指定要提取的子串的长度

ascii()、ord()
功能:返回字符串最左边字符的ASCII码值
语法格式:ascii(str),ord(str)

cast()、convert()
功能:获取一个类型的值,并产生另一个类型的值。
>语法格式:cast(value as type),convert(value,type)

 基于时间的盲注

 

基于时间的SQL盲注又称延时注入,即使用具有延时功能的函数sleep、benchmark等,通过判断这些函数是否正常执行来获取数据库中的数据

sleep()
功能:让语句延退执行一段时间,执行成功后返回0。
语法格式:sleep(N),即延退执行N秒。

benchmark()
功能:让某语句执行一定的次数,执行成功后返回0。
语法格式:benchmark(coun,texpr),即让expr执行count次
注:仅MySQL支持该函数。

 基于报错的盲注

 

基于报错的SQL盲注是通过输入特定语句使页面报错,网页中则会输出相关错误信息,从而是我们得到想要的基本信息——数据库名、版本、用户名等 

直接使用报错:' union select 1,count(*),concat('/',(select @@datadir),'/',floor(rand(0)*2))a from information_schema.columns group by a--+

利用xpath函数—extractvalue报错:' and extractvalue(1,concat(0x7e,(select database()),0x73))--+

利用xpath函数—updatexml报错:' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+

利用数据重复性报错:' union select 1,2,3 from (select name_const(version(),1),name_const(version(),1))x--+

 low等级
<?phpif( isset( $_GET[ 'Submit' ] ) ) {// Get input$id = $_GET[ 'id' ];$exists = false;switch ($_DVWA['SQLI_DB']) {case MYSQL:// Check database$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ); // Removed 'or die' to suppress mysql errors$exists = false;if ($result !== false) {try {$exists = (mysqli_num_rows( $result ) > 0);} catch(Exception $e) {$exists = false;}}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);break;case SQLITE:global $sqlite_db_connection;$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";try {$results = $sqlite_db_connection->query($query);$row = $results->fetchArray();$exists = $row !== false;} catch(Exception $e) {$exists = false;}break;}if ($exists) {// Feedback for end user$html .= '<pre>User ID exists in the database.</pre>';} else {// User wasn't found, so the page wasn't!header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );// Feedback for end user$html .= '<pre>User ID is MISSING from the database.</pre>';}}?>

当sql语句执行成功则显示以下这段话

User ID exists in the database.

当sql语句执行失败则显示以下这段话

User ID is MISSING from the database. 

通过回显可以判读是否注入成功

medium等级
<?phpif( isset( $_POST[ 'Submit' ]  ) ) {// Get input$id = $_POST[ 'id' ];$exists = false;switch ($_DVWA['SQLI_DB']) {case MYSQL:$id = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $id ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));// Check database$query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ); // Removed 'or die' to suppress mysql errors$exists = false;if ($result !== false) {try {$exists = (mysqli_num_rows( $result ) > 0); // The '@' character suppresses errors} catch(Exception $e) {$exists = false;}}break;case SQLITE:global $sqlite_db_connection;$query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";try {$results = $sqlite_db_connection->query($query);$row = $results->fetchArray();$exists = $row !== false;} catch(Exception $e) {$exists = false;}break;}if ($exists) {// Feedback for end user$html .= '<pre>User ID exists in the database.</pre>';} else {// Feedback for end user$html .= '<pre>User ID is MISSING from the database.</pre>';}
}?>

利用mysql_real_escape_string函数对特殊符号

\x00,\n,\r,\,’,”,\x1a进行转义

前端使用下拉式,控制用户输入

high等级
<?phpif( isset( $_COOKIE[ 'id' ] ) ) {// Get input$id = $_COOKIE[ 'id' ];$exists = false;switch ($_DVWA['SQLI_DB']) {case MYSQL:// Check database$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ); // Removed 'or die' to suppress mysql errors$exists = false;if ($result !== false) {// Get resultstry {$exists = (mysqli_num_rows( $result ) > 0); // The '@' character suppresses errors} catch(Exception $e) {$exists = false;}}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);break;case SQLITE:global $sqlite_db_connection;$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";try {$results = $sqlite_db_connection->query($query);$row = $results->fetchArray();$exists = $row !== false;} catch(Exception $e) {$exists = false;}break;}if ($exists) {// Feedback for end user$html .= '<pre>User ID exists in the database.</pre>';}else {// Might sleep a random amountif( rand( 0, 5 ) == 3 ) {sleep( rand( 2, 4 ) );}// User wasn't found, so the page wasn't!header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );// Feedback for end user$html .= '<pre>User ID is MISSING from the database.</pre>';}
}?>

利用cookie传递参数id,当SQL查询结果为空时,会执行函数sleep(seconds),目的是为了扰乱基于时间的盲注。

同时在 SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。但是我们可以通过#将其注释掉。

但由于服务器端执行sleep函数,会使得基于时间盲注的准确性受到影响,这里我们只能使用基于布尔的盲注。

impossible等级
<?phpif( isset( $_GET[ 'Submit' ] ) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );$exists = false;// Get input$id = $_GET[ 'id' ];// Was a number entered?if(is_numeric( $id )) {$id = intval ($id);switch ($_DVWA['SQLI_DB']) {case MYSQL:// Check the database$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );$data->bindParam( ':id', $id, PDO::PARAM_INT );$data->execute();$exists = $data->rowCount();break;case SQLITE:global $sqlite_db_connection;$stmt = $sqlite_db_connection->prepare('SELECT COUNT(first_name) AS numrows FROM users WHERE user_id = :id LIMIT 1;' );$stmt->bindValue(':id',$id,SQLITE3_INTEGER);$result = $stmt->execute();$result->finalize();if ($result !== false) {// There is no way to get the number of rows returned// This checks the number of columns (not rows) just// as a precaution, but it won't stop someone dumping// multiple rows and viewing them one at a time.$num_columns = $result->numColumns();if ($num_columns == 1) {$row = $result->fetchArray();$numrows = $row[ 'numrows' ];$exists = ($numrows == 1);}}break;}}// Get resultsif ($exists) {// Feedback for end user$html .= '<pre>User ID exists in the database.</pre>';} else {// User wasn't found, so the page wasn't!header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );// Feedback for end user$html .= '<pre>User ID is MISSING from the database.</pre>';}
}// Generate Anti-CSRF token
generateSessionToken();?>

Impossible级别的代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入;

同时只有返回的查询结果数量为1时,才会输出; 

这篇关于DVWA靶场-SQL Injection (Blind)SQL注入盲注的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/828443

相关文章

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

MySQL中的锁机制详解之全局锁,表级锁,行级锁

《MySQL中的锁机制详解之全局锁,表级锁,行级锁》MySQL锁机制通过全局、表级、行级锁控制并发,保障数据一致性与隔离性,全局锁适用于全库备份,表级锁适合读多写少场景,行级锁(InnoDB)实现高并... 目录一、锁机制基础:从并发问题到锁分类1.1 并发访问的三大问题1.2 锁的核心作用1.3 锁粒度分

MySQL数据库中ENUM的用法是什么详解

《MySQL数据库中ENUM的用法是什么详解》ENUM是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,下面:本文主要介绍MySQL数据库中ENUM的用法是什么的相关资料,文中通过代码... 目录mysql 中 ENUM 的用法一、ENUM 的定义与语法二、ENUM 的特点三、ENUM 的用法1

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

mysql中的服务器架构详解

《mysql中的服务器架构详解》:本文主要介绍mysql中的服务器架构,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、mysql服务器架构解释3、总结1、背景简单理解一下mysqphpl的服务器架构。2、mysjsql服务器架构解释mysql的架

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的

MySQL中的InnoDB单表访问过程

《MySQL中的InnoDB单表访问过程》:本文主要介绍MySQL中的InnoDB单表访问过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、访问类型【1】const【2】ref【3】ref_or_null【4】range【5】index【6】

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分