← Back to list

Deep Dive Into Moka: Analyzing a Babylon RAT-Based Information Stealer and Keylogger

Executive Summary

Ayush Pathania · 2026-06-26 15:51 · 0 claps · 11.4 min read
#malware-analysis #yara-rules #sigma-rules #stealer-malware #keylogger
Open on Medium ↗
Wiki topics: 🔒 · Cybersecurity 👨‍👩‍👧 · Family & Parenting 🥊 · Combat Sports

Deep Dive Into Moka: Analyzing a Babylon RAT-Based Information Stealer and Keylogger

Executive Summary

Moka is a Windows-based Remote Access Trojan (RAT) built on top of the open-source Babylon RAT framework. Once executed, it drops a hidden copy of itself into C:\ProgramData\Moka\, establishes persistence via the Windows registry, and immediately begins profiling the victim machine. Its ultimate goal is continuous surveillance — silently capturing keystrokes, clipboard contents, active window titles, and browser-saved credentials, then periodically beaconing all of it back to a remote C2 server over port 443.

Key Takeaways

  • Two-stage execution with a self-check: Moka uses a parent-child process model with a clever path-comparison trick to ensure the payload only executes from its designated install location, making it harder to detonate in ad-hoc sandboxes.
  • Persistent, multi-threaded surveillance: Moka runs several concurrent threads — one for keyboard/clipboard monitoring, one for network beaconing, and one for persistence re-registration — allowing it to keep watching the victim even as it communicates with its C2.
  • Beacon-based C2 over HTTPS port (443): Rather than maintaining a persistent connection, Moka uses a recurring connect → send → disconnect loop to fb88.gay, exfiltrating a 166-byte host profile on every new connection attempt.

1. Sample Metadata

Malware Family: Moka (Babylon RAT-based)
File Type: Win32 PE32 Executable
SHA-256 Hash: 2F8B6FF170D5C231FC25D0ECC9B907448A5CDEA6513BEF52A10856FD1B814479
Packer: UPX
Entropy: 7.92 (consistent with packed/compressed binary)
MalwareBazaar: Search Sample on MalwareBazaar

2. Initial Triage & Static Analysis

Packing & Obfuscation

The sample arrives UPX-packed with an entropy of 7.92 — close to the theoretical maximum of 8.0. High entropy is a reliable red flag that the file’s contents are either compressed or encrypted, and it’s the first thing you’ll notice if you run the file through DIE (Detect-It-Easy) or PEiD. Before any meaningful static analysis can happen, you must unpack it. Standard UPX unpacking (upx -d <sample>) works here.

One important note on imports: in several of its DLL imports, Moka has stripped the function names and calls them by ordinal number only. This is a common technique to slow down static analysis, since ordinal-based imports don’t show up as readable strings in tools like strings or CFF Explorer without additional cross-referencing.

Imported Libraries & What They Hint At

The imported DLLs paint a clear picture of the malware’s capabilities even before it runs:

DLL                  Suspicious Imports / Purpose
-------------------------------------------------------------------------------------------
advapi32.dll         LookupPrivilegeValueW, AdjustTokenPrivileges,
                     RegCreateKey, RegSetValueExW, RegDeleteValueW — privilege 
                     escalation and registry manipulation.
-------------------------------------------------------------------------------------------
ws2_32.dll           Winsock2 networking — C2 communication
-------------------------------------------------------------------------------------------
crypt32.dll          Encryption/decryption — likely used to protect exfiltrated 
                     data or C2 traffic
-------------------------------------------------------------------------------------------
ole32.dll           COM object initialization — used for WMI queries during host profiling
-------------------------------------------------------------------------------------------
oleaut32.dll        OLE Automation — supporting COM/WMI automation
-------------------------------------------------------------------------------------------
urlmon.dll          Downloading content from the internet
-------------------------------------------------------------------------------------------
user32.dll          Clipboard APIs (OpenClipboard, GetClipboardData), keyboard hook APIs,
                    message handling

