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双主搭建+keepalived高可用的实现

《MySQL双主搭建+keepalived高可用的实现》本文主要介绍了MySQL双主搭建+keepalived高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、测试环境准备二、主从搭建1.创建复制用户2.创建复制关系3.开启复制,确认复制是否成功4.同

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

mysql出现ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的解决方法

《mysql出现ERROR2003(HY000):Can‘tconnecttoMySQLserveron‘localhost‘(10061)的解决方法》本文主要介绍了mysql出现... 目录前言:第一步:第二步:第三步:总结:前言:当你想通过命令窗口想打开mysql时候发现提http://www.cpp

MySQL大表数据的分区与分库分表的实现

《MySQL大表数据的分区与分库分表的实现》数据库的分区和分库分表是两种常用的技术方案,本文主要介绍了MySQL大表数据的分区与分库分表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. mysql大表数据的分区1.1 什么是分区?1.2 分区的类型1.3 分区的优点1.4 分

MySQL错误代码2058和2059的解决办法

《MySQL错误代码2058和2059的解决办法》:本文主要介绍MySQL错误代码2058和2059的解决办法,2058和2059的错误码核心都是你用的客户端工具和mysql版本的密码插件不匹配,... 目录1. 前置理解2.报错现象3.解决办法(敲重点!!!)1. php前置理解2058和2059的错误

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

MySQL Workbench 安装教程(保姆级)

《MySQLWorkbench安装教程(保姆级)》MySQLWorkbench是一款强大的数据库设计和管理工具,本文主要介绍了MySQLWorkbench安装教程,文中通过图文介绍的非常详细,对大... 目录前言:详细步骤:一、检查安装的数据库版本二、在官网下载对应的mysql Workbench版本,要是

mysql数据库重置表主键id的实现

《mysql数据库重置表主键id的实现》在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,本文主要介绍了mysql数据库重置表主键id的实现,具有一定的参考价值,感兴趣的可以了... 目录关键语法演示案例在我们的开发过程中,难免在做测试的时候会生成一些杂乱无章的SQL主键数据,当我们