Back to Intelligence

ZDI-26-971: Signal for Windows Remote Code Execution — Detection, Hunting, and Mitigation Guide

SA
Security Arsenal Team
November 13, 2026
12 min read

The Zero Day Initiative (ZDI) has published ZDI-26-971, disclosing an insufficient UI warning vulnerability in Signal for Windows that enables remote attackers to execute arbitrary code on affected installations. Rated CVSS 7.5, this vulnerability is particularly dangerous for organizations whose employees rely on Signal for sensitive or out-of-band communications.

What makes this flaw operationally significant is the minimal user interaction required — the target simply needs to accept a malicious attachment delivered through Signal. Once accepted, the insufficient UI warning fails to alert the user to the danger, allowing attacker-controlled code to execute within the context of the Signal Desktop process.

For SOC teams, CISOs, and endpoint engineers, this is a high-priority, high-impact client-side threat that demands immediate detection coverage, hunting, and compensating controls until a patch is deployed across the fleet.


Technical Analysis

Affected Product & Platform

  • Product: Signal for Windows (Signal Desktop)
  • Platform: Microsoft Windows (all supported versions running vulnerable Signal Desktop builds)
  • Advisory ID: ZDI-26-971
  • CVE Identifier: Not yet assigned at time of writing — track ZDI advisory for updates
  • CVSS v3.x Score: 7.5 (High) — likely vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Vulnerability Breakdown

ZDI-26-971 is classified as an Insufficient UI Warning vulnerability, a client-side flaw rooted in how Signal for Windows handles and presents file attachments to users. From a defender's perspective, the attack chain is:

  1. Delivery: Attacker sends a crafted message with a malicious attachment to a target via Signal (no authentication required beyond being able to message the victim).
  2. User Interaction: Victim accepts/downloads the attachment. Signal's UI fails to render a sufficient security warning (e.g., missing file-type warning, incorrect icon, or suppressed execution prompt).
  3. Execution: The malicious payload — likely an executable, script, or exploit-laden document — is launched or executed in the context of the Signal process or via shell integration.
  4. Code Execution: Attacker gains arbitrary code execution with the privileges of the logged-in user, enabling follow-on actions: credential theft, lateral movement, persistence, and C2.

This class of vulnerability is particularly insidious because it bypasses user trust assumptions — users believe Signal's UI will warn them before executing dangerous content, and this flaw breaks that contract.

Exploitation Status

  • In-the-Wild Exploitation: Not publicly confirmed at time of disclosure.
  • Public PoC: ZDI typically does not release PoCs until after patch availability, but the technical details in ZDI-26-971 lower the bar for threat actors to develop their own.
  • CISA KEV Status: Not currently listed, but monitor closely — client-side RCEs in widely-used secure messaging apps are prime candidates for KEV inclusion once exploitation begins.
  • Threat Actor Interest: Secure messaging platforms are high-value targets for nation-state actors, spyware vendors, and cybercriminals. Expect rapid weaponization, especially given the low interaction requirement.

Detection & Response

This is a technical client-side RCE threat — full detection engineering coverage is required. The following rules and queries focus on the most reliable observable behaviors: Signal Desktop spawning unexpected child processes, execution of files from Signal's attachment directories, and network connections from non-Signal processes initiated after Signal activity.

SIGMA Rules

YAML
---
title: Signal Desktop Spawning Suspicious Child Process
id: 8f3a2b1c-4d5e-4f6a-9b8c-7d2e1f3a4b5c
status: experimental
description: Detects Signal Desktop (Signal.exe) spawning unexpected child processes such as cmd.exe, powershell.exe, wscript.exe, or rundll32.exe — a strong indicator of successful exploitation of ZDI-26-971 or attachment-based code execution.
references:
  - http://www.zerodayinitiative.com/advisories/ZDI-26-971/
  - https://attack.mitre.org/techniques/T1204/002/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.execution
  - attack.t1204.002
  - attack.initial_access
  - attack.t1566.001
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith: '\Signal.exe'
  selection_child:
    Image|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\mshta.exe'
      - '\rundll32.exe'
      - '\regsvr32.exe'
      - '\certutil.exe'
      - '\bitsadmin.exe'
      - '\wmic.exe'
      - '\schtasks.exe'
      - '\msiexec.exe'
  condition: selection_parent and selection_child