Interesting Strings

Running strings on the unpacked binary reveals several artifacts:

  • Manifest declaration:
requestedExecutionLevel level="asInvoker" uiAccess="false"

The malware requests to run with the current user’s privileges only — no UAC prompt. This is intentional; it keeps execution silent by never triggering a UAC elevation dialog.

  • Open-source RAT identifier:
Babylon RAT Client

This string directly links Moka to the publicly available Babylon RAT codebase. The developer built on top of it rather than writing a RAT from scratch.

  • Browser credential theft paths:
\AppData\Local\Google\Chrome\User Data\Default\Login Data
 %s\Mozilla\Firefox\Profiles\%s 
\signons.sqlite
 \logins.json

These are hardcoded paths to credential storage databases in Chrome and Firefox. Moka will read and exfiltrate saved passwords from both.

  • Developer artifact (PDB path):
C:\Users\Stefan\documents\visual studio 2013\Projects\sqliteProject\Release\sqliteProject.pdb

This is the Program Database (PDB) path left behind from the developer’s build environment. It tells us:

  • The developer’s username is likely Stefan.
  • The project was built in Visual Studio 2013.
  • The project is named sqliteProject — suggesting SQLite is used internally, likely to store stolen data locally before exfiltration.
  • Persistence string artifacts: Strings referencing registry Run / RunOnce key names are present, confirming the persistence mechanism seen in dynamic analysis.

3. Dynamic Analysis (Behavioral Observations)

This is where Moka’s full picture comes together. The malware’s execution is split across a parent process and a child process, each with distinct roles.

3.1 The Two-Stage Execution Model

When you first run the sample, the original executable acts as a Loader / Dropper. Here’s the exact API call sequence for the parent:

Stage 1 — Parent Process (Loader)

SHGetFolderPath(CSIDL_COMMON_APPDATA)   → Resolves C:\ProgramData
        ↓
DeleteFile(C:\ProgramData\Moka\Moka.exe:Zone.Identifier)  → MOTW removal
        ↓
SetFileAttributes(FILE_ATTRIBUTE_HIDDEN) → Hides the dropped file
        ↓
AdjustTokenPrivileges(SeDebugPrivilege, SeShutdownPrivilege, SeTcbPrivilege)
        ↓
CreateProcess(C:\ProgramData\Moka\Moka.exe) → Launches child
        ↓
ExitProcess(0)  → Parent terminates immediately

Mark-of-the-Web (MOTW) Removal: The DeleteFile call targeting Moka.exe:Zone.Identifier is notable. Windows appends this NTFS Alternate Data Stream to files downloaded from the internet, and it's what triggers SmartScreen warnings. Removing it makes the dropped file look like a locally-created file to the OS.

Privilege Escalation Attempt: The parent attempts to enable three powerful privileges:

Privilege What It Allows SeDebugPrivilege Attach to and read/write memory of any other process SeShutdownPrivilege Initiate system shutdown or reboot SeTcbPrivilege "Act as part of the operating system" — near-kernel-level access

3.2 The Path-Comparison Self-Check (Anti-Analysis Trick)

This is one of Moka’s most interesting behaviors. When the child process (C:\ProgramData\Moka\Moka.exe) starts, its first action is to compare its own current execution path against the hardcoded install path using lstrcmp:

lstrcmp(
    lpString1 = L"C:\\Users\\root\\Documents\\...\\Moka.exe",  // Actual path
    lpString2 = L"C:\\ProgramData\\Moka\\Moka.exe"            // Expected path
) -> 0x1  // Not equal → exit

If the paths don’t match (i.e., the malware is running from somewhere other than C:\ProgramData\Moka\), the process exits immediately without doing anything. This is a simple but effective anti-sandbox/anti-analysis trick. If a researcher just double-clicks the sample from their desktop, the payload never fires.

