Example #1
0
inline void CPppMsChap2::GenerateNTResponseL(
    const TDesC8& aAuthenticatorChallenge,
    const TDesC8& aPeerChallenge,
    const TDesC8& aUserName,
    const TDesC16& aPassword,
    TDes8& aResponse)
/**
   Generates a MS-CHAP-V2 NT-Response.
   @param aAuthenticatorChallenge [in] The MS-CHAP-V2 authenticator
   challenge (16 octets).
   @param aPeerChallenge [in] The MS-CHAP-V2 peer challenge (16
   octets).
   @param aUserName [in] The Microsoft Windows NT username (0 to 256
   char).
   @param aPassword [in] The Microsoft Windows NT password (0 to 256
   unicode char).
   @param aResponse [out] The MS-CHAP-V2 Challenge Response,
   NT-Response (24 octets).
   @note This function implements the GenerateNTResponse routine
   specified in RFC 2759.
   @internalComponent
*/
{
    ASSERT(aAuthenticatorChallenge.Length() ==
           KPppMsChap2AuthenticatorChallengeSize);
    ASSERT(aPeerChallenge.Length() ==
           KPppMsChap2PeerChallengeSize);
    ASSERT(aUserName.Length() <= KPppMsChapMaxNTUserNameLength);
    ASSERT(aPassword.Length() <= KPppMsChapMaxNTPasswordLength);
    ASSERT(aResponse.Length() == KPppMsChap2NTResponseSize);

    HBufC8* challengeHashBuf =
        HBufC8::NewMaxLC(KPppMsChap2ChallengeHashSize);
    TPtr8 challengeHash(challengeHashBuf->Des());
    ChallengeHashL(aPeerChallenge,
                   aAuthenticatorChallenge,
                   aUserName,
                   challengeHash);

    HBufC8* paddedPasswordHashBuf =
        HBufC8::NewLC(KPppMsChap2PaddedHashSize);
    TPtr8 paddablePasswordHash(paddedPasswordHashBuf->Des());

    paddablePasswordHash.SetLength(KPppMsChap2HashSize);
    NtPasswordHashL(aPassword, paddablePasswordHash);

    ChallengeResponseL(challengeHash,
                       paddablePasswordHash,
                       aResponse);

    CleanupStack::PopAndDestroy(paddedPasswordHashBuf);
    CleanupStack::PopAndDestroy(challengeHashBuf);

    ASSERT(aResponse.Length()==KPppMsChap2NTResponseSize);
}
Example #2
0
inline void CPppMsChap2::GenerateAuthenticatorResponseL(
    const TDesC16& aPassword,
    const TDesC8& aNTResponse,
    const TDesC8& aPeerChallenge,
    const TDesC8& aAuthenticatorChallenge,
    const TDesC8& aUserName,
    TDes8& aAuthenticatorResponse)
