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中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

mysql重置root密码的完整步骤(适用于5.7和8.0)

《mysql重置root密码的完整步骤(适用于5.7和8.0)》:本文主要介绍mysql重置root密码的完整步骤,文中描述了如何停止MySQL服务、以管理员身份打开命令行、替换配置文件路径、修改... 目录第一步:先停止mysql服务,一定要停止!方式一:通过命令行关闭mysql服务方式二:通过服务项关闭

SQL Server数据库磁盘满了的解决办法

《SQLServer数据库磁盘满了的解决办法》系统再正常运行,我还在操作中,突然发现接口报错,后续所有接口都报错了,一查日志发现说是数据库磁盘满了,所以本文记录了SQLServer数据库磁盘满了的解... 目录问题解决方法删除数据库日志设置数据库日志大小问题今http://www.chinasem.cn天发

mysql主从及遇到的问题解决

《mysql主从及遇到的问题解决》本文详细介绍了如何使用Docker配置MySQL主从复制,首先创建了两个文件夹并分别配置了`my.cnf`文件,通过执行脚本启动容器并配置好主从关系,文中还提到了一些... 目录mysql主从及遇到问题解决遇到的问题说明总结mysql主从及遇到问题解决1.基于mysql

MySQL的索引失效的原因实例及解决方案

《MySQL的索引失效的原因实例及解决方案》这篇文章主要讨论了MySQL索引失效的常见原因及其解决方案,它涵盖了数据类型不匹配、隐式转换、函数或表达式、范围查询、LIKE查询、OR条件、全表扫描、索引... 目录1. 数据类型不匹配2. 隐式转换3. 函数或表达式4. 范围查询之后的列5. like 查询6

Linux下MySQL8.0.26安装教程

《Linux下MySQL8.0.26安装教程》文章详细介绍了如何在Linux系统上安装和配置MySQL,包括下载、解压、安装依赖、启动服务、获取默认密码、设置密码、支持远程登录以及创建表,感兴趣的朋友... 目录1.找到官网下载位置1.访问mysql存档2.下载社区版3.百度网盘中2.linux安装配置1.

PostgreSQL如何用psql运行SQL文件

《PostgreSQL如何用psql运行SQL文件》文章介绍了两种运行预写好的SQL文件的方式:首先连接数据库后执行,或者直接通过psql命令执行,需要注意的是,文件路径在Linux系统中应使用斜杠/... 目录PostgreSQ编程L用psql运行SQL文件方式一方式二总结PostgreSQL用psql运

SQL中的外键约束

外键约束用于表示两张表中的指标连接关系。外键约束的作用主要有以下三点: 1.确保子表中的某个字段(外键)只能引用父表中的有效记录2.主表中的列被删除时,子表中的关联列也会被删除3.主表中的列更新时,子表中的关联元素也会被更新 子表中的元素指向主表 以下是一个外键约束的实例展示

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

如何去写一手好SQL

MySQL性能 最大数据量 抛开数据量和并发数,谈性能都是耍流氓。MySQL没有限制单表最大记录数,它取决于操作系统对文件大小的限制。 《阿里巴巴Java开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐分库分表。性能由综合因素决定,抛开业务复杂度,影响程度依次是硬件配置、MySQL配置、数据表设计、索引优化。500万这个值仅供参考,并非铁律。 博主曾经操作过超过4亿行数据