版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
新型SQL截断攻击和防御方法本文讨论: 本文使用了以下技术:SQLServer分隔标识符和字符串实用的T-SQL函数截断和修改攻击找出Bug和漏洞目录利用SQL注入方法的漏洞攻击已经引起了广泛关注,因为这些漏洞能够穿过防火墙和入侵检测系统,从而破坏您的数据层。无论是第一级还是第二级注入攻击,如果您看一下基本的代码模式它与其他任何注入攻击问题都类似,即您在构造语句时都使用了不受信任的数据。大多数开发人员已经开始通过在后端使用参数化SQL查询和存储过程来减少Web前端的这些漏洞,但有些情况下,开发人员仍使用动态构建的SQL,例如根据用户输入或为C/C++编写的应用程序构造数据定义语言(DDL)语句时。在本文中我将讨论一些新观点,其结果可能会修改SQL语句或注入SQL代码,即使代码对分隔字符进行了转义。我首先介绍一些构建分隔标识符和SQL字符串的最佳实践,然后我将介绍攻击者注入SQL代码的几种新方法,以帮助您保护您的应用程序。分隔标识符和字符串在SQLServer中,有两种字符串变量:唯一可识别SQL对象(如表、视图和存储过程)的SQL标识符,以及用于表示数据的字符串。分隔SQL标识符的方法与分隔数据字符串的方法不同。我们将讨论需要使用这些数据变量的动态SQL构建方法的最佳实践。如果SQL对象名使用了关键字,或者对象名中包含了特殊字符,则您需要使用分隔标识符。假如您需要删除my_dbreader登录名,则可以执行以下语句:复制代码DROPLOGINmy_dbreader如果您试着删除一个使用DROP作为其名称(也是关键字)的登录名会怎样?如果您使用以下SQL语句,SQLServer会返回一个语法错误。复制代码DROPLOGINDROP如果您要删除像my][dbreader这样的登录名又会怎样?这也会引发语法错误。在上面两个例子中,由于登录名为关键字或包含特殊字符,因此您需要提供一些开始和结束标记,以便SQLServer可以识别SQL语句中的对象名。您可以使用双引号或方括号作为SQL标识符的分隔符,而在QUOTED_IDENTIFIER设置(一种基于连接的设置)启用时您可以只使用双引号。为简便起见,最好始终使用方括号。要成功删除DROP登录名,您可以使用方括号来构造您的SQL语句:复制代码DROPLOGIN[DROP]但以下语句会怎样?复制代码DROPLOGIN[my][dbreader]在这种特殊情况下,由于登录名my][dbreader中包含分隔字符,因此SQL会认为[my]是登录名,因为它被包含在方括号内。由于[dbreader]跟在登录名后面,因此该语句并不构成正确的SQL语句,会导致语法错误。您可以通过用另一个右方括号对上面的右方括号进行转义来解决这一问题。因此,如果您执行以下语句,SQLServer将成功删除my][dbreader登录名:复制代码DROPLOGIN[my]][dbreader]转义机制只是使右方括号的出现次数增加了一倍。您无需改动其他字符,包括左方括号。准备分隔字符串与准备分隔SQL标识符类似,主要区别就是需要使用的分隔字符。在介绍与构建分隔字符串相似的规则之前,先来看以下几个例子。假设您希望创建dbreader登录名,密码是P@$$w0rd。您会使用以下SQL语句:复制代码CREATELOGIN[dbreader]WITHPASSWORD='P@$$w0rd'在该语句中,P@$$w0rd是由单引号分隔的字符串数据,因此SQL知道该字符串从哪里开始,到哪里结束。但如果字符串数据中包含单引号会怎样?SQLServer会引发一个错误,因为该语句为无效语句:复制代码CREATELOGIN[dbreader]WITHPASSWORD='P@$$'w0rd'您需要对字符串中出现的所有单引号进行转义,构造有效的SQL语句:复制代码CREATELOGIN[dbreader]WITHPASSWORD='P@$$''w0rd'当您执行该语句时,SQLServer将创建dbreader登录名,密码为P@$$'w0rd。您还可以使用双引号作为分隔符,但正如我前面提到的,这种方法是否成功完全取决于QUOTED_IDENTIFIER设置是否已开启。因此,最好始终使用单引号作为字符串的分隔符。T-SQL函数可以看出,处理标识符和字符串的规则相对比较简单,如果您预先知道该字符串,可以手动对其进行分隔。但如果您要根据用户输入构建动态的T-SQL语句,该怎么办?您需要通过自动的方法来完成。两种T-SQL函数可帮您准备分隔字符串,它们是QUOTENAME和REPLACE。QUOTENAME会返回一个Unicode字符串,并添加了分隔符,以使该输入字符串成为有效标识符。QUOTENAME函数使用以下语法:复制代码QUOTENAME('string'[,'delimiter'])您可以将要分隔的字符串和一个用作分隔符的单字符字符串传给QUOTENAME。分隔符可以是方括号、单引号或双引号。此函数主要用于准备分隔SQL标识符,因此它只接受sysname类型,在SQLServer中为nvarchar(128)。您还可以使用此函数准备分隔SQL字符串,但由于参数长度的限制,因此它支持的字符串长度最多为128个字符(在这一点上,REPLACE函数可发挥其用途)。图1显示了sp_addlogin如何使用QUOTENAME来准备分隔登录名和密码字符串。可以看出,由于@loginname和@passwd均为sysname类型,因此可使用QUOTENAME函数准备分隔SQL标识符和分隔字符串。因此,即使有人传递的是@loginname='my[]dbreader'和@passwd='P@$$''w0rd',也不会有任何SQL注入机会,因为QUOTENAME对分隔字符进行了适当转义:复制代码createlogin[my[]]dbreader]withpassword='P@$$''w0rd'Figure1DelimitingStringswithQUOTENAMEREPLACE函数会将某个给定字符串的所有出现之处全部替换为指定的替代字符串。QUOTENAME不同,REPLACE函数对其接受的参数没有长度限制:复制代码REPLACE('stringl','string2','string3')REPLACE带有三个字符串:stringl是要编辑的表达式,string2是stringl中要被替换的项,string3是用于取代string2的项。任何字符串表达式都可由字符或二进制数据组成。要准备分隔SQL字符串,您可以使用REPLACE使单引号的出现次数增加一倍,但您需要手动添加分隔符(开始和结束的单引号)。图2显示了sp_attach_single_file_db如何使用此函数准备一个文件的已转义的物理名称。由于@physname是nvarchar(260),因此您无法使用QUOTENAME准备分隔字符串,这就是为何要使用REPLACE的原因。因此,即使有人传递带单引号的字符串,他们也无法打破SQL语句,注入任何SQL代码。Figure2DelimitingStringswithREPLACESQL注入漏洞接下来介绍存储过程,它可在验证了当前密码后更改用户帐户的密码(参图3)。Figure3ChangingaPassword快速浏览存储过程,会发现没有任何参数对单引号进行转义,这同样容易受至SQL注入攻击。攻击者可以传递几个特定的参数,并将SQL语句修改为:复制代码updateUserssetpassword='NewP@ssw0rd'whereusername='admin'--'andpassword='dummy'结果是,无需实际密码即可设置管理员帐户(或任何已知的帐户)的密码。在T-SQL函数中,您可以通过使用REPLACE或QUOTENAME函数修复此代码。图4显示了使用REPLACE函数后正确的代码。Figure4UsingREPLACEtoAvoidInjection可以看出,REPLACE会将参数中所有单引号的出现次数都增加一倍。因此,如果攻击者传递相同的参数,该语句会变为:复制代码updateUserssetpassword='NewP@ssw0rd'whereusername='admin''--'andpassword='dummy'这样就不容易受到通常的SQL注入问题的影响了。通过截断进行修改如果您仔细留意上面显示的存储过程,您会发现@command变量只能存放100个字符,但当25个字符都为单引号时,这些字符的每个变量经过REPLACE函数处理后可返回50个字符。如果变量没有足够大的缓冲区,SQLServer2000SP4和SQLServer2005SP1会自行截断数据。这就为攻击者提供了截断命令字符串的机会。在此例中,如果有人可以在username='username'表达式后截断命令,那么无需知道已知用户的当前密码,就可更改其帐户的密码。假设攻击者知道administrator用户名存在于Web应用程序中(这可以是任何用户帐户)。攻击者需要提供长度为41个字符的新密码,以使命令的长度足以被适当截断一之所以是41个字符,是因为在用于命令的100个字符中,27个字符用于更新语句,17个字符用于where子句,13个字符用于"administrator”,2个字符用于新密码前后的单引号。攻击者只能传递25个字符作为新密码。但他可以通过传递单引号避开这一限制,因为REPLACE函数会使单引号数量增加一倍。因此,通过传递18个单引号、1个大写字母、1个符号、2个小写字母和1个数字,攻击者就可以截断whereusername='administrator'表达式后面的命令了。如果攻击者将 !Abb1传递给@new参数,并将administrator作为用户名参数,那么@command就会变成:复制代码updateUserssetpassword=,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!Abb1,whereusername='administrator'图5使用QUOTENAME而非REPLACE。上面的例子和此例的唯一不同在于,在上例中,开发人员为用户名、新密码和旧密码添加了单引号分隔符,而在此例中,股UOTENAME函数添加。由于用户提供的数据没有变化,因此上例中使用的同一攻击字符串仍然可以被攻击者利用图6是在中间层应用程序中编写的C/C++函数的缩写版本,可实现相同功能。它容易受到相同的攻击。Figure6TruncationProblemsinC++Figure5UsingQUOTENAMEtoAvoidInjection通过截断进行SQL注入图7显示了相同代码的另一变体,但可使用单独的变量进行修复。可以看出,此代码将转义后的字符串存放在单独的变量中,而且@command有足够的缓冲区来存放整个字符串。@escaped_username、@escaped_oldpw和@escaped_newpw被声明为varchar(25),但如果@username、@old和@new中的所有字符是25个单引号,则它们需要存放50个字符。这就为截断已转义的字符串创造了机会。Figure7UsingSeperateVariablestoAvoidInjection攻击者可以传递123...n'作为新密码,其中n是第24个字符,使@escaped_newpw也成为123...n'(REPLACE函数返回的第二个单引号字符会被截断),使最后的查询如下所示,攻击者可以通过用户名字段注入代码,从而利用此查询:复制代码updateuserssetpassword=T23...n''whereusername='<SQLInjectionhereusingUsername>这种代码模式更危险,因为这为注入SQL代码(而不仅仅是截断现有SQL)提供了机会。图8提供了使用QUOTENAME函数而非REPLACE的同一变体的另一个例子。由于QUOTENAME函数要添加分隔符,因此负载会有所不同,但仍旧容易受到SQL注入攻击。Figure8UsingQUOTENAMEwithSeperateVariables在此例中,代码将分隔后的字符串存放在单独的变量中,而且@command有足够的缓冲区来存放整个命令字符串。正如上例所示,问题在于被引用的变量@quoted_username、@quoted_oldpw和@quoted_newpw。它们都被声明为varchar(25),但如果@username、@old和@new中的所有字符是25个单引号,则它们需要存放52个字符(QUOTENAME还将添加开始和结束的分隔符。)这就为攻击者截断已分隔的字符串创造了机会。攻击者可以传递123...n(其中n是第24个字符)作为新密码,使@escaped_newpw也成为'123...n(开始的单引号由QUOTENAME添加),使最后的查询如下所示,攻击者可以通过用户名字段注入代码,从而利用此查询:复制代码updateuserssetpassword='123...nwhereusername='<SQLInjectionhereusingUsername>图9是C/C++中此代码的缩写版本,可实现相同功能。它同样容易受到相同攻击。Figure9VariableTruncationIssuesinC++尽管我在演示中使用的是T-SQL代码,但实际上您不需要使用动态SQL来构造数据操作语言(DML)语句,因此大多数包含DML代码的应用程序不易受到这些问题的困扰。下面,我们来看看另一个根据用户输入构造动态DDL语句的例子,如图10所示。就像前面的例子一样,以下语句也存在截断问题:复制代码set@escaped_oldpw=quotename(@old,'''')set@escaped_newpw=quotename(@new,'''')攻击者通过传递@new='123...'(其中从第127个字符(无单引号)开始是@old=';SQLInjection'),会使SQL语句如下所示:复制代码alterlogin[loginname]withpassword='123...old_password=';SQLInjectionFigure10CreatingaDynamicDDLStatement尽管存储过程更可能出现这些问题,但并非所有存储过程都会导致安全漏洞。接下来介绍哪些存储过程需要仔细审查。在SQLServer中,默认情况下,所有存储过程都在调用方的环境下执行。因此,即使某个过程存在SQL注入问题,对该过程具有执行权限的恶意的本地用户也无法提高其权限,并且注入的代码会在其环境下执行。但是如果您有内部维护脚本,作为计算机所有者或某个特定用户可以执行该脚本,那么调用方就可以在不同用户环境下执行代码,并将其权限提升为该用户的权限。所有截断问题肯定都是Bug,但它们不一定是安全漏洞。但最好还是修复这些问题,因为您并不知道将来谁会找出这些问题并对其加以利用。您可以采取其他措施减少您的SQL代码中的注入漏洞。首先,在存储过程中避免使用动态SQL来构造DML语句。如果您无法避免使用动态SQL,那么可以使用sp_executesql。第二,正如本文所举的例子中说明的,您需要正确计算缓冲区的长度。最后,在C/C++代码中,检查字符串运算返回值,并查看字符串是否已截断,如果已截断,则相应的结果错误。参见提要懦洞检测方法”,了解您可以采取的措施的摘要。通过截断检测注入要利用自动化工具通过截断问题检测SQL注入,需要对所有会产生截断可能性的代码模式有非常清楚的了解。您可以针对不同的特定代码模式使用不同的字符串数据。在下述情形中,假定?是输入缓冲区的长度。要检测QUOTENAME分隔问题,首先假设使用QUOTENAME(或C/C++应用程序采用的类似函数)来准备分隔标识符或字符串,并且分隔字符串缓冲区大小小于2*n+2。当分隔字符串缓冲区长度等于n时,要捕获这些问题,可传递未分隔的长字符串。尾部分隔符将被截断,利用其他某个输入变量,您将获得注入机会。当分隔缓冲区长度为奇数时,要捕获这些问题,可传递单引号字符或右方括号或双引号)的长字符串。由于QUOTENAME会将所有分隔符出现的次数增加一倍,并添加开始的分隔字符,因此当已转义的字符串缓冲区只能存放奇数个字符时,尾部分隔符会被截断。当分隔缓冲区长度为偶数时,要捕获这些问题,可传递像1'、1''、1'''、1''''等这样的字符串,每次迭代时使单引号(或右方括号)数量递增。由于QUOTENAME会使所有单引号的出现次数增加一倍,因此在返回的字符串中会有偶数个单引号,加上开始的分隔符和1,最终会有偶数个字符。因此,尾部的分隔符会被截断。如果使用REPLACE(或C/C++应用程序采用的类似函数)来准备已转义的字符串,并且当已转义的字符串缓冲区大小小于2勺时,您也可以检测出上述问题。当已转义的字符串缓冲区长度等于?时,要捕获这些问题,可传递像1'、12'、123'和123...n'等这样的字符串,每次迭代时使输入字符串的长度递增。在这种情况下,如果您达到合适的长度,那么REPLACE函数就会将最后一个单引号字符再增加一个。由于已转义的字符串变量不具备足够的缓冲区空间因此最后一个单引号会被截断,并在传递时保存起来,从而为打破SQL语句提供了机会。当已转义的缓冲区长度为奇数时,要通过REPLACE捕获问题,可传递长度逐渐递增的单引号字符串,如’'、’'’和’'''...’(或者只传递单引号字符的长字符串)。在这种情况下,REPLACE将使所有单引号的出现次数增加一倍。但是由于有的缓冲区长度是奇数,因此最后一个单引号会被截断这就为打破语句提供了机会。当已转义缓冲区长
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2026学年海岛夏日教案
- 2025-2026学年关于蚯蚓的教案
- 18.2.2 第1课时 菱形的性质八年级下册数学同步教案(人教版)
- 2024-2025学年5 风儿轻轻吹教案设计
- 1.6细菌和真菌的繁殖 教学设计-2023-2024学年浙教版七年级下册科学
- 2025-2026学年安全教案乖乖吃饭
- 安全负责人培训制度
- 安全生产(管理)责任制度
- 2025-2026学年搞笑天气预报教学目标设计
- 外出打卡制度
- GB/T 713.7-2023承压设备用钢板和钢带第7部分:不锈钢和耐热钢
- 2023年06月上海华东师范大学教育学部行政管理人员招考聘用笔试历年难、易错考点试题含答案解析
- 多彩贵州,魅力贵州
- 全国小学信息技术优质课教学课件-语音识别技术
- CT增强扫描的临床应用演示文稿
- 抗菌药物临床应用指导原则(2015版)
- 新教材人教版2019年高中生物课本课后问题参考答案(全集)
- 海尔集团PIP-绩效改进计划
- GB/T 4338-2006金属材料高温拉伸试验方法
- GB/T 32900-2016光伏发电站继电保护技术规范
- 礼仪11:鞠躬,手势,握手
评论
0/150
提交评论