c0w5lip@wired:~$

🏷️ write-up cryptography

Root-Xmas

Day 06 - Unwrap The Gift

Challenge

Root-Me’s Santa is being very generous this year, giving everyone who comes to see him a little present, but he’s made sure you can’t open it until the 25th…

app.py:

from os import environ, urandom
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from binascii import hexlify

SANTA="""  .-""-.
 /,..___\\
() {_____}
  (/-@-@-\)
  {`-=^=-'}
  {  `-'  } Oh Oh Oh! Merry Root-Xmas to you!
   {     }
    `---'"""

FLAG = environ.get('FLAG', 'RM{REDACTED_FAKE_FLAG_DONT_SUBMIT}')

class Gift:
    """
    A custom class to wrap and unwrap gifts
    """
    def __init__(self):
        self.key = urandom(16)
        self.iv = urandom(12)
    
    def wrap(self, data):
        """
        Wrap the data with strong AES encryption
        """
        cipher = AES.new(self.key, 6, nonce=self.iv)
        data = data.encode()
        return hexlify(cipher.encrypt(pad(data, 16))).decode()
    
    def unwrap(self, data):
        """
        Unwrap the data
        """
        cipher = AES.new(self.key, 6, nonce=self.iv)
        return cipher.decrypt(bytes.fromhex(data)).decode()
    
def santa_says(message):
    print(f"[SANTA]: {message}")

if __name__ == '__main__':
    print("-"*50)
    print(SANTA)
    print("-"*50)

    gift = Gift()
    
    santa_says(f"Hello player, welcome! Here is your gift for this christmas: {gift.wrap(FLAG)}")
    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!")
    print("-"*50)

    santa_says("While I'm at it, do you wish to wrap a present for someone? (Y/N)")
    ans = input().lower()
    if ans == 'y':
        santa_says("Enter the message you wish to wrap:")
        message = input()
        santa_says(f"Here is your wrapped present: {gift.wrap(message)}")
    else:
        santa_says("Alright, have a nice day!")
    santa_says("Merry Christmas!")
    exit(0)

Solution

from pwn import *


s = remote("163.172.68.42", 10006)

flag_ciphertext = bytes.fromhex(
    s.recvuntil(
        b"While I'm at it, do you wish to wrap a present for someone? (Y/N)"
    ).decode().split(
        "Hello player, welcome! Here is your gift for this christmas: "
    )[-1].split(
        '\n'
    )[0]
)

s.sendline(b'Y') # ask to wrap a message

plaintext_character = '?' # arbitrary character to construct a known plaintext
s.sendline((plaintext_character*64).encode()) # arbitrary number of character

input_ciphertext = bytes.fromhex(
    s.recvuntil(
        b"Merry Christmas!"
    ).decode().split(
        "Here is your wrapped present: "
    )[-1].split(
        '\n'
    )[0]
)

flag = [
    chr(flag_ciphertext[i] ^ input_ciphertext[i] ^ ord(plaintext_character))
    for i in range(len(flag_ciphertext))
]

print("[*] Flag: {}".format(''.join(flag)))