Hello World
Spiga

浅谈这次ASP.NET的Padding Oracle Attack相关内容

2010-09-25 02:25 by 老赵, 4484 visits

上一周爆出了一个关于ASP.NET的安全漏洞,有关这个漏洞的第一篇文章应该是ScottGu的说明,但是其中各方面谈的也是语焉不详。由于这个漏洞关系到“安全”这样敏感的话题,其中又涉及到密码学这样常人看不明白的技术,于是导致了各种猜测和推测,其中甚至与我对ASP.NET的了解所有矛盾,因此我觉得也大都不靠谱。中秋休息在家,我简单地了解了一下与这个漏洞有关的内容,总结出了一些“能够说服自己”的内容,在此记录下来。因此,这篇文章的面向读者是那些和我差不多的同学:对ASP.NET有所了解,但对密码学知之甚少。

什么是Padding和Oracle

要谈这个问题,先要了解什么是Padding Oracle Attack。有些文章把Padding和Oracle,与CSS样式表或是那个收购了Sun的甲骨文公司联系起来,这就驴唇不对马嘴了。

Padding在这里的含义是“填充”,因为对于加密算法来说,它们是基于等长的“数据块”进行操作的(如对于RC2,DES或TripleDES算法来说这个长度是8字节,而对于Rijndael算法来说则是16、24或32字节)。但是,我们的输入数据长度是不规则的,因此必然需要进行“填充”才能形成完整的“块”。“填充”时比较常用的是PKCS #5规则,简单地说,便是根据最后一个数据块所缺少的长度来选择填充的内容。

例如,数据块长度要求是8字节,如果输入的最后一个数据块只有5个字节的数据,那么则在最后补充三个字节的0x3。如果输入的最后一个数据块正好为8字节长,则在最后补充一个完整的长为8字节的数据块,每个字节填0x8。使用这个规则,我们便可以根据填充的内容来得知填充的长度,以便在解密后去除填充的字节。

在解密时,如果算法发现解密后得到的结果,它的填充方式不符合规则,那么表示输入数据有问题,对于解密的类库来说,往往便会抛出一个异常,提示Padding不正确。Oracle在这里便是“提示”的意思,和甲骨文公司没有任何关系。

如何进行Padding Oracle Attack

刚才已经提到,如果输入的密文不合法,类库则会抛出异常,这便是一种提示。攻击者可以不断地提供密文,让解密程序给出提示,不断修正,最终得到的所需要的结果。这里的一个关键在于,攻击者所需要的提示仅仅是“解密成功与否”这样一个二元信息,例如它在一个Web程序中可能只是“200 - OK”及“500 - Internal Server Error”这样的表现形式,而不需要其他任何详细信息。

例如,现代流行的Web框架大都是开源的,因此它的加密方式完全透明(当然这点其实并不是必须的,只是大有帮助而已),对于攻击者来说唯一不知道的便是密钥。于是攻击者便可以根据这个加密方式设计有针对性的密文,最终得到密钥(及IV等信息)。在很多时候,一个网站都会使用同样的密钥和IV,于是只需从一个漏洞,便可以在网站的其他方面进行破坏,或解密信息,或绕开验证。

在具体操作上还可以有许多方式进行辅助,在Juliano Rizzo和Thai Duong的《Practical Padding Oracle Attacks》(及此)论文(下文称PPOA)中便提到了很多方式,例如使用Google搜索异常的关键字(这说明许多站点都把异常信息输出在页面上),检查代码,从外表检查一些BASE64形式的字符串,猜测常见的分割符,如“--”,“|”或是“:”等等。PPOA认为,如今Padding Oracle漏洞与SQL注入,脚本注入等漏洞一样无处不在,论文中还详细讨论了利用这个漏洞来攻击eBay拉丁美洲站点,CAPTCHA等应用,以及在JSF(包括Apache MyFacesSun Mojarra实现),Ruby on Rails等Web框架中的漏洞——奇怪的是其中反而没有提到ASP.NET。

关于Padding Oracle Attack的具体细节,您可以从《Automated Padding Oracle Attacks with PadBuster》及《Padding Oracle Attacks on CBC-mode Encryption with Secret and Random IVs》两篇文章中得到更详细的信息,它们似乎并不像表面那样高深莫测,尤其是前者,有机会我也打算将它翻译一下。

针对ASP.NET的攻击及其危害

那么,这次又是如何对ASP.NET站点进行攻击的呢?方式有不少,例如攻击者可以为一个需要认证的请求发送自定义的cookie值,如果没有通过认证,则会得到一个转向登陆页面的302跳转。一个更为直观和通用的作法来自于PPOA论文的作者所提供的一段视频,其中使用了WebResources.axd?d=xyz进行探测工作。WebResource.axd有一个特点,便是会对错误的密文(即d=xyz中的xyz)产生500错误,而对正确的密文产生404错误,这便形成了足够的提示。

