Back to Intelligence

Russian APT Group UAC-0050 Expands Targeting: European Financial Institutions Under RMS Malware Attack

SA
Security Arsenal Team
March 3, 2026
12 min read

Russian APT Group UAC-0050 Expands Targeting: European Financial Institutions Under RMS Malware Attack

Introduction

In a concerning development for cybersecurity professionals in the financial sector, a Russia-aligned threat actor known as UAC-0050 has launched sophisticated attacks against European financial institutions. This expansion of targeting beyond Ukraine signals a significant escalation in cyber threat activities against entities supporting the war-torn nation. The attack employs sophisticated social engineering tactics combined with RMS (Remote Monitoring and Management) malware, highlighting how threat actors increasingly repurpose legitimate administrative tools for malicious purposes.

Analysis: Deep-Dive Into UAC-0050's Tactics

Targeting Strategy and Motivation

UAC-0050's pivot toward European financial institutions represents a calculated expansion beyond their traditional Ukrainian targets. This strategic shift likely serves dual objectives: intelligence gathering on financial flows supporting Ukraine and potential direct financial theft. Financial institutions that facilitate transactions to Ukrainian entities are particularly vulnerable, as they represent critical infrastructure nodes in the broader geopolitical conflict.

Attack Vector Breakdown

The primary attack vector employed by UAC-0050 involves sophisticated domain spoofing techniques designed to establish trust before delivering the malicious payload. The threat actor creates near-identical domains to legitimate financial entities, leveraging social engineering to deceive employees into clicking malicious links or downloading infected documents.

RMS Malware: The Weapon of Choice

Remote Monitoring and Management (RMS) tools represent a particularly insidious threat when weaponized by threat actors like UAC-0050. These legitimate administrative tools, often used by IT departments for system management, provide attackers with powerful capabilities once compromised:

  • Remote command execution
  • File transfer and manipulation
  • Credential harvesting
  • Lateral movement capabilities
  • Persistence mechanisms

What makes RMS malware especially dangerous is its ability to blend in with normal administrative traffic, making detection challenging for traditional security controls.

Technical TTPs Observed

Based on recent intelligence, UAC-0050 employs the following technical tactics, techniques, and procedures:

  1. Initial Access: Spear-phishing with spoofed domains masquerading as legitimate financial entities
  2. Execution: PowerShell scripts to deliver RMS malware payload
  3. Persistence: Registry run keys and scheduled tasks
  4. Defense Evasion: Living-off-the-land binaries (LOLBins) and process hollowing
  5. Credential Access: Mimikatz and similar credential dumping tools
  6. Discovery: Network enumeration commands to map the target infrastructure

Detection and Threat Hunting

To effectively detect UAC-0050 activity and RMS malware threats, security teams should implement the following detection mechanisms across their environments:

KQL Queries for Microsoft Sentinel/Defender

The following KQL queries can help identify potential UAC-0050 activity in your Microsoft Sentinel or Defender environment:

Script / Code
// Detect suspicious PowerShell script block logging related to RMS malware
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where ProcessCommandLine has_any ("DownloadString", "IEX", "Invoke-Expression")
| where ProcessCommandLine has_any ("rms", "remote monitoring", "management")
| extend CustomEntity = AccountName, HostCustomEntity = DeviceName, IPCustomEntity = InitiatingProcessAccountObjectId
| project Timestamp, DeviceName, FileName, ProcessCommandLine, AccountName, InitiatingProcessAccountName
| sort by Timestamp desc


// Detect domain spoofing attempts related to financial services
let financial_domains = dynamic(["bank", "creditunion", "financial", "finance", "lending", "investment"]);
let suspicious_tlds = dynamic([".xyz", ".top", ".tk", ".ml", ".cf", ".ga"]);
DeviceNetworkEvents
| where Timestamp > ago(14d)
| where RemoteUrl has_any (financial_domains)
| where RemoteUrl has_any (suspicious_tlds)
| extend IsNewUrl = iif(RemoteUrl in (DeviceNetworkEvents 
    | where Timestamp > ago(90d) 
    | distinct RemoteUrl), false, true)
| where IsNewUrl == true
| project Timestamp, DeviceName, RemoteUrl, RemotePort, InitiatingProcessFileName, InitiatingProcessAccountName
| sort by Timestamp desc


