SQL Injection | MySQL 手工注入全流程

0x01:MySQL 手工注入 —— 理论篇

手工注入 MySQL 数据库,一般分为以下五个阶段,如下图所示:

  • 第一阶段 - 判断注入点: 在本阶段中,我们需要判断注入点的数据类型(数字型、字符型、搜索型、XX 型)与后端查询方式,并使用对应的 SQL 语句进行测试,判断出目标是否存在注入点。

  • 第二阶段 - 猜解列名数量: 当目标会将数据库内容回显(使用报错注入可以无视这步)时,我们还需要猜测目标返回的数据库中的字段数量,以方便我们后续的注入。

  • 第三阶段 - 判断回显点: 知道了目标返回的字段数量后,我们需要判断这些字段中哪些内容是可以直接显示在页面上的(有回显点),以方便我们后续获取数据库中的内容。

  • 第四阶段 - 数据库信息收集: 在本阶段中,我们会利用第三阶段的回显点,使用各种 SQL 语句与函数,获取目标数据库的信息。

  • 第五阶段 - SQL 注入漏洞利用: 在本阶段,我们会利用之前收集到的目标数据库的信息,对目标实施更进一步的渗透攻击,如脱裤(将数据库内容全部扒拉下来)和写入木马(需要目标开放对应的权限)。

0x0101:MySQL 数据库查询语句

下面是我们需要提前了解的一些关于 MySQL 数据库的查询语句(基础版):

 # 查数据库名,即查询当前数据库服务器中存在哪些数据库select schema_name from information_schema.schemata;# 查表名,即查询指定数据库中存在哪些数据表select table_name from information_schema.tables where table_schema='数据库名'; # 查字段名,即查询指定数据库的某个数据表中存在哪些字段select column_name from information_schema.columns where table_schema='数据库名' and table_name='数据表名'; 

0x0102:MySQL 数据库查询函数

下面是我们需要提前了解的一些关于 MySQL 数据库的查询函数(基础版):

函数名函数解析用法示例
order by对指定列排序select * from table_name order by 3
group_concat()将查询出来的结果用, 号分隔拼接起来select group_concat(schema_name) from information_schema.schemata;
mid(字符串,起始位置(从1开始),取几位)按照指定规则截取字符串的内容select mid('12',2,1);
user()获取当前登录的用户权限select user();
version()数据库版本收集select version();
database()查看当前正在操作的数据库名称select database();
@@secure_file_priv查看当前数据库是否开启了读写权限。select @@secure_file_priv;

0x02:MySQL 手工注入 —— 实战篇

本节重点在于熟悉 SQL 注入流程,以及注入原理。练习靶场为 Sqli-labs(Less -2 GET - Error based - Intiger based),靶场的配套资源如下(附安装教程):

实验工具准备

  • PHP 运行环境:phpstudy_x64_8.1.1.3.zip(PHP 7.X + Apache + MySQL)

  • SQLI LABS 靶场:sqli-labs-php7.zip(安装教程:SQLI LABS 靶场安装)

0x0201:第一阶段 — 判断注入点

进入靶场,靶场提示 Please input the ID as parameter with numeric value 要我们输入一个数字型的 ID 作为参数进行查询,那我们就按它的意思传入 id 看看网页返回的结果:

如上,靶场返回了用户的 Login name 和 Password 参数,如果你试着多传递几个不同的值,你还能查询到更多的内容,比如这里,笔者传递了 ?id=3-1 成功获取了 id 为 2 的用户的数据,顺带提一个小思考题(为什么不能直接传递 ?id=1+1):

这里不卖关子了,因为在 GET 请求的 URL 中,+ 号通常被解释为空格,所以在上面这个例子中,你传递的 ?id=1+1 被后端解析后,就变成了 ?id= 1 1,明显不对,所以当你想要传递 + 号给后端时,最好对 + 号进行 URL 编码,比如下面这个例子:

在上面的测试中,我们发现了,我们传递的数据其实是会被后端解析执行的(MySQL 数据库能够执行一些简单的运算),其实到这里,我们已经可以基本判断这个 id 处存在注入点了。

通过上面测试的结果,我们可以尝试推测目标后端执行的 SQL 语句模板:

 select * from users where id=$_GET['id'];

这里的 $_GET['id'] 就是我们的注入点,我们传入的值会直接替换 $_GET['id'] 然后被传入后端数据库进行执行。