好,那么假设攻击者已经得到了站点的Machine Key,也就是网站所使用的密钥,那么它又能造成什么危害呢?

一些危害是很容易理解的,例如解密(或注入)ViewState,或是如视频里那样设置一个管理员的cookie。在ScottGu等文章中描述这个漏洞的危害时还提到,这个漏洞可以用来下载web.config等私密文件,这又是如何办到的呢?要知道web.config文件的下载是被IIS和ASP.NET所禁止的,它似乎和加密解密或是Machine Key无关。不过您是否意识到,在ASP.NET 3.5 SP1以后,我们可以利用ScriptManager来打包输出本地的脚本文件?例如:

<asp:ScriptManager ID="sm" runat="server">
    <CompositeScript>
        <Scripts>
            <asp:ScriptReference Path="~/scripts/core.js" />
            <asp:ScriptReference Path="~/scripts/lib.js" />
        </Scripts>
    </CompositeScript>
</asp:ScriptManager>

这段内容会在页面上放置一段ScriptResource.axd的引用,它的Query String便包含了需要输出的文件路径,它是与ScriptManager等组件完全独立的。那么,如果攻击者告诉它输出“~/web.config”的时候……

有趣的是,PPOA论文作者同时还在今年两月和六月分别提供了攻击CAPTCHA攻击Apache MyFaces的视频,同时也提供了一个针对JSF的自动攻击工具,不过它们并没有形成微软对ASP.NET的漏洞那样强烈反应。

防止攻击

目前ScottGu给出了多个workaround,归根结底便是消除“Oracle”,也就是提示信息。例如他强调要为404和500错误提供完全相同的反馈——不止是输出的错误页面,也包括所有的头信息(如Server Time等自然除外),这种做法会让攻击者无法得到提示信息,自然也就无法解密了。此外,ScottGu的一些代码同时让错误页面Sleep一小段时间,这也是种常用的混淆手段,让攻击者无法从响应时间长短上来了解这个请求“性质”如何。

从上面的分析中我们可以知道,这种统一错误信息的作法似乎是针对WebResource.axd和ScriptResource.axd的。由于我们知道了攻击的手段,便也可以采取其他作法。例如对于不需要这两个Handler的站点,就把它们从ASP.NET或IIS里直接摘除吧。还有,如果在日志中发现太多CryptographicException异常,便要关注站点是否遭受的攻击。

但是,Padding Oracle Attack的危害之处在于它所需要的信息实在太少,攻击者只需分辨两种状态便可以进行攻击,即便WebResource.axd的攻击被您防止了,那么之前提到的用户认证所带来的302跳转又如何?对于我们独立编写的应用程序来说,要绕开这个问题可以使用各种技巧。但对于微软来说可能就不容易了,因为ASP.NET作为一个框架,它提供的是一种统一的,普适的机制,这也是为什么这个漏洞会影响几乎所有微软ASP.NET产品的缘故。

此外还有一些做法也是可取的。例如:

  • 避免在ViewState和Cookie中存放敏感数据。
  • 不要过度依赖Machine Key。
  • 在认证cookie里保存的不只是用户名,而是外界无法得知的ID,或是同时保存checksum等额外的验证信息。
  • 为ScriptResource.axd写一个Wrapper,只让它输出扩展名为js的内容。

这些做法的目的是:即使攻击者得到了Machine Key,也无法对站点造成破坏。

总结

安全性漏洞总是不令人愉快的,但是在遇到这种状况的同时,我们也要努力得知问题的真实情况。在如今信息爆炸的时代,产生和获取一条没有多大价值甚至是错误的信息,可谓是非常容易的。排除干扰寻求真相,即便只是种态度和意愿,也是一名技术人员的基本素质。因此在这个问题上,我最反感的便是“微软的产品就是不安全”,“反正我不会被攻击”这样的态度。

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

