科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网安全频道Web应用客户端木马战情景分析

Web应用客户端木马战情景分析

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

今天,我们跟大家聊聊Web应用的客户端安全的故事。这个故事讲述的是攻击者如何从Web应用的客户端下手发动攻击的战术。这是一种非常简单却又令人胆寒的战术:之所以说它令人胆寒是因为攻击者能给其它的用户施展摄魂大法,让他们梦游般的去做一些他们不想做的事情;之所以说它简单,是因为攻击者要想达到上述目的,只需向用户发送一封电子邮件或设法让他们去一个web页面就足够了。有时候,人们将这个安全问题称为“客户端木马攻击”——可能是受到古代木马攻城故事的启发吧。不过即便你对这个遥远的故事不熟也不要紧,本文将向读者详细解释这个问题,并讨论可能解决方案。

来源:论坛整理 2008年11月24日

关键字: 黑客 攻击防范 网络入侵

  • 评论
  • 分享微博
  • 分享邮件
今天,我们跟大家聊聊Web应用的客户端安全的故事。这个故事讲述的是攻击者如何从Web应用的客户端下手发动攻击的战术。这是一种非常简单却又令人胆寒的战术:之所以说它令人胆寒是因为攻击者能给其它的用户施展摄魂大法,让他们梦游般的去做一些他们不想做的事情;之所以说它简单,是因为攻击者要想达到上述目的,只需向用户发送一封电子邮件或设法让他们去一个web页面就足够了。有时候,人们将这个安全问题称为“客户端木马攻击”——可能是受到古代木马攻城故事的启发吧。不过即便你对这个遥远的故事不熟也不要紧,本文将向读者详细解释这个问题,并讨论可能解决方案。

一、Web应用客户端的木马攻城

介绍这个安全问题最好的方法就是进行实例分析。按照循序渐进的原则,我们首先介绍一个较为简单的例子,然后再讨论更为复杂的例子,如网络银行等(是的,网络银行也同样面临这种威胁)。我们首先考察的是一个假想的投票站点,该站点允许用户给不同的候选人投票,并统计出选举结果。用于投票的web页面可能包含下列HTML代码:

<form action="http://www.example.com/vote.asp" method="get">
<input type="radio" name="alt" value="1"/>Alternative 1<br/>
<input type="radio" name="alt" value="2"/>Alternative 2<br/>
……
</form>

由于该表单使用的是GET方式,所以用户给他心仪的候选人投票时,将通过类似下面的URL来提交表单:

http://www.example.com/vote.asp?alt=2

现在,攻击者会设法诱骗其他用户来点击这些链接,比如复制以上URL并通过电子邮件大量发送,并向收件人声称这些URL链接到一个能诱惑人的事物上,比如非常好玩的游戏、裸体美女、耸人听闻的报道、有趣的笑话,等等。事实上,我们几乎没有办法阻止他们这么做——诸位,有谁没收到过垃圾邮件?!如果某些人点击了这些链接,那么他们就会给攻击者喜爱的候选人投上一票,这样的话,统计结果就有猫腻了。

也许您对这个例子持有异议。首先,您可能会说,大部分用户都不会点击这样的链接,因为这个链接看上去非常可疑。但是对攻击者来说这不是个问题,因为他们可以使用重定向技术来隐藏URL,从而迷惑更多的用户。他可以在邮件中使用不直接指向投票站点,而是指向其它页面的URL,比如使用一个指向他自己的服务器的URL:

http://www.badguy.com/nicejoke.html

看到链接中“nicejoke”,您也许以为这是一个关于笑话的页面。实际上,与您所认为的正好相反,这个nicejoke.html页面中并没有任何笑话,而是包含下列HTML代码:

<meta http-equiv="refresh"
content="0, url=http://www.example.com/vote.asp?alt=2">

一旦浏览器读取meta标签,它就会被重定向至投票页面的URL,等用户明白过来是怎么回事的时候,已经为时完矣!当然,攻击者使用脚本或者HTTP的Location报头的话,也能达到同样的效果。

您对该示例持有疑议的第二个理由可能是:就本例而言,使用一个GET请求是错误的。根据定义HTTP的RFC 2616文档,当动作具有副作用(比如有安全隐患)的时候,应该使用POST请求。当使用POST后,就无法在一个URL中放入投票细节,因为POST请求中的参数被隐藏在请求本身之中。但是这并不能阻止攻击者的脚步——他们完全可以不去诱骗浏览器访问以上URL,而是欺骗受害者浏览一个自动提交的表单,例如下面的表单:

<form name="f" action="http://www.example.com/vote.asp" method="post">
<input type="hidden" name="alt" value="2"/>
</form>
<script>document.f.submit()</script>

这个名为“f”的表单包含了一个隐藏字段,其中的参数“alt”已经被攻击者设为他们选定的值了。表单之下是JavaScript代码,它的作用实际上就是提交该表单,就像是用户按下了并不存在的提交按钮那样。

那些坏家伙可以将这些代码插入一个web页面,并哄骗用户访问它。这样一来,当受害者明白过来的时候,他们已经替别人投完票了。

