先占坑 真鸡儿难 给爷看吐了要


看懂了 回来填坑了

00×0 CBC分组模式简介

简单写一下CBC加密和解密的过程
1.先把数据分成一个个等长的区块 也就是block
2.使用初始向量IV与第一个区块的数据进行异或运算,然后使用指定的加密算法进行加密得到第一块密文
3.使用第一块密文作为第二个IV,与第二个区块进行异或运算,然后再使用指定的加密算法进行加密 之后的都以此类推
由于异或运算具有可逆性 不难推断出解密的过程
1.将第一个区块的密文进行算法上的解密,然后与初始向量IV进行异或得到第一个明文
2.将第二个区块的密文进行解密,然后与第一个区块的密文进行异或得到第二个明文,之后的内容以此类推
为了方便,把密文进行解密之后的值称为中间值(对应了在加密过程中,异或运算得到的内容)
中间值可以由IV和明文异或而来 也可以由密文解密得到 中间值在与IV(即前一段的密文或初始向量)进行异或即可得到明文

0x01 padding的规则

为了了解padding oracle的攻击点,还需要介绍一下padding的规则
padding即为填充,因为CBC是分组加密,需要把明文分成小块,就一定会出现最后一段不够分一组的情况 所以会进行填充
填充的规则:缺几字节补几字节,如果不缺字节则填充一整组的字节 并且填充了多少字节 填充的字节就是几 比如填充了八字节,最后八位就都是0x08 在DES加密中,密文为八位一组 也就是字节范围在0x01到0x08之间 在AES加密中,密文为16位一组,字节范围在0x01到0x10之间。
原理都是一样的,为了方便就拿八字节做例子了。
在服务端进行验证的时候,首先就会验证padding的字节是否正确(由于padding是一定会进行的,最后一组的明文一定是按照padding规则存在的)
比如最后一字节是0x04,那后四个字节就必须都是0x04 最后一字节是0x01,那OK,这个解密就过了,因为只填充了一字节,不用再管别的了(也正是这个关键的一字节,让我们能够进行猜解)。

0x02 PaddingOracleAttack

PaddingOracleAttack就是出现在解密验证过程中的攻击,如果我们能够得知初始向量,并且能够通过服务端的响应判断解密是否成功的话,就可以通过构造IV(前一段密文),对所有的中间值进行按位猜解,而中间值只要与前一段密文异或,就能得到明文 这就是PaddingOracleAttack(我个人喜欢叫做明文推断攻击,这样更能体现它的作用)
攻击的流程:
1.将密文分组,然后假定最后一组密文填充了一字节,对IV(倒数第二组密文)的最后一字节进行构造 当密文可以正常解密的时候,构造的IV最后一位与中间值异或为0x01,根据异或的运算性质,使用构造的IV与0x01进行异或即可求得正确的中间值,而中间值只要与原本的IV进行异或即可得到明文。 再假定最后两位字节为0x02,最后一位的中间值已经得知 由IV最后一位^中间值=0x02可以推知 IV最后一位=中间值^0x02 然后构造倒数第二位字节,

/*

这里再记录两个不容易搞明白的点
1.当时费解了很久为什么可以这么构造,其实对服务器解密判断的过程有了透彻了解就懂了:最后一字节只可能是0x01到0x08之间 服务器会根据最后一字节的数值确定填充的字节数 然后向前回溯指定的字节数,如果这些字节都与最后一字节相同,即可正常解密。 当我们构造出最后一字节是0x01时,服务器只会对当前字节进行判断,就通过了解密。

2.为了防止碰撞,在构造最后一字节的同时,一般指定前面的字节为0x00 原理:原本的IV与中间值异或->后面出现padding字节 构造的0x00密文与中间值异或->除非原本的IV也全0x00才会出现碰撞 这也是我之前钻牛角尖的一个点

*/
2.在推出最后一个区块的所有中间值并且推得明文之后,即可舍弃掉这个区块,构造倒数第三个区块的密文作为IV,推算倒数第二个区块,过程和1一样
之后的剩余区块全部可以使用这个方法
值得一提的是,这个流程也可以从第一个区块开始 方便写脚本
另外就是在构造的时候可以只取用到的两个区块,减少字符串处理时不必要的的麻烦

00×3 脚本编写

占坑 懒得写暂时

Categories: 技术

0 Comments

发表评论

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注