ECB CBC WTF

题目描述

本题,采用CBC的方式对flag进行加密,但是采用ECB的方式对flag进行解密。

题目代码

from Crypto.Cipher import AES


KEY = ?
FLAG = ?


@chal.route('/ecbcbcwtf/decrypt/<ciphertext>/')
def decrypt(ciphertext):
ciphertext = bytes.fromhex(ciphertext)

cipher = AES.new(KEY, AES.MODE_ECB)
try:
decrypted = cipher.decrypt(ciphertext)
except ValueError as e:
return {"error": str(e)}

return {"plaintext": decrypted.hex()}


@chal.route('/ecbcbcwtf/encrypt_flag/')
def encrypt_flag():
iv = os.urandom(16)

cipher = AES.new(KEY, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(FLAG.encode())
ciphertext = iv.hex() + encrypted.hex()

return {"ciphertext": ciphertext}

解题思路

加密时,

解密时,

此时,都是已知的,那么,,进而获得flag值。

解题代码

import requests
from pwn import xor
url="https://aes.cryptohack.org/ecbcbcwtf/encrypt_flag/"

r=requests.get(url)

cipher=r.text[15:-3]

c1=cipher[:32]
c2=cipher[32:64]
c3=cipher[64:]

urls="https://aes.cryptohack.org/ecbcbcwtf/decrypt/"
urls=urls+cipher

r=requests.get(urls)

plaintext=r.text[14:-3]
p1=plaintext[:32]
p2=plaintext[32:64]
p3=plaintext[64:]

p2=bytes.fromhex(p2)
c1=bytes.fromhex(c1)
p3=bytes.fromhex(p3)
c2=bytes.fromhex(c2)

print(xor(p2,c1))
print(xor(p3,c2))

FLIPPING COOKIE

题目描述

你拿到了我网站的cookie,但是这对你获得flag没有任何的帮助。

题目描述

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}

解题思路

首先,我们观察这个源代码当中的两个函数,首先当我们调用get_cookie函数的时候,

expires_at = (datetime.today() + timedelta(days=1)).strftime("%s")
cookie = f"admin=False;expiry={expires_at}".encode()

函数用这两行代码固定了我们的cookie,并且使用CBC对其进行加密。

当我们调用,check_admin函数的时候,函数根据我们输入的cookie和iv,对cookie进行解密,只有当cookie当中存在admin=True才会得到flag。

因此,我们的解决方式,就是构造一个合适的iv,使得原始明文当中的admin=False修改为admin=true。

本题考点是CBC明文伪造。

我们观察CBC的解密过程,,,我们用指代我们最终需要构造的明文。

为我们需要构造的新的

两式左右分别进行异或,我们可以得到

我们可以得到

然后,我们将和cookie作为输入,进行check,就可以得到flag

解题代码

import requests
from pwn import xor

url="https://aes.cryptohack.org/flipping_cookie/get_cookie"
r=requests.get(url)

cookie=r.text[11:-3]

iv=cookie[:32] #根据CBC加密规则,第一个密文块,就是我们的iv

p1=b"admin=False;expi"
pt=b"admin=True;expi\x01" #根据填充规则,15个字节,后边要补充01
iv=bytes.fromhex(iv)
iv_new=xor(xor(p1,pt),iv)
iv_new=bytes.hex(iv_new)
urls="https://aes.cryptohack.org/flipping_cookie/check_admin/"
urls+=(cookie[32:64]+'/'+iv_new) #我们只借助第一个块
print(urls)
r=requests.get(urls)
print(r.text)

SYMMETRY

题目描述

某些分组密码模式(如 OFB、CTR 或 CFB)将分组密码转换为流密码。流密码背后的想法是生成一个伪随机密钥流,然后用明文进行异或运算。流密码的一个优点是它们可以处理任意长度的明文,不需要填充。

OFB 是一种晦涩难懂的密码模式,如今与使用 CTR 相比没有真正的好处。这个挑战引入了OFB的一个不寻常的特性。

题目代码

from Crypto.Cipher import AES


KEY = ?
FLAG = ?


@chal.route('/symmetry/encrypt/<plaintext>/<iv>/')
def encrypt(plaintext, iv):
plaintext = bytes.fromhex(plaintext)
iv = bytes.fromhex(iv)
if len(iv) != 16:
return {"error": "IV length must be 16"}

cipher = AES.new(KEY, AES.MODE_OFB, iv)
encrypted = cipher.encrypt(plaintext)
ciphertext = encrypted.hex()

return {"ciphertext": ciphertext}


@chal.route('/symmetry/encrypt_flag/')
def encrypt_flag():
iv = os.urandom(16)

cipher = AES.new(KEY, AES.MODE_OFB, iv)
encrypted = cipher.encrypt(FLAG.encode())
ciphertext = iv.hex() + encrypted.hex()

return {"ciphertext": ciphertext}

解题思路

我们观察OFB加密的过程

题目当中,给出了两个加密函数。

当我们调用encrypt_flag函数时,函数会返回此时随机的IV和flag加密后的结果。

当我们调用encrypt函数时,我们指定参数plaintext,IV,可以得到对应的加密结果。

我们用指代flag的明文和密文信息,用指代我们构造的明文和密文,首先对flag进行加密时,我们得到

此时,我们借助这个IV作为我们的输入对我们构造的信息进行加密。

,那么我们可以得到,将此结果带入到之前的式子当中。

我们可以得到。进而,我们对其他明文段进行相同的操作,我们可以得到完整的flag信息。

解题代码

import requests

# Getting the Ciphertext of Flag
u1 = f"http://aes.cryptohack.org/symmetry/encrypt_flag/"
r = requests.get(u1)
p = eval(r.text)['ciphertext']
hex_iv = p[:32] # IV
hex_c = p[32:] # Flag

#Sending the Same Ciphertext and IV as the Encryption and Decryption is Symmetric
u1 = f"http://aes.cryptohack.org/symmetry/encrypt/{hex_c}/{hex_iv}"
r = requests.get(u1)
q = eval(r.text)['ciphertext']
print(bytes.fromhex(q).decode('ascii'))