基于约束的SQL攻击

前言

值得庆幸的是如今开发者在构建网站时,已经开始注重安全问题了。绝大部分开发者都意识到SQL注入漏洞的存在,在本文我想与读者共同去探讨另一种与SQL数据库相关的漏洞,其危害与SQL注入不相上下,但却不太常见。接下来,我将为读者详细展示这种攻击手法,以及相应的防御策略。

注意:本文不是讲述SQL注入攻击

背景介绍

最近,我遇到了一个有趣的代码片段,开发者尝试各种方法来确保数据库的安全访问。当新用户尝试注册时,将运行以下代码:

<?php
// Checking whether a user with the same username exists
$username = mysql_real_escape_string($_GET[‘username‘]);
$password = mysql_real_escape_string($_GET[‘password‘]);
$query = "SELECT *
          FROM users
          WHERE username=‘$username‘";
$res = mysql_query($query, $database);
if($res) {
  if(mysql_num_rows($res) > 0) {
    // User exists, exit gracefully
    .
    .
  }
  else {
    // If not, only then insert a new entry
    $query = "INSERT INTO users(username, password)
              VALUES (‘$username‘,‘$password‘)";
    .
    .
  }
}

使用以下代码验证登录信息:

<?php
$username = mysql_real_escape_string($_GET[‘username‘]);
$password = mysql_real_escape_string($_GET[‘password‘]);
$query = "SELECT username FROM users
          WHERE username=‘$username‘
              AND password=‘$password‘ ";
$res = mysql_query($query, $database);
if($res) {
  if(mysql_num_rows($res) > 0){
      $row = mysql_fetch_assoc($res);
      return $row[‘username‘];
  }
}
return Null;

安全考虑:

  • 过滤用户输入参数了吗? — 完成检查
  • 使用单引号(’)来增加安全性了吗? — 完成检查

按理说应该不会出错了啊?

然而,攻击者依然能够以任意用户身份进行登录!

攻击手法

在谈论这种攻击手法之前,首先我们需要了解几个关键知识点。

  1. 在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。换句话说“vampire”等同于“vampire ”,对于绝大多数情况来说都是成立的(诸如WHERE子句中的字符串或INSERT语句中的字符串)例如以下语句的查询结果,与使用用户名“vampire”进行查询时的结果是一样的。

    SELECT * FROM users WHERE username=‘vampire     ‘;
    

    但也存在异常情况,最好的例子就是LIKE子句了。注意,对尾部空白符的这种修剪操作,主要是在“字符串比较”期间进行的。这是因为,SQL会在内部使用空格来填充字符串,以便在比较之前使其它们的长度保持一致。

  2. 在所有的INSERT查询中,SQL都会根据varchar(n)来限制字符串的最大长度。也就是说,如果字符串的长度大于“n”个字符的话,那么仅使用字符串的前“n”个字符。比如特定列的长度约束为“5”个字符,那么在插入字符串“vampire”时,实际上只能插入字符串的前5个字符,即“vampi”。

现在,让我们建立一个测试数据库来演示具体攻击过程。

vampire@linux:~$ mysql -u root -p
mysql> CREATE DATABASE testing;
Query OK, 1 row affected (0.03 sec)
mysql> USE testing;
Database changed

接着创建一个数据表users,其包含username和password列,并且字段的最大长度限制为25个字符。然后,我将向username字段插入“vampire”,向password字段插入“my_password”。

mysql> CREATE TABLE users (
    ->   username varchar(25),
    ->   password varchar(25)
    -> );
Query OK, 0 rows affected (0.09 sec)
mysql> INSERT INTO users
    -> VALUES(‘vampire‘, ‘my_password‘);
Query OK, 1 row affected (0.11 sec)
mysql> SELECT * FROM users;
+----------+-------------+
| username | password    |
+----------+-------------+
| vampire  | my_password |
+----------+-------------+
1 row in set (0.00 sec)

为了展示尾部空白字符的修剪情况,我们可以键入下列命令:

mysql> SELECT * FROM users
    -> WHERE username=‘vampire       ‘;
+----------+-------------+
| username | password    |
+----------+-------------+
| vampire  | my_password |
+----------+-------------+
1 row in set (0.00 sec)

