Exemplo n.º 1
0
def win_money(block1, guessed_state, odds=4):
    """
    With a given block1 and internal md5 state, craft md5s hashes that will
    meet the game's requirements. Play until enough money has been won.

    md5_compress(state, block1 + attack padding + forged block2 + padding)
    """
    set_bet_all()
    set_odds(odds)

    for i in range(2**16 - 1):

        block2 = '_{}'.format(str(i))
        fake_pad = padding((16 + len(block1)) * 8)  # server nonce is 16 bytes

        pad = padding((16 + len(block1 + fake_pad + block2)) * 8)
        h = _encode(md5_compress(guessed_state, block2 + pad),
                    16).encode('hex')

        # will I win with this hash?
        if (int(h, 16) & ((2 << (odds - 1)) - 1)) == 0:
            print("I should win with this: {} (md5 will be: {})".format(
                block2, h))

            reply = play(block1 + fake_pad + block2)
            if 'Holy shit you have a lot of money.' in reply:
                return reply

            set_bet_all()

        # show some progress
        if (i % 1000) == 0:
            print("working hard...")
def win_money(block1, guessed_state, odds=4):
    """
    With a given block1 and internal md5 state, craft md5s hashes that will
    meet the game's requirements. Play until enough money has been won.

    md5_compress(state, block1 + attack padding + forged block2 + padding)
    """
    set_bet_all()
    set_odds(odds)

    for i in range(2**16-1):

        block2 = '_{}'.format(str(i))
        fake_pad = padding((16+len(block1))*8) # server nonce is 16 bytes

        pad = padding((16+len(block1 + fake_pad + block2))*8)
        h = _encode(md5_compress(guessed_state, block2 + pad), 16).encode('hex')

        # will I win with this hash?
        if (int(h, 16) & ((2<<(odds-1))-1)) == 0:
            print("I should win with this: {} (md5 will be: {})".format(block2, h))

            reply = play(block1 + fake_pad + block2)
            if 'Holy shit you have a lot of money.' in reply:
                return reply

            set_bet_all()

        # show some progress
        if (i % 1000) == 0:
            print("working hard...")
Exemplo n.º 3
0
def bruteforce_block1_state(block1):
    """
    * Perform a one block md5 where we control partially what's in block1.
    * Grab 112 bits of state out of this one-block md5 from the server.
    * Perform a two-block md5 where block1 is the same as our one-block md5,
      hash-length extend it (w/ home-made padding) and reach a second block.
    * Grab 112 bits of state out of this two-block md5 from the server.

    * Locally, use md5's internal functions (md5_compress) directly to brute
      force the missing bits of the leaked state of the 1-block md5. Use the 
      bits from the two-block md5 leak to know when you guessed state1
      correctly.
    Returns the state that can be used to predict future two-block md5 hashes
    """

    # set odds to 112 to get the largest server leak
    set_odds(112)

    # small bet, lets gather intel first
    set_bet(1)

    # gather information on state1
    state1_leak = play(block1, return_leak=True)
    print("State 1 server leak: {}".format(state1_leak))

    # generate a two block md5
    block2 = str(1)
    fake_pad = padding((16 + len(block1)) * 8)  # server nonce is 16 bytes
    combined = block1 + fake_pad + block2

    # play with our two-block md5, grab leaked information of resulting hash
    target_hash = play(combined, return_leak=True)
    print("Target hash server leak: {}".format(target_hash))

    # to validate that we guessed state1 correctly, lets try to predict the
    # result of a 2-block hash where state1 is fixed by us. Compare that with
    # target_hash from the server and if we have a match we know that we guessed
    # state1 correctly.
    found = False
    guessed_state = ""
    pad = padding((16 + len(combined)) * 8)
    for i in range(2**16 - 1):
        attempt = "{:04x}{}".format(i, state1_leak)

        guessed_state = _decode(unhexlify(attempt), 16)
        h = _encode(md5_compress(guessed_state, block2 + pad),
                    16).encode('hex')

        # have I guessed state1 right?
        if (target_hash in h):
            print("Hash found: {} / mid-state guessed: {}".format(h, attempt))
            found = True
            break

    if not found:
        print("Couldn't find the state. I won't be able to cheat. Goodbye")
        sys.exit(1)

    return guessed_state
def bruteforce_block1_state(block1):
    """
    * Perform a one block md5 where we control partially what's in block1.
    * Grab 112 bits of state out of this one-block md5 from the server.
    * Perform a two-block md5 where block1 is the same as our one-block md5,
      hash-length extend it (w/ home-made padding) and reach a second block.
    * Grab 112 bits of state out of this two-block md5 from the server.

    * Locally, use md5's internal functions (md5_compress) directly to brute
      force the missing bits of the leaked state of the 1-block md5. Use the 
      bits from the two-block md5 leak to know when you guessed state1
      correctly.
    Returns the state that can be used to predict future two-block md5 hashes
    """

    # set odds to 112 to get the largest server leak
    set_odds(112)

    # small bet, lets gather intel first
    set_bet(1)

    # gather information on state1
    state1_leak = play(block1, return_leak=True)
    print("State 1 server leak: {}".format(state1_leak))

    # generate a two block md5
    block2 = str(1)
    fake_pad = padding((16+len(block1))*8) # server nonce is 16 bytes
    combined = block1 + fake_pad + block2

    # play with our two-block md5, grab leaked information of resulting hash
    target_hash = play(combined, return_leak=True)
    print("Target hash server leak: {}".format(target_hash))

    # to validate that we guessed state1 correctly, lets try to predict the
    # result of a 2-block hash where state1 is fixed by us. Compare that with
    # target_hash from the server and if we have a match we know that we guessed
    # state1 correctly.
    found = False
    guessed_state = ""
    pad = padding((16+len(combined))*8)
    for i in range(2**16-1):
        attempt = "{:04x}{}".format(i, state1_leak)

        guessed_state = _decode(unhexlify(attempt), 16)
        h = _encode(md5_compress(guessed_state, block2 + pad), 16).encode('hex')

        # have I guessed state1 right?
        if (target_hash in h):
            print("Hash found: {} / mid-state guessed: {}".format(h, attempt))
            found = True
            break

    if not found:
        print("Couldn't find the state. I won't be able to cheat. Goodbye")
        sys.exit(1)

    return guessed_state