CBC 位翻转攻击


CBC加密解密过程:

09303f99c9433872fbaffcb2b043b7b1

1、核心思想

​ CBC的位翻转攻击通过对初始向量(IV)的优化,使得解密之后的明文块发生需要的变化,在CBC模式中密文的分组第一块通常为IV本身,我们需要考虑的是密文分组2的解密,明文分组1之后开始才是FLAG字段。

根据例题:https://aes.cryptohack.org/flipping_cookie/get_cookie/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from Crypto.Cipher import AES
import os
from Crypto.Util.Padding import pad, unpad
from datetime import datetime, timedelta


KEY = ?
FLAG = ?


@chal.route('/flipping_cookie/check_admin/<cookie>/<iv>/')
def check_admin(cookie, iv):
cookie = bytes.fromhex(cookie)
iv = bytes.fromhex(iv)

try:
cipher = AES.new(KEY, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(cookie)
unpadded = unpad(decrypted, 16)
except ValueError as e:
return {"error": str(e)}

if b"admin=True" in unpadded.split(b";"):
return {"flag": FLAG}
else:
return {"error": "Only admin can read the flag"}


@chal.route('/flipping_cookie/get_cookie/')
def get_cookie():
expires_at = (datetime.today() + timedelta(days=1)).strftime("%s")
cookie = f"admin=False;expiry={expires_at}".encode()

iv = os.urandom(16)
padded = pad(cookie, 16)
cipher = AES.new(KEY, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(padded)
ciphertext = iv.hex() + encrypted.hex()

return {"cookie": ciphertext}

iv为一个任意的16字节字段,其定义了每个块的大小也都为16字节,而cookie的前16个字符便为明文分组2的内容

1
admin=False;expi

而在源代码中,明确指出当admin=False存在在cookie中的时候,是访问不到flag的,于是我们选择对初始向量进行优化

假设原明文分组2为 a1

a1 = 密文分组1 XOR IV

假设需要的明文分组2为a2

a2 = 密文分组1 XOR IV XOR a1 XOR a2

所以新的IV就为

New_IV = IV ^ a1 ^ a2

得到翻转后的New_IV 位翻转成功!!!!!

其余正常操作即可!!!!!!!!!

总结

CBC位翻转攻击的核心主要就是对初始向量的优化,将明文第一块变成自己想要的值,以下位wp,博主在后续会优化对代码的注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests
from Crypto.Util.number import *

result = requests.get('https://aes.cryptohack.org/flipping_cookie/get_cookie/')
ciphertext = result.json()["cookie"]
# print(result.text)

# print(len(bytes.fromhex(ciphertext)))
ciphertext = bytes.fromhex(ciphertext)
c1 = hex(bytes_to_long(ciphertext[0:16]))[2:]
c2 = hex(bytes_to_long(ciphertext[16:32]))[2:]
c3 = hex(bytes_to_long(ciphertext[32:48]))[2:]
# print(c1)
cookie = c2 + c3
# print(cookie)
# IV = c1

a1 = b'admin=False;expi'
a2 = b'admin=True;00000'
k1 = bytes_to_long(a1)
k2 = bytes_to_long(a2)
m1 = hex(k1)
m2 = hex(k2)
# print(m1)
# print(m2)

# print(m1)
IV_new = int(m1, 16) ^ int(m2, 16) ^ int(c1 , 16)
# print(IV_new)
IV_new = hex(IV_new)[2:]
print(IV_new)
result2 = requests.get(f'http://aes.cryptohack.org/flipping_cookie/check_admin/{cookie}/{IV_new}')
l = result2.json()
print(l)

在最近的做题过程中,发现之前爬虫学的一部分知识最近有在反复用到

request.get()以这一段代码来获取网页内容,之后再用json格式读取需要的内容