黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解

先来讲一讲CBC模式加密原理:
加密过程:

黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解

文章插图
 
1.首先将明文(Plaintext)分组(常见的以16或8字节为一组),位数不足的使用特殊字符填充 。
2.生成一个随机的初始化向量(IV)和一个密钥 。
3.将IV和第一组明文异或(xor运算) 。
4.用密钥对3中xor后产生的密文加密 。
5.用4中产生的密文对第二组明文进行xor操作 。
6.用密钥对5中产生的密文加密 。
7.重复4-7,到最后一组明文 。
8.将IV和加密后的密文拼接在一起,得到最终的密文
解密过程:
黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解

文章插图
 
1.先从密文中取出IV,然后对剩下的密文分组(16或8字节为一组)
2.使用秘钥解密第一组密文,将解密结果与IV做异或运算,得到明文1
3.然后使用秘钥解第二组密文,将解密的结果与上一组密文进行异或运算,得出明文2
4.重复2-3,直至所有密文解密完毕
以上就是CBC模式的加密解密过程,接下来讲两种手段:
Padding Oracle Attack
直译为 "填充Oracle攻击",这里主要关注一下解密过程:
黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解

文章插图
【黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解】 
密文cipher首先进行一系列处理,如图中的Block Cipher Decryption
我们将处理后的值称为 middle 中间值
然后 middle 与我们输入的iv进行异或操作
得到的即为明文
但这里有一个规则叫做Padding填充:
因为加密是按照16位一组分组进行的
而如果不足16位,就需要进行填充
黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解

文章插图
 
有几个空,就要填充几个"几"
比如明文为admin,那么需要填充的就是
admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b (11个\x0b)
如果我们输入一个错误的IV(初始向量),依旧是可以解密的,但是 middle 和我们输入的IV经过异或后得到的填充值可能出现错误
比如本来应该是 admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b
而我们错误的得到 admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x3b\x2c
这样解密程序往往会抛出异常(Padding Error)
当这个CBC解密模式应用在web程序里的时候,往往是302或是500报错
而正常解密的时候是200 。
所以这时,我们可以根据服务器的反应来判断我们输入的IV
一个例子
我们假设middle中间值为:
0x39 0x73 0x23 0x22 0x07 0x6a 0x26 0x3d
正确的解密IV应该为
0x6d 0x36 0x70 0x76 0x03 0x6e 0x22 0x39
解密后正确的明文为:
T E S T 0x04 0x04 0x04 0x04
但是关键点在于,我们可以知道iv的值,却不能得到中间值和解密后明文的值
而我们的目标是只根据我们输入的iv值和服务器的状态去判断出解密后明文的值
这里的攻击即叫做 Padding Oracle Attack 攻击
是一种根据页面回显来爆破密文的攻击
如果我们构造一个IV为:
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
那么 middle 的值和这个iv异或将会得到原封不动的 middle 的值
0x39 0x73 0x23 0x22 0x07 0x6a 0x26 0x3d
现在这个解密结果是不对的,web程序抛出错误 。
黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解

文章插图
 
正确的 padding 值只可能是:
1个字节的padding为0x01
2个字节的padding为0x02,0x02
3个字节的padding为0x03,0x03,0x03
4个字节的padding为0x04,0x04,0x04,0x04
……
因此我们希望慢慢调整IV的值,并且希望解密后最后一个值为正确的 padding 比如一个0x01,我们于是遍历最后一位IV:
黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解

文章插图
 
那么最后一位中间密文就是: 0x01^0x3C=0x3D (这个一定成立,看图),原来的明文就是 0x3D^0x0F=0x32(中间密文^原来的iv)
知道了最后一位的中间密文,就可以遍历倒数第二位iv了,这个时候应该为 0x02 而非 0x01 了 。看图就懂:
黑客教程——Padding Oracle Attack&CBC字节翻转攻击详解

文章插图
 
以此类推,我们可以就能推算所有中间密文,再用 中间密文^原来的iv 就能算出明文了
CBC字节翻转攻击
有了上面的CBC加密解密过程的基础,这个手段其实很容易理解;


推荐阅读