Exemple #1
0
def generateChallengeResponseV1(password,
                                server_challenge,
                                has_extended_security=False,
                                client_challenge=None):
    """
    Generate a NTLMv1 response

    @param password: User password string
    @param server_challange: A 8-byte challenge string sent from the server
    @param has_extended_security: A boolean value indicating whether NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY flag is enabled in the NTLM negFlag
    @param client_challenge: A 8-byte string representing client challenge. If None, it will be generated randomly if needed by the response generation
    @return: a tuple of ( NT challenge response string, LM challenge response string )

    References:
    ===========
    - http://ubiqx.org/cifs/SMB.html (2.8.3.3 and 2.8.3.4)
    - [MS-NLMP]: 3.3.1
    """
    _password = (password.upper() + '\0' * 14)[:14]
    d1 = des(expandDesKey(_password[:7]))
    d2 = des(expandDesKey(_password[7:]))
    lm_response_key = d1.encrypt("KGS!@#$%") + d2.encrypt(
        "KGS!@#$%"
    )  # LM password hash. In [MS-NLMP], this is the result of LMOWFv1 function

    d = MD4()
    d.update(password.encode('UTF-16LE'))
    nt_response_key = d.digest(
    )  # In [MS-NLMP], this is the result of NTOWFv1 function

    if has_extended_security:
        if not client_challenge:
            client_challenge = ''
            for i in range(0, 8):
                client_challenge += chr(random.getrandbits(8))

        assert len(client_challenge) == 8

        lm_challenge_response = client_challenge + '\0' * 16
        nt_challenge_response = DESL(
            nt_response_key,
            MD5(server_challenge + client_challenge).digest()[0:8])
    else:
        nt_challenge_response = DESL(
            nt_response_key,
            server_challenge)  # The result after DESL is the NT response
        lm_challenge_response = DESL(
            lm_response_key,
            server_challenge)  # The result after DESL is the LM response

    d = MD4()
    d.update(nt_response_key)
    session_key = d.digest()

    return nt_challenge_response, lm_challenge_response, session_key
Exemple #2
0
def generateChallengeResponseV2(password,
                                user,
                                server_challenge,
                                server_info,
                                domain='',
                                client_challenge=None):
    client_timestamp = '\0' * 8

    if not client_challenge:
        client_challenge = ''
        for i in range(0, 8):
            client_challenge += chr(random.getrandbits(8))
    assert len(client_challenge) == 8

    d = MD4()
    d.update(password.encode('UTF-16LE'))
    ntlm_hash = d.digest()  # The NT password hash
    response_key = hmac.new(ntlm_hash, (
        user.upper() + domain
    ).encode('UTF-16LE')).digest(
    )  # The NTLMv2 password hash. In [MS-NLMP], this is the result of NTOWFv2 and LMOWFv2 functions
    temp = '\x01\x01' + '\0' * 6 + client_timestamp + client_challenge + '\0' * 4 + server_info
    ntproofstr = hmac.new(response_key, server_challenge + temp).digest()

    nt_challenge_response = ntproofstr + temp
    lm_challenge_response = hmac.new(
        response_key,
        server_challenge + client_challenge).digest() + client_challenge
    session_key = hmac.new(response_key, ntproofstr).digest()

    return nt_challenge_response, lm_challenge_response, session_key