// Detect potential RMS malware network connections
let rms_ports = dynamic([8888, 9999, 4444, 34567]);
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where RemotePort in (rms_ports) or LocalPort in (rms_ports)
| where InitiatingProcessFileName !in~ ("TeamViewer.exe", "AnyDesk.exe", "Splashtop.exe", "ConnectWiseControl.exe")
| project Timestamp, DeviceName, RemoteUrl, RemotePort, LocalPort, InitiatingProcessFileName, InitiatingProcessAccountName
| sort by Timestamp desc

PowerShell Detection Scripts

The following PowerShell scripts can be deployed to detect potential RMS malware infections:

Script / Code
# Check for suspicious registry persistence mechanisms
function Test-MalwarePersistence {
    param(
        [string[]]$ComputerName = $env:COMPUTERNAME
    )
    
    $results = @()
    $suspiciousPaths = @(
        "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
        "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",
        "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
        "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
    )
    
    foreach ($computer in $ComputerName) {
        foreach ($path in $suspiciousPaths) {
            try {
                $properties = Get-ItemProperty -Path "Registry::$path" -ErrorAction SilentlyContinue
                foreach ($prop in $properties.PSObject.Properties) {
                    if ($prop.Name -notin @("PSPath", "PSParentPath", "PSChildName", "PSDrive", "PSProvider")) {
                        $propValue = $prop.Value
                        if ($propValue -match 'powershell.*-encodedcommand' -or $propValue -match 'rms|remote\s+monitoring') {
                            $results += [PSCustomObject]@{
                                ComputerName = $computer
                                RegistryPath = $path
                                PropertyName = $prop.Name
                                PropertyValue = $propValue
                                DetectionTime = Get-Date
                            }
                        }
                    }
                }
            }
            catch {
                Write-Verbose "Could not access registry path: $path on $computer"
            }
        }
    }
    
    return $results
}

# Run the function
Test-MalwarePersistence | Format-Table -AutoSize


# Check for unusual scheduled tasks that may indicate malware persistence
function Get-SuspiciousScheduledTasks {
    $suspiciousTasks = @()
    
    # Get all scheduled tasks
    $tasks = Get-ScheduledTask -TaskPath '\' | Where-Object {$_.TaskName -ne 'Task Scheduler'}
    
    foreach ($task in $tasks) {
        $taskInfo = $task | Get-ScheduledTaskInfo
        $taskAction = $task.Actions.Execute
        $taskArguments = $task.Actions.Arguments
        
        # Check for suspicious patterns
        if ($taskAction -match 'powershell' -and $taskArguments -match '-encodedcommand|-encoded|-e') {
            $suspiciousTasks += [PSCustomObject]@{
                TaskName = $task.TaskName
                TaskPath = $task.TaskPath
                Execute = $taskAction
                Arguments = $taskArguments
                LastRunTime = $taskInfo.LastRunTime
                NextRunTime = $taskInfo.NextRunTime
                State = $task.State
            }
        }
        
        # Check for suspicious tasks running from temp directories
        if ($taskAction -match 'C:\\Windows\\Temp|C:\\Users\\.*\\AppData\\Local\\Temp') {
            $suspiciousTasks += [PSCustomObject]@{
                TaskName = $task.TaskName
                TaskPath = $task.TaskPath
                Execute = $taskAction
                Arguments = $taskArguments
                LastRunTime = $taskInfo.LastRunTime
                NextRunTime = $taskInfo.NextRunTime
                State = $task.State
            }
        }
    }
    
    return $suspiciousTasks
}

# Run the function and output results
Get-SuspiciousScheduledTasks | Format-Table -AutoSize

Python Detection Scripts

Script / Code
#!/usr/bin/env python3
"""
Script to detect suspicious network connections related to RMS malware
Can be run as part of a regular threat hunting process
"""

import subprocess
import re
import 
import socket
from datetime import datetime

def get_network_connections():
    """Retrieve current network connections using netstat"""
    try:
        # Run netstat command to get established connections
        result = subprocess.run(['netstat', '-ano'], capture_output=True, text=True)
        connections = result.stdout
        return connections
    except Exception as e:
        print(f"Error getting network connections: {e}")
        return ""