The intended flow is:

Parent drops Moka.exe → C:\ProgramData\Moka\Moka.exe
        ↓
Parent launches child from C:\ProgramData\Moka\Moka.exe
        ↓
Child compares path → Paths MATCH → Execute payload

3.3 Registry Changes (Persistence)

Moka uses the RunOnce key for persistence, meaning it re-registers itself after every execution cycle:

Key:   HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
Value: "Moka"
Data:  C:\ProgramData\Moka\Moka.exe

The API call sequence captured:

RegCreateKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce")
RegSetValueEx(hKey, "Moka", REG_SZ, "C:\\ProgramData\\Moka\\Moka.exe")
RegCloseKey(hKey)

RunOnce keys execute once on the next login and then self-delete. This is why a dedicated thread (Thread 0x2F50) is responsible for re-registering the key periodically — it ensures persistence survives even if the system is restarted or the key is removed.

3.4 File System Changes

The malware creates two key filesystem artifacts, both hidden:

Path                                Attribute                     Purpose
--------------------------------------------------------------------------------------
C:\ProgramData\Moka\Moka.exe        FILE_ATTRIBUTE_HIDDEN         Dropped payload
--------------------------------------------------------------------------------------
C:\Users\<USER>\AppData\Roaming     FILE_ATTRIBUTE_HIDDEN         Exfiltration staging 
\ConfigsEx\                         FILE_ATTRIBUTE_ARCHIVE        directory
--------------------------------------------------------------------------------------
C:\Users\<USER>\AppData\Roaming     FILE_ATTRIBUTE_HIDDEN         Timestamped keylog
\ConfigsEx\2026 06 24 - 12 22 PM    FILE_ATTRIBUTE_ARCHIVE        /data files

The ConfigsEx directory uses timestamped subdirectories to organise stolen data. The timestamp is built using GetTimeZoneInformation and GetLocalTime, then formatted with WideCharToMultiByte — meaning the filenames reflect the victim's local time zone, which also leaks geographic info to the attacker.

3.5 Network Activity (C2 Communication)

Domain resolution:

GetAddrInfoW("fb88.gay")
  → inet_ntop(AF_INET) → "104.21.47.35"
  → htons(443)
  → socket(AF_INET, SOCK_STREAM, TCP)
  → connect(104.21.47.35:443)

Secondary IP observed: 172.67.170.89 .

The connection is made over TCP port 443 — the standard HTTPS port. This is deliberate: most corporate and home firewalls allow outbound 443 freely, making the traffic blend in with normal web browsing. Moka does not implement a full TLS stack in the captured traces; the port is used as camouflage.

The Beaconing Pattern:

Moka does not maintain a persistent connection. Instead, it follows a recurring loop:

Resolve fb88.gay
        ↓
Create TCP socket → Connect to 104.21.47.35:443
        ↓
SetEvent() → Wake worker thread
        ↓
Send 4-byte length header + 166-byte host profile packet
        ↓
Attempt recv() → Fails (SOCKET_ERROR = 0xFFFFFFFF)
        ↓
Close socket → ResetEvent()
        ↓
Monitor user activity (keyboard, clipboard)
        ↓
[Repeat]

The server appears to be receiving only in these traces — Moka connects, dumps its host profile, waits briefly for a command, gets no response, and disconnects. This is consistent with a RAT that is waiting for the operator to come online and issue commands.

3.6 Host Profiling & Surveillance

Before sending its first packet, Moka collects a full profile of the infected machine. The profiling happens across multiple threads and API calls:

System Information Collected:

GetUserName()                                   → Victim's Windows username
GetComputerName()                               → Machine hostname
GetLocaleInfo()                                 → System language/locale
GetTimeZoneInformation()                        → Time zone (geographic indicator)
WMI: SELECT * FROM Win32_OperatingSystem        → OS version, build, install date
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS)    → Full list of running processes
+ Process32First/Next()                      

