# CVE-2014-3566 SSLv3 POODLE原理分析

Author: 乌云历史资料库 (@wooyun_archive)
Published: 2014-10-15T06:11:00Z
Canonical: https://wepostx.com/topics/593

> 乌云历史资料归档
>
> **原始作者：** insight-labs
> **原始编号：** superkieran-wooyundrops:364
> **原始发布时间：** 2014-10-15 14:11
> **声明：内容仅用于技术研究和个人使用，版权归 wooyun.org。**

---

## 0x00 背景

POODLE攻击是针对SSLv3中CBC模式加密算法的一种padding oracle攻击。这个攻击方式和之前的BEAST攻击方式很像，可以让攻击者获取SSL通信中的部分信息的明文，比如cookie。和BEAST不同的是，它不需要对明文内容的完全控制，所以操作起来更加贴近实战。
从根本上说，这是SSL设计上的问题，就像 [Lucky13](http://www.isg.rhul.ac.uk/tls/Lucky13.html) 和 [Vaudenay's two atacks](http://www.thoughtcrime.org/blog/the-cryptographic-doom-principle/) 这些漏洞里面描述的一样，SSL的加密和认证过程搞反了，SSL先进行认证之后再加密。

## 0x01 细节

首先考虑这个明文HTTP请求, 我把它分成了 8字节的块，就像3DES加密，但是这个方法对16字节的AES块加密一样适用:

![原文图片](/media/2016/06/cf7c62420fcfdbae959e42779887b059)

最后一个块里包含了7个字节的填充(padding),用·来表示，最后一个字节7是填充长度，我用了虚构的8字节MAC校验码。在传输前，这些数据都会被3DES或者AES加密。现在来回顾下CBC解密的过程，这张图来自wikipedia:

![原文图片](/media/2016/06/e6ca6895cac6c00021cecc3f0de4ccc8)

攻击者可以控制HTTP请求中的路径和主体，从而让请求的内容满足如下条件:

```text
后面的padding填充部分填充了一整个block cookie的第一个字节正好在某个块的末尾的字节
```
攻击者需要做的是把包含cookie第一个字节(出现在这个块的末尾，例如块中的内容是 Cookie:a，a正好在8字节块的末尾)的那个块,替换padding的那个块发送给接收者(服务器)。
一般来说，服务器会拒绝这段密文，因为CBC校验失败了，攻击者需要重新发送，平均来说，每256个请求中有一个会被服务器接受，只要服务器接受了，根据CBC的解密过程，攻击者就知道了cookie的第一个字节(明文)的和上一个块最后一个字节的密文 XOR 后是 7或者15(分别对应块长度8或16)。
作为中间人，我们可以看到任何一段密文，所以

```text
P XOR K = C C XOR K = P
```
三个变量我们只要知道了两个就可以解密出另一个，所以 Cookie第一字节 XOR 密文最后一个字节 = 15
我们只要把 15 XOR 密文最后一个字节就知道了cookie的第一个字节。
因为可以解密的窗口大小只有1字节(前面任意一个块的最后一个字节)，所以需要通过js控制HTTP请求路径的长度，比如 GET/, GET /A, GET /AA...把需要解密的cookie的位置逐渐顶到解密窗口中，每次解密一个字节平均需要256次请求，攻击者就可以用256*n次构造的请求来解密SSLv3中任意位置的明文。
这个漏洞的主要成因是因为SSLv3没有规定padding填充块字节的内容，只校验填充块最后一个字节，因为TLS会检查填充块的内容所以在TLS上同样的攻击方式成功率只有2^-64或者2^-128。

## 0x02 解决方式

把SSLv3关了，SSLv3已经过期用了15年了。
参考： [https://www.imperialviolet.org/2014/10/14/poodle.html](https://www.imperialviolet.org/2014/10/14/poodle.html) [https://www.openssl.org/~bodo/ssl-poodle.pdf](https://www.openssl.org/~bodo/ssl-poodle.pdf)

## Replies
