神刀安全网

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

为什么说是再解读呢?目前关于Padding Oracle攻击的介绍,比较好的文章包括的内容,都取自于 这篇外文 。但是,该文在论述一个关键问题,即如何确认Padding位数时,并没有提及,这让许多较真的读者会有很大的疑惑。本人亦如此。因此,我想再把思路做个梳理。

1.分组密码和填充

常用的对称加密算法,如DES和AES,在用密钥加密数据时,只能加密和密钥长度相同的数据。对于超长数据,我们需要将其切分成块。这就带来一个问题,可能最后一个块,无法和密钥“对齐”(当然,这也包括原始数据本来就比密钥短的情况)。这就需要一些数据去填充最后的几位。常用的填充算法即PKCS#5,在数据填充中,使用缺失的位数长度来统一填充,说起来麻烦,上图即可明白:

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

即缺5位,就用0×05填充;缺2位,就用0×02填充;如果刚刚好,还要扩展出一个块,全用0×08填充。

2.初始向量和CBC加解密过程

如果每一个块都用同一个密钥加密,很容易使用统计学原理去分析和破解密文(原理大致如同e字母在英文单词中出现的概率是非常高的,因此通过统计分析,大致可能猜出X代表了e),为此CBC加密过程引入了一个初始向量,使得每一个块的加密密钥,都包涵有上一个块的密文的反馈,从而解决了统计学攻击问题。还是上图比较容易理解,因为仅仅涉及到一个异或运算,所以不做解释,其中的Encryption/Decryption,就是加密算法所在。但是,Padding Oracle攻击,恰恰是避过了这一块的实现细节,因此大家可以忽律那个框框,如图:

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

而解谜,就是一个反过程

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

因此,双方除了要交换密文外,还需要交换初始向量

3.Padding Oracle的攻击条件

并不是使用CBC的服务都有弱点.我们可以构想如下一个可以被利用的漏洞服务器,来解释其特点:对于请求,会有如下反馈:

1. 如果解密过程没有问题,明文验证(如用户名密码验证)也通过,则会返回正常 HTTP 200

2. 如果解密过程没有问题,但是明文验证出错(如用户名密码验证),则还是会返回 HTTP 200,只是内容上是提示用户用户名密码错误

3. 如果解密过程出问题了,比如Padding规则核对不上,则会爆出 HTTP 500错误。

这样举例,仅仅是为了说明,可被利用的服务器的特点是:对于解密过程自身的异常,会有一个特殊的错误提示,有别于明文验证出错。

4.Padding Oracle攻击过程

该例子还是沿用 这篇外文 中的例子。

假设一个服务的请求如下: http://sampleapp/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 ,注意其前8字节 7B216A634951170F 是初始化向量。

我们来看看这样一个服务,是如何加解密一个字符串 BARIN;12;1 的(加密本身用了3DES,但这不是问题的重点,可以忽略)。

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

解密过程如下

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

注意: 最终的Padding是符合验证的。

通过解密过程我们可以看出,因为初始化向量是可以知道的,如果我们知道中间值,即 Intermediary Value ,在不需要知道加密过程时,通过简单的异或,就可以知道明文是什么了。甚至,我们还可以通过中间值仿造任意的明文字段做暴力攻击。

现在假设有一个中间人,截获了报文,那么它可以这样操作:首先,向服务器发送请求时,把初始化向量全部设为0×00,且只保留第一个块,最终报文是 http://sampleapp/home.jsp?UID=0000000000000000F851D6CC68FC9537 。其解密过程如下:

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

因为最终填充校验有误,自然服务器会报错HTTP 500。

之后,中间人将初始向量递增1,用 http://sampleapp/home.jsp?UID=0000000000000001F851D6CC68FC9537 去试探,自然也是报错

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

因为对于固定的中间值,即图中的 Intermediary Value 的最后一位,必然有一个字节和它异或时,能够达成Padding为0×01使其满足Padding规则。因此,我们不断递增测试,必然有一个初始向量,使得最后一位的Padding规则满足条件,如 000000000000003C ,如图

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

但是这里有一个问题,是其它几篇文章没有分析到的,我在这里继续说明一下

是不是当我们递增初始向量最后一位时,如果碰到服务器返回200时,必然Padding最后一位是0×01呢??答案并不是