The WMI query sequence:

CoInitializeEx()
CoInitializeSecurity()
CoCreateInstance()       // IWbemLocator
CoSetProxyBlanket()
// Execute: SELECT * FROM Win32_OperatingSystem

All of this is serialized into a 166-byte packet that is sent to the C2 on every new connection.

3.7 Keylogging & Clipboard Monitoring

This is where Moka earns its “information stealer” classification.

3.7.1 Keyboard Hook Installation:

SetWindowsHookEx(WH_KEYBOARD_LL, ...)

A low-level keyboard hook (WH_KEYBOARD_LL) captures every keystroke system-wide, regardless of which application the user is typing in.

3.7.2 Clipboard Monitoring Loop :

while (true) {
    GetForegroundWindow()           // Which app is active?
    OpenClipboard()
    GetClipboardData(CF_UNICODETEXT) // Read clipboard text
    GlobalLock() / GlobalUnlock()
    CloseClipboard()
    Sleep(300ms)                    // Check ~3 times per second
}

3.7.3 Keylog File Writing:

CreateFile / OpenFile               // Open the keylog file in ConfigsEx
SetFilePointerEx(FILE_END)          // Move to end of file (append mode)
WriteFile(captured_keystroke)       // Write the captured data
CloseHandle()

3.7.4 Combined surveillance per cycle

WH_KEYBOARD_LL hook fires
        ↓
GetForegroundWindow() → Active window handle
        ↓
GetWindowText() → Window title (e.g., "Gmail - Google Chrome")
        ↓
GetWindowThreadProcessId() → Process ID of active window
        ↓
CreateToolhelp32Snapshot → Enumerate processes → Map PID to process name
        ↓
GetClipboardData(CF_UNICODETEXT) → Read clipboard
        ↓
GetLocalTime() → Timestamp the entry
        ↓
WriteFile → Append formatted log to ConfigsEx\<timestamp> file

This means Moka logs in context: a victim typing their password into Chrome will produce a log entry like [12:22 PM] [chrome.exe - "Gmail"] [keystroke data] [clipboard: <pasted_content>].

The hidden folder which saves user data and sends to the C2 server . This could also copy cryto wallets passwords and user credentials . Also copies users saved profiles .

The hidden folder which saves user data and sends to the C2 server . This could also copy cryto wallets passwords and user credentials . Also copies users saved profiles .

3.8 Multi-Threaded Architecture

Moka is not a simple single-threaded program. The observed thread activity:

Task                 Description
----------------------------------------------------------------------------------------
Initialization        Drops payload to C:\ProgramData\Moka\, spawns child 
(Main Thread)         process, then exits
----------------------------------------------------------------------------------------
Mutex & Network       Checks for existing instance via mutex, initializes Winsock,
Bootstrap(0x291C)     sends initial C2 beacon
----------------------------------------------------------------------------------------
Network Send          Handles outbound data transmission to the C2 server
(0x3678)
----------------------------------------------------------------------------------------
Network Worker        Manages the full connect → send → close beaconing cycle in a loop
(0x37EC)
----------------------------------------------------------------------------------------
Persistence Guard     Periodically re-registers the RunOnce registry key and re-
(0x2F50)
----------------------------------------------------------------------------------------
Host Reconnaissance   Initializes COM/WMI and queries Win32_OperatingSystem for
(0x1590)              OS profiling
----------------------------------------------------------------------------------------
Surveillance Loop     Continuously polls clipboard every 300ms, processes keyboard
(0xDC0)               hook events, and writes to keylog files

The threads coordinate using Windows Event objects:

Main Thread: CreateEvent() → handle 0x2E4
Network Thread:
    connect() → success
    SetEvent(0x2E4)          ← signals "connection is ready"
Worker Thread:
    WaitForSingleObject(0x2E4) ← blocks until connection is ready
    wakes up → send data

