ECB CBC WTF
题目描述
本题,采用CBC的方式对flag进行加密,但是采用ECB的方式对flag进行解密。
题目代码
from Crypto.Cipher import AESKEY = ? 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 requestsfrom pwn import xorurl="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 AESimport osfrom Crypto.Util.Padding import pad, unpadfrom datetime import datetime, timedeltaKEY = ? 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 requestsfrom pwn import xorurl="https://aes.cryptohack.org/flipping_cookie/get_cookie" r=requests.get(url) cookie=r.text[11 :-3 ] iv=cookie[:32 ] p1=b"admin=False;expi" pt=b"admin=True;expi\x01" 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 AESKEY = ? 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 requestsu1 = f"http://aes.cryptohack.org/symmetry/encrypt_flag/" r = requests.get(u1) p = eval (r.text)['ciphertext' ] hex_iv = p[:32 ] hex_c = p[32 :] 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' ))