现在我们假设一个存在漏洞的网站使用了前面提到的PHP代码来处理用户的注册及登录过程。为了侵入任意用户的帐户(在本例中为“vampire”),只需要使用用户名“vampire[许多空白符]1”和一个随机密码进行注册即可。对于选择的用户名,前25个字符应该只包含vampire和空白字符,这样做将有助于绕过检查特定用户名是否已存在的查询。

mysql> SELECT * FROM users
    -> WHERE username=‘vampire                   1‘;
Empty set (0.00 sec)

需要注意的是,在执行SELECT查询语句时,SQL是不会将字符串缩短为25个字符的。因此,这里将使用完整的字符串进行搜索,所以不会找到匹配的结果。接下来,当执行INSERT查询语句时,它只会插入前25个字符。

mysql>   INSERT INTO users(username, password)
    -> VALUES (‘vampire                   1‘, ‘random_pass‘);
Query OK, 1 row affected, 1 warning (0.05 sec)
mysql> SELECT * FROM users
    -> WHERE username=‘vampire‘;
+---------------------------+-------------+
| username                  | password    |
+---------------------------+-------------+
| vampire                   | my_password |
| vampire                   | random_pass |
+---------------------------+-------------+
2 rows in set (0.00 sec)

很好,现在我们检索“vampire”的,将返回两个独立用户。注意,第二个用户名实际上是“vampire”加上尾部的18个空格。现在,如果使用用户名“vampire”和密码“random_pass”登录的话,则所有搜索该用户名的SELECT查询都将返回第一个数据记录,也就是原始的数据记录。这样的话,攻击者就能够以原始用户身份登录。这个攻击已经在MySQL和SQLite上成功通过测试。我相信在其他情况下依旧适用。

防御手段

毫无疑问,在进行软件开发时,需要对此类安全漏洞引起注意。我们可采取以下几项措施进行防御:

  1. 将要求或者预期具有唯一性的那些列加上UNIQUE约束。实际上这是一个涉及软件开发的重要规则,即使你的代码有维持其完整性的功能,也应该恰当的定义数据。由于’username’列具有UNIQUE约束,所以不能插入另一条记录。将会检测到两个相同的字符串,并且INSERT查询将失败。
  2. 最好使用’id’作为数据库表的主键。并且数据应该通过程序中的id进行跟踪
  3. 为了更加安全,还可以用手动调整输入参数的限制长度(依照数据库设置)
时间: 2024-10-22 07:45:03

基于约束的SQL攻击的相关文章

基于约束条件的SQL攻击

一.背景 今天看了一篇基于约束条件的SQL攻击的文章,感觉非常不错,但亲自实践后又发现了很多问题,虽然利用起来有一定要求,不过作者的思想还是很值得学习的.原文中的主旨思想是利用数据库对空格符的特殊处理方式来达到水平越权的目的.以下内容以MySQL为例,其它数据库可能也存在这个问题(文章作者实验了MySQL和SQLite),我也在MySQL上复现了这个问题. 二.知识点 数据库字符串比较:在数据库对字符串进行比较时,如果两个字符串的长度不一样,则会将较短的字符串末尾填充空格,使两个字符串的长度一致

宽字节、基于约束的注入

1.宽字节注入:‘被转义成\',可以通过宽字节绕过转义把’逃逸出来 gbk 占用两字节 ASCII占用一字节 如果网站的字符集是GBK,MYSQL使用的编码也是GBK的话,利用gbk取值范围(第一个字节129-254,第二个字节64-254), 会解析为一个汉字,这样\就会是去应有的作用. 例如%df%5C%27(%bb%5C%27),前两个合并为一个汉字“縗’”(%5C是\), 然后‘就被逃逸出来了,然后就可以进行注入测试. 宽字节注入与HTML页面编码是无关的值型SQL注入无效. 2.基于约

基于oracle的sql优化方法论