falsepositives:
  - Signal updates or plugin execution (rare — validate with software inventory)
  - Enterprise software deployment tools running in user context
level: high
---
title: Execution from Signal Attachments Directory
id: 2b4c6d8e-1f3a-4b5c-9d7e-6a8f2b4c6d8e
status: experimental
description: Detects process execution from Signal Desktop's default attachments/download directories. Attackers exploiting ZDI-26-971 will likely drop and execute payloads from these paths after the victim accepts a malicious attachment.
references:
  - http://www.zerodayinitiative.com/advisories/ZDI-26-971/
  - https://attack.mitre.org/techniques/T1204/002/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.execution
  - attack.t1204.002
  - attack.defense_evasion
  - attack.t1036
logsource:
  category: process_creation
  product: windows
detection:
  selection_paths:
    Image|contains:
      - '\AppData\Roaming\Signal\attachments\'
      - '\AppData\Roaming\Signal\downloads\'
      - '\Downloads\Signal\'
  selection_ext:
    Image|endswith:
      - '.exe'
      - '.dll'
      - '.bat'
      - '.cmd'
      - '.ps1'
      - '.vbs'
      - '.js'
      - '.hta'
      - '.scr'
      - '.msi'
  condition: selection_paths and selection_ext
falsepositives:
  - Legitimate user-saved files executed intentionally (tune with file hash reputation and user baseline)
level: high
---
title: Signal Desktop Process Making Unusual Network Connections
id: 5e7f9a1b-3c5d-4e6f-8a9b-2c4d6e8f1a3b
status: experimental
description: Detects Signal.exe establishing network connections to non-Signal infrastructure or unusual ports, potentially indicating post-exploitation C2 activity following successful ZDI-26-971 exploitation.
references:
  - http://www.zerodayinitiative.com/advisories/ZDI-26-971/
  - https://attack.mitre.org/techniques/T1071/001/
author: Security Arsenal
date: 2026/04/06
tags:
  - attack.command_and_control
  - attack.t1071.001
  - attack.exfiltration
  - attack.t1041
logsource:
  category: network_connection
  product: windows
detection:
  selection_image:
    Image|endswith: '\Signal.exe'
  selection_ports:
    DestinationPort:
      - 4444
      - 5555
      - 6666
      - 7777
      - 8888
      - 9999
      - 1337
      - 31337
  filter_signal_domains:
    DestinationHostname|contains:
      - 'signal.org'
      - 'whispersystems.org'
      - 'signalusers.org'
  condition: selection_image and selection_ports and not filter_signal_domains
falsepositives:
  - Signal beta builds or development environments connecting to test infrastructure
  - Corporate proxies intercepting Signal traffic (validate DestinationHostname is not proxy)
level: medium

KQL (Microsoft Sentinel / Defender)

The following KQL query hunts for suspicious process execution chains originating from Signal Desktop, correlating process creation events with network activity to identify potential ZDI-26-971 exploitation and post-compromise behavior.

KQL — Microsoft Sentinel / Defender
// Hunt for Signal.exe spawning suspicious child processes — potential ZDI-26-971 exploitation
let SuspiciousChildren = dynamic([
    "cmd.exe", "powershell.exe", "pwsh.exe", "wscript.exe", "cscript.exe",
    "mshta.exe", "rundll32.exe", "regsvr32.exe", "certutil.exe", "bitsadmin.exe",
    "wmic.exe", "schtasks.exe", "msiexec.exe", "whoami.exe", "net.exe", "nltest.exe"
]);
let SignalPaths = dynamic([
    @"\AppData\Roaming\Signal\attachments\",
    @"\AppData\Roaming\Signal\downloads\",
    @"\Downloads\Signal\"
]);
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName =~ "Signal.exe"
| where FileName in~ (SuspiciousChildren)
    or ProcessCommandLine has_any (SignalPaths)
