全网首一份!你最必要的PPTP MS-CHAP V2 挑衅响应编程模拟计算教程!代码基 ...

打印 上一主题 下一主题

主题 852|帖子 852|积分 2556

本文基于网络密码课上的实验
本来想水一水就过去,代码就网上找找,不行就GPT写,但是!一份都找不到,找到的代码都是跑不了的,总会是就是乱七八糟。所以预备认真的写一份。
代码编译成功的前提是要预先装好openssl库!
本随笔主要有三个内容:

  • 编写程序,模拟计算NTResponse、AuthenticatorResponse,
  • 根据前期PPTP实验中捕捉的数据包中CHAP协议的挑衅响应认证数据,在未知用户口令情况下编程实现CHAP认证口令的破解
在单向数据条件下(仅能截获用户数据)实现CHAP认证口令的破解
首先放一个我自己抓的包,可以看到,这是chap协议挑衅响应的三次握手,

 那么我们继承举行,编程模拟,就要先搞清楚每个字段代表的什么,文档中第一个包的描述,给的是Authenticator challenge

也就是我住的第一个包里的value

这是第二个包,16字节peer-challenge,8位的0,24位的NT-Response

value内的值,对应看

 
 第三个包,内容是s=authticator-response


接下来我们开始编程实现,每一个字段都是由对应的函数计算得出
一、编写程序,模拟计算NTResponse、AuthenticatorResponse
1.查阅RFC2759文档,找到描述的计算NTResponse的函数
  1. NT-Response的值是由GenerateNTResponse()计算得出,看到该函数有四个输入,分别是AuthenticatorChallenge(16)、PeerChallenge(16)、UserName和Password,一个输出Response(24)
复制代码
  1.  
复制代码
 
  1. 此外,有三个函数对输入进行处理:ChallengeHash:对两个挑战值hash,结果放到challenge中。NtPasswordHash:对password做hash,结果放到password中。ChallengeResponse:对challenge和passwordhash做运算,结果得到NT-Response。
复制代码
2.根据文档描述编写代码
GenerateNTResponse()函数
  1. 1 void GenerateNTResponse(const HCRYPTPROV hProv, const BYTE* auth_challenge, const BYTE* peer_challenge, const char* user_name, const wchar_t* password, BYTE* response)
  2. 2 {
  3. 3     BYTE challenge[8];
  4. 4     BYTE password_hash[16];
  5. 5
  6. 6     _ChallengeHash(hProv, peer_challenge, auth_challenge, user_name, challenge);
  7. 7     _NtPasswordHash(hProv, password, password_hash);
  8. 8     _ChallengeResponse(hProv, challenge, password_hash, response);
  9. 9 }
复制代码
_ChallengeHash()函数,对peer challenge、auth challenge、user name连接然后举行sha1哈希,结果放到challenge中返回
  1. 1 void _ChallengeHash(const HCRYPTPROV hProv, const BYTE* peer_challenge, const BYTE* auth_challenge, const char* user_name, BYTE* challenge)
  2. 2 {
  3. 3     HCRYPTHASH hHash = 0;
  4. 4     if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
  5. 5         throw "CryptCreateHash failed (SHA1)";
  6. 6     if (!CryptHashData(hHash, peer_challenge, 16, 0))
  7. 7         throw "CryptHashData failed (peer challenge)";
  8. 8     if (!CryptHashData(hHash, auth_challenge, 16, 0))
  9. 9         throw "CryptHashData failed (auth challenge)";
  10. 10     if (!CryptHashData(hHash, (const BYTE*)user_name,
  11. 11         (DWORD)strlen(user_name), 0))
  12. 12         throw "CryptHashData failed (user name)";
  13. 13     DWORD hash_len = SHA1LEN;
  14. 14     BYTE hash_buffer[SHA1LEN];
  15. 15     if (!CryptGetHashParam(hHash, HP_HASHVAL, hash_buffer,
  16. 16         &hash_len, 0))
  17. 17         throw "CryptGetHashParam failed (challenge hash)";
  18. 18     memcpy(challenge, hash_buffer, 8);
  19. 19
  20. 20 }
复制代码
_NtPasswordHash函数():将password做MD4哈希,然后返回password_hash中
 
  1. 1 void _NtPasswordHash(const HCRYPTPROV hProv, const wchar_t* password, BYTE* password_hash)
  2. 2 {
  3. 3     HCRYPTHASH hHash = 0;
  4. 4     if (!CryptCreateHash(hProv, CALG_MD4, 0, 0, &hHash))
  5. 5         throw "CryptCreateHash failed (MD4)";
  6. 6     if (!CryptHashData(hHash, (const BYTE*)password, lstrlenW(password) << 1, 0))
  7. 7         throw "CryptHashData failed (user password)";
  8. 8     DWORD hash_len = MD4LEN;
  9. 9     BYTE hash_buffer[MD4LEN];
  10. 10     if (!CryptGetHashParam(hHash, HP_HASHVAL, hash_buffer, &hash_len, 0))
  11. 11         throw "CryptGetHashParam failed (NT password hash)";
  12. 12     memcpy(password_hash, hash_buffer, 16);
  13. 13 }