上面的测试,是针对数字型注入点的一种特殊的测试思路,下面我这里再啰嗦一点,提供一个通用的测试思路,即通过拼接布尔表达式,再根据页面返回的结果,判断其是否存在注入点(下面内容可以略过,本节的主要目的就是判断其是否存在注入点,上面的测试已经证明了目标存在注入点,这里只是提供一个通用的方法而已)。

针对我们推测的目标后端 SQL 语句模板,我们可以传递如下两条 Payload 进行测试:

 测试 Payload 01: ?id=1 and 1=1 # 若存在注入点,则页面不会发生任何变化,否则页面异常推测后端执行语句: select * from users where id=1 and 1=1;

 测试 Payload 02: ?id=1 and 1=0 # 若存在注入点,则页面不会返回任何值,因为 1=0 为假推测后端执行语句: select * from users where id=1 and 1=0;

注意:在浏览器中,用户传递的内容会自动进行一次 URL 编码,比如空格会自动变为 %20

通过比对两次的输出结果,我们发现,当在原有的查询基础上添加一个恒真的 SQL 表达式时,查询结果不变;当加上一个恒为假的 SQL 表达式时,服务端未返回任何结果。由此我们可以确定,我们输入的内容成功带入到数据库中执行了,且目标未作任何过滤。所以 id 处存在 SQL 注入漏洞。

0x0202:第二阶段 — 猜解列名数量

在第一阶段的测试中,我们确定了 ?id= 处存在 SQL 注入漏洞,接下来,我们需要通过 order by (根据某一列进行排序)函数确定服务端返回的数据库字段数量:

测试语句1 -> ?id=1 order by 1 -> 将返回的数据根据第1列进行排序,若返回的数据少于1列会报错推测后端执行语句: select * from users where id=1 order by 1;​测试语句2 -> ?id=1 order by 2 -> 将返回的数据根据第2列进行排序,若返回的数据少于2列会报错推测后端执行语句: select * from users where id=1 order by 2;​测试语句3 -> ?id=1 order by 3 -> 将返回的数据根据第3列进行排序,若返回的数据少于3列会报错推测后端执行语句: select * from users where id=1 order by 3;​测试语句4 -> ?id=1 order by 4 -> 将返回的数据根据第4列进行排序,若返回的数据少于4列会报错推测后端执行语句: select * from users where id=1 order by 4;............................ 如果没遇到报错还得继续查下去 .............................

如上,当我们要求数据库返回的数据按照第 4 列排序的时候,数据库返回了报错信息,说没有找到第 4 列;但是当我们要求其按照第 3 列进行排序的时候,它成功返回了结果。由此,我们可以推断,目标数据库返回了 3 列数据。

0x0203:第三阶段 — 判断回显点

在上一阶段中,我们确定了目标数据库会返回三列值,接下来我们需要使用 union 联合查询,来判断这三列值中,哪个值会成为回显点 (其实在很多测试中,数据库返回的值不会直接回显回页面,这个时候,我们需要使用 “盲注” 技术 ,该技术笔者会在后续的笔记中讲解) 。不过在此之前,笔者先简单介绍以下联合查询:

MySQL Union 联合查询
MySQL 的 UNION 操作符用于将两个或多个 SELECT 语句的结果集合并成一个结果集。它通常用于从多个表中获取数据,或者从同一个表中根据不同的条件获取数据,并将这些数据合并到一起。

示例:使用 UNION 操作符将两个 SELECT 语句的结果集合并到一个结果集
 

 mysql> select username, password from users union select 'key1', 1;+----------+----------------------------------+| username | password                         |+----------+----------------------------------+| admin    | e10adc3949ba59abbe56e057f20f883e || pikachu  | 670b14728ad9902aecba32e22fa4f6bd || test     | e99a18c428cb38d5f260853678922e03 || key1     | 1                                | # 注意这行,是我们通过 union select 'key1', 1; 额外添加上的。+----------+----------------------------------+4 rows in set (0.00 sec)

注意:MySQL Union 查询特性

  • 特性 1:Union 操作符会默认去除重复的行,这可能会增加一些计算开销。

  • 特性 2:Union 前面查询的语句和后面查询的语句结果互不干扰(不用在意数据类型)。

  • 特性 3:Union 前面查询语句的字段数量和后面查询语句的字段数量要一致!

接下来,我们对靶场传入如下 Payload 进行测试:

 测试语句: ?id=-1 union select 1,2,3推测后端执行语句:select * from users where id=-1 union select 1,2,3;

Payload 中传入 id=-1 是为了确保 select * from users where id=-1 查询不出任何值,导致目标可以返回后半段的查询结果,即 select 1,2,3 的查询结果 (为什么是 select 1,2,3?因为我们前面的测试中发现目标返回了 3 列结果,且 Union 需要确保前后两个 select 语句查询的结果字段数量要一致)

