Rating:

My friend developed this encryption service, and he's been trying to get us all to use it. Sure, it's convenient and easy to use, and it allows you to send encrypted messages easily, and...

Well, I want to get control of his service so I can monitor all the messages! I think he's hidden some features and files behind a secret admin passphrase. Can you help me access those hidden files?

Author: eiis1000

We're given a program that performs an encryption/decryption service. If two people connect at the same time, then they are able to encrypt or decrypt messages, and send the ciphertext to each other without fear of anybody else understanding the messages a few hours later. This is described within the program

Welcome to your Friendly Neighborhood Encryption Service (FNES)! If you and a friend both run this service at the same time, you should be able to send messages to each other! Here are the steps:

  1. Friends A and B connect to the server at the same time (you have about a five second margin)
  2. Friend A encodes a message and sends it to Friend B
  3. Friend B decodes the message, encodes their reply, and sends it to Friend A
  4. Friend A decodes the reply, rinse and repeat

Make sure to not make any mistakes, though, or your keystreams might come out of sync...

PS: For security reasons, there are four characters you aren't allowed to encrypt. Sorry!

Our goal is to decrypt a message to the target text "Open sesame... Flag please!".

Messages are RC4 encrypted, and the key is a secret int added to the current time. The two friends have to join at the same time because the key relates to the current time. The friends also can't make any mistakes because the keystream will get out of sync.

I believe the intended solution was to take advantage of the RC4 keystream. It's dependent on the key but not the data at all, and RC4 just XORs the data against the keystream. For example, here's first few bytes from an RC4 keystream where the key is "encryption": c2 53 53 e9 b4 ba 35 13 1e 3a e5 a8 10 7f ff

Now, here's some plaintext and ciphertext for phrases:

plain textciphertext
my name is johnaf 2a 73 87 d5 d7 50 33 77 49 c5 c2 7f 17 91
my Name is adamaf 2a 73 a7 d5 d7 50 33 77 49 c5 c9 74 1e 92

The ciphertext only begins to differ at the end, where the plaintext diverges. It also differs specifically where characters differ. Whether N in name is capitalised doesn't affect the rest of the ciphertext. Therefore, if we know the ciphertext and plaintext we can use that to find the keystream, and then arbitrarily encrypt our own messages! Here's a quick demo.

>>> import binascii

>>> # finding the keystream
>>> ciphertext = b'\xaf\x2a\x73\x87\xd5\xd7\x50\x33\x77\x49\xc5\xc2\x7f\x17\x91'
>>> plaintext = b'my name is john'
>>> keystream = b''.join([bytes([c^p]) for c,p in zip(ciphertext, plaintext)])
>>> binascii.hexlify(keystream)
b'c25353e9b4ba35131e3ae5a8107fff'

>>> # encrypting our own message
>>> attack_plaintext = b'my Name is adam'
>>> attack_ciphertext = b''.join([bytes([k^p]) for k,p in zip(keystream, attack_plaintext)])
>>> binascii.hexlify(attack_ciphertext)
b'af2a73a7d5d750337749c5c9741e92'

Flag: bcactf{why-would-you-attack-your-FNES????-4x35rcg}

Original writeup (https://eb-h.github.io/bcactf-2021/#fnes-1).