3.8.1 Mutex: At startup, the child process creates a mutex named 2e591605-f3c6-4f28-ac1c-4c6708598eea to prevent multiple instances from running simultaneously:

OpenMutex("2e591605-f3c6-4f28-ac1c-4c6708598eea")   // Check if already running
CreateMutex("2e591605-f3c6-4f28-ac1c-4c6708598eea") // If not, claim it

4. Indicators of Compromise (IoCs)

4.1 Network IoCs

Type          Value            Notes
------------------------------------------------------------------------------
Domain        fb88.gay         Primary C2 domain
----------------------------------------------------------------------------
IP            104.21.47.35     Resolved IP for fb88.gay, port 443
----------------------------------------------------------------------------
IP            172.67.170.89    Secondary IP (Cloudflare fronting)
---------------------------------------------------------------------------
Port          443 (TCP)        Used as camouflage for HTTPS traffic

4.2 Host IoCs

Type            Value                                                Notes
------------------------------------------------------------------------------------------------------
File            C:\ProgramData\Moka\Moka.exe                         Dropped payload (HIDDEN)
------------------------------------------------------------------------------------------------------
File            C:\ProgramData\Moka\Moka.exe                         Dropped payload (HIDDEN)
------------------------------------------------------------------------------------------------------
Directory       C:\Users\<USER>\AppData\Roaming\ConfigsEx\           Exfil staging dir (HIDDEN)
------------------------------------------------------------------------------------------------------
Registry        KeyHKCU\SOFTWARE\Microsoft\Windows\CurrentVersion    Persistence key
                \RunOnce
------------------------------------------------------------------------------------------------------
RegistryValue   Moka                                                 Value name under RunOnce
------------------------------------------------------------------------------------------------------
Registry Data   C:\ProgramData\Moka\Moka.exe                         Executable path in RunOnce value
------------------------------------------------------------------------------------------------------
Mutex           2e591605-f3c6-4f28-ac1c-4c6708598eea                 Single-instance guard
------------------------------------------------------------------------------------------------------
SHA-256         2F8B6FF170D5C231FC25D0ECC9B907448A5CDEA6513B         hash of malware
                EF52A10856FD1B814479                                  

4.3 Developer Artifact

Type          Value
---------------------------------------------------------------------------
PDB           C:\Users\Stefan\documents\visual studio 2013\Projects
Path          \sqliteProject\Release\sqliteProject.pdb

5. Detection — YARA & Sigma Rules

5.1 YARA Rule

rule Moka_RAT_BabylonBased
{
    meta:
        description   = "Detects Moka RAT based on Babylon RAT framework"
        author        = "Ayush-Pathania"
        date          = "2026-06-24"
        sha256        = "2F8B6FF170D5C231FC25D0ECC9B907448A5CDEA6513BEF52A10856FD1B814479"
        reference     = "MalwareBazaar"
        severity      = "high"

strings:
        // Unique mutex identifier
        $mutex        = "2e591605-f3c6-4f28-ac1c-4c6708598eea" ascii wide
        // C2 domain
        $c2_domain    = "fb88.gay" ascii wide nocase
        // Developer PDB artifact
        $pdb          = "sqliteProject.pdb" ascii
        // Babylon RAT identification string
        $rat_string   = "Babylon RAT Client" ascii wide
        // Persistence registry value name
        $reg_value    = "Moka" wide
        // Exfiltration staging directory name
        $config_dir   = "ConfigsEx" wide ascii
        // Accompanying C2 Infrastructure IPs
        $c2_ip1 = "104.21.47.35" ascii wide
        $c2_ip2 = "172.67.170.89" ascii wide
    condition:
        uint16(0) == 0x5A4D                         // MZ header (PE file)
        and (
           $mutex or
            $c2_domain or
            $pdb or
            any of ($c2_ip*) or                     // Triggers if either IP is found
            ($rat_string and $config_dir) or
            ($reg_value and $config_dir)
        )
}

