Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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(""), ""
Exemplo n.º 3
0
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")
Exemplo n.º 4
0
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]
Exemplo n.º 5
0
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"
    )