Warmup Salsa Sauce On this page Description#
from Crypto.Cipher import Salsa20
from secret import FLAG
from secrets import token_bytes as tb
def encText ( text , key , nonce ):
cipher = Salsa20 . new ( key = key , nonce = nonce )
ciphertext = cipher . nonce + cipher . encrypt ( text )
return ciphertext
if __name__ == "__main__" :
text = b "We covered the drugs with our favourite salsa sauce. The stupid cops will not find it."
key , nonce = tb ( 32 ), tb ( 8 )
enc_text = encText ( text , key , nonce )
enc_flag = encText ( FLAG , key , nonce )
with open ( 'out.txt' , 'w' ) as f :
f . write ( f "Encrypted flag: { enc_flag . hex () } \n " )
f . write ( f "Encrypted text: { enc_text . hex () } " )
Encrypted flag: fa1c26b66ad926ab75cd51524f05ec08f7f3160c74bec57f8aec3f7cace6fbb7370923e8c540673f657dada9e9540101d7f4dc0b6627f147fc47627a244c88b2ea6c3340
Encrypted text: fa1c26b66ad926ab45cb05575b0ab90fcdf1060d72bfba6f90aa076cbcf2f3aa311a13fc800638382570bcbee142001290f1d41d3761e315b91730663c2cd8e1fe7a25482ce0cd69745028635ef5dae54282f162e448fec5f6b0e7d8ff85
Solution# This challenge involves the help of ChatGPT
from Crypto.Cipher import Salsa20
import itertools
import string
def decText ( ciphertext , key ):
nonce = ciphertext [: 8 ] # The first 8 bytes are the nonce
encrypted_message = ciphertext [ 8 :] # The rest is the actual encrypted message
cipher = Salsa20 . new ( key = key , nonce = nonce )
decrypted_message = cipher . decrypt ( encrypted_message )
return decrypted_message
def brute_force ( ciphertext , known_plaintext ):
keyspace = string . ascii_letters + string . digits # Alphanumeric characters
for key_candidate in itertools . product ( keyspace , repeat = 5 ): # Adjust the length based on assumptions
key_candidate = '' . join ( key_candidate ) . encode () # Create the candidate key
try :
decrypted_text = decText ( ciphertext , key_candidate )
if known_plaintext . encode () in decrypted_text : # Check for known plaintext
print ( f "Key found: { key_candidate } " )
print ( f "Decrypted text: { decrypted_text . decode () } " )
break
except Exception :
continue # Ignore decryption failures
if __name__ == "__main__" :
# Reading the encrypted data from the 'out.txt' file
with open ( 'out.txt' , 'r' ) as f :
lines = f . readlines ()
# Extract the encrypted flag and text from the file
enc_flag_hex = lines [ 0 ] . split ( "Encrypted flag: " )[ 1 ] . strip ()
enc_text_hex = lines [ 1 ] . split ( "Encrypted text: " )[ 1 ] . strip ()
# Convert the hex strings to bytes
enc_text = bytes . fromhex ( enc_text_hex )
# Known plaintext (a part of the original message)
known_plaintext = "We covered the drugs with our favourite salsa sauce."
# Attempt brute-force decryption
brute_force ( enc_text , known_plaintext )
The vulnerability in the encrypting script is the repeating use of key
and nonce
for encrypting process. Therefore, we can create a script to brute force the encryption key in order to recover the original plaintext. It reads the encrypted data from a file, extracts the nonce, and generates possible 5-character keys from an alphanumeric set. For each candidate key, the script uses the nonce and key to decrypt the message with Salsa20. If the decrypted text contains a known portion of the original message, the correct key is identified. This process exploits the fact that the same key and nonce were reused for multiple messages, making brute-force attempts feasible.