由于客户端可提交任意输入,Web应用程序的核心安全因此受到威胁。尽管如此,大部分的Web应用程序仍然依靠在客户端执行各种措施,对它提交给服务器的数据进行控制。通常,这种做法造成一个基本的安全缺陷:用户能够完全控制客户端和由其提交的数据,并可以避开任何在客户端执行但服务器并不采用的控件。
应用程序依靠客户端控件限制用户输入表现在两个方面:首先,应用程序可通过客户端组件,使用某种它认为可防止用户修改的机制传送数据。其次,应用程序可在客户端执行保护措施,控制用户与其客户端的交互,从而对功能实施限制,并(或)在提交用户输人之前对这些输入进行控制。我们可通过使用HTML表单功能、客户端脚本或浏览器扩展技术实现这种控制。
应用程序通常以终端用户无法直接查看或修改的方式向客户端传送数据,希望客户端在随后的请求中将这些数据送回服务器。
由于客户端向服务器传送的一切内容都完全处于用户的控制范围内,认为通过客户端传送的数据不会被修改,这种看法往往是错误的,并致使应用程序易于遭受一种或几种攻击。
隐藏HTML表单字段是一种表面看似无法修改,通过客户端传送数据的常用机制。如果一个表单标记为隐藏,它就不会显示在屏幕上。但是,用户提交表单时,保存在表单中的字段名称和值仍被送交给应用程序。
在隐藏表单字段中保存产品价格的零售应用程序就是存在这种安全缺陷的典型示例。在Web应用程序发展的早期阶段,这种漏洞极其普遍,现在也绝没有消失。
创建隐藏表单的代码如下:
❗️❗️❗️表单字段名为price,其被标记为隐藏。用户提交表单时,这个字段将被送交给服务器:
虽然用户无法对price字段进行编辑,但是在客户端进行的一切操作最终将由用户控制,用户需要编辑价格时就可解除这个限制。要实现编辑操作,有以下两种方法:
代理服务器位于Web浏览器和目标应用程序之间。它拦截应用程序发布和收到的每一个HTTP或HTTPS请求和响应。用户可通过它拦截任何消息,对其进行检查或修改。
&emspHTTP cookie是通过客户端传送数据的另一种常用机制。和隐藏表单字段一样,HTTP cookie一般并不显示在屏幕上,也不可由用户直接修改。用户可使用拦截代理服务器,通过更改设置cookie的服务器响应或随后发布这些cookie的客户端请求,对HTTP cookie进行修改。
下面以前面的示例(稍作修改)为例进行说明。消费者登录应用程序后,收到以下响应:
DiscountAgreed cookie是依靠客户端控件(基于cookie一般无法被修改这个事实)保护通过客户端传送的数据的典型示例。如果应用程序信任DiscountAgreed cookie返回给服务器的值,那么消费者修改这个值就可获得任意折扣。例如:
应用程序常常使用预先设定的URL参数通过客户端传送数据。例如,用户浏览产品目录时,应用程序会向他们提供指向下列URL的超链接:
http: / /mdsec.net/shop/ ?prod=3&pricecode=32
如果包含参数的URL显示在浏览器的地址栏中,任何用户不需要使用工具就可任意修改其中的参数。但是,在许多情况下,应用程序并不希望普通用户查看或修改URL参数。例如:
浏览器在大多数HTTP请求中使用Referer消息头。浏览器使用这个消息头指示提出当前请求的页面的URL——或者是因为用户单击了一个超链接或提交了一个表单,或者是因为该页面引用了其他资源(如图像)。因此,我们可以利用这个消息头通过客户端传送数据。
以帮助忘记密码的用户重新设置密码的机制为例。应用程序要求用户按规定的顺序完成几个步骤,然后再通过以下请求重新设置密码值:
应用程序可以使用Referer消息头证实这个请求是在正确的阶段(Admin.ashx)提出的,然后才允许用户访问请求的功能。
但是,因为用户控制着每一个请求,包括HTTP消息头,他可以直接进人CreateUser.ashx,并使用拦截代理服务器将Referer消息头的值修改为应用程序需要的值,从而轻易避开这种控制。
有时候,通过客户端传送的数据被加密或进行了某种形式的模糊处理,因而变得晦涩难懂。有几种方法可以对通过客户端传送的模糊数据实施攻击。
ASP.NETViewState是一种通过客户端传送模糊数据的常用机制。它是一个由ASP.NET Web应用程序默认创建的隐藏字段,其中包含关于当前页面状态的序列化信息。ASP.NET平台使用ViewState提高服务器的性能——服务器通过它在连续提交请求的过程中保存用户界面中的元素,而不需要在服务器端维护所有相关的状态信息。
除这种核心功能外,开发者还在连续提交请求的过程中使用viewState保存任意信息。例如,应用程序可以不将产品价格保存在隐藏表单字段中,而是将其保存在viewState中,如下所示:
返回给用户的表单如下:
很显然,上面的请求中并不包含产品价格——只有订购的数量和模糊处理后的ViewState参数。随意更改这个参数将会导致应用程序显示错误消息,导致交易终止。
ViewState参数实际上是一个Base64编码字符串,用户可以轻松对这个字符串进行解码,以查看其代表的价格参数,如下所示:
在对一个可能为Base64编码的字符串进行解码时,可能会犯一个错误,即从字符串的错误位置开始解码。鉴于Base64编码的特点,如果从错误的位置开始解码,解码后的字符串中会出现乱码。Base64采用基于数据块的格式,每4字节的编码数据解码后会变为3个字节。因此,如果解码后的Base64字符串并无意义,请尝试从编码字符串中的4个相邻的偏移值位置开始解码。
此外,默认情况下,ASP.NET平台通过在ViewState中加人一个密钥散列(称为MAC保护)来防止篡改。但是,一些应用程序禁用了这项默认启用的保护,这意味着攻击人员可以修改viewstate的值,以确定其是否会对应用程序的服务器端处理产生影响。
Burp Proxy提供一个指示ViewState是否受MAC保护的viewState解析器,如下图所示。如果ViewState未受到保护,则攻击人员可以使用viewState树下的十六进制编辑器在Burp中编辑ViewState的内容。在向服务器或客户端发送消息时,Burp将发送经过更新的ViewState。
渗透测试步骤: