科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网安全频道数据安全小心你的WEB应用程序成为数据窃贼的帮凶(二)

小心你的WEB应用程序成为数据窃贼的帮凶(二)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在上一篇文章中,我们介绍了攻击者如何通过SQL注入攻击来利用Web应用程序的漏洞。本文我们将继续介绍SQL注入攻击的两种方法,并举例自动SQL注入。

来源:TechTarget中国 2011年9月27日

关键字: 数据泄漏 Web应用安全

  • 评论
  • 分享微博
  • 分享邮件

  在上一篇文章中,我们介绍了攻击者如何通过SQL注入攻击来利用Web应用程序的漏洞。本文我们将继续介绍SQL注入攻击的两种方法,并举例自动SQL注入。

  自动攻击

  攻击者可以使用两种主要的攻击方法来利用SQL注入漏洞:自动攻击和手动攻击。从字面上看似乎很容易理解,但这两种攻击在机制上是非常不同的。自动攻击一般是为特定目的而编制的一种工具所导致的结果。例如,有的攻击使用大规模的注入攻击,其目的是为了让其攻击范围最大化并任意扩散其代码。这种大规模的攻击一般针对非常具体的应用程序架构,如运行ASP的IIS服务器等。而Asprox攻击,其目的是为了将一个JavaScript或iframe标记注入到网页中,从而传播病毒。

  自动SQL注入举例

  下面是一个高级SQL注入攻击的例子,它能够注入到某些字段类型中。很长一段时间以来,此类代码可以有效的帮助攻击者传播病毒。

  wangzhan.com/ssp.asp?username=zhangsan’;DECLARE @T VARCHAR  (255),@C VARCHAR(255) DECLARE TABLE_CURSOR CURSOR FOR SELECT   A.NAME,B.NAME FROM SYSOBJECTS A,SYSCOLUMNS B WHERE A.ID=B.ID AND   A.XTYPE=‘U’ AND (B.XTYPE=99 OR
  B.XTYPE=35 OR B.XTYPE=231 OR B.XTYPE=167) OPEN TABLE_CURSOR FETCH   NEXT
  FROM TABLE_CURSOR INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN 
  EXEC(‘UPDATE [‘+@T+’] SET
  [‘+@C+’]=RTRIM(CONVERT(VARCHAR(4000),[‘+@C+’]))+’<script   code>‘) FETCH NEXT FROM TABLE_CURSOR INTO @T,@C END CLOSE   TABLE_CURSOR DEALLOCATE TABLE_CURSOR;--

  下面,我们简单地看一下这段代码是如何针对后端数据库实施攻击的。首先,攻击者声明了Table (T) 和 Column (C)这两个变量。

  DECLARE @T VARCHAR(255),@C VARCHAR(255)

  并声明了一个可以保存查询结果的表cursor:

  DECLARE TABLE_CURSOR CURSOR FOR

  下面的SELECT语句通过“text”、“sysname”、“varchar”等列来检索所有的用户对象,并且将结果存储在前面创建的CURSOR中。

  SELECT A.NAME,B.NAME FROM SYSOBJECTS A,SYSCOLUMNS B WHERE A.ID=B.ID AND A.XTYPE=‘U’ AND (B.XTYPE=99 OR B.XTYPE=35 OR B.XTYPE=231 OR B.XTYPE=167)

  在下面的代码中,数据表CURSOR检索结果,并将其分配给表和列变量:

  OPEN TABLE_CURSOR FETCH NEXT FROM TABLE_CURSOR INTO @T,@C WHILE(@@FETCH_STATUS=0)

  此时,攻击者已经检索了数据库中基于文本的这些列,其意图是为了修改这些列的内容。在这里,攻击者虽然没有篡改数据,但已经完成了所有必要的侦察。然后,执行更新语句,将JavaScript置于列变量中的每一列中。攻击完成后,包含Web内容(这些内容源自数据库的任何字段)的任何网页都会提交攻击者的恶意JavaScript代码。然后,该JavaScript用一个病毒感染Web用户的计算机:

  WHILE(@@FETCH_STATUS=0) BEGIN EXEC(‘UPDATE [‘+@T+’] SET [‘+@C+’]=RTRIM(CONVERT(VARCHAR(4000),[‘+@C+’]))+’<script code>‘) FETCH NEXT FROM TABLE_CURSOR INTO @T,@C END

  在注入的结尾,攻击者执行清理,覆盖所有的攻击痕迹:

  CLOSE TABLE_CURSOR DEALLOCATE TABLE_CURSOR;--

  这些攻击是完全自动化的;黑客攻击只需使用搜索引擎简单地搜索互联网,查找运行经典的ASP代码的Web服务器即可。别再自欺欺人的相信“我的网站很小,谁会愿意攻击它呢?”这种愚蠢的谎言。如果你正在通过互联网做商务,不管企业大小,都易于遭到攻击。

  接管

  在很多情况下,攻击者能够完全控制SQL服务器的底层操作系统;攻击者甚至可以接管Web应用程序,并最终接管Web服务器。

  接管数据库服务器可以导致损害其它的应用程序,甚至损害DMZ中的其它服务器。现代的Web应用程序架构一般都有数据库集群,与其它系统共享数据存储,或者位于网络中不太安全的地方。如果攻击者考虑到这个方面,他就可以使用前面提到的方法绕过防火墙中一般的IP源过滤规则,从而攻击内部网络,甚至还可以使用SQL服务器来存储病毒、黄色图片或其它非法内容。

  此外,通过首先接管数据库服务器,攻击者可以篡改Web应用程序的行为。通常,这种行为包括借助Web服务器的服务账户在本地服务器上运行命令。如果服务账户有了被提升的特权,攻击者就可以通过数据库服务器,将命令直接发送给Web服务器的操作系统。

  有时,数据是根据计划例程从DMZ数据库服务器析取出来的。如果通过公司Intranet(内联网)中的Web接口来查看数据,情况就更危险,因为多数内联网的Web应用程序在运行时,其信任等级更高。

  不要小看盲目攻击

  通常,控制框架会把SQL错误搞得不易分辨,如Java或.NET框架。有时,这些错误是由错误处理代码自动处理的,或者是由底层的代码解释程序处理的。例如,攻击者可以使用撇号(‘)而不是合法的输入:

  wangzhan.com/userdetail.asp?username=‘

  其结果为:用户未找到。

  这就告诉我们,Web应用程序正在正确地检查用户输入,或者是程序框架正在阻止显示明显的错误消息。在这种情况下,执行SQL注入就变得困难了,但并不是不可能。这就引出了下一种攻击:盲目SQL注入。

  盲目SQL注入攻击是如何工作的呢?它要查看数据库服务器是否真正地处理请求,或者查看该请求是否会触发来自Web服务器或SQL服务器的其它响应。

  例如,我们已经看到了能够向我们提供张三(Zhangsan)用户细节的请求,能够看出该攻击是否成功。不过,“WAITFOR DELAY”命令要求SQL服务器在用查询结果响应之前,先暂停一分钟。

  wangzhan.com/userdetail.asp?username=zhangsan;WAITFOR DELAY ‘0:1:0’—

  如果网站能够正确地处理用户输入,它应当返回一个消息,说明找不到用户,或者发出其它的通知,说明“zhangsan;WAITFOR DELAY ‘0:1:0’--”不是一个合法用户。

  必须指出,只有在将用户名变量的值被提交给SQL服务器时,并且Web应用程序能够正确地处理用户名变量的值时,才会出现这种情况。

  传统的SQL注入将会返回错误,让用户知道有关查询失败的原因的细节。从本质上讲,盲目SQL注入依赖的是一种来自服务器的布尔逻辑响应(是/否,真/假等):查询请求要么被处理,要么遭遇失败。盲目SQL注入攻击一旦得以发现,它就会提供与典型的SQL注入一样的功能,但它更难以执行,为了获取信息也需要更多的时间。

  让盲目攻击起作用

  假设在示例页面中,我们已经发现了盲目注入,我们希望发现关于表和数据库设计的细节。请看下面的请求:

  wangzhan.com/userdetail.asp?username=zhangsan AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtype=0x55),1,1)),0)>65—

  如果我们分解一下,会看出这个查询的结果实际上是一个是或否的回答,“这个表名的第一个字符是一个比65大的ASCII值吗?”先看最里面的查询:
SELECT TOP 1 name from sysObjects WHERE xtype=0x55

  这意味着:获取来自sysObjects(所有的表)列表最上面的一个名字,其xtype(对象类型)等于ASCII码0x55(大写的字母“U”),转换成用户(user)表。所以,基本而言,我们获取了用户在数据库中所创建的第一个表。为简单起见,假设这个表就是“users”:

  SUBSTRING(users),1,1

  现在,我们创建了一个子串,它包含了表名users的首个字符。其值为“u”:

  ISNULL(ASCII(u),0)>65

  在这里我们查看u的ASCII码值的结果是否大于65,确认表名以字母开头。如果答案是肯定的,查询就会被处理。否则,查询就不会被处理。

  使用这种方法,我们可以对每个查询简单地增加数字,从而发现首个用户名的第一个字母。例如,假设我们在大于117时(>117)得到了一个否定的响应,我们知道第一个字母是字母“u”,因为“u”的ASCII值是117。在发现这一点之后,我们可以简单地改变SUBSTRING参数来选择第二个字母,然后是第三个字母,等等。

  最后,在没有错误代码时,我们借助于盲目注入就可以发现有漏洞的Web应用程序的数据库的完整的表结构。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章