Get the MSN Messenger password saved by the current account via DPAPI
Tomekeeper posted a code for saved MSN passwords over DPAPI on the Shuimu BBS. Its core idea is to save the key in the registry from the MSN encryption, and the encrypted string is removed, and then use the DPAPI's function CRYPTUNPROTECTDATA to decrypt. The key code is as follows:
//...Ret = regopenkeyex (HKEY_CURRENT_USER, "Software // Microsoft // MsnMessenger", 0, Key_Read, & HKey); // ... Ret = RegQueryValueex (HKEY, "Password.net Messenger Service", //. ..);
Datain.pbdata = DATA 2; // 口 密 文 文 from the second bit Datain.cbdata = dwsize-2;
CryptunProtectdata (& DataIn, Null, Null, NULL, NULL, 1, & DATAOUT);
Base64_decode (DataOut.pbdata, Data, Strlen (DataOut.pbdata); Printf ("MSN Password:% S / N", DATA);
However, this method is no effect on the new version of MSN in the XP / 2003 environment, because the latest version of MSN no longer saves the encrypted password directly in the registry key. So I installed similar ideas, using Windbg and IDA Pro to analyze the new version of the save password method. Since the conclusion is that the MSN uses a function of XP / 2003 to manage the current user credential set, put the encrypted password in this in this unified management. You can use the new CredReadDomaincredentials function, give the read goal to get encrypted credentials, such as:
typedef struct _CREDENTIAL_TARGET_INFORMATIONW {LPWSTR TargetName; LPWSTR NetbiosServerName; LPWSTR DnsServerName; LPWSTR NetbiosDomainName; LPWSTR DnsDomainName; LPWSTR DnsTreeName; LPWSTR PackageName; ULONG Flags; DWORD CredTypeCount; LPDWORD CredTypes;} CREDENTIAL_TARGET_INFORMATIONW, * PCREDENTIAL_TARGET_INFORMATIONW;
DWORD CREDTYPES = CRED_TYPE_DOMAIN_VISIBLE_PASSWORD;
Credential_target_informationw target = {l "Messenger.hotmail.com", NULL, NULL, NULL, L "Passport.Net", Null, L "Passport1.4", 0, 1, & CredTypes};
DWORD DWCOUNT = 0; pcredentialw * CREDs;
Win32check (CredreadDomaincreditionw (& Target, Cred_cache_target_information, & dwcount, & credg), "Cannot Read User / 'S Domain Credential, Maybe You Are Not Save Your Password");
The Credential_Target_informationW structure here specifies the source and package name to get the credential; CredReadDomaincredentialsw, according to this information, send RPC calls through the NDrClientCall2 function to complete the actual function. Reads out this credential credentials include a user name (UserName) and credentials content (CredentialBlob): typedef struct _CREDENTIALW {DWORD Flags; DWORD Type; LPWSTR TargetName; LPWSTR Comment; FILETIME LastWritten; DWORD CredentialBlobSize; LPBYTE CredentialBlob; DWORD Persist; DWORD AttributeCount; pcredential_attributew attributes; lpwstr targetalias; lpwstr usrname;} Credentialw, * pcredentialw;
PCRedentialw Cred = CREDs [0];
For MSN Messenger, Credentialw :: UserName is the login account. MSN Messenger When the file menu is displayed, you will get the current account name from the credentials for display. Each time you log in, you will further decrypt the contents of the CRYPTUNPROTECTDATA function, the code is as follows:
Static unsigned char entropydata [] = {0xE0, 0x00, 0x01, 0x10, 0x01, 0x01, 0x00, 0x14, 0x01, 0x00, 0x00, 0x0, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x18, 0x01, 0x14, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x10, 0x01, 0x01, 0x18, 0x01, 0x14, 0x01, 0x01, 0x00, 0x08, 0x01, 0x00, 0x00, 0x0, 0x00, 0x01, 0x00, 0x08, 0x01, 0xc0, 0x00, 0x00, 0x00};
Pcredentialw Cred = CREDs [0]; DATA_BLOB DATA = {CRED-> CredentialBlobsize, Cred-> CredentialBlob}, Entropy = {SizeOf (EntropyData), EntropyData}, Pass = {0, NULL};
Bool Ret = CryptunProtectData (& Data, Null, & Entropy, Null, Null, Cryptprotect_ui_Forbidden, & Pass)
Here, EntropyData saves the use of fixed encryption keys directly from the MSN Messenger code from the MSN Messenger code, which may change depending on the version. Because the new MSN Messenger is not directly encrypted, but use this key encryption, it is slightly different from Tomekeeper. Saved in the decrypted Pass is the password of the current MSN Messenger account, huh, huh.
static const std :: string toString (LPCWSTR lpStr, DWORD cbStr) {std :: string str; str.resize (WideCharToMultiByte (CP_ACP, 0, lpStr, cbStr, NULL, 0, NULL, NULL)); WideCharToMultiByte (CP_ACP, 0 , LPSTR, CBSTR, (Char *) Str.c_STR (), Str.Size (), NULL, NULL);
Return Str;}
Static const st :: string toString (lpcwstr lpstr) {Return Tostring (LPSTR, WCSLEN (LPSTR));
m_username = TOSTRING (CRED-> username);
M_fcredfree (CREDs);
Win32Check (Ret, "Cannot Decrypt Credential);
M_Password = TOSTRING ((lpcwstr) Pass.pbdata, pass.cbdata / sizeof (wchar_t));
:: localfree (Pass.pbdata);
It seems that the storage password seems to be very unsafe, but it is also okay, huh, huh. Because CredreadDomainCredentials and CryptunProtectData are used, the default is the security context of the current account for encryption, which is no longer meaningful if the encrypted data is changed. Therefore, unless you are getting the current account or Administrator account permission, the password is still safe; in turn, if the two accounts are made by others, it is possible to install a keyboard logger to achieve a similar effect. Therefore, in general, it is still safe. This code can only be used as a recovery tool when forgetting to record the MSN password: P is actually the main purpose of our two, huh, huh
In addition, XP / 2003 has a new command line command cmdkey, using its / list parameters, can list all saved credential information in the current user credentials, such as login information on other machines, login information, .NET Passport account information, etc. Wait. You can make changes to this method to get the password saved in all of these accounts.