def main(message, injection): """ Your goal is to bypass the oracle's integrity check. This will break UF-CMA security of the scheme and demonstrate a length extension attack on the underlying SHA1 hash function, which relies on the Merkle-Damgard construction internally. Specifically, you must somehow craft a message that includes the given parameter WITHIN the default message AND find a valid tag for it WITHOUT querying the oracle. Your attack should be able to inject any message you want, but we want you to include your GT username specifically. """ print("forging message that includes %s within %s" % (injection, message)) # # TODO: Find a way to break UF-CMA security of the scheme. # # # The following is all purely sample code to familiarize yourself with some # of the available functions and methods. YOU CAN DELETE IT ALL. # forgery = message + injection # you can make queries to the oracle tag = oracle.query(message) # craft new message/tag based on those queries hasher = crypto.Sha1() hasher.update(forgery + tag) new_tag = hasher.hexdigest() hasher.clear() # convert easily between bytes and strings assert crypto.b2s(crypto.s2b(message)) == message assert crypto.s2b(crypto.b2s(b"cs6260")) == b"cs6260" # use sha1 internals directly: # hasher.sha1() # hasher.pad_message() # hasher.create_padding() manual_tag = hasher.sha1(crypto.s2b(forgery + tag), extra_length=0, initial_state=None) assert new_tag == manual_tag # check the validity of novel tags if oracle.verify(message, tag): pass return forgery, oracle.query(forgery)
def main(message, injection): # Get original tag original_tag = oracle.query(message) # Get initial hasher state by parsing digest state = get_initial_state() # Iterate all possible key lengths, 1 - 100 for key_length in range(0, 110): hasher = crypto.Sha1() # Create original message payload, with unknown key of "****" original_message = b'*' * key_length + crypto.s2b(message) # Pad this message, removing key from beginning padded_original = hasher.pad_message(original_message)[key_length:] # Create our new message string, the original padded plus injection new_message = padded_original + crypto.s2b(injection) # Create a hash using extra padding and intial state extra_length = int( math.ceil((len(padded_original) + key_length) * 8 / 512.0)) * 512 new_hash = hasher.sha1(crypto.s2b(injection), extra_length=extra_length, initial_state=state) # If the hash works, return it if oracle.check(new_message, new_hash): return crypto.b2s(new_message), new_hash return crypto.s2b(""), ""
def main(message, injection): """ Your goal is to bypass the oracle's integrity check. This will break UF-CMA security of the scheme and demonstrate a length extension attack on the underlying SHA1 hash function, which relies on the Merkle-Damgard construction internally. Specifically, you must somehow craft a message that includes the given parameter WITHIN the default message AND find a valid tag for it WITHOUT querying the oracle. Your attack should be able to inject any message you want, but we want you to include your GT username specifically. """ print("forging message that includes %s within %s" % (injection, message)) # # TODO: Find a way to break UF-CMA security of the scheme. # # # The following is all purely sample code to familiarize yourself with some # of the available functions and methods. YOU CAN DELETE IT ALL. # # forgery = message + injection tag = oracle.query(message) tag_bytes = crypto.s2b(tag) #tag initual state (tis) tis = int(tag_bytes, 16) a = tis >> 128 b = (tis >> 96) & 0xffffffff c = (tis >> 64) & 0xffffffff d = (tis >> 32) & 0xffffffff e = tis & 0xffffffff inital_state = [a, b, c, d, e] message_bytes = crypto.s2b(message) message_padded = crypto.Sha1.pad_message(message_bytes, 512) injection_bytes = crypto.s2b(injection) # injection_padded = crypto.Sha1.pad_message(injection_bytes, 512) forgery = message_padded + injection_bytes sha = crypto.Sha1() updated_tag = sha.sha1(injection_bytes, (len(message_padded) * 8) + 512, initial_state=inital_state) # string_message = if oracle.check(crypto.b2s(forgery), updated_tag): print("message BROKEDN") else: print("you failed")
def initialize(message): tag = oracle.query(message) tag_bytes = crypto.s2b(tag) tis = int(tag_bytes, 16) a = tis >> 128 b = (tis >> 96) & 0xffffffff c = (tis >> 64) & 0xffffffff d = (tis >> 32) & 0xffffffff e = tis & 0xffffffff return [a, b, c, d, e]
def main(message, injection): """ Your goal is to bypass the oracle's integrity check. This will break UF-CMA security of the scheme and demonstrate a length extension attack on the underlying SHA1 hash function, which relies on the Merkle-Damgard construction internally. Specifically, you must somehow craft a message that includes the given parameter WITHIN the default message AND find a valid tag for it WITHOUT querying the oracle. Your attack should be able to inject any message you want, but we want you to include your GT username specifically. """ print("forging message that includes %s within %s" % (injection, message)) # # TODO: Find a way to break UF-CMA security of the scheme. # # Step #1: we calculate the message we want to forge appending_for_forgery = " " + injection print( "The \'appending_for_forgery\' string we want to include = \"{0}\"\n". format(appending_for_forgery)) # Step #2: we need to get the the SHA-1 hash of the original message # into which we are going to inject the "injection" string print("First, we get the original message's SHA-1 Hash") print() original_message_hash_string = oracle.query(message) print() print("DEBUG: the original message hash string is: {0}\n".format( original_message_hash_string)) # Step #3: we need to create a new "initial_state" based on the original message # This new initial state is a list of 5 32-bit values which allows the # attacker to "pick up where we left off" and perform the length extension attack new_state = calculate_length_extension_attack_continuation_state( original_message_hash_string) print( "The new_state is the following list of 5 32-bit values: {0}\n".format( new_state)) # Step #4: We now have the message that we want to forge being "Key || message || appending_for_forgery" # We know the length of the message and the appending_for_forgery but don't know the length of the key # In this extension attack, we continue from here henceforth by determining the length of the Key. # Doing so is necessary because per SHA-1's RFC section 4 [https://tools.ietf.org/html/rfc3174#section-4] # We have to pad the message depending on its original length. # Because we know the max key size, we will brute force our way through MAX_SIZE_KEY_IN_BYTES = 100 for key_length_in_bytes in range(0, MAX_SIZE_KEY_IN_BYTES + 1): # We now brute force our way through different key length possibilities and see if we can FORGE THE MESSAGE! print( "DEBUG: key length in bytes is = {0}".format(key_length_in_bytes)) forged_message, forged_tag = create_forged_message_candidate( new_state, message, appending_for_forgery, key_length_in_bytes) if oracle.verify(forged_message, forged_tag): print("We have cracked the puzzle!") print("\tThe secret key's length in bytes is: {0}".format( key_length_in_bytes)) print("\tThe forged message is: {0}".format(forged_message)) print("\tThe forged tag is: {0}".format(forged_tag)) else: print( "\tDEBUG: The forged_tag was not successfully verified against the forged_message for key_length {0}" .format(key_length_in_bytes)) #------------------------------------------------------------------------------------------------ print() print() print( "DONE WITH THE PROGRAM HERE! If there was no cracking of the puzzle by this point, something went wrong" )