def query(message: str) -> str: """ Simulates sending a message to an oracle. NOTE: Despite the fact that you know the secret hidden within `secret.txt` and could obviously break integrity in this way, we will use a DIFFERENT secret in the autograder. It's included for simplicity and so that you can see the "guts" of the oracle. The only REAL knowledge you have about the secret is that it's <=100 bytes long. Again, YOUR EXPLOIT SHOULD NOT RELY ON THE VALUE OF SECRET.TXT. """ sha1 = crypto.Sha1() with open("secret.txt", "rb") as secret_file: sha1.update(secret_file.read()) binary_message = message if isinstance(message, str): binary_message = crypto.s2b(message) _SEEN.append(message) sha1.update(binary_message) tag = sha1.hexdigest() print("Message:", repr(message)) print("Tag: ", tag) return tag
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] inital_state = initialize(message) 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) if oracle.check(crypto.b2s(forgery), updated_tag): print("message BROKEDN") else: print("you failed") return crypto.b2s(forgery), updated_tag
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 create_forged_message_candidate(fixed_state_array, original_message, message_to_append_in_the_forgery, length_of_key_in_bytes): # We perform a linear extension attack for a specified key length to see if it works print("\t\tDEBUG: IN CREATE_FORGED_MESSAGE_CANDIDATE") print() print("\t\tProvided parameters: ") print("\t\t\tFixed State Array: {0}".format(fixed_state_array)) print("\t\t\tOriginal message: {0}".format(original_message)) print("\t\t\tMessage to append in the forgery: \'{0}\'".format( message_to_append_in_the_forgery)) print( "\t\t\tLength of the key in bytes: {0}".format(length_of_key_in_bytes)) print() print() #------------------------------------------------------------------------ start_of_forged_message = crypto.s2b("B" * length_of_key_in_bytes + original_message + message_to_append_in_the_forgery) forged_message = crypto.Sha1.pad_message(start_of_forged_message) print("\t\tDEBUG: the start of the forged message = {0}".format( forged_message)) print("\t\tDEBUG: type of forged_message = {0}".format( type(forged_message))) # OK we need to remove our key from the forged message here because it is not the correct key ANYWAYS! print( "\t\tDEBUG: testing the byte slicing from the forged message to remove the fake key from the beginning!" ) forged_message = forged_message[length_of_key_in_bytes:] print("\t\t\tDEBUG: the result is: {0}".format(forged_message)) # OK, now we call the SHA-1 function with the fixed state and the extra message information we have to forge the final result hasher = crypto.Sha1() hasher.update(forged_message) print() print("\t\tDEBUG: the extra_length parameter = {0}".format( (length_of_key_in_bytes + len(forged_message)) * 8)) new_tag = hasher.hexdigest( (length_of_key_in_bytes + len(forged_message)) * 8, fixed_state_array) # FIX THIS LINE print() print("\t\tThe result of the new Sha-1 invocation is as follows:") print("\t\t\tThe new forged_message = {0}".format(forged_message)) print("\t\t\tThe new tag = {0}".format(new_tag)) print() return forged_message, new_tag
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. # inital_state = initialize(message) message_bytes = crypto.s2b(message) message_padded = crypto.Sha1.pad_message(message_bytes, 512) injection_bytes = crypto.s2b(injection) forgery = message_padded + injection_bytes forgery_string = crypto.b2s(forgery) sha = crypto.Sha1() message_length = (len(message_padded) * 8) + 512 updated_tag = sha.sha1(injection_bytes, message_length, initial_state=inital_state) # sanityCheck(forgery_string, updated_tag) return forgery_string, updated_tag