def parse_netstat_output(netstat_output):
    """Parse netstat output to extract connection details"""
    connections = []
    lines = netstat_output.split('\n')
    
    # Common RMS/remote administration ports to monitor
    suspicious_ports = [8888, 9999, 4444, 34567, 5900, 5901, 8080, 8443, 3389]
    
    for line in lines:
        # Parse established TCP connections
        if 'ESTABLISHED' in line:
            parts = re.split(r'\s+', line.strip())
            if len(parts) >= 5:
                proto = parts[0]
                local_address = parts[1]
                foreign_address = parts[2]
                state = parts[3]
                pid = parts[4]
                
                # Extract port from local address
                try:
                    local_port = int(local_address.split(':')[-1])
                except (ValueError, IndexError):
                    continue
                    
                # Extract port from foreign address
                try:
                    foreign_ip, foreign_port = foreign_address.rsplit(':', 1)
                    foreign_port = int(foreign_port)
                except (ValueError, IndexError):
                    continue
                
                # Check for suspicious ports
                if local_port in suspicious_ports or foreign_port in suspicious_ports:
                    connections.append({
                        'timestamp': datetime.now().isoformat(),
                        'protocol': proto,
                        'local_address': local_address,
                        'foreign_address': foreign_address,
                        'state': state,
                        'pid': pid,
                        'suspicious_reason': f"Suspicious port: {local_port if local_port in suspicious_ports else foreign_port}"
                    })
    
    return connections

def get_process_info(pid):
    """Get process information for a given PID"""
    try:
        result = subprocess.run(['tasklist', '/FI', f'PID eq {pid}', '/FO', 'CSV'], capture_output=True, text=True)
        process_info = result.stdout
        return process_info
    except Exception as e:
        print(f"Error getting process info for PID {pid}: {e}")
        return ""

def main():
    print("[*] Starting RMS Malware Network Connection Detection...")
    print("[*] Gathering network connections...")
    
    # Get network connections
    netstat_output = get_network_connections()
    
    # Parse and analyze connections
    suspicious_connections = parse_netstat_output(netstat_output)
    
    if suspicious_connections:
        print(f"\n[!] Found {len(suspicious_connections)} suspicious connection(s):")
        for conn in suspicious_connections:
            print(f"  - {conn['local_address']} <-> {conn['foreign_address']}")
            print(f"    PID: {conn['pid']}")
            print(f"    Reason: {conn['suspicious_reason']}")
            
            # Get additional process information
            process_info = get_process_info(conn['pid'])
            print(f"    Process: {process_info}")
            print()
    else:
        print("[+] No suspicious network connections detected.")
    
    # Save results to JSON
    with open('rms_malware_detection.', 'w') as f:
        .dump({
            'scan_time': datetime.now().isoformat(),
            'suspicious_connections': suspicious_connections
        }, f, indent=2)
    
    print("[*] Results saved to rms_malware_detection.")

if __name__ == "__main__":
    main()

Mitigation Strategies

To protect against UAC-0050 and similar RMS malware attacks, financial institutions should implement the following security measures:

1. Email Security Enhancements

  • Implement DMARC, DKIM, and SPF authentication protocols to prevent domain spoofing
  • Deploy advanced email filtering with sandboxing capabilities to detect malicious attachments
  • Train employees on identifying sophisticated phishing attempts, particularly those targeting financial operations
Script / Code
# Example PowerShell script to configure SPF/DKIM/DKIM for Office 365
# Connect to Exchange Online first
# Connect-ExchangeOnline

# Get domains in the tenant
$domains = Get-AcceptedDomain

foreach ($domain in $domains) {
    Write-Host "Checking email authentication for $($domain.DomainName)"
    
    # Check SPF record
    $spfRecord = Resolve-DnsName -Name $domain.DomainName -Type TXT -ErrorAction SilentlyContinue | 
                 Where-Object {$_.Strings -like "*v=spf1*"}
    
    if ($spfRecord) {
        Write-Host "  SPF record found: $($spfRecord.Strings)" -ForegroundColor Green
    } else {
        Write-Host "  SPF record NOT found - Action required" -ForegroundColor Yellow
    }
    
    # Check DMARC record
    $dmarcRecord = Resolve-DnsName -Name "_dmarc.$($domain.DomainName)" -Type TXT -ErrorAction SilentlyContinue | 
                   Where-Object {$_.Strings -like "*v=DMARC1*"}
    
    if ($dmarcRecord) {
        Write-Host "  DMARC record found: $($dmarcRecord.Strings)" -ForegroundColor Green
    } else {
        Write-Host "  DMARC record NOT found - Action required" -ForegroundColor Yellow
    }
}