5.2 Sigma Rule — Persistence via RunOnce

title: Moka RAT Persistence via RunOnce Registry Key
id: b7e91d3f-9c44-4a2b-8f36-0a1c2d3e4f56
status: experimental
description: >
  Detects Moka RAT establishing persistence by writing to the RunOnce
  registry key with the value name "Moka" pointing to C:\ProgramData\Moka\Moka.exe
author: Ayush-Pathania
date: 2026/06/24
references:
  - https://bazaar.abuse.ch
tags:
  - attack.persistence
  - attack.t1547.001   # Boot or Logon Autostart Execution: Registry Run Keys
logsource:
  category: registry_set
  product: windows
detection:
  selection:
   # TargetObject captures the registry key path AND the value name 'Moka' at the end
    TargetObject|contains|all:
        - '\CurrentVersion\RunOnce'
        - '\Moka'
    # Details captures the string data stored within that registry value
    Details|contains: 'C:\ProgramData\Moka\Moka.exe'
  filter:
    Image|startswith:
      - 'C:\Windows\'
      - 'C:\Program Files\'
  condition: selection and not filter
level: high

5.3 Sigma Rule — Hidden File Drop in ProgramData

title: Moka RAT Hidden Executable Drop in ProgramData
id: c8f02e4a-1b55-5c3d-9g47-1b2c3d4e5f67
status: experimental
description: >
  Detects the creation of a hidden executable under C:\ProgramData\Moka\,
  a hallmark of the Moka RAT dropper stage.
author: Ayush-Pathania
date: 2026/06/24
tags:
  - attack.defense_evasion
  - attack.t1564.001   # Hide Artifacts: Hidden Files and Directories
  - attack.t1036.005   # Masquerading: Match Legitimate Name or Location
logsource:
  category: file_event
  product: windows
detection:
  selection:
    TargetFilename|startswith: 'C:\ProgramData\Moka\'
    TargetFilename|endswith: '.exe'
  condition: selection
level: critical

6. Conclusion

Moka is not a sophisticated, nation-state-grade tool — but it doesn’t need to be. Built on the Babylon RAT open-source framework, it combines reliable techniques: UPX packing to evade static scanners, a path-comparison self-check to avoid casual sandbox detonation, MOTW removal to bypass SmartScreen, and RunOnce re-registration to survive reboots.

What makes it genuinely dangerous is its persistence of surveillance. The multi-threaded design means it is simultaneously monitoring keystrokes, polling the clipboard every 300ms, recording active window context, and beaconing collected data back to fb88.gay — all at the same time, indefinitely. A victim running this on a machine where they access banking portals, corporate SSO, or password managers would be fully compromised with minimal noise.

The developer PDB path (C:\Users\Stefan\...) is an OPSEC failure that could be valuable for attribution if correlated with other samples.

For blue teams: Block outbound connections to fb88.gay and 104.21.47.35 immediately. Hunt for the mutex 2e591605-f3c6-4f28-ac1c-4c6708598eea and the ConfigsEx directory in user AppData. The YARA and Sigma rules above should give you solid coverage across endpoint and registry telemetry.

Analyzed on MalwareBazaar sample. All dynamic analysis conducted in an isolated sandbox environment. No production systems were used.


메타데이터
post_id
f29b5e61dfc4
slug
deep-dive-into-moka-analyzing-a-babylon-rat-based-information-stealer-and-keylogger-f29b5e61dfc4
url
https://medium.com/@ayush.pathania0107/deep-dive-into-moka-analyzing-a-babylon-rat-based-information-stealer-and-keylogger-f29b5e61dfc4
canonical_url
https://medium.com/@ayush.pathania0107/deep-dive-into-moka-analyzing-a-babylon-rat-based-information-stealer-and-keylogger-f29b5e61dfc4
author_url
https://medium.com/@ayush.pathania0107
status
ok
fetched_at
2026-07-29 20:10:56