/**
   Generates the expected MS-CHAP-V2 Authenticator Response Value.
   @param aPassword [in] The Microsoft Windows NT password (0 to 256
   Unicode char).
   @param aNTResponse [in] The MS-CHAP-V2 NT-Response (24 octets).
   @param aPeerChallenge [in] The Peer Challenge (16 octets).
   @param aAuthenticatorChallenge [in] The Authenticator Challenge (16
   octets).
   @param aUserName [in] The Microsoft Windows NT username (0 to 256
   char).
   @param aAuthenticatorResponse [out] The expected MS-CHAP-V2
   Authenticator Response Value encoded in the format
   "S=<auth_string>" as specified in RFC 2759 (42 octets).
   @note This function implements the GenerateAuthenticatorResponse
   routine specified in RFC 2759.
   @internalComponent
*/
{
    ASSERT(aPassword.Length()<=KPppMsChapMaxNTPasswordLength);
    ASSERT(aNTResponse.Length() == KPppMsChap2NTResponseSize);
    ASSERT(aPeerChallenge.Length() ==
           KPppMsChap2PeerChallengeSize);
    ASSERT(aAuthenticatorChallenge.Length() ==
           KPppMsChap2AuthenticatorChallengeSize);
    ASSERT(aUserName.Length()<=KPppMsChapMaxNTUserNameLength);
    ASSERT(aAuthenticatorResponse.Length() ==
           KPppMsChap2AuthenticatorResponseSize);

    HBufC8* passwordHashBuf=HBufC8::NewMaxLC(KPppMsChap2HashSize);
    TPtr8 passwordHash(passwordHashBuf->Des());

    NtPasswordHashL(aPassword, passwordHash);

    HashNtPasswordHashL(passwordHash, passwordHash);

    CSHA1* sha1 = CSHA1::NewL();
    CleanupStack::PushL(sha1);

// A magic string literal specified in RFC 2759 used in reponse
// generation by the GenerateAuthenticatorResponse routine for SHA-1
// encryption.
    _LIT8(KMagic1, "Magic server to client signing constant");


    sha1->Update(passwordHash);
    sha1->Update(aNTResponse);
    TPtrC8 hash(sha1->Final(KMagic1));


    HBufC8* challengeHashBuf =
        HBufC8::NewMaxLC(KPppMsChap2ChallengeHashSize);
    TPtr8 challengeHash(challengeHashBuf->Des());
    ChallengeHashL(aPeerChallenge,
                   aAuthenticatorChallenge,
                   aUserName,
                   challengeHash);

// Another magic string literal specified in RFC 2759 used in reponse
// generation by the GenerateAuthenticatorResponse routine for SHA-1
// encryption.
    _LIT8(KMagic2, "Pad to make it do more than one iteration");


    sha1->Update(hash);
    sha1->Update(challengeHash);
    const TUint8* pHash = sha1->Final(KMagic2).Ptr();


    _LIT8(KFormat,
          "S=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
          "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X");
    aAuthenticatorResponse.Format(KFormat,
                                  *pHash,
                                  *(pHash + 1),
                                  *(pHash + 2),
                                  *(pHash + 3),
                                  *(pHash + 4),
                                  *(pHash + 5),
                                  *(pHash + 6),
                                  *(pHash + 7),
                                  *(pHash + 8),
                                  *(pHash + 9),
                                  *(pHash + 10),
                                  *(pHash + 11),
                                  *(pHash + 12),
                                  *(pHash + 13),
                                  *(pHash + 14),
                                  *(pHash + 15),
                                  *(pHash + 16),
                                  *(pHash + 17),
                                  *(pHash + 18),
                                  *(pHash + 19));

    CleanupStack::PopAndDestroy(challengeHashBuf);

    CleanupStack::PopAndDestroy(sha1);
    CleanupStack::PopAndDestroy(passwordHashBuf);

    ASSERT(aAuthenticatorResponse.Length() ==
           KPppMsChap2AuthenticatorResponseSize);
}
void SessionParser::parse(const boost::uint8_t* p_data, boost::uint16_t p_length, boost::uint32_t p_srcAddr)
{
    switch(m_state) {
        case k_none:
            if (p_length > 13 && memcmp(p_data, "POST /jsproxy", 13) == 0) {
                std::cout << "[+] Initial request found." << std::endl;
                m_state = k_request;
            }
            break;
        case k_request:
            if (p_length > 17 && memcmp(p_data, "HTTP/1.1 200 OK\r\n", 17) == 0) {
                std::cout << "[+] Server challenge received." << std::endl;
                m_serverAddress = p_srcAddr;
                std::string packet;
                packet.assign(reinterpret_cast<const char*>(p_data), p_length);
                if (moveToPayload(packet) && packet.length() > 32) {
                    std::size_t index = 0;
                    for (std::size_t i = 0; i < 24 && index < packet.length(); i++) {
                        if (i < 8) {
                            codePointAt(packet, index);
                        } else {
                            m_rchallenge.push_back(codePointAt(packet, index));
                        }
                    }
                }
                m_state = k_challenge;
            }
            break;
        case k_challenge:
        {
            if (p_length < 13 || memcmp(p_data, "POST /jsproxy", 13) != 0) {
                break;
            }

            std::cout << "[+] Challenge response found." << std::endl;
            m_state = k_done;

            std::string packet;
            packet.assign(reinterpret_cast<const char*>(p_data), p_length);
            if (!moveToPayload(packet)) {
                std::cerr << "Failed to find the payload." << std::endl;
                break;
            }
            std::size_t index = 0;
            for (std::size_t i = 0; i < 26; i++) {
                codePointAt(packet, index);
            }
            m_lchallenge.assign(packet.data() + index, 16);
            index += 16;
            for (std::size_t i = 0; i < 8; i++) {
                codePointAt(packet, index);
            }
            for (std::size_t i = 0; i < 8 && index < packet.length(); i++) {
                m_response1.push_back(codePointAt(packet, index));
            }
            for (std::size_t i = 0; i < 8 && index < packet.length(); i++) {
                m_response2.push_back(codePointAt(packet, index));
            }
            for (std::size_t i = 0; i < 8 && index < packet.length(); i++) {
                m_response3.push_back(codePointAt(packet, index));
            }
            m_response.assign(m_response1);
            m_response.append(m_response2);
            m_response.append(m_response3);
            m_username.assign(packet.data() + index, packet.length() - index);
            std::cout << "Username: "******"Failed to recover key3!" << std::endl;
                return;
            }
            std::cout << "DES Key 3: ";
            printHexString(key3, true);

            // guess des key 2
            std::string key2;
            if (!getKey2(key2, m_response2, challengeHash)) {
                std::cerr << "Failed to recover key2!" << std::endl;
                return;
            }
            std::cout << "DES Key 2: ";
            printHexString(key2, true);

            // guess des key 1
            std::string key1;
            if (!getKey1(key1, m_response1, challengeHash)) {
                std::cerr << "Failed to recover key1!" << std::endl;
                return;
            }
            std::cout << "DES Key 1: ";
            printHexString(key1, true);

            // retrieve the pwdhash from our 3 keys
            std::string pwdHash(makePwdHash(key1));
            pwdHash.append(makePwdHash(key2));
            pwdHash.append(makePwdHash(key3));
            pwdHash.resize(16);
            std::cout << "Password SHA-1: ";
            printHexString(pwdHash);

            // create the pwd hash hash for master key creation
            std::string pwdHashHash(MD4::md4(pwdHash));
            std::cout << "SHA-1(Password SHA-1): ";
            printHexString(pwdHashHash);

            // create the master key
            std::string masterKey(pwdHashHash);
            masterKey.append(m_response);
            masterKey.append("This is the MPPE Master Key");

            unsigned char sharesult[20] = { 0 };
            sha1::calc(masterKey.data(), masterKey.size(), sharesult);
            masterKey.assign((char*)sharesult, 16);
            std::cout<< "Master Key: ";
            printHexString(masterKey);
        }
            break;
        case k_challenge_response:
        case k_decrypt:
        case k_done:
        default:
            break;
    }
}