2. Endpoint Detection and Response (EDR) Optimization

  • Deploy behavioral-based EDR solutions capable of detecting suspicious RMS tool usage
  • Implement application control to whitelist only authorized remote administration tools
  • Monitor for unusual PowerShell activity and encoded commands
Script / Code
# Create a PowerShell script block logging policy
function Enable-AdvancedScriptBlockLogging {
    <#
    .SYNOPSIS
    Enables advanced PowerShell script block logging to detect malicious scripts
    #>
    
    # Set the registry keys for script block logging
    $registryPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
    
    if (-not (Test-Path $registryPath)) {
        New-Item -Path $registryPath -Force | Out-Null
    }
    
    Set-ItemProperty -Path $registryPath -Name "EnableScriptBlockLogging" -Value 1 -Force
    Set-ItemProperty -Path $registryPath -Name "EnableScriptBlockInvocationLogging" -Value 1 -Force
    
    # Enable module logging
    $moduleLoggingPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging"
    
    if (-not (Test-Path $moduleLoggingPath)) {
        New-Item -Path $moduleLoggingPath -Force | Out-Null
    }
    
    Set-ItemProperty -Path $moduleLoggingPath -Name "EnableModuleLogging" -Value 1 -Force
    Set-ItemProperty -Path $moduleLoggingPath -Name "ModuleNames" -Value "*" -Force
    
    # Enable transcription
    $transcriptionPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription"
    
    if (-not (Test-Path $transcriptionPath)) {
        New-Item -Path $transcriptionPath -Force | Out-Null
    }
    
    $logDirectory = "C:\ProgramData\PowerShellLogs"
    if (-not (Test-Path $logDirectory)) {
        New-Item -Path $logDirectory -ItemType Directory -Force | Out-Null
    }
    
    Set-ItemProperty -Path $transcriptionPath -Name "EnableTranscripting" -Value 1 -Force
    Set-ItemProperty -Path $transcriptionPath -Name "EnableInvocationHeader" -Value 1 -Force
    Set-ItemProperty -Path $transcriptionPath -Name "OutputDirectory" -Value $logDirectory -Force
    
    Write-Host "Advanced PowerShell logging has been enabled." -ForegroundColor Green
}

# Run the function to enable advanced logging
Enable-AdvancedScriptBlockLogging

3. Network Segmentation and Access Controls

  • Implement strict network segmentation to limit lateral movement
  • Restrict outbound connections to only necessary services and ports
  • Deploy next-generation firewalls with application inspection capabilities
Script / Code
# Example iptables rules to restrict RMS tool communications
# These should be customized for your environment

# Create a custom chain for RMS tool filtering
iptables -N RMS_FILTER

# Block common RMS ports from untrusted networks
iptables -A RMS_FILTER -p tcp --dport 8888 -j DROP
iptables -A RMS_FILTER -p tcp --dport 9999 -j DROP
iptables -A RMS_FILTER -p tcp --dport 4444 -j DROP
iptables -A RMS_FILTER -p tcp --dport 34567 -j DROP

# Allow RMS ports only from approved management stations
# Replace MANAGEMENT_IPS with your actual management IP addresses
for IP in MANAGEMENT_IPS; do
    iptables -A INPUT -p tcp --dport 8888 -s $IP -j ACCEPT
    iptables -A INPUT -p tcp --dport 9999 -s $IP -j ACCEPT
    iptables -A INPUT -p tcp --dport 4444 -s $IP -j ACCEPT
    iptables -A INPUT -p tcp --dport 34567 -s $IP -j ACCEPT
done

# Apply the filter chain to the INPUT chain
iptables -A INPUT -j RMS_FILTER