比如,当中间值最后两位是 0x02 0x00 ,而我们测试的初始向量最后两位是 0x00 0x02 时,也就是探测最后一位是 0x02 时,最终的Padding的最后两位是 0x02 0x02 ,必然也满足Padding规则,服务器当然也会返回200。可见,仅仅依靠我们递增最后一位和测试服务器是否返回200,是没办法确认最终的Padding是0×01的。

那么怎么才能确认呢?观察异或的过程,可以看出,如果padding是0×01,那么,倒数第二位是什么,并不会影响服务器测试结果(因为改变倒数第二位,仅仅是改变了解码后的明文,会导致明文验证过程异常,但是解密过程是没有任何异常的),此时服务器还是返回200。但如果Padding是 0x02 0x02 ,则改变倒数第二位,会导致解密异常,服务器返回500。因此,我们通过测试倒数第二位,确认了探测过程中得到的Padding是0×01。

有了确定的初始向量最后一位,和确定的Padding最后一位0×01,我们就可以推出确定的中间值最后一位。

之后,我们再通过碰撞Padding最后两位是 0x02 0x02 ,来测试出中间值的第二位是什么。这里有一个技巧要注意,因为中间值最后一位,已经碰撞出来,而要得到Padding最后一位是0×02,势必初始向量的最后一位也是固定了(就是个简单的异或),因此,我们要递增的是初始向量的倒数第二位,如图

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

依此类推,我们最终可以确认出全部中间值来

技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

正如前面所说,有了确认的中间值,和已知的初始化向量,我们就可以知道第一块的明文了。依此类推,我们可以测试出所有块的明文来。

5.关于HTTPS中的CBC的Padding Oracle攻击防御

那么HTTPS中,如何防范CBC攻击呢。答案是禁用SSLv3。但是为了浏览器兼容性(比如IE6仅支持到SSLv3),可能没法废除SSLv3时,那么可以禁用以下CipherSuite

IDEA-CBC-SHA, EXP-DES-CBC-SHA, DES-CBC-SHA, DES-CBC3-SHA, EXP-DH-DSS-DES-CBC-SHA, DH-DSS-DES-CBC-SHA, DH-DSS-DES-CBC3-SHA, EXP-DH-RSA-DES-CBC-SHA, DH-RSA-DES-CBC-SHA, DH-RSA-DES-CBC3-SHA, EXP-DHE-DSS-DES-CBC-SHA, DHE-DSS-CBC-SHA, DHE-DSS-DES-CBC3-SHA, EXP-DHE-RSA-DES-CBC-SHA, DHE-RSA-DES-CBC-SHA, DHE-RSA-DES-CBC3-SHA, EXP-ADH-DES-CBC-SHA, ADH-DES-CBC-SHA, ADH-DES-CBC3-SHA, EXP-RC2-CBC-MD5, IDEA-CBC-SHA, EXP-DES-CBC-SHA, DES-CBC-SHA, DES-CBC3-SHA, EXP-DHE-DSS-DES-CBC-SHA, DHE-DSS-CBC-SHA, DHE-DSS-DES-CBC3-SHA, EXP-DHE-RSA-DES-CBC-SHA, DHE-RSA-DES-CBC-SHA, DHE-RSA-DES-CBC3-SHA, ADH-DES-CBC-SHA, ADH-DES-CBC3-SHA, AES128-SHA, AES256-SHA, DH-DSS-AES128-SHA, DH-DSS-AES256-SHA, DH-RSA-AES128-SHA, DH-RSA-AES256-SHA, DHE-DSS-AES128-SHA, DHE-DSS-AES256-SHA, DHE-RSA-AES128-SHA, DHE-RSA-AES256-SHA, ADH-AES128-SHA, ADH-AES256-SHA

注意, 并不是都包涵CBC字样,有些没有包涵,一样要禁用了

关于这个问题,详见 这篇文章

6.结语

首先感谢 V2EX论坛的用户讨论 ,正是因为彼此之间的交流,才让本人弄清楚了Padding Oracle攻击中一个很重要的点:Padding长度的确认。

本文的部分内容来自于 该篇文章 以及其使用的 原始文章 ,我补充了个人认为非常重要的一个章节,即刚才谈及的Padding长度的确认。

* 作者:Tony Lee,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 技术分享:CBC中Padding Oracle攻击的再解读,如何攻破HTTPS?

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