SQL手工注入进阶篇

0.前言

  上一篇咱们介绍了SQL手工注入的流程以及步骤,但在实际的安全问题以及CTF题目中,查询语句多种多样,并且是确定会对用户的输入进行一个安全过滤的,而这些过滤并不必定是百分百安全的,如何利用一些技巧绕过一些安全过滤,这就是咱们这一篇要介绍的事情。php

  若是你还不熟悉SQL注入的流程以及步骤,请先阅读个人上一篇博文。sql

  文中有误之处,还请各位师傅指出。数据库

 

1.各类select语句绕过

 (1)select xxx from xxx limit $num;

  上篇咱们讲解了where条件查询的注入方法,那么若是不是where而是其余语句呢,例如limit限制,这可能会出如今限制每页展现多少行中用到,例如对于以下语句后端

  select * from student limit $num;安全

  $num是咱们上传的变量,假如咱们依然使用order进行查列数将于返回以下结果函数

 

   Mysql会提示语法错误,由于排序须要在分页的前面使用,那么这个时候咱们该如何查列数呢,答案是上次提到的利用into @,@,@,@就是‘@’字符,它表明Mysql的一个临时变量。测试

  例如  编码

 

  必须保证变量数等于列数,利用这个特性咱们就能够查出列数。加密

  (2)updata,insert,delete相关

  和select相似,仍是先找到参数的位置,再判断注入类型,最后构造表达式进行SQL注入。spa

  (3)order by注入

  前面已经讲了利用order by查列数,实际上order by能够经过位运算来执行表达式

select * from student order by 1|(sleep(5));

 

2.时间函数进行盲注

  有些时候当网页没有错误回显时,能够考虑使用时间函数进行盲注。原理是利用条件判断进行睡眠,咱们只须要观察响应时间便可。

  例如

select * from student where id=1 and if(user()='root@localhost',sleep(5),null);#判断用户

select * from student where id=1 and if(substr(user(),1,1)='r',sleep(5),null);#逐字判断

  咱们能够先用一个永真条件判断sleep()是否可用,当sleep()被禁用的时候,咱们能够用下面其余几种延时方法代替。

 (1)延时方法

  • sleep()函数。
  • benchmark(count,expr),重复expr函数count次,咱们能够利用一些MySql自带的加密函数做为expr执行屡次达到睡眠的效果。具体执行次数能够根据CPU来进行变更。
select * from student where id=1 and if(true,benchmark(10000000,sha(1)),null);
  • 笛卡尔积,利用计算笛卡尔积达到延时;
select count(*) from information_schema.columns A,information_schema.columns B;#count(*)返回行数
  • get_lock(str,timeout),这个须要开启两次会话,第一次给str进行上锁,第二次再执行就会等待timeout的时间,若timeout为负,则无限等待。get_lock()只会在执行release_lock()或隐式的会话停止时显式释放锁,事务提交或回滚不会释放锁。
  • length(str),利用rpad构造长字符串,再用length返回一列。
select LENGTH(concat(rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a')));

 

  • rlike,regexp,先利用rpad或者式repeat构造长字符串再利用rlike正则匹配返回一列,经过控制构造的字符串长度控制时间。
select concat(rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a'),rpad(1,9999999,'a')) rlike '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)';

  p.s.构造字符串长度不能超出MySql内存限制,不然会报错。

 (2)条件判断

  • if(expr,expr1,expr2).
  • case when xx then xx;利用case when语法达到判断条件的方法。

 (3)字符串截取

  • substr(str,pos,len),同Python的substr()函数,但MySql中首位置为1或-len。
  • mid(str,pos,len),基本同上
  • substring_index(str,delim,count),返回第count个delim串左边的全部内容
select substring_index('a.b.c.d','.',3);#返回a.b.c
  • left(str,len),返回str左边len个字符。
  • right(str,len),返回str右边len个字符。

  本质上时间盲注就是bool盲注的一种,利用回显消息不一样,只是这里的回显没有显式显示在屏幕上罢了。

 

3.bool盲注

  利用回显的不一样来猜想数据库的信息,例如order by就是一种bool盲注,通常能够利用二分或者逐位拆解的方式进行盲注。能够利用一些位运算的短路机制进行链接表达式。

 

4.多行注入

  当调用数据库函数支持多行sql语句才能使用,原理就是利用';'结束语句插入本身的sql语句。

 

5.MySql编码注入

(1)弱类型转换

  先来看这样一个查询语句select * from student where name=1;

  

 

  为何能够被查询呢,由于name会被转换成数字和1比较,而MySql的默认转换和php的转换相似,找到第一个不为数字的字符就结束。利用这个特性咱们能够进行一些查询判断。

(2)宽字节注入

  当当前数据库使用了GBK编码的时候,会把两个字符转化为汉字(前一个字符大于128),利用这个特性再配合后端的过滤实现注入。

  例如当后端过滤'将其变成\'的时候,若是式gbk编码,则传入的就是%5C%27,这时候咱们提交%df'则会被编码成%df%5C%27,而前面的%df%5c则会被编码成中文,达到了注入效果。

(3)SQL字符集特性

  对于utf8_unicode_ci字符集,不区分大小写,并且Ä=A,Ö=O,Ü=U等条件都成立,且ß=ss,

  对于utf8_general_ci字符集,ß=s。

  更多条件等式能够自行测试。

(4)进制转换

  若是表名和列名过滤了字符能够将其转换为16进制实现,前面带上0x

6.总结

  本篇博文就是在上一篇的基础上讲解了一些其余的注入方法,已经引入了不少MySql函数。到如今 对Mysql的知识已经讲完了,下一篇咱们将会着重讲解如何绕事后端对传输参数的一些过滤绕过。

  若是还有什么补充的地方,请各位师傅在评论区留言。

相关文章
相关标签/搜索