Post

BabbleLoader

Purpose

Overview

BabbleLoader is a loader-type Windows malware used to evade both traditional and AI-based detection systems. It uses junk code insertions and metamorphic transformations to change its structure and flow, avoiding detection while executing its payload. By resolving API functions only at runtime, it bypasses common API monitoring and sandbox-injected DLLs. The malware can also decrypt shellcode directly into memory, evading file-based scanning.

The malware has been deployed in multiple campaigns and observed as targeting English and Russian-speaking users, often posing as cracked software or accounting tools for finance professionals. Its able to make analysis difficult with excessive junk code and random instructions, which also cause tools such as Ghidra, IDA, and Binary Ninja to crash.

Each build of BabbleLoader is unique, which can lead to missed detections and false positives. It tricks AI by making irrelevant actions appear meaningful.

The malware dynamically resolves API calls using hashes and performs anti-sandbox checks by checking the graphics adapter on the current system and with VDLL checks that look for the Windows Defender’s emulator. It ensures execution only in genuine environments by verifying the presence of at least 85 unique processes before proceeding with its payload.

Useful structures in BabbleLoader


The loader uses dynamic API resolution and sidesteps common API monitoring by only resolving its functions at runtime. The malware bypasses sandboxes and can identify sandbox-injected DLLs that hook API calls. It uses shellcode loading decryption into memory to bypass file-based scanning. The loader has been utilised across multiple campaigns targeting both English and Russian-speaking individuals.

BabbleLoader itself has been used to target a large variety of users including those looking to download generic cracked software, such as video editing, gaming, VPN, browsers and utilities. Intezer reported campaigns that had targeted users particularly those that are professionals in the finance and administration sectors, masquerading as accounting software used to fill out eligibility checks used by HR or payroll professionals.

The malware uses junk code to hamper analysis by confusing the analyst with many paths of code that are never actually accessed and using random imports with randomly generated hardcoded strings. The loader makes use of excessive random instructions adds values to local variables and moves data around registers for no particular functionality.

The amount of junk code can increase to the point where it’s too many instructions for a decompiler to show in both Ghidra, IDA and Binary Ninja.

The loader is also metamorphic and each build of the loader will have unique strings, metadata, hashes, encryption and control flow. Each sample of the malware only has a few snippets of code that are shared, which has a large impact on AI-based analysis techniques due to the constant variation in code structures forcing AI models to constantly relearn what to look for which leads to missed detections and false positives.

The loader also tricks AI into interpreting irrelevant actions as meaningful ones, leading it to predict that the malware will perform operations that never actually execute.

Babble Loader starts off using dynamic API resolution by resolving API calls from API hashes and getting the module handle for “NTDLL.DLL”, which is decrypted using a rolling XOR cypher. The malware reads the PE header of “NTDLL.DLL” using the returned handle and locates the export directory to build up the following structure:

1
2
3
4
5
6
7
struct _NtDllExportInfo {  
    DWORD* AddressOfFunctions;  
    DWORD* AddressOfNames;  
    DWORD* AddressOfNameOrdinals;  
    DWORD NumberOfNames;  
    HMODULE NtdllModuleHandle;  
}

It then proceeds to iterate through the export names, hashing the names to compare hard-coded values in binary, and getting pointers for imports while the exports remain the same for each build.

Hash Call
1ABEC790 NtCreateSection
993C0058 NtMapViewOfSection
92263458 NtUnmapViewOfSection
9DA1D253 NtClose
6AF3F390 NTQuerySystemInformation
0A96AB0E4 RtlAllocateHeap
8A21A480 RtlFreeHeap

Once BabbleLoader resolves pointers for the imports, it calls “NtCreateSection” and “NtMapViewOfSection” so that it can allocate and manage memory outside the standard process space, it randomly rearranges stored encrypted chunks of a payload in their correct order within mapped memory before proceeding to decrypt each block. But before this process, the loader performs an anti-sandbox check by checking the graphics adapter within the current environment, which it does by importing “dxgi.dll” which provides a means for systems to interface with graphics hardware.

The exported “CreateDXGiFactory” is called with the “IDXGIFactory” object, allowing the loader to enumerate information from the graphics adapter by calling “EnumAdapters” followed by “GetDesc” to get the “DXGI_ADAPTER_DESC” structure:

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct DXGI_ADAPTER_DESC  
    {  
    WCHAR Description[ 128 ];  
    UINT VendorId;  
    UINT DeviceId;  
    UINT SubSysId;  
    UINT Revision;  
    SIZE_T DedicatedVideoMemory;  
    SIZE_T DedicatedSystemMemory;  
    SIZE_T SharedSystemMemory;  
    LUID AdapterLuid;  
    } DXGI_ADAPTER_DESC;

It parses the “VendorId” from this structure and compares it against three values that form the vendor whitelist below:

8086 - Intel 10DE - Nvidia 1002 - AMD

BabbleLoader takes extra measures to hide the Vendor ID numbers using simple XOR keys and a few assembly instructions. These instructions are separated by a large amount of junk code to hide the values when it’s statically analysed within a disassembler.

BabbleLoaader also uses VDLL checks to combat Windows Defender Anti-virus Emulator. It decodes two DLLs with exports and checks to get “kernel32.dll”. It checks for the ProcAddress of “MpSwitchToNextThread_WithCheck”. The malware then uses “ntdll.dll” with the export of “MpDispatchException”, if these calls are successful it will set a variable for the loader to exit later, but a successful import of any of these calls indicates that the malware is being emulated within Windows Defenders sandbox. Due to VDLLs only existing within this emulator, this has been observed in malware such as Raspberry Robin.

When the shellcode payload stored within the mapped memory of a newly created section is executed, it performs another anti-sandbox check by checking the number of running processes on the machine. This is achieved by calling “NtQuerySystemInformation” which was previously resolved from “ntdll.dll”, and getting the “SystemProcessInformation” class. This returns as an array of “SYSTEM_PROCESS_INFORMATION” structures, which details each process along with their names. This is gathered and hashed as a checksum which is then compared with the hash name within the next array. A counter is also incremented, but if the checksum matches the counter is reduced by one, giving the total number of each process that has a unique name running.

If at least 85 unique processes are running on the machine, the malware will continue to the next stage which involves decoding and executing the payload.


This post is licensed under CC BY 4.0 by the author.