更好的方法是将上述表单嵌入一封HTML编码的电子邮件中。一些流行的电子邮件客户端不仅能查看HTML邮件,甚至可以执行JavaScript代码。不幸的用户可能仅仅由于阅读攻击者的邮件而神不知鬼不觉地将它们的票投给了攻击者,如果邮件程序自动地预览来信的话,甚至根本都不需要阅读邮件。

请注意,微软公司的Outlook在显示HTML格式的电子邮件时会用到IE浏览器的组件。作者在Windows 2000上测试时发现,Outlook 使用的IE实例会跟已打开的IE共享一切,包括会话cookie。所以您一定要记住这一点,尤其是到后文的网络银行的时候,因为正是这一点为更酷的远程控制电子邮件铺平了道路。幸运的是,Windows XP默认时不会运行嵌入HTML格式电子邮件中的脚本——至少我测试的脚本没有被执行。

迄今为止,我们已经考察了一个用于投票的简单应用程序。但是,让人胆寒的客户端木马战还涉及到身份验证。因为这些特洛伊木马攻击是通过欺骗用户或者他的浏览器访问目标站点来运作的,所以只有用户业已登录到目标站点的时候,特洛伊木马才能以该用户的名义做各种事情。
假设一个用户已登录到他的网络银行,而这时一个攻击者想要冒充那个用户来发财的话,只要能欺骗用户浏览下列内容就足矣:

<form name="f" action="https://bank.example.com/pay.asp" method="post">
<input type="hidden" name="from-account" value="1234.56.78901"/>
<input type="hidden" name="to-account" value="9876.54.32109"/>
<input type="hidden" name="amount" value="10000.00"/>
</form>
<script>document.f.submit()</script>

现在,如果受害者早已登录到银行,而该银行也接受此类表单,那么该用户就会在毫不知情的情况下把钱转到攻击者的帐户上,当然攻击者也可以利用此特权给别人栽赃。

要做到这一点,受害者必须已经登录到目标站点,否则攻击者也无可奈何。然而,如果用户选择了“记住密码”选项,那么他就会一直处于登录状态。如果目标站点是一个基于域认证(例如Microsoft IIS上的NTLM)的内部网的话,情况同样如此。幸运的是,银行之类的“严肃”站点却不会提供自动认证——攻击者也许以为这很“不幸”。

如果该用户没有总处于登录状态的话,那么攻击者就必须在诱骗用户浏览恶意的HTML之前,首先以某种方式设法让受害者先登录到目标站点。对于那些允许用户添加内容的站点(如论坛)来说,这可能很容易:只需添加一个非常诱人的声明来邀请人们查看一个链接即可。然而,很多情况下,攻击者是无法在目标站点上插入消息的,这样的话,他就不得不另外想辙了,这时,社交工程恐怕就能派上用场了!比方说,我们的目标站点是一个名为bank.example.com的银行,攻击者想要设法先让用户登录该银行,继而诱骗该用户浏览上面的转账表单。

为此,攻击者可以向受害者发送一封貌似来自该银行的电子邮件,如:

To: 受害者
From: security@bank.example.com
Subject:紧急通知,请立即拆阅!

尊敬的客户:您好!

根据入侵检测系统的报告,我们怀疑您的帐户受到恶意攻击,

所以恳请您协助我们对您的帐户进行调查。务请收到本通知后,立即登录您的帐户,

并于登录后单击下面的链接:

http://bank.example.com@167772161/check.html

在此之后,请按照提示操作即可。对于给您造成的不便,我们深感歉意!并顺祝商祺!

XX银行紧急响应小组,敬上

大多数用户会都认为其中这个URL指向的是该银行的Web服务器,但事实并非如此。使用@符号后,这个URL实际上是命令浏览器以用户名bank.example.com连接到站点167772161。这个长整数167772161实际上就是攻击者的IP地址10.0.0.1,只不过现在已经编码为一个32位整数而已;而check.html则是一个包含HTML代码的页面,而这些HTML代码将自动提交转帐请求。受害者一旦上钩,攻击者就会发一笔横财。

 

对于一些银行,进行一次转帐需要两个步骤。首先,您要提供全部转帐细节:转出方帐户和转入方帐户,金额,支付日期等等,所有这些信息都被临时存放在该用户的会话session中。收集这些信息之后,银行还有一个确认的步骤,即要求用户验收这些交易细节。请不要认为这些银行在客户端木马战面前会比那些自动化的银行更加安全一些。这些站点可能会像一步式的站点那样容易被骗:根据确认步骤的实现方式,设法让受害者浏览包含多个框架(frame)的站点,每个框架对应于一个步骤,如下所示:

<frameset rows="50%,50%">
<frame src="http://www.badguy.com/info.html"/>
<frame src="http://www.badguy.com/confirm.html"/>
</frameset>

文件info.html中有一个自动提交的填有交易细节的表单;而文件confirm.html则存放一个提交确认页面的脚本,但是要等待适当的延迟,以确保确认消息在info.html之后到达服务器。至于其他的,我想就没有必要再多说了吧。

