基于SOAP的Web服务攻击及防范
摘要:该文讨论了基于SOAP协议的Web服务攻击的方法,进行了攻击的实验,并针对实验结果提出了防止攻击的措施。
关键词:SOAP Web Service SQL欺骗攻击
Web Services的广泛应用使当今互联网上应用程序之间的通信日益增加。Web Service已经成为各大公司进行电子商务革命的理想选择。
SOAP(简单对象访问协议)也已经成为W3C推荐的标准,SOAP的目的是使各种不同的组件实现远程通信时就像在本地一样。
1、 SOAP通信
SOAP是一种简单、轻便的以XML为基础的协议,在Web上进行结构化、类型化数据的交换。SOAP的Envelope结构有两种:请求和响应。
请求Envelope包括了进行远程调用所需的信息。每个调用消息包括消息头和消息体。消息头存储消息路由,安全信息等内容,消息体存储的是处理调用所需的信息。包括以下几个内容:
? 调用的服务的名称
? 服务的位置
? 传给服务的参数名和数据
响应Envelope返回结果数据。成功返回的响应包括以下几个内容:
? 调用的方法
? 返回值的类型
? 返回的数据
2、SQL欺骗攻击SOAP Web 服务的实例
SQL欺骗攻击是经常使用的攻击方式。
一般Web Service把客户端传递的参数作为String来接收,如果服务没有对字符串做严格的输入检查,也就是说对输入参数进行验证或简化不安全的字符。那么,程序很容易就受到SQL欺骗攻击。比如,攻击者在参数中加入了一个单引号字符,程序在接收参数时如果不做检查,程序根据输入的参数生成了SQL查询语句,而单引号的出现势必会引发不安全的返回值,这个服务就已经遭到了攻击。
当然,Web服务的方法一般都指定了每个参数的数据类型。那么攻击者尝试在一个需要整型参数的Web方法上进行SQL参数欺骗就不会那么容易。在参数字符串中加入单引号将会导致SOAP执行后返回一个客户端错误信息,进行欺骗的参数不会传给调用的方法。
2.1攻击步骤1——了解Web Service的弱点
SQL欺骗攻击的第一步是确定是否Web服务对输入参数是否进行验证和检查。下面是一个用C#编写的简单的基于SOAP的Web服务的例子。这个Web服务实现了一个简单的产品目录系统,包括产品信息、供应商信息和供应商所给的折扣。本例中我们使用的user ID 为551-457-4487,password 为123456。程序除了指定了每个参数的数据类型,还包含了每个参数的具体说明。这个服务包括以下四个方法:
图1 Web服务中的四个方法
服务将从数据库中查询出相关数据。
首先我们要了解有关服务器和参数的信息,实验1中我们将一些参数传给GetProductInformationByName方法,看看服务器对这些参数是如何响应的。同时我们知道Name参数的数据类型为String,这是很容易遭到参数欺骗攻击的一种数据类型。
图2 实验1(在name参数中输入“’”以及服务器的响应)
从上面服务器的响应可以看出,Web方法对ProductName参数没有进行最基本的参数检查。根据服务器返回的FaultString来看,Web服务存取的信息是存储在后台数据库中的。对FaultString做仔细分析,我们可以了解Web服务内部处理的过程以及问题出现在哪里。FaultString表示Web服务出现了异常。如图2所示,在FaultString的最后几行看到我们所调用的web方法是ProductInfo.ProductInfo.GetProductInformationByName(String name,String uid,String password)。内部调用ProductDBAcess.GetProductInformation(String productName,String uid,String password)用来与后台数据库通信。传入数据库中的SQL查询语句中有一个语法错误。System.Data.OleDb.OleDbException:语法错误(缺少操作符)in query expression ‘productname like ‘‘’ and providerid=’551-457-4487’ ,这句话告诉我们内部的SQL查询使用了SQL语句的LIKE表达式,应用程序根据我们给出的用来欺骗的单引号等参数生成最终的SQL查询语句。通过以上分析,我们知道既然Web服务使用了Like表达式,那么我们用通配符%作为参数,来观察应用程序如何响应。我们想定的结果是程序将返回至少一个产品记录。
图3 实验2(在参数中输入“%”及服务器响应)
从图3可以看出,正如我们所想定的,服务器返回了一条产品记录。但我们发现,服务器只返回了一条记录而不是全部的记录。逻辑上来说,输入通配符%,内部查询应该返回所有的产品记录。但是,我们定义的GetProductInformationByName方法,返回参数的类型是String而不是ArrayOfString。这是SOAP协议进行强制的类型和输入输出编码检查的一个方面。
通过实验1和实验2,我们可以得到结论——SQL的Like表达式可以返回一些我们本不能得到的信息。Web服务本应该确认用户身份,而且在技术上来说,不能显示与参数Providerid无关的产品信息。我们要进行Web服务的欺骗,我们就要想办法利用现有的用户认证得到更多的产品信息。分析GetProductInformationByName方法用户认证的执行过程,实验3中我们还是利用实验1中对name参数采用的方法,将单引号插入uid参数,看看是否会影响用户认证SQL表达式。
’
图4 实验3(在用户id参数中加入“’”及服务器返回的结果)
在这个实验的想定中,服务器返回的FaultSstring告诉我