✅ Day 06 - Unwrap The Gift
- CRYPTOGRAPHY
- Date de résolution : 06/12/2024
Reconnaissance
Il s'agit d'un chall de crypto et Sont fournis: 1 IP+port et 1 script python assez simple :
1from os import environ, urandom
2from Crypto.Cipher import AES
3from Crypto.Util.Padding import pad
4from binascii import hexlify
5
6SANTA=""" .-""-.
7 /,..___\\
8() {_____}
9 (/-@-@-\)
10 {`-=^=-'}
11 { `-' } Oh Oh Oh! Merry Root-Xmas to you!
12 { }
13 `---'"""
14
15FLAG = environ.get('FLAG', 'RM{REDACTED_FAKE_FLAG_DONT_SUBMIT}')
16
17class Gift:
18 """
19 A custom class to wrap and unwrap gifts
20 """
21 def __init__(self):
22 self.key = urandom(16)
23 self.iv = urandom(12)
24
25 def wrap(self, data):
26 """
27 Wrap the data with strong AES encryption
28 """
29 cipher = AES.new(self.key, 6, nonce=self.iv)
30 data = data.encode()
31 return hexlify(cipher.encrypt(pad(data, 16))).decode()
32
33 def unwrap(self, data):
34 """
35 Unwrap the data
36 """
37 cipher = AES.new(self.key, 6, nonce=self.iv)
38 return cipher.decrypt(bytes.fromhex(data)).decode()
39
40def santa_says(message):
41 print(f"[SANTA]: {message}")
42
43if __name__ == '__main__':
44 print("-"*50)
45 print(SANTA)
46 print("-"*50)
47
48 gift = Gift()
49
50 santa_says(f"Hello player, welcome! Here is your gift for this christmas: {gift.wrap(FLAG)}")
51 santa_says("Oh, I forgot to tell you, you will only be able to unwrap it on the 25th, come back to me on that date to get the key!")
52 print("-"*50)
53
54 santa_says("While I'm at it, do you wish to wrap a present for someone? (Y/N)")
55 ans = input().lower()
56 if ans == 'y':
57 santa_says("Enter the message you wish to wrap:")
58 message = input()
59 santa_says(f"Here is your wrapped present: {gift.wrap(message)}")
60 else:
61 santa_says("Alright, have a nice day!")
62 santa_says("Merry Christmas!")
63 exit(0)
Le serveur nous fournit le FLAG chiffré et il faut le déchiffrer avec une possiblité de chiffrer n'importe quel texte en réutilisant la même clé et le même iv/nonce...
En analysant, le chiffrement utilisé est AES en mode COUNTER (CTR=6)
Pour rappel, ce chiffrement agit comme suit : Wikipedia
CipherFlag = Flag ⊕ AES(Key,Nonce)
En utilisant la capacité de chiffrer n'importe quel texte connu, on aurait :
CipherText = KnownText ⊕ AES(Key,Nonce)
Et dans le script, il s'agit bien de la même clé et du même IV/Nonce
Par conséquent :
AES(Key,Nonce) = CipherFlag ⊕ Flag
AES(Key,Nonce) = CipherText ⊕ KnownText
Et donc :
CipherFlag ⊕ Flag = CipherText ⊕ KnownText
Flag = CipherText ⊕ KnownText ⊕ CipherFlag !!
Exploit
Exemple :
1$ nc 163.172.68.42 10006
2--------------------------------------------------
3[SANTA]: Hello player, welcome! Here is your gift for this christmas: ca826dd5b35fb14d74d6c1f35fd2c6cb5c6efd0342abe011cb4ead0c935a3a4b2498daa441cf2e3b62e41a63a0af6fcb38842887658fa6bb7dbaaa0bfa329d03
4[SANTA]: Oh, I forgot to tell you, you will only be able to unwrap it on the 25th, come back to me on that date to get the key!
5--------------------------------------------------
6[SANTA]: While I'm at it, do you wish to wrap a present for someone? (Y/N)
7Y
8[SANTA]: Enter the message you wish to wrap:
9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
10[SANTA]: Here is your wrapped present: d98e57d0c250a45362c5b4e241cac8df4f70fb0b45bef20fdd3eb8058d4c484b2e86d8b759de3b3564f71a72a9b714a204ca66c92bc1e8f533f4e445b47cd34d4b5511cc6283db564501b68babce882d
11[SANTA]: Merry Christmas!
On réalise l'opération de double XOR :
1from pwn import xor
2
3CipheredFlag = bytes.fromhex("ca826dd5b35fb14d74d6c1f35fd2c6cb5c6efd0342abe011cb4ead0c935a3a4b2498daa441cf2e3b62e41a63a0af6fcb38842887658fa6bb7dbaaa0bfa329d03")
4KnownText = b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
5CipheredText = bytes.fromhex("d98e57d0c250a45362c5b4e241cac8df4f70fb0b45bef20fdd3eb8058d4c484b2e86d8b759de3b3564f71a72a9b714a204ca66c92bc1e8f533f4e445b47cd34d4b5511cc6283db564501b68babce882d")
6Flag = xor(xor(CipheredText, KnownText), CipheredFlag)
7print(f"{Flag = }")
The flag is : RM{D0NT_WR4P_YOUR_GIFTS_W1TH_W3AK_CRYPTOGRAPHY:(}