Web应用程序使用各种不同的技术实现其功能。本章简要介绍渗透测试员在攻击Web应用程序时可能遇到的关键技术。我们将分析HTTP协议、服务器和客户端常用的技术以及用于在各种情形下呈现数据的编码方案。这些技术大都简单易懂,掌握其相关特性对于向Web应用程序发动有效攻击极其重要。
如果读者已经熟悉Web应用程序所使用的关键技术,可以快速浏览本章内容,确定其中没有不了解的技术。如果还在学习Web应用程序的工作原理,那么在继续阅读分析特殊漏洞的后续章节前,应当先阅读本章内容。为了进一步学习本书后续章节涉及的内容,我们推荐读者阅读David Gourley和Brian Totty合著的HTTP: The Definitive Guide一书(O'Reilly,2002),也可在万维网联盟网站(www.w3.02g)上阅读电子版。
HTTP(HyperText Transfer Protocol,超文本传输协议)是访问万维网使用的核心通信协议,也是今天所有Web应用程序使用的通信协议。最初,HTTP只是一个为获取基于文本的静态资源而开发的简单协议,后来人们以各种形式扩展和利用它,使其能够支持如今常见的复杂分布式应用程序。
HTTP使用一种基于消息的模型:客户端送出一条请求消息,而后由服务器返回一条响应消息。该协议基本上不需要连接,虽然HTTP使用有状态的TCP协议作为它的传输机制,但每次请求与响应交换都自动完成,并且可能使用不同的TCP连接。
所有HTTP消息(请求与响应)中都包含一个或几个单行显示的消息头(header),然后是一个强制空白行,最后是消息主体(可选)。以下是一个典型的HTTP请求:
每个HTTP请求的第一行都由3个以空格间隔的项目组成。
一个说明HTTP方法的动词。最常用的方法为GET,它的主要作用是从Web服务器获取一个资源。GET请求并没有消息主体,因此在消息头后的空白行中没有其他数据。
所请求的URL。该URL通常由所请求的资源名称,以及一个包含客户端向该资源提交的参数的可选查询字符串组成。在该URL中,查询字符串以?字符标识,上面的示例中有一个名为uid、值为129的参数。
使用的HTTP版本。因特网上常用的HTTP版本为1.0和1.1,多数浏览器默认使用1.1版本。这两个版本的规范之间存在一些差异;然而,当攻击Web应用程序时,渗透测试员可能遇到的唯一差异是1.1版本必须使用Host请求头。
请求示例中的其他一些要点如下。
Referer消息头用于表示发出请求的原始URL(例如,因为用户单击页面上的一个链接)。请注意,在最初的HTTP规范中,这个消息头存在拼写错误,并且这个错误一直保留了下来。
User-Agent消息头提供与浏览器或其他生成请求的客户端软件有关的信息。请注意,由于历史原因,大多数浏览器中都包含Mozilla前缀。这是因为最初占支配地位的Netscape浏览器使用了User-Agent字符串,而其他浏览器也希望让Web站点相信它们与这种标准兼容。与计算领域历史上的许多怪异现象一样,这种现象变得很普遍,即使当前版本的Internet Explorer也保留了这一做法,示例的请求即由Internet Explorer提出。
Host消息头用于指定出现在被访问的完整URL中的主机名称。如果几个Web站点以相同的一台服务器为主机,就需要使用Host消息头,因为请求第一行中的URL内通常并不包含主机名称(请参阅第17章了解更多与虚拟主机Web站点有关的信息)。
Cookie消息头用于提交服务器向客户端发布的其他参数(请参阅本章后续内容了解更多详情)。
以下是一个典型的HTTP响应:
每个HTTP响应的第一行由3个以空格间隔的项目组成。
使用的HTTP版本。
表示请求结果的数字状态码。200是最常用的状态码,它表示成功提交了请求,正在返回所请求的资源。
一段文本形式的“原因短语”,进一步说明响应状态。这个短语中可包含任何值,当前浏览器不将其用于任何目的。
响应示例中的其他一些要点如下。
Server消息头中包含一个旗标,指明所使用的Web服务器软件。有时还包括其他信息,如所安装的模块和服务器操作系统。其中包含的信息可能并不准确。
Set-Cookie消息头向浏览器发送另一个cookie,它将在随后向服务器发送的请求中由Cookie消息头返回。
Pragma消息头指示浏览器不要将响应保存在缓存中。Expires消息头指出响应内容已经过期,因此不应保存在缓存中。当返回动态内容时常常会发送这些指令,以确保浏览器随时获得最新内容。
几乎所有的HTTP响应在消息头后的空白行下面都包含消息主体,Content-Type消息头表示这个消息主体中包含一个HTML文档。
Content-Length消息头规定消息主体的字节长度。
当渗透测试员攻击Web应用程序时,几乎肯定会遇到最常用的方法:GET和POST。这些方法之间存在一些必须了解的重要差异,忽略这些差异可能会危及应用程序的安全。
GET方法的作用在于获取资源。它可以用于URL查询字符串的形式向所请求的资源发送参数。这使用户可将一个包含动态资源的URL标注为书签,用户自己或其他用户随后可重复利用该书签来获取等价的资源(作用与标注为书签的搜索查询相似)。URL显示在屏幕上,并被记录在许多地方,如浏览器的历史记录和Web服务器的访问日志中。如果单击外部链接,还可以用Referer消息头将它们传送到其他站点。因此,请勿使用查询字符串传送任何敏感信息。
POST方法的主要作用是执行操作。使用这个方法可以在URL查询字符串与消息主体中发送请求参数。尽管仍然可以将URL标注为书签,但书签中并不包含消息主体发送的任何参数。许多维护URL日志的位置及Referer消息头也将这些参数排除在外。因为POST方法旨在执行操作,如果用户单击浏览器上的“后退”按钮,返回一个使用这种方法访问的页面,那么浏览器不会自动重新发送请求,而是就即将发生的操作向用户发出警告,如图3-1所示。这样做可防止用户无意中多次执行同一个操作。因此,在执行某一操作时必须使用POST请求。
图3-1 浏览器不会自动重新发送用户提出的POST请求,因为这样做会导致多次执行某一操作
除了GET和POST方法以外,HTTP协议还支持许多其他因特殊目的而建立的方法。需要了解的其他方法如下。
HEAD。这个方法的功能与GET方法相似,不同之处在于服务器不会在其响应中返回消息主体。服务器返回的消息头应与对应GET请求返回的消息头相同。因此,这种方法可用于检查某一资源在向其提交GET请求前是否存在。
TRACE。这种方法主要用于诊断。服务器应在响应主体中返回其收到的请求消息的具体内容。这种方法可用于检测客户端与服务器之间是否存在任何操纵请求的代理服务器。
OPTIONS。这种方法要求服务器报告对某一特殊资源有效的HTTP方法。服务器通常返回一个包含Allow消息头的响应,并在其中列出所有有效的方法。
PUT。这个方法试图使用包含在请求主体中的内容,向服务器上传指定的资源。如果激活这个方法,渗透测试员就可以利用它来攻击应用程序。例如,通过上传任意一段脚本并在服务器上执行该脚本来攻击应用程序。
还有许多其他与攻击Web应用程序没有直接关系的HTTP方法。然而,如果激活某些危险的方法,Web服务器可能面临攻击风险。请参阅第18章了解更多关于这些方法的详情,以及在攻击中使用它们的示例。
URL(Uniform Resource Locator,统一资源定位符)是标识Web资源的唯一标识符,通过它即可获取其标识的资源。最常用的URL格式如下:
这个结构中有几个部分是可选的。如果端口号与相关协议使用的默认值不同,则只包含端口号即可。用于生成前面的HTTP请求的URL为:
除这种绝对形式外,还可以相对某一特殊主机或主机上的一个特殊路径指定URL,例如:
Web页面常常使用这些相对形式描述Web站点或应用程序中的导航。
注解 URL的正确技术术语实际为URI(Uniform Resource Identifier,统一资源标识符),但这一术语仅用于正式规范中,或者被那些希望炫耀学识的人所使用。
表述性状态转移(REST)是分布式系统的一种体系架构,在这类体系架构中,请求和响应包含系统资源当前状态的表述。万维网,包括HTTP协议和URL格式中使用的核心技术,均符合REST体系架构风格。
虽然在查询字符串中包含参数的URL本身遵循REST约束,但“REST风格的URL”一词通常指在URL文件路径而非查询字符串中包含参数的URL。例如,下面这个包含查询字符串的URL:
与以下包含“REST风格”参数的URL相对应:
在第4章中,我们将讨论如何在解析应用程序的内容和功能、以及确定其受攻击面时处理这些不同风格的参数。
HTTP支持许多不同的消息头,其中一些专用于特殊用途。一些消息头可用在请求与响应中,而其他一些消息头只能专门用在某个特定的消息中。下面列出渗透测试员在攻击Web应用程序时可能遇到的消息头。
Connection。这个消息头用于告诉通信的另一端,在完成HTTP传输后是关闭TCP连接,还是保持连接开放以接收其他消息。
Content-Encoding。这个消息头为消息主体中的内容指定编码形式(如gzip),一些应用程序使用它来压缩响应以加快传输速度。
Content-Length。这个消息头用于规定消息主体的字节长度。(HEAD语法的响应例外,它在对应的GET请求的响应中指出主体的长度。)
Content-Type。这个消息头用于规定消息主体的内容类型。例如,HTML文档的内容类型为 text/html。
Transfer-Encoding。这个消息头指定为方便其通过HTTP传输而对消息主体使用的任何编码。如果使用这个消息头,通常用它指定块编码。
Accept。这个消息头用于告诉服务器客户端愿意接受哪些内容,如图像类型、办公文档格式等。
Accept-Encoding。这个消息头用于告诉服务器,客户端愿意接受哪些内容编码。
Authorization。这个消息头用于为一种内置HTTP身份验证向服务器提交证书。
Cookie。这个消息头用于向服务器提交它以前发布的cookie。
Host。这个消息头用于指定出现在所请求的完整URL中的主机名称。
If-Modified-Since。这个消息头用于说明浏览器最后一次收到所请求的资源的时间。
如果自那以后资源没有发生变化,服务器就会发出一个带状态码304的响应,指示客户端使用资源的缓存副本。
If-None-Match。这个消息头用于指定一个实体标签。实体标签是一个说明消息主体内容的标识符。当最后一次收到所请求的资源时,浏览器提交服务器发布的实体标签。服务器可以使用实体标签确定浏览器是否使用资源的缓存副本。
Origin。这个消息头用在跨域Ajax请求中,用于指示提出请求的域(请参阅第13章了解相关内容)。
Referer。这个消息头用于指示提出当前请求的原始URL。
User-Agent。这个消息头提供与浏览器或生成请求的其他客户端软件有关的信息。
Access-Control-Allow-Origin。这个消息头用于指示可否通过跨域Ajax请求获取资源。
Cache-Control。这个消息头用于向浏览器传送缓存指令(如M-cache)。
ETag。这个消息头用于指定一个实体标签。客户端可在将来的请求中提交这个标识符,获得和If-None-Match消息头中相同的资源,通知服务器浏览器当前缓存中保存的是哪个版本的资源。
Expires。这个消息头用于向浏览器说明消息主体内容的有效时间。在这个时间之前,浏览器可以使用这个资源的缓存副本。
Location。这个消息头用于在重定向响应(那些状态码以3开头的响应)中说明重定向的目标。
Pragma。这个消息头用于向浏览器传送缓存指令(如no-cache)。
Server。这个消息头提供所使用的Web服务器软件的相关信息。
Set-Cookie。这个消息头用于向浏览器发布cookie,浏览器会在随后的请求中将其返回给服务器。
WWW-Authenticate。这个消息头用在带401状态码的响应中,提供与服务器所支持的身份验证类型有关的信息。
X-Frame-Options。这个消息头指示浏览器框架是否及如何加载当前响应(请参阅第13章了解相关内容)。
cookie是大多数Web应用程序所依赖的HTTP协议的一个关键组成部分,攻击者常常通过它来利用Web应用程序中的漏洞。服务器使用cookie机制向客户端发送数据,客户端保存cookie并将其返回给服务器。与其他类型的请求参数(存在于URL查询字符串或消息主体中)不同,无须应用程序或用户采取任何特殊措施,随后的每一个请求都会继续重新向服务器提交cookie。
如前所述,服务器使用Set-Cookie响应消息头发布cookie:
然后,用户的浏览器自动将下面的消息头添加到随后返回给同一服务器的请求中:
如上所示,cookie一般由一个名/值对构成,但也可包含任何不含空格的字符串。可以在服务器响应中使用几个Set-Cookie消息头发布多个cookie,并可在同一个Cookie消息头中用分号分隔不同的cookie,将它们全部返回给服务器。
除cookie的实际值外,Set-Cookie消息头还可包含以下任何可选属性,用它们控制浏览器处理cookie的方式。
expires。用于设定cookie的有效时间。这样会使浏览器将cookie保存在永久性的存储器中,在随后的浏览器会话中重复利用,直到到期时间为止。如果没有设定这个属性,那么cookie仅用在当前浏览器会话中。
domain。用于指定cookie的有效域。这个域必须和收到cookie的域相同,或者是它的父域。
path。用于指定cookie的有效URL路径。
secure。如果设置这个属性,则仅在HTTPS请求中提交cookie。
HttpOnly。如果设置这个属性,将无法通过客户端JavaScript直接访问cookie。
上述每一个cookie属性都可能影响应用程序的安全,其造成的主要不利影响在于攻击者能够直接对应用程序的其他用户发动攻击。请参阅第12章和第13章了解更多详情。
每条HTTP响应消息都必须在第一行中包含一个状态码,说明请求的结果。根据代码的第一位数字,可将状态码分为以下5类。
1xx——提供信息。
2xx——请求被成功提交。
3xx——客户端被重定向到其他资源。
4xx——请求包含某种错误。
5xx——服务器执行请求时遇到错误。
还有大量特殊状态码,其中许多状态码仅用在特殊情况下。下面列出渗透测试员在攻击Web应用程序时最有可能遇到的状态码及其相关的原因短语。
100 Continue。当客户端提交一个包含主体的请求时,将发送这个响应。该响应表示已收到请求消息头,客户端应继续发送主体。请求完成后,再由服务器返回另一个响应。
200 Ok。本状态码表示已成功提交请求,且响应主体中包含请求结果。
201 Created。PUT请求的响应返回这个状态码,表示请求已成功提交。
301 Moved Permanently。本状态码将浏览器永久重定向到另外一个在Location消息头中指定的URL。以后客户端应使用新URL替换原始URL。
302 Found。本状态码将浏览器暂时重定向到另外一个在Location消息头中指定的URL。客户端应在随后的请求中恢复使用原始URL。
304 Not Modified。本状态码指示浏览器使用缓存中保存的所请求资源的副本。服务器使用If-Modified-Since与If-None-Match消息头确定客户端是否拥有最新版本的资源。
400 Bad Request。本状态码表示客户端提交了一个无效的HTTP请求。当以某种无效的方式修改请求时(例如在URL中插入一个空格符),可能会遇到这个状态码。
401 Unauthorized。服务器在许可请求前要求HTTP进行身份验证。WWW-Authenticate消息头详细说明所支持的身份验证类型。
403 Forbidden。本状态码指出,不管是否通过身份验证,禁止任何人访问被请求的资源。
404 Not Found。本状态码表示所请求的资源并不存在。
405 Method Not Allowed。本状态码表示指定的URL不支持请求中使用的方法。例如,如果试图在不支持PUT方法的地方使用该方法,就会收到本状态码。
413 Request Entity Too Large。如果在本地代码中探查缓冲器溢出漏洞并就此提交超长数据串,则本状态码表示请求主体过长,服务器无法处理。
414 Request URI Too Long。与前一个响应类似,本状态码表示请求中的URL过长,服务器无法处理。
500 Internal Server Error。本状态码表示服务器在执行请求时遇到错误。当提交无法预料的输入、在应用程序处理过程中造成无法处理的错误时,通常会收到本状态码。应该仔细检查服务器响应的所有内容,了解与错误性质有关的详情。
503 Service Unavailable。通常,本状态码表示尽管Web服务器运转正常,并且能够响应请求,但服务器访问的应用程序还是无法作出响应。应该进行核实,是否因为执行了某种行为而造成这个结果。
HTTP使用普通的非加密TCP作为其传输机制,因此,处在网络适当位置的攻击者能够截取这个机制。HTTPS本质上与HTTP一样,都属于应用层协议,但HTTPS通过安全传输机制——安全套接层(Secure Socket Layer,SSL)——传送数据。这种机制可保护通过网络传送的所有数据的隐密性与完整性,显著降低非入侵性拦截攻击的可能性。不管是否使用SSL进行传输,HTTP请求与响应都以完全相同的方式工作。
注解 如今的SSL实际上已经由TLS(Transport Layer Security,传输层安全)代替,但后者通常还是使用SSL这个名称。
HTTP代理服务器是一个协调客户端浏览器与目标Web服务器之间访问的服务器。当配置浏览器使用代理服务器时,它会将所有请求提交到代理服务器,代理服务器再将请求转送给相关Web服务器,并将响应返回给浏览器。大多数代理还使用其他服务,如缓存、验证与访问控制。
值得注意的是,如果使用代理服务器,HTTP的工作机制会出现两方面的差异。
当浏览器向代理服务器发布HTTP请求时,它会将完整的URL(包括协议前缀http://与服务器主机名称,在非标准URL中,还包括端口号)插入请求中。代理服务器将提取主机名称和端口,并使用这些信息将请求指向正确的目标Web服务器。
当使用HTTPS时,浏览器无法与代理服务器进行SSL握手,因为这样做会破坏安全隧道,使通信易于遭受拦截攻击。因此,浏览器必须将代理作为一个纯粹的TCP级中继,由它传递浏览器与目标Web浏览器之间的所有网络数据,并与浏览器进行正常的SSL握手。浏览器使用CONNECT方法向代理服务器提交一个HTTP请求,并指定URL中的目标主机名称与端口号,从而建立这种中继。如果代理允许该请求,它会返回一个含200状态码的HTTP响应,一直开放TCP连接,从此以后作为目标Web服务器的纯粹TCP级中继。
从某种程度上说,攻击Web应用程序时最有用的工具是一个处在浏览器与目标Web站点之间的专用代理服务器,使用它可以拦截并修改所有使用HTTPS的请求与响应。我们将在第4章开始分析如何使用这种工具。
HTTP拥有自己的用户身份验证机制,使用不同的身份验证方案。
Basic。这是一种非常简单的身份验证机制,它在请求消息头中随每条消息以Base64编码字符串的形式发送用户证书。
NTLM。这是一种质询-响应式机制,它使用某个Windows NTLM协议版本。
Digest。这是一种质询-响应式机制,它随同用户证书一起使用一个随机值MD5校验和。
虽然组织内部经常使用这些身份验证协议访问内联网服务,但因特网上的Web应用程序基本很少使用它们。
错误观点 “基本身份验证并不安全。”
基本身份验证将未加密的证书插入HTTP请求中,因此,人们普遍认为这种协议并不安全,不应该使用它们。但实际上,许多银行使用的基于表单的身份验证也将未加密的证书插入HTTP请求中。
可以使用HTTPS作为传输机制,防止任何HTTP消息受到窃听攻击;每一个具有安全意识的应用程序都应采用这种机制。至少从窃听方面来说,基本身份验证机制并不比今天绝大多数Web应用程序使用的身份验证机制更加糟糕。
除了在客户端与服务器之间发送消息时使用的核心通信协议外,Web应用程序还使用许多不同的技术来实现其功能。任何具有一定功能的应用程序都会在其服务器与客户端组件中采用若干种技术。在向Web应用程序发动猛烈攻击前,渗透测试员必须对应用程序如何实现其功能、所使用技术的运作方式及其可能存在的弱点有一个基本的了解。
早期的万维网仅包含静态内容。Web站点由各种静态资源组成,如HTML页面与图片;当用户提交请求时,只需将它们加载到Web服务器,再传送给用户即可。每次用户请求某个特殊的资源时,服务器都会返回相同的内容。
如今的Web应用程序仍然使用相当数量的静态资源。但它们主要向用户提供动态生成的内容。当用户请求一个动态资源时,服务器会动态建立响应,每个用户都会收到满足其特定需求的内容。
动态内容由在服务器上执行的脚本或其他代码生成。在形式上,这些脚本类似于计算机程序:它们收到各种输入,并处理输入,然后向用户返回输出结果。
当用户的浏览器提出访问动态资源的请求时,它并不仅仅是要求访问该资源的副本。通常,它还会随请求提交各种参数。正是这些参数保证了服务器端应用程序能够生成适合各种用户需求的内容。HTTP请求使用3种主要方式向应用程序传送参数:
通过URL查询字符串;
通过REST风格的URL的文件路径;
通过 HTTP cookie;
通过在请求主体中使用POST方法。
除了这些主要的输入源以外,理论上,服务器端应用程序还可以使用HTTP请求的任何一个部分作为输入。例如,应用程序可能通过User-Agent消息头生成根据所使用的浏览器类型而优化的内容。
像常见的计算机软件一样,Web应用程序也在服务器端使用大量技术实现其功能。这些技术包括:
脚本语言,如PHP、VBScript和Perl;
Web应用程序平台,如ASP.NET和Java;
Web服务器,如Apache、IIS和Netscape Enterprise
数据库,如MS-SQL、Oracle和MySQL;
其他后端组件,如文件系统、基于SOAP的Web服务和目录服务。
本书将详细介绍这些技术及其相关漏洞。下面将介绍一些可能遇到的最常见的Web应用程序平台和语言。
错误观点 “我们的应用程序只需要粗略的安全检查,因为它们采用了非常实用的框架。”
在开发Web应用程序时,使用实用框架往往是人们放松警惕的主要原因,因为人们认为这样做就可以自动避免SQL注入等常见的漏洞。但由于以下两方面的原因,这种看法并不正确。
首先,大量Web应用程序漏洞在应用程序的设计,而不是实施阶段发生,而且,这些漏洞与所采用的开发框架或语言无关。
其次,上述实用框架通常采用最新的插件或程序包,而这些程序包很可能并未经过安全检查。有趣的是,如果之后在应用程序中发现漏洞,支持使用框架的开发者马上会改变立场,转而批评他们使用的框架或第三方程序包。
近几年来,Java平台企业版(原J2EE)事实上已经成为大型企业所使用的标准应用程序。该平台由Sun公司开发(现在则属于Oracle公司)。它应用多层与负载平衡架构,非常适于模块化开发与代码重复利用。由于其历史悠久、应用广泛,因此,开发者在开发过程中可以利用许多高质量的开发工具、应用程序服务器与框架。Java平台可在几种基础型操作系统上运行,包括Windows、 Linux与Solaris。
描述基于Java的Web应用程序时,往往会使用许多易于混淆的术语,读者应该对它们有所警觉。
Enterprise Java Bean(EJB)是一个相对重量级的软件组件,它将一个特殊业务功能的逻辑组合到应用程序中。EJB旨在处理应用程序开发者必须解决的各种技术挑战,如交易完整性。
简单传统Java对象(Plain Old Java Object,POJO)是一个普通的Java对象,以区别如EJB之类的特殊对象。POJO常用于表示那些用户定义的、比EJB更加简单且更加轻量级的对象以及用在其他框架中的对象。
Java Servle提应用程序服务器中的一个对象,它接收客户端的HTTP请求并返回HTTP响应。Servlet可使用大量接口来促进应用程序开发。
Java Web容器是一个为基于Java的Web应用程序提供运行时环境的平台或引擎。Apache Tomcat、BEA WebLogic和JBoss都属于Java Web容器。
许多Java Web应用程序在定制代码中使用第三方与开源组件。这种做法非常具有吸引力,因为它能够减轻开发工作,而且Java非常适于使用这种模块式的方法。关键应用程序功能常用的组件包括:
身份验证——JAAS、ACEGI;
表示层——SiteMesh、Tapestry;
数据库对象关系映射——Hibernate;
日志——Log4J。
如果能够确定受攻击的应用程序所使用的开源软件包,渗透测试员就可以下载这些软件包进行代码审查,或者安装它们开始攻击实验。这些组件中的任何一个漏洞都可能被攻击者利用。
ASP.NET是Microsoft开发的一种Web应用程序框架,也是Java平台的主要竞争对手。ASP.NET比Java平台晚几年推出,但它已经占领了Java平台的部分市场。
ASP.NET使用Microsoft的.NET Framework,提供一个虚拟机[CLR(Common Language Runtime,通用语言运行时)]与一组强大的API。因此,ASP.NET应用程序可使用任何.NET语言(如C#或VB.NET)来编写。
ASP.NET采用传统桌面软件常用的事件驱动编程范型,而非许多早期Web应用程序框架所使用的基于脚本的方法。基于这种特点,再结合Visual Studio提供的强大开发工具,任何人即使并不具备熟练的编程技能,也能迅速开发出功能强大的Web应用程序。
不需要开发者做任何工作,ASP.NET框架就能防御一些常见的Web应用程序漏洞,如跨站点脚本。但这种明显简化的特点也造成一个现实问题,即许多小型的ASP.NET应用程序实际上由初学者开发,他们对于Web应用程序面临的核心安全问题缺乏了解。
PHP语言源于一个业余项目[最初该缩写词代表个人主页(Personal Home Page)]。之后,该项目迅速发展成为一个功能强大、应用丰富的Web应用程序开发框架。PHP常常与其他免费技术整合,如所谓的LAMP组合(包括操作系统Linux、Web服务器Apache、数据库服务器MySQL和Web应用程序编程语言PHP)。
人们使用PHP开发出大量的开源应用程序与组件,它们为常用的应用程序功能提供了现成的解决方案,并将其整合到应用更加广泛的定制应用程序中,例如:
公告牌——PHPBB、PHP-Nuke;
管理前端——PHPMyAdmin;
Web邮件——SquirrelMail、IlohaMail;
相册——Gallery;
购物车——osCommerce、ECW-Shop;
维客——MediaWiki、WakkaWikki。
由于PHP完全免费,简单易用,因此许多编写Web应用程序的初学者往往使用它作为首选语言。但是,由于历史原因,PHP框架的设计方法与默认配置导致程序员很容易不经意间在代码中引入安全漏洞,因此使用PHP编写的应用程序中可能包含大量安全漏洞。除此之外,PHP平台本身也存在若干缺陷,在平台上运行应用程序就可对其加以利用。请参阅第19章了解有关PHP应用程序常见漏洞的详情。
Rails 1.0于2005年发布,主要侧重于模型-视图-控制器体系架构。Rails的主要优势在于,使用它能够以极快的速度创建成熟的数据驱动应用程序。如果开发者遵循Rails编码风格和命名约定,则可以使用Rails自动生成数据库内容的模型、修改该模型的控制器操作以及供应用程序用户使用的默认视图。与其他功能强大的新技术一样,人们已在Ruby On Rails中发现了一些漏洞,包括能够避开“安全模式”,这与在PHP中发现的漏洞类似。
有关最近发现的漏洞的详细信息,请参阅www.ruby-lang.org/en/security/。
结构化查询语言(SQL)用于访问Oracle、MS-SQL服务器和MySQL等关系数据库中的数据。目前,绝大多数的Web应用程序都将基于SQL的数据库作为它们的后端数据仓库,而且,几乎所有应用程序的功能都需要以某种方式与这些数据仓库进行交互。
关系数据库将数据存储在表中,每个表又由许多行和列构成。每一列代表一个数据字段,如“名称”或“电子邮件地址”,每一行则代表为这些字段中的一些或全部字段分配值的项。
SQL使用查询来执行常用的任务,如读取、添加、更新和删除数据。例如,要检索用户的具有指定名称的电子邮件地址,应用程序可以执行以下查询:
要实现它们所需的功能,Web应用程序可能会将用户提交的输入组合到由后端数据库执行的SQL查询中。如果以危险的方式进行组合,攻击者就可以提交恶意输入来干扰数据库的行为,从而读取和写入敏感数据。我们将在第9章中介绍这些攻击,并详细说明SQL语言及其用法。
可扩展标记语言(XML)是一种机器可读格式的数据编码规范。与其他标记语言一样,XML格式将文档划分为内容(数据)和标记(给数据作注解)。
标记主要用标签表示,它们包括起始标签、结束标签和空元素标签:
起始和结束标签成对出现,其中可以包括文档内容或子元素:
标签可以包含以名/值对出现的属性:
XML之所以可扩展,是因为它可以使用任意数量的标签和属性名。XML文档通常包含文档类型定义(DTD),DTD定义文档中使用的标签、属性及其组合方式。
服务器端和客户端Web应用程序广泛采用XML及由XML派生的技术,我们将在本章后面部分介绍这些内容。
虽然本书主要介绍Web应用程序攻击,但本书介绍的许多漏洞同样适用于Web服务。实际上,许多应用程序本质上就是一组后端Web服务的GUI前端。
Web服务使用简单对象访问协议(SOAP)来交换数据。通常,SOAP使用HTTP协议来传送消息,并使用XML格式表示数据。
典型的SOAP请求如下所示:
在使用浏览器访问Web应用程序时很可能会遇到SOAP,服务器端应用程序使用它与各种后端系统进行通信。如果将用户提交的数据直接组合到后端SOAP消息中,就可能产生与SQL注入类似的漏洞。我们将在第10章详细介绍这些问题。
如果Web应用程序还直接公开Web服务,那么,我们还需要检查这些Web服务。即使前端应用程序是基于Web服务编写的,但它们在输入处理以及服务本身所披露的功能方面仍存在区别。正常情况下,服务器会以Web服务描述语言(WSDL)格式公布可用的服务和参数。攻击者可以使用soapUI之类的工具、基于已公布的WSDL文件创建示例请求,以调用身份验证Web服务,获得身份验证令牌,并随后提出任何Web服务请求。
服务器端应用程序要接收用户输入与操作,并向用户返回其结果,它必须提供一个客户端用户界面。由于所有Web应用程序都通过Web浏览器进行访问,因此这些界面共享一个技术核心。然而,建立这些界面的方法各不相同。而且,近些年来,应用程序利用客户端技术的方式也一直在发生急剧变化。
HTML是建立Web界面所需的核心技术。这是一种用于描述浏览器所显示的文档结构的基于标签的语言。最初,HTML只能对文本文档进行简单的格式化处理。如今,它已经发展成为一种应用丰富、功能强大的语言,可用于创建非常复杂、功能强大的用户界面。
XHTML是HTML的进化版本,它基于XML,并采用比旧版HTML更严格的规范。之所以推出XHTML,部分是因为需要转而采用一种更加严格的HTML标记标准,以避免由于浏览器必须接受不太严格的HTML格式而导致的各种攻击和安全问题。
有关HTML及相关技术的详情,请参阅下面的几节。
客户端与服务器之间的大量通信都由用户单击超链接驱动。Web应用程序中的超链接通常包含预先设定的请求参数,这些数据项不需由用户输入,而是由服务器将其插入用户单击的超链接的目标URL中,以这种方式提交。例如,Web应用程序中可能会显示一系列新闻报道链接,其形式如下:
当用户单击这个链接时,浏览器会提出以下请求:
服务器收到查询字符串中的参数(newsid),并使用它的值决定向用户返回什么内容。
虽然基于超链接的导航方法负责客户端与服务器之间的绝大多数通信,但许多Web应用程序还是需要采用更灵活的形式收集输入,并接收用户输入。HTML表单是一种常见的机制,允许用户通过浏览器提交任意输入。以下是一个典型的HTTP表单:
当用户在表单中输入值并单击“提交”按钮时,浏览器将提出以下请求:
在这个请求中,有几个要点说明了请求如何使用各种因素控制服务器端处理过程。
因为HTML表单标签中包含一个指定POST方法的属性,浏览器就使用这个方法提交表单,并将表单中的数据存入请求消息主体中。
除用户输入的两个数据外,表单中还包含一个隐藏参数(redir)与一个提交参数(submit)。这两个参数都在请求中提交,服务器端应用程序可使用它们控制其逻辑。
与前面显示的超链接示例一样,负责表单提交的目标URL也包含一个预先设定的参数(app)。该参数可用于控制服务器端的处理过程。
请求中包含一个cookie参数(SESS),服务器在早先的响应中将其发布给浏览器。该参数可用于控制服务器端处理过程。
前面的请求中包含一个消息头,它规定消息主体中的内容类型为x-www-form-urlencoded。这表示和URL查询字符串中的一样,消息主体中的参数也以名/值对表示。multipart/form-data是提交表单数据时可能遇到的另一种类型的内容。应用程序可在表单标签的enctype属性中要求浏览器使用多部分编码。使用这种编码形式,请求中的Content-Type消息头还会指定一个随机字符串,用它来分隔请求主体中的参数。例如,如果表单指定多部分编码,其生成的请求如下所示:
层叠样式表(CSS)是一种描述以标记语言编写的文档的表示形式的语言。在Web应用程序中,CSS用于指定HTML内容在屏幕上(以及打印页面等其他媒介中)的呈现方式。
现代的Web标准力求将文档的内容与其表示形式尽可能地区分开来。这种区分具有许多好处,包括简化和缩小HTML页面,更易于更新网页的格式以及提高可访问性等。
CSS以各种格式化规则为基础,这些规则可以通过不同的详细程度进行定义。如果多个规则与一个文档元素相匹配,在这些规则中定义的不同属性将进行“层叠”,从而将适当的样式属性组合应用于该元素。
CSS语法使用选择器来定义一类标记元素(应将一组指定的属性应用于这些元素)。例如,下面的CSS规则定义使用<h2>标签标记的标题的前景颜色:
h2 { color: red; }
在Web应用程序安全的早期阶段,CSS在很大程度上被人们所忽略,人们认为它们不可能造成安全威胁。今天,CSS本身正不断成为安全漏洞的来源,并且被攻击者作为传送针对其他类型的漏洞的入侵程序的有效手段(有关详细信息,请参阅第12章和第13章)。
超链接与表单可用于建立能够轻易接收大多数Web应用程序所需输入的丰富用户界面。然而,许多应用程序使用一种更加分布式的模型,不仅使用客户端提交用户数据与操作,还通过它执行实际的数据处理。这样做主要出于两个原因。
改善应用程序的性能,因为这样可在客户端组件上彻底执行某些任务,不需要在服务器间来回发送和接收请求与响应。
提高可用性,因为这样可根据用户操作动态更新用户界面,而不需要加载服务器传送的全新HTML页面。
JavaScript是一种相对简单但功能强大的编程语言,使用它可方便地以各种仅使用HTML无法实现的方式对Web界面进行扩展。JavaScript常用于执行以下任务。
确认用户输入的数据,然后将其提交给服务器避免因数据包含错误而提交不必要的请求。
根据用户操作动态修改用户界面,例如,执行下拉菜单和其他类似于非Web界面的控制。
查询并更新浏览器内的文档对象模型(Document Object Model,DOM),控制浏览器行为(稍后就会介绍浏览器DOM)。
VBScript可用于替代只有Internet Explorer浏览器才支持的JavaScript。VBScript以Visual Basic为基础,并可以与浏览器DOM进行交互。但通常而言,VBScript不如JavaScript强大和成熟。
由于VBScript只能在特定浏览器中使用,今天的Web应用程序已经很少使用VBScript。从安全角度看,我们之所以对它感兴趣,是因为在使用JavaScript无法传送入侵程序时,攻击者可以通过它来传送针对跨站点脚本之类漏洞的入侵程序(请参阅第12章)。
文档对象模型(DOM)是可以通过其API查询和操纵的HTML文档的抽象表示形式。
DOM允许客户端脚本按id访问各个HTML元素并以编程方式访问这些元素的结构。DOM还可用于读取和更新当前URL和cookie等数据。另外,DOM还包括一个事件模型,以便于代码钩住各种事件,如表单提交、通过链接导航及键击。
如下一节所述,浏览器DOM操纵是基于Ajax的应用程序采用的关键技术。
Ajax是一组编程技术,用于在客户端创建旨在模拟传统桌面应用程序的流畅交互和动态行为的用户界面。
Ajax是“异步JavaScript和XML"的缩写,尽管今天的Web Ajax请求既不需要是异步请求,也不使用XML。
最早的Web应用程序基于完整的页面。每个用户操作,如单击链接或提交表单,都会启动窗口级别的导航事件,导致服务器加载新页面。这种运行方式会导致不连续的用户体验,在应用程序收到来自服务器的庞大响应并重新显示整个页面时,会出现长时间的延迟。
使用Ajax,一些用户操作将由客户端脚本代码进行处理,并且不需要重新加载整个页面。相反,脚本会“在后台”执行请求,并且通常会收到较小的响应,用于动态更新一部分用户界面。例如,在基于Ajax的购物应用程序中,如果用户单击“添加到购物车”按钮,应用程序将启动一个后台请求,在服务器端更新用户的购物车记录,随后,一个轻量级响应会更新用户屏幕上显示的购物车中商品的数量。浏览器中的整个页面几乎保持不变,这样就为用户带来更快速、更满意的体验。
Ajax使用的核心技术为XMLHttpRequest。经过一定程度的标准整合之后,这种技术现在已转化为一个本地JavaScript对象,客户端脚本可以通过该对象提出“后台”请求,而无须窗口级别的导航事件。尽管其名称仅包含请求,但XMLHttpRequest允许在请求中发送以及在响应中接收任意数量的内容。虽然许多Ajax应用程序确实使用XML对消息数据进行格式化,但越来越多的Ajax倾向于使用其他表示方法来交换数据(下一节提供了一个相关示例)。
值得注意的是,虽然大多数Ajax应用程序确实与服务器进行异步通信,但这并不是必需的。在某些情况下,如执行特殊操作时,可能需要阻止用户与应用程序进行交互。这时,由于不需要重新加载整个页面,Ajax将提供更加无缝的体验。
以前,使用Ajax已在Web应用程序中引入了一些新的漏洞。从更广义的角度看,使用Ajax会在服务器端和客户端引入更多潜在的攻击目标,因而增加了典型应用程序的受攻击面。在设计针对其他漏洞的更加高效的入侵程序时,攻击者也可以利用Ajax技术。有关详细信息,请参阅第12章和第13章。
JavaScript对象表示法(JSON)是一种可用于对任意数据进行序列化的简单数据交换格式。JSON可直接由JavaScript解释器处理。Ajax应用程序经常使用JSON,以替换最初用于数据传输的XML格式。通常,如果用户执行某个操作,客户端JavaScript将使用XMLHttpRequest将该操作传送到服务器。服务器则返回一个包含JSON格式的数据的轻量级响应。然后,客户端脚本将处理这些数据,并对用户界面进行相应地更新。
例如,基于Ajax的Web邮件应用程序可能提供显示所选联系人的详细资料的功能。如果用户单击某位联系人,浏览器将使用XMLHttpRequest检索所选联系人的详细资料,并使用JSON返回这些资料:
客户端脚本将使用JavaScript解释器来处理JSON响应并基于其内容更新用户界面的相关部分。
此外,当前的应用程序还将JSON用于封装传统上位于请求参数中的数据。例如,如果用户更新联系人的详细资料,则可以使用以下请求将新信息传送至服务器:
同源策略是浏览器实施的一种关键机制,主要用于防止不同来源的内容相互干扰。基本上,从一个网站收到的内容可以读取并修改从该站点收到的其他内容,但不得访问从其他站点收到的内容。
如果不使用同源策略,那么,当不知情的用户浏览到某个恶意网站时,在该网站上运行的脚本代码将能够访问这名用户同时访问的任何其他网站的数据和功能。这样,该恶意站点就可以从用户的网上银行进行转账、阅读用户的Web邮件,或在用户网上购物时拦截他的信用卡信息。为此,浏览器实施限制,只允许相同来源的内容进行交互。
实际上,将这一概念应用于各种Web功能和技术会导致各种复杂情况和风险。关于同源策略,需要了解的一些主要特点如下。
位于一个域中的页面可以向另一个域提出任意数量的请求(例如,通过提交表单或加载图像)。但该页面本身无法处理上述请求返回的数据。
位于一个域中的页面可以加载来自其他域的脚本并在自己的域中执行这个脚本。这是因为脚本被假定为包含代码,而非数据,因此跨域访问并不会泄露任何敏感信息。
位于一个域中的页面无法读取或修改属于另一个域的cookie或其他DOM数据。
这些特点可能导致各种跨域攻击,如诱使用户执行操作和捕获数据。此外,由于浏览器扩展技术以各种方式实施同源限制,这一问题变得更加复杂。我们将在第13章详细讨论这些问题。
HTML5是对HTML标准的重大更新。当前,HTML5仍处在开发阶段,仅在浏览器中进行了小规模实施。
从安全角度看,我们对HTML5感兴趣主要出于以下原因。
它引入了各种可用于传送跨站点脚本及实施其他攻击的新标签、属性和API(会在第12章讲述)。
它对XMLHttpRequest这一核心Ajax技术进行了修改,在某些情况下可以实现双向跨域交互。这可能导致新的跨域攻击(会在第13章讲述)。
它引入了新的客户端数据存储机制,这可能导致用户隐私问题以及新型攻击,如客户端SQL注入(会在第13章讲述)。
近些年来,Web 2.0这个专业术语已经成为一个流行词汇,用于Web应用程序领域内的各种相关趋势(尽管并不准确)的描述,这些趋势包括:
大量使用Ajax执行各种异步后台请求;
使用各种技术提高跨域集成;
在客户端使用各种新技术,包括XML、JSON和Flex;
采用更先进的技术来支持用户生成的内容、信息共享和交互。
和技术领域的所有新技术一样,这些趋势也造成了各种安全漏洞。但是,总体而言,这些漏洞并未形成新的Web应用程序安全问题。Web 2.0相关的漏洞在很大程度上与这种趋势出现之前的漏洞相同,或派生自之前的漏洞。总的来说,“Web 2.0安全”是一个错误的概念,它对于我们考虑重要的问题并无帮助。
除JavaScript功能外,一些Web应用程序还通过采用浏览器扩展技术,使用定制代码从各方面扩展浏览器的内置功能。这些组件可配置为字节码,由适当的浏览器插件执行,或需要在客户计算机上安装本地可执行程序。在攻击Web应用程序时,可能遇到的厚客户端技术包括:
Java applet;
ActiveX控件;
Flash对象;
Silverlight对象。
我们将在第5章详细讨论这些技术。
迄今为止,本书讨论的技术主要用于帮助Web应用程序服务器和客户端组件以各种方式进行数据交换和处理。但是,为实现各种有用的功能,应用程序需要追踪每名用户通过不同的请求与应用程序交互的状态。例如,一个购物应用程序允许用户浏览产品目录、往购物车内添加商品、查看并更新购物车内容、结账并提供个人与支付信息。
为实现这种功能,应用程序必须维护一组在提交各种请求过程中由用户操作生成的有状态数据。这些数据通常保存在一个叫做会话的服务器端结构中。当用户执行一个操作(如在购物车中添加一件商品)时,服务器端应用程序会在用户会话内更新相关信息。以后用户查看购物车中的内容时,应用程序就使用会话中的数据向用户返回正确的信息。
在一些应用程序中,状态信息保存在客户端组件而非服务器中。服务器在响应中将当前的数据传送给客户端,客户端再在请求中将其返回给服务器。当然,由于通过客户端组件传送的任何数据都可被用户修改,因此,应用程序需要采取措施阻止攻击者更改这些状态信息,破坏应用程序的逻辑。ASP.NET平台利用隐藏表单字段ViewState保存与用户的Web界面有关的状态信息,从而减轻服务器的工作负担。默认情况下,ViewState的内容中还包括一个密钥散列,以防止受到破坏。
因为HTTP协议本身并没有状态,为使用正确的状态数据处理每个请求,大多数应用程序需要采用某种方法在各种请求中重新确认每一名用户的身份。通常,应用程序会向每名用户发布一个令牌,对用户会话进行唯一标识,从而达到这一目的。这些令牌可使用任何请求参数传输,但许多应用程序往往使用HTTP cookie来完成这项任务。会话处理过程中也会产生几种漏洞,第7章将详细讨论这些内容。
Web应用程序对其数据采用几种不同的编码方案。在早期阶段,HTTP协议和HTML语言都是基于文本的,于是人们设计出不同的编码方案,确保这些机制能够安全处理不常见的字符和二进制数据。攻击Web应用程序通常需要使用相关方案对数据进行编码,确保应用程序按照想要的方式对其进行处理。而且,在许多情况下,攻击者甚至能够控制应用程序所使用的编码方案,造成其设计人员无法预料的行为。
URL只允许使用US-ASCII字符集中的可打印字符(也就是ASCII代码在0x20 ~ 0x7e范围内的字符)。而且,由于其在URL方案或HTTP协议内具有特殊含义,这个范围内的一些字符也不能用在URL中。
URL编码方案主要用于对扩展ASCII字符集中的任何有问题的字符进行编码,使其可通过HTTP安全传输。任何URL编码的字符都以%为前缀,其后是这个字符的两位十六进制ASCII代码。以下是一些常见的URL编码字符:
%3d代表=;
%25代表%;
%20代表空格;
%0a代表新行;
%00代表空字节。
另一个值得注意的编码字符是加号(+),它代表URL编码的空格(除%20代表空格外)。
注解 当攻击Web应用程序时,如果需要将以下字符当做数据插入HTTP请求中,渗透测试员必须对它们进行URL编码。
空格 % ? & = ; + #
(当然,当修改请求时,往往需要使用这些字符的特殊含义,例如,给查询字符串添加另外一个请求参数。这时应使用这些字符的字面量形式。)
Unicode是一种为支持全世界所使用的各种编写系统而设计的字符编码标准,它采用各种编码方案,其中一些可用于表示Web应用程序中的不常见字符。
16位Unicode编码的工作原理与URL编码类似。为通过HTTP进行传输,16位Unicode编码的字符以%u为前缀,其后是这个字符的十六进制Unicode码点。例如:
%u2215代表/;
%u00e9代表é。
UTF-8是一种长度可变的编码标准,它使用一个或几个字节表示每个字符。为通过HTTP进行传输,UTF-8编码的多字节字符以%为前缀,其后用十六进制表示每个字节。例如:
%c2%a9代表©;
%e2%89%a0代表≠。
攻击Web应用程序时之所以要用到Unicode编码,主要在于有时可用它来破坏输入确认机制。如果输入过滤阻止了某些恶意表达式,但随后处理输入的组件识别Unicode编码,就可以使用各种标准与畸形Unicode编码避开过滤。
HTML编码是一种用于表示问题字符以将其安全并入HTML文档的方案。有许多字符具有特殊的含义(如HTML内的元字符),并被用于定义文档结构而非其内容。为了安全使用这些字符并将其用在文档内容中,就必须对其进行HTML编码。
HTML编码定义了大量HTML实体来表示特殊的字面量字符,例如:
"代表”;
'代表’;
&代表&;
代表<;
代表>。
此外,任何字符都可以使用它的十进制ASCII码进行HTML编码,例如:
"代表";
#39;代表’。
或者使用十六进制的ASCII码(以x为前缀),例如:
"代表”;
'代表’。
当攻击Web应用程序时,HTML编码主要在探查跨站点脚本漏洞时发挥作用。如果应用程序在响应中返回未被修改的用户输入,那么它可能易于受到攻击;但是,如果它对危险字符进行HTML编码,也许比较安全。请参阅第12章了解有关这些漏洞的更多详情。
Base64编码仅用一个可打印的ASCII字符就可安全转换任何二进制数据,它常用于对电子邮件附件进行编码,使其通过SMTP安全传输。它还可用于在基本HTTP验证机制中对用户证书进行编码。
Base64编码将输入数据转换成3个字节块。每个块被划分为4段,每段6个数据位。这6个数据位有64种不同的排列组合,因此每个段可使用一组64个字符表示。Base64编码使用以下字符集,其中只包含可打印的ASCII字符:
如果最后的输入数据块不能构成3段输出数据,就用一个或两个等号(=)补足输出。
例如,The Web Application Hacker’s Hand book的Base64编码为:
许多Web应用程序利用Base64编码在cookie与其他参数中传送二进制数据,甚至用它打乱敏感数据以防止即使是细微的修改。应该总是留意并解码发送到客户端的任何Base64数据。由于这些数据使用特殊的字符集,而且有时会在字符串末尾添加补足字符(=),因此可以轻易辨别出Base64编码的字符串。
许多应用程序在传送二进制数据时直接使用十六进制编码,用ASCII字符表示十六进制数据块。例如,对cookie中的用户名daf进行十六进制编码,会得到以下结果:
646166
和Base64编码的数据一样,十六进制编码的数据通常也很容易辨认。为了解十六进制编码的功能应当对服务器发送到客户端的任何十六进制数据进行解码。
近些年出现了各种用于创建用户界面的框架,这些框架中的客户端代码可以远程访问服务器端实施的编程API。利用这些框架,开发者可以在一定程度上忽略Web应用程序的分布式本质,而以与开发传统桌面应用程序类似的方式编写代码。这些框架通常提供客户端上使用的存根API。它们还能够自动处理以下两个任务:通过这些API远程调用相关服务器端功能,对传送给上述功能的任何数据进行序列化。
这类远程和序列化框架包括:
Flex和AMF;
Silverlight和WCF;
Java序列化对象。
我们将在第4章和第5章讨论使用这些框架的技巧以及由此引发的安全问题。
到现在为止,我们已经介绍了Web应用程序的当前安全(风险)状况,分析了Web应用程序的核心防御机制,并简要介绍了当今应用程序所采用的关键技术。基于这些基础知识,现在我们将开始研究渗透测试员如何向Web应用程序发动攻击。
在实施任何攻击之前,首要任务是仔细分析目标应用程序的内容及功能,了解它的工作原理、防御机制及其使用的技术。我们将在下一章详细介绍这个解析过程,说明如何通过它深入了解应用程序的受攻击面。实践证明,这个过程对于渗透测试员发现并利用目标应用程序的安全漏洞至关重要。
欲知问题答案,请访问http://mdsec.net/wahh。
(1)OPTIONS方法有什么作用?
(2)If-Modified-Since和If-None-Match消息头的作用是什么?它们为何引起攻击者的兴趣?
(3)当服务器设置cookie时,secure标签有什么意义?
(4)常用状态码301与302有什么不同?
(5)使用SSL时,浏览器如何与Web代理实现互操作?
Copyright ©2010-2022 比特日记 All Rights Reserved.