要谈这个问题先要了解什么是Padding Oracle Attack。有些文章把Padding和Oracle与CSS样式表或是那个收购了Sun的甲骨文公司联系起来这就驴唇不对马嘴了。Padding在这里的含义是“填充”因为对于加密算法来说它们是基于等长的“数据块”进行操作的如对于RC2DES或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 MyFaces和Sun 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?dxyz进行探测工作。WebResource.axd有一个特点便是会对错误的密文即dxyz中的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 IDsm runatserver 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产品的缘故。此外还有一些做法也是可取的。例如
什么是Padding和Oracle
要谈这个问题先要了解什么是Padding Oracle Attack。有些文章把Padding和Oracle与CSS样式表或是那个收购了Sun的甲骨文公司联系起来这就驴唇不对马嘴了。Padding在这里的含义是“填充”因为对于加密算法来说它们是基于等长的“数据块”进行操作的如对于RC2DES或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 MyFaces和Sun 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?dxyz进行探测工作。WebResource.axd有一个特点便是会对错误的密文即dxyz中的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 IDsm runatserver 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产品的缘故。此外还有一些做法也是可取的。例如