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数据库实现批量表分区完整示例

《MySQL数据库实现批量表分区完整示例》通俗地讲表分区是将一大表,根据条件分割成若干个小表,:本文主要介绍MySQL数据库实现批量表分区的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考... 目录一、表分区条件二、常规表和分区表的区别三、表分区的创建四、将既有表转换分区表脚本五、批量转换表为分区

宝塔安装的MySQL无法连接的情况及解决方案

《宝塔安装的MySQL无法连接的情况及解决方案》宝塔面板是一款流行的服务器管理工具,其中集成的MySQL数据库有时会出现连接问题,本文详细介绍两种最常见的MySQL连接错误:“1130-Hostisn... 目录一、错误 1130:Host ‘xxx.xxx.xxx.xxx’ is not allowed

sql语句字段截取方法

《sql语句字段截取方法》在MySQL中,使用SUBSTRING函数可以实现字段截取,下面给大家分享sql语句字段截取方法,感兴趣的朋友一起看看吧... 目录sql语句字段截取sql 截取表中指定字段sql语句字段截取1、在mysql中,使用SUBSTRING函数可以实现字段截取。例如,要截取一个字符串字

SQL Server身份验证模式步骤和示例代码

《SQLServer身份验证模式步骤和示例代码》SQLServer是一个广泛使用的关系数据库管理系统,通常使用两种身份验证模式:Windows身份验证和SQLServer身份验证,本文将详细介绍身份... 目录身份验证方式的概念更改身份验证方式的步骤方法一:使用SQL Server Management S

MySQL 字符串截取函数及用法详解

《MySQL字符串截取函数及用法详解》在MySQL中,字符串截取是常见的操作,主要用于从字符串中提取特定部分,MySQL提供了多种函数来实现这一功能,包括LEFT()、RIGHT()、SUBST... 目录mysql 字符串截取函数详解RIGHT(str, length):从右侧截取指定长度的字符SUBST

MySQL中的事务隔离级别详解

《MySQL中的事务隔离级别详解》在MySQL中,事务(Transaction)是一个执行单元,它要么完全执行,要么完全回滚,以保证数据的完整性和一致性,下面给大家介绍MySQL中的事务隔离级别详解,... 目录一、事务并发问题二、mysql 事务隔离级别1. READ UNCOMMITTED(读未提交)2

MySQL Workbench工具导出导入数据库方式

《MySQLWorkbench工具导出导入数据库方式》:本文主要介绍MySQLWorkbench工具导出导入数据库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录mysql Workbench工具导出导入数据库第一步 www.chinasem.cn数据库导出第二步

一文详解如何查看本地MySQL的安装路径

《一文详解如何查看本地MySQL的安装路径》本地安装MySQL对于初学者或者开发人员来说是一项基础技能,但在安装过程中可能会遇到各种问题,:本文主要介绍如何查看本地MySQL安装路径的相关资料,需... 目录1. 如何查看本地mysql的安装路径1.1. 方法1:通过查询本地服务1.2. 方法2:通过MyS

Mysql数据库中数据的操作CRUD详解

《Mysql数据库中数据的操作CRUD详解》:本文主要介绍Mysql数据库中数据的操作(CRUD),详细描述对Mysql数据库中数据的操作(CRUD),包括插入、修改、删除数据,还有查询数据,包括... 目录一、插入数据(insert)1.插入数据的语法2.注意事项二、修改数据(update)1.语法2.有

SQL Server中的PIVOT与UNPIVOT用法具体示例详解

《SQLServer中的PIVOT与UNPIVOT用法具体示例详解》这篇文章主要给大家介绍了关于SQLServer中的PIVOT与UNPIVOT用法的具体示例,SQLServer中PIVOT和U... 目录引言一、PIVOT:将行转换为列核心作用语法结构实战示例二、UNPIVOT:将列编程转换为行核心作用语