# Log dropped packets
iptables -A RMS_FILTER -j LOG --log-prefix "RMS_FILTER_DROP: "

# Save the rules
iptables-save > /etc/iptables/rules.v4

4. Identity and Access Management

  • Implement multi-factor authentication for all privileged accounts
  • Apply the principle of least privilege to remote administration tools
  • Regularly audit and review account access permissions
Script / Code
# Script to audit privileged accounts in Active Directory
function Test-PrivilegedAccountSecurity {
    <#
    .SYNOPSIS
    Audits privileged accounts for security compliance
    #>
    
    $results = @()
    
    # Get Domain Admins group members
    $domainAdmins = Get-ADGroupMember -Identity "Domain Admins" -Recursive
    
    foreach ($admin in $domainAdmins) {
        $user = Get-ADUser -Identity $admin.SID -Properties LastLogonDate, PasswordLastSet, Enabled, SmartcardLogonRequired
        
        # Check for MFA enrollment (this will depend on your MFA solution)
        $mfaEnabled = $false  # This should be replaced with actual MFA check logic
        
        $results += [PSCustomObject]@{
            Username = $user.SamAccountName
            AccountEnabled = $user.Enabled
            LastLogon = $user.LastLogonDate
            PasswordLastSet = $user.PasswordLastSet
            SmartCardRequired = $user.SmartcardLogonRequired
            MFAEnabled = $mfaEnabled
            SecurityIssue = -not ($user.SmartcardLogonRequired -or $mfaEnabled)
        }
    }
    
    # Get Enterprise Admins group members if applicable
    $enterpriseAdmins = Get-ADGroupMember -Identity "Enterprise Admins" -Recursive -ErrorAction SilentlyContinue
    
    if ($enterpriseAdmins) {
        foreach ($admin in $enterpriseAdmins) {
            $user = Get-ADUser -Identity $admin.SID -Properties LastLogonDate, PasswordLastSet, Enabled, SmartcardLogonRequired
            
            # Check for MFA enrollment
            $mfaEnabled = $false  # This should be replaced with actual MFA check logic
            
            $results += [PSCustomObject]@{
                Username = $user.SamAccountName
                Group = "Enterprise Admins"
                AccountEnabled = $user.Enabled
                LastLogon = $user.LastLogonDate
                PasswordLastSet = $user.PasswordLastSet
                SmartCardRequired = $user.SmartcardLogonRequired
                MFAEnabled = $mfaEnabled
                SecurityIssue = -not ($user.SmartcardLogonRequired -or $mfaEnabled)
            }
        }
    }
    
    return $results
}

# Run the audit and output results
$privilegeAudit = Test-PrivilegedAccountSecurity
$privilegeAudit | Format-Table -AutoSize

# Export to CSV for further analysis
$privilegeAudit | Export-Csv -Path "PrivilegedAccountAudit.csv" -NoTypeInformation

5. Incident Response Preparation

  • Develop and regularly test incident response playbooks specifically for RMS malware threats
  • Establish threat hunting procedures to detect potential UAC-0050 activity
  • Create communication channels with relevant information sharing and analysis centers (ISACs)

Executive Takeaways

  1. Geographic Expansion: The targeting of European financial institutions by UAC-0050 represents a significant escalation beyond their traditional Ukrainian targets, suggesting a broader strategic objective.

  2. Legitimate Tool Abuse: The weaponization of legitimate RMS tools demonstrates the ongoing trend of "living-off-the-land" tactics used by sophisticated threat actors to evade detection.

  3. Sector-Specific Threats: Financial institutions supporting Ukraine face elevated risk levels and should implement enhanced security measures accordingly.

  4. Proactive Detection: Traditional signature-based defenses are insufficient against these sophisticated threats; organizations must adopt behavioral-based detection and proactive threat hunting.

  5. Cross-Functional Defense: Effective protection requires coordinated efforts across email security, endpoint protection, network security, and identity management domains.

Financial institutions should review their current security posture against the recommendations provided and consider engaging with specialized security services to enhance their defense capabilities against sophisticated nation-state threats like UAC-0050.

Related Resources

Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub

socmdrmanaged-socdetectionapt-groupfinancial-securityuac-0050malware-detection

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.