| extend Suspicious = true
| join kind=leftouter (
    DeviceNetworkEvents
    | where TimeGenerated > ago(7d)
    | where InitiatingProcessFileName =~ "Signal.exe"
    | where RemotePort in (4444, 5555, 6666, 7777, 8888, 9999, 1337, 31337)
    | where not(RemoteUrl has_any ("signal.org", "whispersystems.org"))
    | summarize NetworkHits = make_set(strcat(RemoteIP, ":", RemotePort)) by DeviceId, InitiatingProcessId
) on DeviceId, $left.ProcessId == $right.InitiatingProcessId
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          ProcessId, NetworkHits, SHA256, FolderPath
| extend Severity = case(
    NetworkHits != "", "Critical — Signal spawned shell + suspicious network",
    ProcessCommandLine has_any (SignalPaths), "High — Execution from Signal attachment dir",
    "High — Signal spawned suspicious child"
)
| order by TimeGenerated desc

Velociraptor VQL

Use this VQL artifact to hunt across your Windows fleet for evidence of ZDI-26-971 exploitation — specifically Signal process trees, execution from attachment directories, and anomalous network activity.

VQL — Velociraptor
-- Hunt: Signal Desktop Exploitation Artifacts (ZDI-26-971)
-- Author: Security Arsenal DFIR
-- Purpose: Identify Signal.exe spawning suspicious children, files in attachment dirs, and anomalous network connections

LET SignalProcesses =
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE Name =~ 'Signal.exe'
   OR Exe =~ 'Signal\\Signal.exe'

LET SuspiciousChildren =
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime,
       SignalPid = SignalProcesses.Pid,
       SignalUser = SignalProcesses.Username
FROM pslist()
JOIN SignalProcesses ON pslist.Ppid = SignalProcesses.Pid
WHERE Name =~ '(cmd|powershell|pwsh|wscript|cscript|mshta|rundll32|regsvr32|certutil|bitsadmin|wmic|schtasks|msiexec)\.exe$'

LET AttachmentArtifacts =
SELECT FullPath, Size, Mtime, Ctime, IsDir
FROM glob(globs='C:/Users/*/AppData/Roaming/Signal/attachments/**/*')
WHERE NOT IsDir
  AND FullPath =~ '\.(exe|dll|bat|cmd|ps1|vbs|js|hta|scr|msi)$'
  AND Mtime > now() - 604800  // Last 7 days

LET NetworkAnomalies =
SELECT Pid, Name, LocalAddr, LocalPort, RemoteAddr, RemotePort, Status
FROM netstat()
WHERE Name =~ 'Signal.exe'
  AND RemotePort IN (4444, 5555, 6666, 7777, 8888, 9999, 1337, 31337)
  AND NOT RemoteAddr =~ '^(127\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)'

SELECT
    'SuspiciousChild' AS FindingType,
    SuspiciousChildren.Pid AS Pid,
    SuspiciousChildren.Name AS ProcessName,
    SuspiciousChildren.Exe AS Executable,
    SuspiciousChildren.CommandLine AS CommandLine,
    SuspiciousChildren.Username AS Username,
    SuspiciousChildren.CreateTime AS EventTime
FROM SuspiciousChildren

UNION ALL

SELECT
    'AttachmentArtifact' AS FindingType,
    NULL AS Pid,
    FullPath AS ProcessName,
    NULL AS Executable,
    NULL AS CommandLine,
    NULL AS Username,
    Mtime AS EventTime
FROM AttachmentArtifacts

UNION ALL

SELECT
    'NetworkAnomaly' AS FindingType,
    Pid,
    Name AS ProcessName,
    NULL AS Executable,
    strcat(LocalAddr, ':', LocalPort, ' -> ', RemoteAddr, ':', RemotePort) AS CommandLine,
    NULL AS Username,
    NULL AS EventTime
FROM NetworkAnomalies

ORDER BY EventTime DESC

Remediation Script (PowerShell)

Deploy this PowerShell script via your EDR, SCCM, or GPO to audit Signal versions, enforce update compliance, and apply compensating controls until the vendor patch is fully deployed.