通过上面的回显结果,可以看到,页面最终回显了 select 1,2,3; 中 2 号位和 3 号位的信息,那这里的 2 号位和 3 号位就是最终的回显点,我们接下来就可以利用这两个回显点,进行数据库的信息搜集了。

0x0204:第四阶段 — 数据库信息收集

通过第三阶段,我们确定了 2 号位和 3 号位为数据的回显点。所以,接下来我们进行信息收集的语句就可以放在这两个位置上(任意一个都可以)。

在本阶段中,我们将会全面收集目标数据库的详细信息,信息收集的越详细,最后能进行攻击的手段就越多。

1. 用户权限收集

SQL 注入攻击,其实就是通过伪造合法的数据库用户,利用它们的权限,来对数据库进行合法的操作。所以第一步,我们就需要了解我们当前获取的数据库用户的权限,以此来了解我们到底能干嘛:

 攻击 Payload: ?id=-1 union select 1,2,user()推测后端执行语句:select * from users where id=-1 union select 1,2,user();

传入测试语句后,在 3 号位回显了 root@localhost 证明了当前我们渗透的用户拥有 root 权限,可以对数据库进行任意的操作。

2. 数据库版本收集

MySQL version() 函数会返回当前数据库的版本信息。我们通常将 5.0 以上的版本称为高版本数据库,因为在这些高版本数据库中会内置 information_schema 这张数据表,这张表对我们后续的信息收集工作很重要。如果渗透的是低版本的 MySQL 数据库,我们可以采用字典暴力猜解的方式来尝试确定目标数据库中的信息。

攻击 Payload: ?id=-1 union select 1,2,version()
推测后端执行语句:select * from users where id=-1 union select 1,2,version();

3. 数据库读写权限收集

在前面的信息收集中,我们发现了我们渗透获取的用户为 root,属于一个高权限用户了。所以我们就可以更进一步的尝试测试目标是否开启了文件的读写权限,如果目标开启了该权限,我们就可以通过 MySQL 数据库向目标指定文件夹中写入木马,进而控制整个服务器了。

在进行攻击之前,我先简单介绍一下 MySQL 的文件读写权限:在 MySQL 高版本(5.0 以上)中,添加了一个新的特性 secure_file_priv,该选项限制了 mysql 导出文件的权限。

  • secure_file_priv='' 时,对 MySQL 的读写没有任何限制。

  • secure_file_priv='NULL' 时,MySQL 不能对文件进行读写操作。

  • secure_file_priv='文件路径' 时,MySQL 只能对目标路径下的文件进行读写。

攻击 Payload: ?id=-1 union select 1,2,@@secure_file_priv
推测后端执行语句:select * from users where id=-1 union select 1,2,@@secure_file_priv;

目标的 secure_file_priv 设置为 NULL,证明目标关闭了文件读写的权限,所以这条路就走不通咯(笔者后续会专门出一期 “MySQL 高权限注入” 的内容,讲解如何利用这种漏洞,这里就先略过了)。

0x0205:第五阶段 — SQL 注入漏洞利用

通过前面的四个阶段,我们已经对目标站点有了足够清晰的认识,并且已经可以总结出一个注入模板了:

攻击 Payload: ?id=-1 union select 1,2,攻击参数

接下来,我们将会利用这个这个注入模板,尝试获取目标数据库中的一些敏感信息。

1. 获取数据库信息

通过前面对数据库信息的收集,我们可以知道,对方使用的是高版本的数据库,且我们拥有 root 权限。结合这两个信息,我们很轻松就可以推测出,我们拥有查看多个数据库的权限。

查看其它数据库,就需要知道这些数据库的名字,这里我们利用 information_schema 这个系统库,来获取目标数据库服务器中存在的数据库名:

攻击 Payload: ?id=-1 union select 1,2,group_concat('<br>',schema_name) from information_schema.schemata
推测后端执行语句:select * from users where id=-1 union select 1,2,group_concat('<br>',schema_name) from information_schema.schemata;

如上,我们已经成功获取了目标数据库服务器中存在的其它数据库名称。

2. 获取数据表信息

接下来,我们以 pikachu 数据库为例,演示如何收集 pikachu 数据库中的数据表信息,依旧是使用 information_schema 系统库:

攻击 Payload: ?id=-1 union select 1,2,group_concat('<br>',table_name) from information_schema.tables where table_schema='pikachu'
推测后端执行语句:select * from users where id=-1 union select 1,2,group_concat('<br>',table_name) from information_schema.tables where table_schema='pikachu'

