前言

值得庆幸的是如今开发者在构建网站时,已经开始注重安全问题了。绝大部分开发者都意识到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     ';
  1. 但也存在异常情况,最好的例子就是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. 为了更加安全,还可以用手动调整输入参数的限制长度(依照数据库设置)

文章参考自:https://dhavalkapil.com/blogs/SQL-Attack-Constraint-Based/

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

  1. 基于约束条件的SQL攻击

    一.背景 今天看了一篇基于约束条件的SQL攻击的文章,感觉非常不错,但亲自实践后又发现了很多问题,虽然利用起来有一定要求,不过作者的思想还是很值得学习的.原文中的主旨思想是利用数据库对空格符的特殊处理 ...

  2. 滥用基于资源约束委派来攻击Active Directory

    0x00 前言 早在2018年3月前,我就开始了一场毫无意义的争论,以证明TrustedToAuthForDelegation属性是无意义的,并且可以在没有该属性的情况下实现“协议转换”.我相信,只要 ...

  3. 基于时间的 SQL注入研究

    SQL注入攻击是业界一种非常流行的攻击方式,是由rfp在1998年<Phrack>杂志第54期上的“NT Web Technology Vulnerabilities”文章中首次提出的.时 ...

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

    CREATE TABLE 语句 CREATE TABLE 语句用于创建数据库中的表. SQL CREATE TABLE 语法 CREATE TABLE 表名称 ( 列名称1 数据类型, 列名称2 数据 ...

  5. 基于Oracle的SQL优化(社区万众期待 数据库优化扛鼎巨著)

    基于Oracle的SQL优化(社区万众期待数据库优化扛鼎巨著) 崔华 编   ISBN 978-7-121-21758-6 2014年1月出版 定价:128.00元 856页 16开 编辑推荐 本土O ...

  6. 基于iSCSI的SQL Server 2012群集测试(四)--模拟群集故障转移

    6.模拟群集故障转移 6.1 模拟手动故障转移(1+1) 模拟手动故障转移的目的有以下几点: 测试群集是否能正常故障转移 测试修改端口是否能同步到备节点 测试禁用full-text和Browser服务 ...

  7. 判断字符串中是否有SQL攻击代码

    判断一个输入框中是否有SQL攻击代码 public const string SQLSTR2 = @"exec|cast|convert|set|insert|select|delete|u ...

  8. 数据库 基于索引的SQL语句优化之降龙十八掌(转)

    一篇挺不错的关于SQL语句优化的文章,因不知原始出处,故未作引用说明! 1 前言      客服业务受到SQL语句的影响非常大,在规模比较大的局点,往往因为一个小的SQL语句不够优化,导致数据库性能急 ...

  9. 基于oracle的sql优化

    [基于oracle的sql优化] 基于oracle的sql优化 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 一.编写初衷描述 在应有系统开发初期,由于数据库 ...

随机推荐

  1. 【JAVA】使用 jedis操作redis——连接、存储数据、切库等

    本篇运用Java调用jedis包(jedis在线文档API ),做简单操作实例. 安装jedis 1. 2.9.0 jar 版本下载: jedis-2.9.0.jar 2. 新建项目,添加该驱动包 连 ...

  2. sqlserver性能调优中的逻辑读,物理读,预读是什么意思

    表 'T_EPZ_INOUT_ENTRY_DETAIL'.扫描计数 1,逻辑读 4825 次,物理读 6 次,预读 19672 次.SQL SERVER 数据库引擎当遇到一个查询语句时,SQL SER ...

  3. Java 设计模式笔记

    0. 说明 转载 & 参考大部分内容 JAVA设计模式总结之23种设计模式 1. 什么是设计模式 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设 ...

  4. 安全之路 —— C/C++实现后门的服务自启动

    简介 Windows NT系统后门要实现自启动,有许多种方法,例如注册表自启动,映像劫持技术,SVCHost自启动以及本章节介绍的服务自启动等方法,其中服务自启动相对于上述其他三种需要修改注册表的启动 ...

  5. kudu基础入门

    1.kudu介绍 1.1 背景介绍 在KUDU之前,大数据主要以两种方式存储: (1)静态数据: 以 HDFS 引擎作为存储引擎,适用于高吞吐量的离线大数据分析场景.这类存储的局限性是数据无法进行随机 ...

  6. 何为用户体验?附《用户体验的要素》PDF版下载

    一.什么是用户体验? 用户体验(User Experience,简称UE/UX)是用户在使用产品过程中建立起来的一种纯主观感受.但是对于一个界定明确的用户群体来讲,其用户体验的共性是能够经由良好设计实 ...

  7. Linux命令一览

    Linux系统中的命令参数有长短格式之分,长格式和长格式之间不能合并,长格式和短格式之间也不能合并,但短格式和短格式之间是可以合并的,合并后仅保留一个-(减号)即可. echo命令:用于在终端输出字符 ...

  8. 关于datatables与jquerUI版本冲突问题

    今天开发项目是,需要用到表格,于是想到,之前的项目中使用过datatables插件,于是就拿了过来,但是发现无法识别 Uncaught TypeError: $(...).DataTable is n ...

  9. node版本查看管理工具

    1.nvm : 有点坑爹,安装完后,发现node not found ,最后卸载了,重装node 2.bower :(前端)包管理器(选用) //安装方法 npm install bower -g / ...

  10. BZOJ4892:[TJOI2017]dna(hash)

    Description 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够表 ...