Oracle数据库里SQL优化的终极目标就是要缩短目标SQL语句的执行时间.要达到上述目的,我们通常只有如下三种方法可以选择: 1.降低目标SQL语句的资源消耗: 2.并行执行目标SQL语句: 3.平衡系统的资源消耗. "方法1:降低目标SQL语句的资源消耗"以缩短执行时间,这是最常用的SQL优化方法.这种方法的核心是要么通过在不更改业务逻辑的情况下改写SQL来降低目标SQL语句的资源消耗,要么不改SQL但通过调整执行计划或相关表的数据来降低目标SQL语句的资源消耗. 方法2:并行执行

基于时间的 SQL注入研究

SQL注入攻击是业界一种非常流行的攻击方式,是由rfp在1998年<Phrack>杂志第54期上的"NT Web Technology Vulnerabilities"文章中首次提出的.时过境迁,相关SQL注入的技术和工具都进行了不断的发展和演化.目前 SQL注入漏洞已经是信息安全的一大领域,无论是小到个人网站,还是大到电子商务网站,都或多或少的存在SQL注入漏洞.为什么SQL注入漏洞会屡禁不止,原因就在于要想防御SQL注入漏洞,需要对SQL语句.业务流程行为.各种主流数据

SQL Server虚拟化系列(3)&mdash;&mdash;构建理想的基于VMware的SQL Server虚拟机

虚拟化变得越来越常见,并且在不了解虚拟化如何工作的情况下,DBA在尝试解决性能问题时会出现盲点,例如减少资源争用或改进备份和恢复操作等. 在本文中我们将主要讲述为您的SQL Server工作负载构建理想的基于VMware的虚拟机.我们的下一篇文章将介绍怎么样在Hyper-V上构建对应的SQL Server虚拟化环境. 现在,作为DBA,您可能没有访问权限来创建用于SQL Server的新虚拟机.这些操作可以交给您的VM管理员,他们将为您部署合适的VM环境. 以下详细信息适用于在Windows S

SQL CREATE TABLE 语句\SQL 约束 (Constraints)\SQL NOT NULL 约束\SQL UNIQUE 约束

CREATE TABLE 语句 CREATE TABLE 语句用于创建数据库中的表. SQL CREATE TABLE 语法 CREATE TABLE 表名称 ( 列名称1 数据类型, 列名称2 数据类型, 列名称3 数据类型, .... ) 数据类型(data_type)规定了列可容纳何种数据类型.下面的表格包含了SQL中最常用的数据类型: 数据类型 描述 integer(size) int(size) smallint(size) tinyint(size) 仅容纳整数.在括号内规定数字的最

SQL攻击-预编译--缓存

PreparedStatement l 它是Statement接口的子接口: l 强大之处: 防SQL攻击: 提高代码的可读性.可维护性: 提高效率! l 学习PreparedStatement的用法: 如何得到PreparedStatement对象: ¨ 给出SQL模板! ¨ 调用Connection的PreparedStatement prepareStatement(String sql模板): ¨ 调用pstmt的setXxx()系列方法sql模板中的?赋值! ¨ 调用pstmt的exe

浅谈基于JavaScript的DDOS攻击

CloudFlare通过对上百万个网站进行防护,总结出最古老.最普遍的攻击非DDoS攻击莫属.在传统的DDoS攻击中,攻击者会控制大量的傀儡机,然后向目标服务器发送大量请求,阻止合法用户访问网站. 然而,最近几年DDoS攻击技术不断推陈出新:攻击者用一种新型且很有趣的方式欺骗用户参与到攻击活动中.去年CloudFlare就见证了一次使用NTP映射的攻击,可能是DDoS攻击史上最大的一次攻击(大于400Gbps). 今年的DDoS攻击又出现了一个新的攻击趋势:使用恶意的JavaScript欺骗用户

使用 Flash Builder 4 创建基于约束的布局

关于基于约束的布局 基于约束的布局示例 基于约束的布局和绝对定位 使用高级约束布局 设置组件的布局约束 当用户调整应用程序窗口的大小时,可以对组件使用约束来自动调整组件的大小及其在容器中的位置.通常在 MXML 编辑器的设计模式下定义布局约束.还可以在源代码模式下编辑组件的属性来定义布局约束. 关于基于约束的布局 Flex 支持基于约束的布局.基于约束的布局在支持绝对定位的容器中可用.对于 Spark 容器,默认布局 BasicLayout 支持绝对定位.在使用基于约束的布局时,可以将组件的一个