如上,我们已经成功获取了 pikachu 数据库中存在的数据表啦。

3. 获取数据表字段信息

知道了数据库,数据库里的数据表,我们还需要知道数据表中的字段,才能够随意的查询数据库中的内容,所以这一步,我们将通过 information_schema 系统库,获取 pikachuusers 这张表的字段信息:

攻击 Payload: ?id=-1 union select 1,2,group_concat('<br>',column_name) from information_schema.columns where table_schema='pikachu' and table_name='users'
推测后端执行语句:select * from users where id=-1 union select 1,2,group_concat('<br>',column_name) from information_schema.columns where table_schema='pikachu' and table_name='users';

如上,我们成功获得了 pikachu 数据库的 users 数据表中的字段信息,接下来,我们就可以任意查询这个数据库中的信息啦。

4. 获取数据表具体内容

通过前面的测试,我们已经完全掌握了 pikachu 数据库的 users 数据表的结构了,接下来,我们就可以构造语句读取数据表信息啦:

攻击 Payload: ?id=-1 union select 1,2,group_concat('<br>' ,username, ':', password) from pikachu.users
推测后端执行语句:select * from users where id=-1 union select 1,2,group_concat('<br>' ,username, ':', password) from pikachu.users;

如上,我们已经成功读取到我们想要的数据啦。重复前面的四个步骤,我们就可以读取任意数据库的任意一张数据表中的信息了。

聪明如你,应该发现了,我们上面渗透的数据库其实不是当前站点使用的数据库,这就是高权限的一个优势,可以 “跨库查询”。至此,MySQL 手工注入的基本流程讲解完毕。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/56659.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【星闪技术】WS63E模块的WiFi客户端测试

引言 我所计划的WS63E测试要实现MQTT联网&#xff0c;所以首先需要确保开发板连接WiFi。今天来测试一下WiFi功能。 程序分析 WiFi客户端的例子在src/application/samples/wifi/sta_sample目录下。这个例子看上去和hi3861的例子差不多。 这段程序是一个用于嵌入式设备的Wi-F…

国产AI逆袭!零一万物新模型Yi-Lightning超越 GPT-4o

近日&#xff0c;由全球千万用户盲测投票产生的 AI 模型排行榜公布&#xff0c;国产 AI 模型“Yi-Lightning”逆袭&#xff0c;超越了此前长期占据榜首的 GPT-4。 “Yi-Lightning”模型由国内知名 AI 公司零一万物研发&#xff0c;在多个分榜中均名列前茅&#xff0c;其中数学…

HDU RSA

翻译成中文后&#xff1a; 思路&#xff1a;由题易得&#xff0c;d * e y * f ( n ) 1 ,且gcd ( e , f ( n ) ) 1,所以用扩展欧几里得求出 d &#xff0c;但要保证 d 是非负的&#xff0c;最有用快速幂求出每个字符即可。 #include<bits/stdc.h> using namespace std;…

HTML5教程(二)- HTML语法及基本结构

1. 介绍 HTML 超文本标记语言&#xff08;HyperText Markup Language&#xff09;浏览器能够识别和解析的语言&#xff0c;通过标签的形式构建页面结构和填充内容&#xff08;用来描述网页的语言&#xff09;。HTML 不是一种编程语言&#xff0c;而是一种标记语言&#xff08;是…

基于SpringBoot+Vue+uniapp微信小程序的教学质量评价系统的详细设计和实现

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

决策树(1)

原理 基础概念 决策树属于判别模型。 决策树算法属于监督学习方法。 决策树是一种树状结构&#xff0c;通过做出一系列决策&#xff08;选择&#xff09;来对数据进行划分&#xff0c;这类似于针对一系列问题进行选择。 决策树的决策过程就是从根节点开始&#xff0c;测试待分…

UNION 联合查询

1.UNION ALL联合查询 同样为了演示方便&#xff0c;先向 teacher 表插入多条测试数据&#xff1a; INSERT INTO teacher (name,age,id_number,email) VALUES (姓名一,17,42011720200604077X,NULL), (姓名二,18,42011720200604099X,123qq.com), (姓名三,19,42011720200604020X…

007、链表的回文结构

0、题目描述 链表回文结构 1、法1 一个复杂的问题可以拆解成几个简单的问题&#xff0c;找中间节点和逆置链表&#xff08;翻转链表&#xff09;之前都做过。 class PalindromeList { public://1、找中间节点ListNode* FindMid(ListNode* A){if (A nullptr || A->next …