PowerShell
#Requires -RunAsAdministrator
# ZDI-26-971 Signal for Windows RCE — Audit & Hardening Script
# Security Arsenal — vulnerability-management

$ErrorActionPreference = 'Continue'
$LogPath = "$env:ProgramData\SecurityArsenal\ZDI-26-971_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
New-Item -ItemType Directory -Path (Split-Path $LogPath) -Force | Out-Null

function Write-Log {
    param([string]$Message, [string]$Level = 'INFO')
    $Entry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [$Level] $Message"
    Add-Content -Path $LogPath -Value $Entry
    Write-Host $Entry
}

Write-Log "=== ZDI-26-971 Signal RCE Audit & Hardening ==="

# 1. Detect installed Signal versions
$SignalPaths = @(
    "$env:LOCALAPPDATA\Programs\signal-desktop\Signal.exe",
    "$env:ProgramFiles\Signal\Signal.exe",
    "$env:ProgramFiles(x86)\Signal\Signal.exe"
)

$SignalFound = $false
foreach ($Path in $SignalPaths) {
    if (Test-Path $Path) {
        $SignalFound = $true
        $Version = (Get-Item $Path).VersionInfo.ProductVersion
        Write-Log "Signal found: $Path | Version: $Version"
        # TODO: Update with patched version once Signal releases fix
        # if ([version]$Version -lt [version]'X.Y.Z') { Write-Log "VULNERABLE" 'WARN' }
    }
}
if (-not $SignalFound) { Write-Log "Signal Desktop not detected on this host." }

# 2. Audit recent execution from Signal attachment directories
$SignalDirs = @(
    "$env:APPDATA\Signal\attachments",
    "$env:APPDATA\Signal\downloads",
    "$env:USERPROFILE\Downloads\Signal"
)

foreach ($Dir in $SignalDirs) {
    if (Test-Path $Dir) {
        $RecentFiles = Get-ChildItem -Path $Dir -Recurse -File -ErrorAction SilentlyContinue |
            Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-14) } |
            Where-Object { $_.Extension -match '\.(exe|dll|bat|cmd|ps1|vbs|js|hta|scr|msi)$' }
        if ($RecentFiles) {
            Write-Log "Potentially malicious files in $Dir :" 'WARN'
            $RecentFiles | ForEach-Object { Write-Log "  - $($_.FullName) | $($_.LastWriteTime)" 'WARN' }
        }
    }
}

# 3. Check for suspicious Signal child processes (last 24h)
$SuspiciousProcs = Get-CimInstance Win32_Process |
    Where-Object { $_.ParentProcessId -in (Get-CimInstance Win32_Process |
        Where-Object { $_.Name -eq 'Signal.exe' }).ProcessId } |
    Where-Object { $_.Name -match 'cmd|powershell|wscript|mshta|rundll32|regsvr32|certutil|bitsadmin|wmic|schtasks' }

if ($SuspiciousProcs) {
    Write-Log "ALERT: Signal.exe has suspicious child processes running NOW:" 'CRITICAL'
    $SuspiciousProcs | ForEach-Object { Write-Log "  - $($_.Name) | PID: $($_.ProcessId) | $($_.CommandLine)" 'CRITICAL' }
}

# 4. Apply Attack Surface Reduction (ASR) rule to block Office child processes (compensating control)
# Note: Enable only if Signal is used in a managed enterprise context where users do not need to open attachments directly
Write-Log "Applying Windows Defender ASR rules as compensating controls..."
$ASRRules = @(
    @{ Id = 'D4F940AB-401B-4EFC-AADC-AD5F3C50688A'; Name = 'Block all Office applications from creating child processes' },
    @{ Id = '26190899-1602-49E8-8B27-EB1D0A1CE869'; Name = 'Block Office communication applications from creating child processes' },
    @{ Id = '3B576869-A4EC-4529-8536-B80A7769E899'; Name = 'Block Office applications from creating executable content' },
    @{ Id = '7674BA52-37EB-4A4F-A9A1-F0F9A1619A2C'; Name = 'Block Adobe Reader from creating child processes' }
)

