SQL注入漏洞

什么是SQL注入漏洞

SQL注入攻击(SQL Injection),简称注入攻击,SQL注入是web开发中最常见的一种安全漏洞。 SQL注入漏洞可以用来从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出文件等一系列恶意操作,甚至有可能获取数据库乃至系统最高权限

SQL注入漏洞原理

由于程序没有过滤用户的输入,攻击者通过响服务器提交恶意的SQL查询语句,应用程序接收后错误的将攻击者的输入作为原始SQL查询语句的一部分执行,导致改变了程序原始的SQL查询逻辑,额外的执行了攻击者构造的SQL查询语句

SQL注入实例

类型1:数字型
$id = $_GET[id];
$sql = SELECT * FROM .$tablepre.announcements WHERE id=$id;
$result = $db->fetchsingleassocbysql( $sql );
$content = $result[content];

提交 and 1=1,语句变成select * from tablepre announcements where id = 71 and 1=1 这时语句前值后值都为真,and以后也为真,返回查询到的数据。执行了攻击者额外的SQL查询语句,导致SQL注入漏洞猜列名

类型2:字符型 
$search = $_GET[key];
$sql = SELECT * FROM users WHERE username LIKE %$search% ORDER BY username;
$result = $db->fetchsingleassocbysql( $sql );
$content = $result[content];

提交%’order by id / 语句变成SELECT * FROM users WHERE username LIKE ‘% %’ order by id /ORDER BY username通过闭合单引号并闭合后面的原始语句,执行了攻击者额外的SQL语句,导致SQL注入漏洞

PHP

参考:http://php.net/manual/zh/security.database.sql-injection.php

<?php
$offset = $argv[0]; // 注意,没有输入验证!
$query  = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result = pg_query($conn, $query);
?>

一般的用户会点击 $offset 已被斌值的“上一页”、“下一页”的链接。原本代码只会认为 $offset 是一个数值。然而,如果有人尝试把以下语句先经过 urlencode() 处理,然后加入URL中的话:

0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
select 'crack', usesysid, 't','t','crack'
from pg_shadow where usename='postgres';
--

那么他就可以创建一个超级用户了。注意那个 0; 只不过是为了提供一个正确的偏移量以便补充完整原来的查询,使它不要出错而已。

ASPX

...
string userName = ctx.getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '" 
                + userName + "' AND itemname = '"  
                + ItemName.Text + "'";
sda = new SqlDataAdapter(query, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
...

本代码打算执行的查询遵循:

SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';

但是,由于查询的动态建立是通过连接常量库查询字符串和用户输入的字符串来实现的,因此只有在itemName中不包含单引号字符时,查询才能正确执行。

如果攻击者以用户名”wiley”进入字符串"name' OR 'a'='a"作为itemName,那么查询就会变成:

SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name' OR 'a'='a'

增加的OR 'a'='a'条件会导致WHERE子句的估值始终为true

因此查询在逻辑上就等同于一个更为简单的查询:SELECT * FROM items;

查询的这种简化使攻击者能够绕过查询只返回身份验证合格的用户所拥有的项目的要求;而查询现在所返回的是存储在项目表中的所有条目,不论所有者是谁。

SQL注入的位置

无论是内网环境还是外网环境(互联网),B/S架构的Web应用(以下指网站)都直接或者间接地受到各种类型的Web攻击的影响。

对于后台数据库来说,以SQL注入攻击危害最为普遍,由于网站服务端语言自身的缺陷与程序员编写代码的安全意识不足,攻击者可以将恶意SQL语句注入到正常的数据库操作指令中去,从而使该恶意SQL语句在后台数据库中被解析执行。

在SQL注入攻击之前,首先要找到网站中各类与数据库形成交互的输入点。通常情况下,一个网站的输入点包括:

  1. 表单提交,主要是POST请求,也包括GET请求。
  2. URL参数提交,主要为GET请求参数。
  3. Cookie参数提交。
  4. HTTP请求头部的一些可修改的值,比如Referer、User_Agent等。
  5. 一些边缘的输入点,比如.mp3文件的一些文件信息等。

服务端从客户端直接或间接获取数据的过程都是一次输入过程, 无论直接或间接,默认情况下输入的数据都应该认为是不安全的。

上面列举的几类输入点,只要任何一点存在过滤不严,过滤缺陷等问题, 都有可能发生SQL注入攻击。 大多数情况下,SQL注入的过程都是由工具完成的, 其中包括大批量注入工具的使用。

SQL注入的危害

这些危害包括但不局限于:

一些类型的数据库系统能够让SQL指令操作文件系统,这使得SQL注入的危害被进一步放大。

常见的SQL注入测试工具

SQL注入漏洞的解决方案

解决SQL注入问题的关键是对所有可能来自用户输入的数据进行严格的检查、对数据库配置使用最小权限原则。

  1. 所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。当前几乎所有的数据库系统都提供了参数化SQL语句执行接口,使用此接口可以非常有效的防止SQL注入攻击。
  2. 对进入数据库的特殊字符('"\尖括号&*;等)进行转义处理,或编码转换。
  3. 严格限制变量类型,比如整型变量就采用intval()函数过滤,数据库中的存储字段必须对应为int型。
  4. 数据长度应该严格规定,能在一定程度上防止比较长的SQL注入语句无法正确执行。
  5. 网站每个数据层的编码统一,建议全部使用UTF-8编码,上下层编码不一致有可能导致一些过滤模型被绕过。
  6. 严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害。
  7. 避免网站显示SQL错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
  8. 在网站发布之前建议使用一些专业的SQL注入检测工具进行检测,及时修补这些SQL注入漏洞。
  9. 确认PHP配置文件中的magic_quotes_gpc选项保持开启

–EOF–
SQL注入漏洞  •  C.Rufus Security Team  •  2010-08-21 13:10

如果显示不正常,请使用Mozilla Firefox或Chrome进行浏览

bigsec.net