流程图 LogicFlow

流程图 LogicFlow 官方文档&#xff1a;https://site.logic-flow.cn/tutorial/get-started <script setup> import { onMounted, ref } from vue import { forEach, map, has } from lodash-es import LogicFlow, { ElementState, LogicFlowUtil } from logicflow/core …

Jmeter监控服务器性能

目录 ServerAgent 安装 打开Jmeter ServerAgent 在Jmeter上监控服务器的性能比如CPU&#xff0c;内存等我们需要用到ServerAgent&#xff0c;这里可以下载我分享 ServerAgent-2.2.3.zip 链接: https://pan.baidu.com/s/1oZKsJGnrZx3iyt15DP1IYA?pwdedhs 提取码: edhs 安装…

FPGA图像处理之均值滤波

文章目录 一、什么是图像滤波&#xff1f;1.1 噪声类型1.2 滤波类型 二、均值滤波原理2.1 3*3窗口滑动过程2.2 图像扩展 三、Matlab实现均值滤波四、FPGA实现均值滤波4.1 生成 3*3 矩阵4.2 仿真3*3矩阵4.3 计算均值4.4 仿真均值滤波 一、什么是图像滤波&#xff1f; 图像滤波是…

得物App3D创新应用引关注,世界设计之都大会启幕

近日&#xff0c;2024世界设计之都大会&#xff08;WDCC&#xff09;在上海盛大启幕。此次大会以“设计无界 新质生长”为主题&#xff0c;汇聚了全球设计领域的精英与前沿成果&#xff0c;展现了设计作为新质生产力的巨大潜力。主场展览占据了整整3个楼面&#xff0c;总面积达…

C#学习笔记(十)

C#学习笔记&#xff08;十&#xff09; 第七章 对象的构造方法与实例方法一、对象的构造方法1. 构造方法初识2. 构造方法的创建3. this关键字4. 构造方法的规范和重载4.1 构造方法的规范 5. 对象初始化器5.1 对象初始化器和构造方法的区别 二、对象的实例方法1. 简单应用2.实例…

代码随想录算法训练营第二天(补) | 滑动窗口、模拟、前缀和

目录 3.4 长度最小的子数组 3.5螺旋矩阵II 3.6 区间和 文章讲解&#xff1a;[58. 区间和 | 代码随想录 3.4 长度最小的子数组 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;拿下滑动窗口&#xff…

Linux历史

Linux 于 1991 年由芬兰学生 Linus Torvalds 作为个人项目开始&#xff0c;旨在创建一个新的免费操作系统内核。在其历史发展中&#xff0c;Linux 内核经历了持续的增长。自 1991 年首次发布源代码以来&#xff0c;Linux 内核从少量的 C 语言文件&#xff0c;且受限于禁止商业发…

机器视觉基础系列四—简单了解背景建模算法

机器视觉基础系列四—简单了解背景建模算法 首先我们应该了解的是背景建模的定义是什么&#xff1f;又有哪些应用场景呢&#xff1f; 背景建模是指通过分析视频序列中的像素值变化情况&#xff0c;从中提取出静态背景部分&#xff0c;并将其用于目标检测、运动跟踪等计算机视觉…

渗透测试导论

渗透测试的定义和目的 渗透测试&#xff08;Penetration Testing&#xff09;是一项安全演习&#xff0c;网络安全专家尝试查找和利用计算机系统中的漏洞。 模拟攻击的目的是识别攻击者可以利用的系统防御中的薄弱环节。 这就像银行雇用别人假装盗匪&#xff0c;让他们试图闯…

LeetCode1004.最大连续1的个数

题目链接&#xff1a;1004. 最大连续1的个数 III - 力扣&#xff08;LeetCode&#xff09; 1.常规解法&#xff08;会超时&#xff09; 遍历数组&#xff0c;当元素是1时个数加一&#xff0c;当元素是0时且已有的0的个数不超过题目限制时&#xff0c;个数加一&#xff0c;若上…

Lumerical学习——优化和参数扫描(Optimization and parameter sweeps)

一、概要介绍 这部分介绍优化和参数扫描项目设定的方法。在有大量数据模拟计算过程中这个特性允许用户使处理方法自动地查找期望的参数值。 ① 创建一个参数扫描任务 ② 创建一个优化任务 ③ 创建一个良率分析任务 ⑤ 打开所选择项目的编辑窗口&#xff0c;编辑其属性…

基于Java+SpringBoot+Uniapp的博客系统设计与实现

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…