foreach ($Rule in $ASRRules) {
    try {
        Set-MpPreference -AttackSurfaceReductionRules_Ids $Rule.Id -AttackSurfaceReductionRules_Actions Enabled
        Write-Log "Enabled ASR: $($Rule.Name)"
    } catch {
        Write-Log "Failed to enable ASR $($Rule.Id): $_" 'ERROR'
    }
}

# 5. Enforce SmartScreen for downloaded files (additional UI warning layer)
Write-Log "Configuring Windows SmartScreen and Mark-of-the-Web (MotW) enforcement..."
Set-MpPreference -EnableSmartScreen $true
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System' -Name 'EnableSmartScreen' -Value 1 -Force
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System' -Name 'ShellSmartScreenLevel' -Value 'Block' -Force

# 6. Block execution from Signal attachment directories via AppLocker (if AppLocker is deployed)
$AppLockerTest = Get-AppLockerPolicy -Effective -ErrorAction SilentlyContinue
if ($AppLockerTest) {
    Write-Log "AppLocker detected. Recommend adding deny rules for:"
    Write-Log "  - %APPDATA%\Signal\attachments\*\*.exe"
    Write-Log "  - %APPDATA%\Signal\downloads\*\*.exe"
    Write-Log "  - %USERPROFILE%\Downloads\Signal\*\*.exe"
} else {
    Write-Log "AppLocker not configured. Consider Software Restriction Policies (SRP) or WDAC as alternative."
}

# 7. Force Signal update check (if auto-update disabled)
$SignalUpdateUrl = 'https://updates.signal.org/desktop/latest.yml'
Write-Log "Manual update check: Instruct users to open Signal > Help > Check for Updates"
Write-Log "Or download latest from: https://signal.org/download/"

Write-Log "=== Audit complete. Log saved to $LogPath ==="
Write-Log "Next steps: Deploy vendor patch immediately upon release. Monitor CISA KEV for ZDI-26-971."

Remediation

Immediate Actions

  1. Patch Signal for Windows Immediately

    • Monitor Signal's official releases and ZDI-26-971 for the patched version number.
    • At time of writing, ZDI has not published a fixed version — assume all current Signal for Windows builds are vulnerable until proven otherwise.
    • Enable and verify auto-update in Signal Desktop settings across the enterprise.
  2. Enforce Attachment Handling Policies

    • Until patched, instruct users to never open attachments from unknown or unverified Signal contacts.
    • Deploy AppLocker/WDAC rules to block execution from Signal attachment directories (paths listed in the PowerShell script).
    • Configure email/web gateways to strip or sandbox Signal attachments if Signal is used for business communications.
  3. Apply Compensating Controls

    • Enable Windows Defender ASR rules to block child process creation from Office and communication apps.
    • Enforce SmartScreen and Mark-of-the-Web (MotW) — ensure downloaded files trigger Windows security warnings.
    • Consider running Signal in a sandboxed environment (Windows Sandbox, VM, or isolated VDI) for high-risk users.
  4. Monitor CISA KEV & Threat Intel

    • Add ZDI-26-971 to your vulnerability tracking. Client-side RCEs in secure messengers are high-value targets for nation-state actors and spyware vendors — expect KEV listing if exploitation is confirmed.
    • Subscribe to Signal security advisories and ZDI RSS feeds.
  5. User Awareness

    • Alert users that Signal's UI may not warn them about malicious attachments.
    • Reinforce: "If you didn't request the file, don't open it — even if it appears to come from a known contact (account takeover risk)."

Longer-Term Hardening

  • Application Allowlisting: Move from ASR to full WDAC/AppLocker enforcement on high-risk endpoints.
  • EDR Tuning: Ensure your EDR has visibility into process lineage (Signal.exe → child processes) and can block execution from user-writable directories.
  • Network Segmentation: Restrict Signal endpoints from accessing sensitive internal resources — treat them as high-risk clients.
  • Incident Response Preparedness: Pre-stage IR playbooks for secure messaging client compromise — credential theft, session hijacking, and message exfiltration are likely post-exploitation objectives.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

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