ctrime

CRIME漏洞–CVE - 2012-4929

学习题目来源:https://aes.cryptohack.org/ctrime/

原理:https://en.wikipedia.org/wiki/CRIME

通过数据压缩过程导致的加密方式,使得敌手不断发送信息加密,判断压缩数据的长度爆破出数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Cipher import AES
from Crypto.Util import Counter
import zlib


KEY = ?
FLAG = ?


@chal.route('/ctrime/encrypt/<plaintext>/')
def encrypt(plaintext):
plaintext = bytes.fromhex(plaintext)

iv = int.from_bytes(os.urandom(16), 'big')
cipher = AES.new(KEY, AES.MODE_CTR, counter=Counter.new(128, initial_value=iv))
encrypted = cipher.encrypt(zlib.compress(plaintext + FLAG.encode()))

return {"ciphertext": encrypted.hex()}

zlib.compress对于多段重复内容,但是不同长度的byte压缩后的长度一样,AES的CRT模式对于任意分组都可以进行加密,不会对加密明文进行填充,通过加入不可能存在的字符,使得需要爆破的字符位置在得到正确的字符后会发生长度变化这个特点得到flag

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
import zlib

import requests, sys
s=zlib.compress(b'crypto{crypto{crypto{')
print(len(s))
ss=zlib.compress(b'crypto{crypto{')
print(len(ss))
assert len(s)==len(ss)
solution = "crypto{"
chars = 'ABCDEFGHIJKLMNOPQRTSUVWXYZ0123456789_abcdefghijklmnopqrstuvwxyz}'
invalid_char = ';'

while True:
p = (solution + invalid_char) * 2
print(p)
r = requests.get("https://aes.cryptohack.org/ctrime/encrypt/" + p.encode('ascii').hex()).json()
sample = len(r['ciphertext'])
print(sample)
for c in chars:
print((solution + c) * 2)
r = requests.get("https://aes.cryptohack.org/ctrime/encrypt/" + ((solution + c) * 2).encode('ascii').hex()).json()
print(len(r['ciphertext']))
if len(r['ciphertext']) < sample:
solution += c
print(solution)
if c == "}":
print("Solution Found!", solution)
sys.exit()
break

参考连接:

https://github.com/MateaLukiccc/CryptoHack/blob/4fd64f8cc7356ed11ceb4f356a3686e7dd84f83f/Symmetric Ciphers/Stream Ciphers/CTRTIME.py