无论攻击者选择什么方法,只要被害者看到由这次转帐引起的页面,就会引起他的怀疑。解决这个问题的方法是把这个页面嵌入一个小到不会引起人们注意的框架(frame)中,并在另外一个框架(frame)中放上一些伪造的信息。如果目标站点的某些地方没有进行HTML输出过滤的话,那么还有一个办法,那就是转帐一旦完成,就立即通过跨站脚本把浏览器重定向到另一个页面。

二、客户端木马问题的实质

目前的大多数站点,包括网上银行、网上商店、论坛和网上书店都都易于受到某种客户端木马骗术的攻击,之所以这样说,是因为他们都缺乏相应的保护机制。要想弄明白如何设计一个没有此类弱点的web站点,我们首先需要熟悉问题本身。

当某人浏览我们的站点时,我们通常为用户生成一个web页面,其中包括一些提示用户可在本站点进行哪些活动的URLs和表单(下文将以“要约”这个词来加以指代)。客户端木马战之所以得逞,就是因为攻击者有可能以我们的名义向被害者提供这些URLs和表单,这是问题的根本所在。为了消除这种威胁,我们必须保证用户是根据我们而绝非其他人所提供的URL和表单来采取行动的。

许多开发人员都认为Referer header是一个用来确保访问者来自我们的站点的法宝。一般情况下,Referer header不该用于安全,因为它毕竟来自于客户端:记住,客户端总能造假。但是,用它来对付客户端特洛伊木马还是管用的——但是,处于保护隐私的考虑,站点经常将Referer headers过滤掉,因此在完全合法的请求中,通常是找不到Referer headers的,所以我们必须寻找一个不用检测Referer headers的办法。

还有一个办法,就是每当用户执行修改某些东西的动作时,都对用户进行重新认证。这种解决方案需要对客户端提供的每个表单都增加一个口令字段。不幸的是,提供口令是一件非常烦人的事情,所以我们将尝试其它方案。

三、防御措施

为了预防客户端木马攻击,开发人员应该实现一个“检票系统”。这个系统的核心在于一些不可预测的随机数,我们称之为票据,它的工作机制如下所示:

web页面通常用一个或多个要约来完成一个有副作用的动作。对于每个这样的要约,都会为其生成一个随机字符串并与该要约相关联:如果该要约是一个表单的话,可以用一个隐藏的字段来存放该票据;如果该要约是一个链接,那么可以把票据附加到URL参数列表中。

对于产生的每一个票据,都为其添加一个字符串来为其所指动作命名,并将这个字符串存放于接收该要约的用户的session的“票据池”中。例如,对编号为1234的单据的删除进行确认这一动作,动作名为“delnote-1234”,其票据被表示为“c90624gHu”,那么该字符串将被存为“delnote-1234-c90624gHu”。如今,我们在客户端和服务器端都有了一个相同的票据。

每当从用户那里收到一个要求执行动作的请求时,就从该请求中提取票据。然后,将要执行的动作的名称加在票据前面,并在票据池中查找匹配项。如果找到了匹配的票据,那就说明该要约是由您的Web 站点所提供的,这时就执行动作,并从票据池中删掉这个票据。

检票系统之所以管用,是因为攻击者无法猜出你已经给客户了哪些票据值,同时他们也无法将票据插入受害者在服务器端的票据池。

然而,这里有两个问题需要注意。首先,如果您在GET请求中包含了票据,那么它们就会变成URLs的一部分,如果点击了一个从您的站点到其它Web服务器的链接的话,票据就有可能通过Referer headers泄漏出去了。如果你的web页面包含来自其它站点的图像或者其它的对象的话,也会导致Referer报头的泄密问题。

如果您使用了独一无二的票据,并且每次请求之后都没有忘记把它从票据池中删除的话,这就不会有问题了。GET请求通常不用于对数据有任何改动的动作,所以,我们根本就不需要在这样的请求中使用票据。

此外,如果你的应用程序容易受到跨站点脚本攻击的攻击,那么该系统就会失效,原因是——如果攻击者能在你的服务器生成的页面内插入JavaScript代码的话,他就能从该页面提取票据。并且,他还能诱骗浏览器进行一些需要两步完成的事情:第一步去请求一个票据,然后在用户不知道的情况下使用该票据。

如您所见,要想防止客户端木马战术,我们必须进行一些额外的程序设计工作,并且还得动一番脑筋——看来Web开发是越来越有挑战性了,必须在开发之初就充分考虑安全问题。

四、结束语

攻击者可以目标站点的名义出现在受害者面前,并欺骗他们做一些从未打算要做的事情。要约可以 是URL或自动提交的表单,并且这些要约可以通过任何可用的信道进行传播,比如电子邮件,以及目标站点之外的Web页面等。为了保护Web 站点及其用户免受客户端木马战术的滋扰,Web开发人员必须实现一些专门的安全机制。遗憾的是,到目前为止,这些机制还没有得到普遍应用,所以许多站点都存在这方面的漏洞。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章