复制代码
至此,我们就算出来了NtResponse
2.计算AunthenticatorResponse
  1. 1 void _ChallengeResponse(const HCRYPTPROV hProv, const BYTE* challenge, const BYTE* password_hash, BYTE* response)
  2. 2 {
  3. 3     BYTE z_password_hash[21];
  4. 4     memset(z_password_hash, 0, 21);
  5. 5     memcpy(z_password_hash, password_hash, 16);
  6. 6
  7. 7     _DesEncrypt(hProv, challenge, z_password_hash, response);
  8. 8     _DesEncrypt(hProv, challenge, z_password_hash + 7, response + 8);
  9. 9     _DesEncrypt(hProv, challenge, z_password_hash + 14, response + 16);
  10. 10 }
复制代码
  1. 1 typedef struct {
  2. 2     BLOBHEADER key_header;
  3. 3     DWORD key_length;
  4. 4     BYTE key_data[8];
  5. 5 } DESKey;
  6. 6
  7. 7 void EXPAND(BYTE* key);
  8. 8
  9. 9 void _DesEncrypt(const HCRYPTPROV hProv, const BYTE* data, const BYTE* key, BYTE* result)
  10. 10 {
  11. 11     // Fill CryptoAPI-required key structure
  12. 12     DESKey des_key;
  13. 13     des_key.key_header.bType = PLAINTEXTKEYBLOB;
  14. 14     des_key.key_header.bVersion = CUR_BLOB_VERSION;
  15. 15     des_key.key_header.reserved = 0;
  16. 16     des_key.key_header.aiKeyAlg = CALG_DES;
  17. 17     des_key.key_length = 8;
  18. 18     memcpy(des_key.key_data, key, 7);
  19. 19     EXPAND(des_key.key_data);
  20. 20
  21. 21     HCRYPTKEY hKey;
  22. 22     // import key BLOB
  23. 23     if (!CryptImportKey(hProv, (BYTE*)&des_key,
  24. 24         sizeof(des_key), 0, 0, &hKey))
  25. 25         throw "CryptImportKey failed";
  26. 26     // set ECB mode required by RFC
  27. 27     DWORD des_mode = CRYPT_MODE_ECB;
  28. 28     if (!CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&des_mode, 0))
  29. 29         throw "CryptSetKeyParam failed (ECB mode)";
  30. 30     // set initialization vector
  31. 31     BYTE IV[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  32. 32     if (!CryptSetKeyParam(hKey, KP_IV, &IV[0], 0))
  33. 33         throw "CryptSetKeyParam failed (init vector)";
  34. 34     // encrypt
  35. 35     DWORD data_len = 8;
  36. 36     memcpy(result, data, 8);    // encrypt in-place
  37. 37     if (!CryptEncrypt(hKey, 0, FALSE, 0, (BYTE*)&result[0], &data_len, 8))
  38. 38         throw "CryptEncrypt failed (DES)";
  39. 39 }
  40. 40
复制代码

  • 该函数里面界说了长度16的PasswordHash和PasswordHashHash,长度为8的Challenge。首先,使用MD4算法对密码举行哈希处理,得到PasswordHash。
  • 然后,对PasswordHash举行再次哈希处理,得到PasswordHashHash。
  • 接着,使用SHA算法对PasswordHashHash、NT-Response和Magic1举行哈希处理,得到Digest。
  • 使用ChallengeHash函数对PeerChallenge、AuthenticatorChallenge和UserName举行哈希处理,得到Challenge。
  • 再次使用SHA算法对Digest、Challenge和Magic2举行哈希处理,得到终极的Digest
 

 
下面是具体实现代码
</ol>  
[code] 1 void GenerateAuthenticatorResponse(const HCRYPTPROV hProv, const wchar_t* password_unicode, const BYTE* NTResponse, const BYTE* PeerChalleng, const BYTE* AuthenticatorChallenge, const char* UserName) 2 { 3     BYTE Magic1[39] = { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, 4     0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, 5     0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 6     0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; 7     BYTE Magic2[41] = { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, 8     0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, 9     0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,10     0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,11     0x6E };12     BYTE Passwordhash[16];13     _NtPasswordHash(hProv, password_unicode, Passwordhash);14     BYTE PasswordHashhash[16];15     _NtPasswordHashHash(hProv, Passwordhash, PasswordHashhash);16     SHA_CTX Context;17     SHA1_Init(&Context);18     SHA1_Update(&Context, PasswordHashhash, 16);19     SHA1_Update(&Context, NTResponse, 24);20     SHA1_Update(&Context, Magic1, 39);21     unsigned char aa[SHA_DIGEST_LENGTH];22     SHA1_Final(aa, &Context);23     BYTE Challenge[8];24     _ChallengeHash(hProv, PeerChalleng, AuthenticatorChallenge, UserName, Challenge);25     SHA1_Init(&Context);26     SHA1_Update(&Context, aa, sizeof(aa));27     SHA1_Update(&Context, Challenge, 8);28     SHA1_Update(&Context, Magic2, 41);29     unsigned char bb[SHA_DIGEST_LENGTH];30     SHA1_Final(bb, &Context);31     cout

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

悠扬随风

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表