17 条回复

  1. cnhzlt
    122.224.140.*
    链接

    cnhzlt 2010-09-25 08:31:53

    这篇看明白了

  2. 老赵博客
    58.210.35.*
    链接

    老赵博客 2010-09-25 08:48:42

    有些文章把Padding和Oracle,与CSS样式表或是那个收购了Sun的甲骨文公司联系起来

    人家那个是调侃吧?

  3. 老赵
    admin
    链接

    老赵 2010-09-25 09:07:21

    @老赵博客

    忘了是在哪儿看到的了,似乎不是调侃,也有可能是我看的不够仔细吧,呵呵。

  4. 链接

    lovecherry 2010-09-25 09:26:59

    就像以前SQL注入,通过搜到产品和搜不到产品两种状态获取SQL密码、获取表名、列名、然后是列中的数据

  5. Duron800
    207.46.92.*
    链接

    Duron800 2010-09-25 10:13:56

    学习一下,看看能不能看懂。

  6. Dennis
    207.46.92.*
    链接

    Dennis 2010-09-25 10:20:06

    通俗易懂,现在很多站点针对验证方面的错误应该还是多采用对外统一错误提示,对内记录log的形式吧。

  7. Yankee
    122.200.76.*
    链接

    Yankee 2010-09-25 10:47:14

    你就别浅谈了,来个详谈吧!

  8. hehe
    116.236.205.*
    链接

    hehe 2010-09-25 16:14:19

    老赵能否介绍下 “理想中的数据访问层” 应该是什么样子的? 博文中多次提到,令人好奇,谢谢!

  9. nfl jerseys
    61.132.128.*
    链接

    nfl jerseys 2010-09-25 17:08:34

    在如今信息爆炸的时代,产生和获取一条没有多大价值甚至是错误的信息,可谓是非常容易的

  10. stainboy
    122.84.23.*
    链接

    stainboy 2010-09-25 22:30:07

    我就想知道,攻击者是怎么发现这个漏洞的,是什么因素启发他发现这个漏洞的。公开的黑客攻击原理一般都比较容易理解的,思想来到比较重要,这就好比艺术家的创作灵感。

  11. stainboy
    122.84.23.*
    链接

    stainboy 2010-09-25 22:32:48

    另外突然想问老赵一个问题,如果我想在Linux(如Ubuntu)上面开发ASP.NET MVC程序,数据层一般选择什么框架呢(假设是MYSQL数据库),LINQ TO SQL/NHIBERNATE,或者其他?请赐教。

  12. 老赵
    admin
    链接

    老赵 2010-09-26 00:21:43

    @stainboy

    就用NHibernate或是更简单的ORM工具吧。

  13. 老赵
    admin
    链接

    老赵 2010-09-26 00:22:42

    @stainboy

    我估计真正熟悉了一种攻击方式,会发现其实漫天都是漏洞的,这和开发程序的感觉应该也差不多吧。

  14. gl
    123.138.30.*
    链接

    gl 2010-09-26 22:15:12

    有趣,这样才能发展嘛。

  15. Joey
    222.209.120.*
    链接

    Joey 2010-09-28 00:49:51

    从老赵的文章来看您大概是看了那个16页的论文,可是关键地方没写清楚。针对Padding Oracle我还有这样几个疑问:

    1. 您提到“攻击者便可以根据这个加密方式设计有针对性的密文,最终得到密钥”,这个过程一句话盖过去可说不过去。根据Juliano Rizzo和Thai Duongy的说法,这个过程并不需要加密算法本身。此外如果只是可以通过尝试密文的方式就可以猜出K和IV,那岂不是目前所有的加密算法都具备数学上的不完备性?因为每种密文都有会被用来验证或者解密的场所,这个几乎难以避免,那岂不是这些所谓加密都形同虚设?这个确实很疑惑。我仔细看了他们关于CAPTCHA和Viewstate的两个例子,但是依然对中间这个最关键的部分没有概念。

    2. 对web站点造成的影响,可以归纳为:所有依赖于客户端加密的ViewState和Cookie数据的场所,如果缺少必要的安全检查,就一定会引发相关的安全问题,比如injection, xss, csrf, bac等等。因为这些数据虽然来自于安全边界以外(客户端数据),但是由于是密文,所以习惯上容易被程序员忽视。利用ScriptManager来download web.config其实属于这类攻击的一个特例。只是由于对asp.net程序员来说web.config泄露听上去比较震撼,所以被拿出来大肆渲染了。如果1的理论被搞清楚了,那么针对任何基于此理论的web app,都有一系列的攻击手段伺候。

    3. 所以看ScottGu的workaround,其实没有解决本质上的问题:依然无法阻止machine key被泄露的命运,而且其他地方对加密客户端数据的不正确使用都难以得到解决。

    所以我的建议是,对所有的web developer,不管你使用什么开发语言,重新检查你对客户端数据的使用,尤其是加密数据。解密之后做过必要的校验和安全检查吗?

    一点浅见,与老赵商榷。

  16. 老赵
    admin
    链接

    老赵 2010-09-28 10:21:21

    @Joey

    加密算法其实没有什么问题,因为它有自己的目标,这里的问题其实是加密算法使用方式上的问题:给攻击者以提示了,要知道加密算法本身是不关心是不是给攻击者提示的。

    的确ScottGu的方法无法完全避免问题,这点我在文章里也有叙述了,因为目前这种攻击方式的危险之处,正是因为只需要“是/否”这样的二元信息。这个问题很容易出现,而且和语言平台无关,所以的确应该每个需要加密解密的地方都进行校验之类的检查。

  17. Joey
    222.209.113.*
    链接

    Joey 2010-09-28 18:24:04

    多谢回复。我现在唯一剩下的疑问就是这个通过修改密文进行试探和破获IV & K的过程了。看了几篇论文都还没有看明白。

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我