SQL 注入攻击与防范

684 阅读4分钟

SQL注入原理

程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。 攻击者可以提交一段精心构造的数据库查询代码,根据返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。 受影响的系统:对输入的参数不进行检查和过滤的系统。

SQL注入实例

假设这么一个情景,一个网页的后台入口处需要验证用户名和密码,验证程序的SQL语句是这样写: Select * from admin where user=‘TxtBox1.txt’ and pass=‘TxtBox2.txt’

如果用户填写的用户名和密码都是: ‘abc’ or 1=1-- 那么将导致SQL语句是: Select * from admin where user=‘abc’ or 1=1-- and pass= =‘abc’ or 1=1-- 这条语句是永真式,因为第一个—代表后面是注释,这条语句就成为: Select * from admin where user=‘abc’ or 1=1 那么攻击者就成功登陆了后台。这就是最简单的SQL注入方式。

SQL注入漏洞分类

数字型注入 当输入的参数为整型时,如id、年龄、页码等,如存在注入漏洞,则是数字型注入。 如URL为HTTP://www.xxser.com/test.php?id…,可猜测SQL语句为: Select * from table where id=8 测试步骤如下: 1.Http://www.xxser.com/test/php?Id=8’ 肯定会出错,脚 本程序无法从数据库中正常获取数据,从而使原来的页面出现异常。

  1. Http://www.xxser.com/test/php?Id=8 and 1=1 SQL 语句Select * from table where id=8 and 1=1,语句执行正常,返回数据与原始请求无异
  2. Http://www.xxser.com/test/php?Id=8 and 1=2 SQL 语句Select * from table where id=8 and 1=2,语句执行正常,但却无法查询出数据,因为“1=2”始终为假,返回与原始有差异。 如这三个步骤全部满足,则程序可能存在SQL注入漏洞。

字符型注入 当输入的参数为字符串时,称为字符型。字符串类型一般使用单引号来闭合。

字符型注入最关键的是如何闭合SQL语句以及注释多余的代码。 想要进行注入,必须闭合单引号以及注释多余的代码,如输入“admin and 1=1--”就可以继续注入,SQL语句如下: Select * from table where username=‘admin’and 1=1- -’

按注入位置分

POST注入:注入字段在POST数据中; Cookie注入:注入字段在Cookie数据中; 延时注入:使用数据库延时特性注入; 搜索注入:注入处为搜索地点; Base64注入:注入字符串需经过base64加密。

SQL注入过程

  1. 寻找可能存在SQL注入漏洞的链接
  2. 测试该网站是否有SQL注入漏洞
  3. 猜管理员帐号表
  4. 猜测管理员表中的字段
  5. 猜测用户名和密码的长度
  6. 猜测用户名
  7. 猜测密码

SQL注入防范

由于SQL注入攻击是从正常的WWW端口访问,而且表面看起来跟一般的Web页面访问没什么区别,所以许多防火墙等都不会对SQL注入发出警报。而目前互联网上存在SQL注入漏洞的Web站点并不在少数,对此,网站管理员和Web应用开发程序员必须引起足够的重视。

SQL注入漏洞在网上极为普遍,通常是由于程序员对用户提交的数据和输入参数没有进行严格的过滤所导致的。

比如过滤逗号,单引号,分号等;如果select、delete、from、*、union之类的字符串同时出现多个的话,也要引起重视;最好对用户提交的参数的长度也进行判断。

严格的数据类型 PHP、ASP没有强制要求处理数据类型,这类语言会根据参数自动推导出数据类型,如id=1,则推导id的数据类型为interger;id=str,则推导id的数据类型为string.这种弱类型语言是相当不安全的。 idid -_GET[‘id’]; sql=selectfromnewswhereid=sql=“select * from news where id=id; news=exec(news=exec(sql); 攻击者把id参数变为1 and 1=2 --,PHP自动把变量$id推导为string类型,带入数据库查询,造成SQL注入漏洞。 需要在程序中严格判断数据类型

摒弃动态SQL语句,而改用用户存储过程来访问和操作数据。这需要在建立数据库后,仔细考虑Web程序需要对数据库进行的各种操作,并为之建立存储过程,然后让Web程序调用存储过程来完成数据库操作。这样,用户提交的数据将不是用来生成动态SQL语句,而是确确实实地作为参数传递给存储过程,从而有效阻断了SQL注入的途径