CBC字节翻转攻击

本来是想借着一道题来讲的,但是bugku上面的那个题目挂了,所以还是随便记录下吧。

CBC字节翻转攻击一般出现在,php中使用aes128cbc加密时候可以被hack。从而达道篡改信息的目的。不过貌似因为会破坏字符串内部的东西,应用范围较小,不过一旦可以被应用是一个毁灭性的漏洞。2333

先来介绍如何进行加密

首先将明文分成每X位一组,位数不足的是用特殊字符填充 !!!!!!!
X常见的为16位,也有32位
这里要注意,CBC的填充规则是缺少N位,就用 N 个 '\xN'填充,如缺少10位则用 10 个 '\x10'填充
然后生成初始向量IV(这里的初始向量如果未特定给出则随机生成)和密钥
将初始向量与第一组明文异或生成密文A
用密钥加密密文A 得到密文A_1
重复3 将密文A_1与第二组明文异或生成密文B
重复4 用密钥加密密文B_1
重复3-6 直到最后一组明文
将IV和加密后的密文拼接在一起,得到最终的密文

解密过程

首先从最终的密文中提取出IV (IV为加密时指定的X位)
将密文分组
使用密钥对第一组密文解密得到密文A,然后用IV进行异或得到第一组明文
使用密钥对第二组密文解密得到密文B,然后用A与B进行异或得到第二组明文
重复3-4 直到最后一组密文

大家不难发现,每组密文中的字符,只和上一组相关。所以可以通过改写单个字符
来达到改写另一个的效果。
一般的攻击点有两个。
第一个是IV,第二是倒数第二组密文。
IV为什么是可被攻击。如果IV被攻击。那么第一组就会相应被改变。
倒数第二组,则可以改变最后一组。
根据解密过程,假设A为明文,B为前一组密文,C为密文经过密钥解密之后的字符串:

$A = Plaintext[0] = 11 ;
$B = Ciphertext[0] = 13 ;
$C = Decrypt(Ciphertext)[0] = 6 ;
 ```
A^B=C
A=B^C
得到了A
想改变第N组,那么就去改变第N-1组的密文。

$A = Plaintext[0] = 'h' ;
$B = IV[0] = 可控;
$C = Decrypt(Ciphertext)[0] = ?;

//所以我们需要伪造一个新的IV向量,使得$C ^ New_IV = 我们需要的明文
//因为有
$C ^ Old_IV = Source_str
//所以
$C = Old_IV ^ Source_str
//并且我们还需要
$C ^ New_IV = Target_str
//即
$C = New_IV ^ Target_str
//所以
Old_IV ^ Source_str = New_IV ^ Target_str
//所以
New_IV = Old_IV ^ Source_str ^ Target_str

可以得到

我们传入的信息=原来密文^原来字符串^目标字符串

可以满足所有需要的条件。
从而达到攻击效果。
下面是密文攻击的点

假如已知异或之后的第N-1组密文(Decrypt之后的密文),我们就可以通过字节翻转改变第N组明文

数学原理和前面一种攻击点类似

下面假设我们要更改第3组明文$Old_pt[1]为第2组明文,$Old_ct[1]为第2组密文,$Old_ct[2]为第3组密文
$Plaintext = [
'comment1=wowsuch',
'%20CBC;userdata=',
'admin=true;come',
'nt2=%20suchsafe%',
'20very%20encrypt',
'wowww'
];//我们要使$Plaintext[2]中的
变成;
//密文全部已知并可控
$Old_pt[1] = Plaintext[1] = '%20CBC;userdata=';
$Old_ct[1] = Decrypt(Ciphertext)[1] = 已知 并且我们攻击的点在这;
$Old_ct[2] = Decrypt(Ciphertext)[2] = 已知;

```
//所以我们需要伪造一个新的第2组密文,使得$Old_ct[2] ^ $New_ct[1] = 我们需要的明文
//因为有 
$Old_ct[1] ^ $Old_ct[2] = $Old_pt[2];
//所以
$Old_ct[2] = $Old_ct[1] ^ $Old_pt[2];
//并且还已知
$New_ct[1] ^ $Old_ct[2] = $New_pt[2];
//即
$Old_ct[2] = $New_ct[1] ^ $New_pt[2];
//所以
$Old_ct[1] ^ $Old_pt[2] = $New_ct[1] ^ $New_pt[2];
//所以
$New_ct[1] = $Old_ct[1] ^ $Old_pt[2] ^ $New_pt[2];

下面给出个小例子。

#-*-coding:utf-8-*-
import base64

'''
    CBC字节翻转攻击例子
    已知密文和原文,要求修改密文中uid=1达到攻击目的。

    原文:
    1234567890abcdef1234567890abcdef1234567890abcdef1234567890auid=9;123123123123
    密文(经base64编码):
    9pzE4775q38+wGl/FqNMfFM53Ra6wTKAGUykoeioOjKzlajhqgjsPjGiXVvkFF2BwdywFE67ELLaNuU5yS0kjiuETsjG0Jdk4LiwwBst8ig=

    解题:
    原文分成16字符一组
    1234567890abcdef
    1234567890abcdef
    1234567890abcdef
    1234567890auid=9;
    123123123123
'''

enc='9pzE4775q38+wGl/FqNMfFM53Ra6wTKAGUykoeioOjKzlajhqgjsPjGiXVvkFF2BwdywFE67ELLaNuU5yS0kjiuETsjG0Jdk4LiwwBst8ig='

_enc = base64.b64decode(enc)
uid = chr(ord(_enc[16*3-1])^ord('9')^ord('1'))

_enc2list = list(_enc)
_enc2list[16*3-1] = uid
_enc = ''.join(_enc2list)

x_enc = base64.b64encode(_enc)
print x_enc

上述例子来自:https://www.cnblogs.com/hellotimo/p/10996372.html
下一篇想了解下和他一起工作的Padding Oracle攻击。

推荐文章