0x01 背景知识
我第一次看到这个的时候,还真的傻乎乎的以为是和Oracle(甲骨文)相关的漏洞,然而,这个和甲骨文的关系并不大emmmm,oracle翻译成中文有预言、神谕的意思。在密码学中,oracle是一个代表 用户或者攻击者 执行给定加密操作的系统。
Padding Oracle Attract是针对CBC模式的攻击,关于CBC加密解密与翻转攻击,上一篇笔记有写到,这里就不再重复了。
0x02 原理
我们已经知道,在常用的对称算法,比如3DES、AES在加密的时候一般都会采用分组密码(Block Cipher),将明文进行分组。但分组的同时就会带来一个问题,我们需要加密的明文不可能全部都是block(我们规定的区块长度)的整数倍,所以需要对不能整除的数据进行填充操作。我们常用的填充操作有PKCS#5和PKCS#7,在最后一个block中将不足的bit位数的值作为内容进行填充,例如如果最后一个区块缺少5个bit,就直接填充5个0x05到后面。我们子在解密的时候也会去检验明文的填充是否满足这个规则,如果满足以n个0x0n结束,就表示解密成功,否则解密失败。所以,当我们向服务器提交一个密文想要解密时,服务器一共会有三种判断结果:
- 密文不能正常解密;
- 密文可以正常解密但解密结果不对;
- 密文可以正常解密并且解密结果对比正确;
0x03 攻击步骤
- 我们先假设存在一组密文
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
将其分为3组
1 | IV(初始化向量):7B 21 6A 63 49 51 17 0F |
对第一组密文进行破解,先假设我们明文只填充了一个字节,首先将IV全部设置为0,我们这时候假设存在一个解密系统,我们输入
00000000000000000F851D6CC68FC9537
运行结果如图
我们可以看到,明文的最后一个字节填充的是0x3D,肯定不满足我们上面说的填充条件的,这里校验肯定就会失败,系统就会和我们返回错误,所以我们需要对IV的最后一个字节从0x01到0xff逐个赋值进行校验,知道最后得到的明文最后一位位0x01,这里我们可以知道我们构造的为0x3C
- 利用xor运算的性质,我们只需要将我们构造的IV的最后一个字节与0x01进行xor运算后就可以得到最后一位密文解密后的中间值是什么了,我们设它为M1,我们再看一张图
这一过程其实就是这张CBC原理图中标记的地方,右边的红圈就是我们想要得到的中间值,左边的红圈就是我们构造的密文,也就是最后一组密文的IV,我们已经知道了最后一组Plaintext的最后一个字节是0x01,从图中可以看到它是由我们构造的IV值与中间值的最后一字节异或得到的
再假定明文填充了两字节也就是明文最后两字节是0×02,接着构造倒数第二组密文,我们把M1与0×02异或可以得到填充两字节时密文的最后一位应该是什么,这时候我们只需要对倒数第二位进行不断地赋值尝试(也是从0×00到0xff),当服务器返回值表示可以正常解密时,我们把此时的倒数第二位密文的取值与0×02异或便可得到最后一组密文倒数第二字节对应的中间值;
再构造出倒数第三倒数第四直到得到最后一组密文的中间值,把这个中间值与截获的密文的倒数第二位异或便可得到最后一组分组的明文;
舍弃掉最后一组密文,只提交第一组到倒数第二组密文,通过构造倒数第三组密文得到倒数第二组密文的铭文,最后我们便可以得到全部的明文
0x04 总结
Padding oracle attract的关键思路其实就在于通过构造IV值,利用服务器的返回结果判断是否构造正确,最终找到正确的中间值,来达到绕过加密算法,直接得到解密内容的效果;
进行这个攻击也需要两个重要的假设前提:
- 攻击者能够获得Ciphertext(密文,包括IV)
- 攻击者需要知道构造得结果是否正确,也就是需要一个带有响应得检测系统
参考链接:
https://blog.skullsecurity.org/2013/padding-oracle-attacks-in-depth
https://blog.skullsecurity.org/2013/a-padding-oracle-example
https://www.jianshu.com/p/833582b2f560
https://www.jianshu.com/p/ad8bdd87e131
https://www.freebuf.com/articles/database/151167.html
这两天我看了很多遍相关的文章,这篇学习笔记包括上一篇CBC翻转攻击其实也是各家抄过来的,但是这样下来也学到了很多很多东西、庆幸至极,同时知道自己需要学习得东西还有很多,总之,加油吧five!