Executive Summary

Today's threat landscape is dominated by a resurgent APT28 offensive deploying a novel modular implant suite (PRISMEX) against NATO-linked logistics and Ukrainian government targets, two actively exploited Ivanti EPMM zero-days now under mass scanning, a 36-package npm supply-chain campaign targeting Strapi CMS ecosystems, and fresh exploitation of Microsoft Patch Tuesday zero-days (SharePoint CVE-2026-32201 and nginx-ui CVE-2026-33032). A ClickFix-style macOS campaign continues to spread Atomic Stealer via abused AppleScript URL scheme.

TierThreats
CriticalAPT28/PRISMEX (nation-state), Ivanti EPMM RCE chain
Highnpm Strapi supply-chain, CVE-2026-33032 nginx-ui, CVE-2026-32201 SharePoint
MediumClickFix macOS Atomic Stealer

Threat 1: APT28 / Pawn Storm — PRISMEX Multi-Stage Campaign

Actor: APT28 (Fancy Bear / Pawn Storm) | Sponsor: Russian GRU
Severity: Critical | Activity Window: Active since September 2025, escalated April 2026

APT28 is conducting a highly targeted offensive against Ukraine's defence supply chain, rail logistics partners in Poland, maritime operators in Romania/Slovenia/Turkey, and NATO-affiliated ammunition logistics across Slovakia and Czech Republic. The campaign delivers a modular implant suite called PRISMEX via spear-phishing lures with hydrometeorology or military-themed content.

The infection chain exploits two vulnerabilities chained together: CVE-2026-21509 (Microsoft Office OLE Shell.Explorer.1 bypass, zero-day exploited ~14 days before patch) and CVE-2026-21513 (MSHTML LNK/IE Frame bypass).

ComponentFunction
PrismexSheetExcel dropper with VBA steganography, initial payload delivery
PrismexDropNative dropper; COM hijacking via adwapi64.dll (CLSID {68DDBB56-9D1D-4FD9-89C5-C0DA2A625392}); persistence via scheduled task "OneDriveHealth"
PrismexLoaderProxy DLL extracting payloads from PNG images using steganography; executes payload in-memory via .NET runtime loading
PrismexStagerCovenant Grunt implant; uses Filen.io cloud storage for C2 to blend with legitimate traffic

IOCs — APT28/PRISMEX

Domains (C2 / Exploit Delivery):
wellnessmedcare[.]org
wellnesscaremed[.]com
freefoodaid[.]com
longsauce[.]com

Persistence Artifacts:
Scheduled Task Name : OneDriveHealth
DLL                 : adwapi64.dll
COM CLSID           : {68DDBB56-9D1D-4FD9-89C5-C0DA2A625392}
Exploit CVEs        : CVE-2026-21509, CVE-2026-21513

Note: C2 abuses Filen.io (legitimate cloud storage) — block or alert on Filen.io connections from non-approved endpoints. WebDAV server domains were registered January 12, 2026.

Threat 2: Ivanti EPMM Zero-Day Chain — CVE-2026-1281 & CVE-2026-1340

Actor: Multiple threat actors (mass exploitation observed)
Severity: Critical | CISA KEV: YES (CVE-2026-1340 added April 9, 2026)

Two chained zero-days in Ivanti Endpoint Manager Mobile (EPMM) allow unauthenticated remote code execution. Exploitation is now widespread and largely automated. The Shadowserver Foundation tracked at least 13 source IPs actively exploiting CVE-2026-1281 in the past 24 hours.

CVETypeCVSSVector
CVE-2026-1281Auth bypassCriticalUnauthenticated HTTP
CVE-2026-1340Code injectionCriticalHTTP GET to /mifs/c/aftstore/fob/

Post-exploitation TTPs include: download and execute /slt second-stage script, deployment of Behinder web shell (default encryption key: 45e329feb5d925b), deployment of Nezha monitoring agent for persistence, and cryptominer installation.

IOCs — Ivanti EPMM

Vulnerable Endpoint Paths:
/mifs/c/aftstore/fob/          (CVE-2026-1340 trigger path)
/mifs/c/aftstore/              (broader enumeration path)

Web Shell Indicator:
Behinder default key : 45e329feb5d925b

Detection in Apache Logs:
Path    : /var/log/httpd/https-access_log
Pattern : HTTP 404 responses to /mifs/c/aftstore/fob/ from external IPs

Threat 3: npm Supply Chain Attack — 36 Malicious Strapi Packages

Actor: Unknown (financially motivated, possibly initial access broker)
Severity: High

Researchers identified 36 malicious npm packages mimicking Strapi CMS plugins, uploaded by four sock-puppet accounts over a 13-hour window on April 3, 2026. The campaign delivered eight distinct payload variants carrying Redis/PostgreSQL RCE, reverse shells, credential harvesting, and persistent C2 implants. All packages followed the naming convention strapi-plugin-*. Dynamic analysis flagged C2 beaconing to a single IP immediately upon install.

IOCs — npm Supply Chain

C2 IP:
144.31.107.231

Malicious npm Account Names:
umarbek1233
kekylf12
tikeqemif26
umar_bektembiev1

Malicious Package Name Pattern:
strapi-plugin-*   (any package matching this pattern from the above accounts)

Threat 4: Microsoft Patch Tuesday Zero-Days — CVE-2026-32201 & CVE-2026-33032

Severity: High (SharePoint) / Critical (nginx-ui)

CVE-2026-32201 — SharePoint Server Spoofing (Zero-Day)

CVE-2026-33032 — nginx-ui Authentication Bypass (Actively Exploited)

Threat 5: ClickFix macOS — Atomic Stealer via AppleScript

Actor: Unknown (financially motivated, MaaS)
Severity: Medium

A ClickFix campaign abuses the applescript:// URL scheme to launch macOS Script Editor with pre-filled malicious code, bypassing Terminal entirely. The payload is a curl | zsh chain delivering Atomic Stealer (AMOS) — a commodity MaaS infostealer targeting Keychain, browser credentials, crypto wallet extensions, autofill data, cookies, and stored credit cards. A second variant ("Matryoshka") uses typosquatted domains as an additional hop to a lightweight shell stage.

IOCs — ClickFix / Atomic Stealer

C2 IP:
83.222.190.214    (ports 22, 80, 3333, 5201)

Domains:
cryptoinfo-news[.]com
odyssey1[.]to
barbermoo[.]xyz

IOC Master Pack

Malicious IPs

83.222.190.214       # ClickFix / Atomic Stealer C2
144.31.107.231       # Malicious npm Strapi C2

Malicious Domains

wellnessmedcare[.]org          # APT28/PRISMEX delivery
wellnesscaremed[.]com          # APT28/PRISMEX delivery
freefoodaid[.]com              # APT28/PRISMEX delivery
longsauce[.]com                # APT28/PRISMEX delivery
cryptoinfo-news[.]com          # ClickFix / Atomic Stealer
odyssey1[.]to                  # ClickFix / Atomic Stealer C2
barbermoo[.]xyz                # ClickFix / Atomic Stealer staging

CVEs (Actively Exploited)

CVE-2026-1281      Ivanti EPMM (unauthenticated RCE) - CISA KEV
CVE-2026-1340      Ivanti EPMM (code injection) - CISA KEV
CVE-2026-21509     Microsoft Office OLE bypass (APT28)
CVE-2026-21513     MSHTML LNK/IE frame bypass (APT28)
CVE-2026-32201     SharePoint Server spoofing (zero-day)
CVE-2026-33032     nginx-ui auth bypass (RCE, CVSS 9.8)
CVE-2026-27944     nginx-ui info leak (chained with above)

KQL Hunting Queries

Platform: Microsoft Sentinel / Microsoft Defender for Endpoint (MDE). Validate table names against your workspace schema. Adjust time ranges as needed.

HQ-01: APT28 PRISMEX — Suspicious Scheduled Task Creation ("OneDriveHealth")

// Hunt for creation of APT28 PRISMEX persistence scheduled task
DeviceProcessEvents
| where Timestamp > ago(24h)
| where ProcessCommandLine has_any ("OneDriveHealth", "schtasks")
    and ProcessCommandLine has "OneDriveHealth"
| project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessCommandLine
| order by Timestamp desc

HQ-02: APT28 PRISMEX — COM Hijack via adwapi64.dll

// Detect loading of PRISMEX COM hijack DLL
DeviceImageLoadEvents
| where Timestamp > ago(24h)
| where FileName =~ "adwapi64.dll"
| project Timestamp, DeviceName, AccountName, FolderPath, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by Timestamp desc

HQ-03: APT28 PRISMEX — Filen.io C2 Beacon Detection

// Detect outbound connections to Filen.io from non-browser, non-approved processes
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteUrl has "filen.io" or RemoteUrl has "filen-io"
| where not(InitiatingProcessFileName in~ ("chrome.exe", "msedge.exe", "firefox.exe", "safari", "brave.exe"))
| project Timestamp, DeviceName, InitiatingProcessFileName, RemoteUrl, RemoteIP, RemotePort
| order by Timestamp desc

HQ-04: APT28 PRISMEX — Known IOC Domain Lookups

// Detect DNS resolution of known PRISMEX delivery domains
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteUrl has_any (
    "wellnessmedcare.org",
    "wellnesscaremed.com",
    "freefoodaid.com",
    "longsauce.com"
)
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, RemoteUrl, RemoteIP
| order by Timestamp desc

HQ-05: Ivanti EPMM — Exploitation Attempt via URL Pattern

// Detect inbound requests targeting Ivanti EPMM vulnerable paths
// Requires network/WAF log ingestion into Sentinel (e.g., CommonSecurityLog or custom table)
CommonSecurityLog
| where TimeGenerated > ago(24h)
| where RequestURL has "/mifs/c/aftstore/fob/"
    or RequestURL has "/mifs/c/aftstore/"
| project TimeGenerated, SourceIP, DestinationIP, RequestURL, RequestMethod, EventOutcome
| order by TimeGenerated desc

HQ-06: Ivanti EPMM — Behinder Web Shell Key in Process Arguments

// Look for Behinder web shell default encryption key in process command lines
DeviceProcessEvents
| where Timestamp > ago(24h)
| where ProcessCommandLine has "45e329feb5d925b"
| project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessCommandLine
| order by Timestamp desc

HQ-07: npm Supply Chain — C2 Beaconing to Malicious npm C2

// Detect outbound connections to malicious npm Strapi C2 IP
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteIP == "144.31.107.231"
| project Timestamp, DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort, RemoteUrl
| order by Timestamp desc

HQ-08: ClickFix macOS / Atomic Stealer C2 — Network IOC Hunt

// Detect outbound connections to Atomic Stealer C2 infrastructure
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteIP == "83.222.190.214"
    or RemoteUrl has_any ("cryptoinfo-news.com", "odyssey1.to", "barbermoo.xyz")
| project Timestamp, DeviceName, InitiatingProcessFileName, RemoteIP, RemoteUrl, RemotePort
| order by Timestamp desc

HQ-09: CVE-2026-33032 nginx-ui — Unauthenticated API Access Attempt

// Detect access attempts to nginx-ui MCP endpoint without authentication
// Adjust table name to match your nginx/web proxy log schema
CommonSecurityLog
| where TimeGenerated > ago(24h)
| where RequestURL has "/api/" and DeviceVendor has_any ("nginx", "nginx-ui")
| where isempty(AdditionalExtensions) or AdditionalExtensions !has "auth"
| where EventOutcome in ("200", "403", "500")
| project TimeGenerated, SourceIP, RequestURL, EventOutcome, RequestMethod
| order by TimeGenerated desc

HQ-10: General — All Known IOC IPs (Consolidated)

// Sweep for any connection to known malicious IPs from this report
let malicious_ips = dynamic([
    "83.222.190.214",    // ClickFix Atomic Stealer C2
    "144.31.107.231"     // Malicious npm Strapi C2
]);
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteIP in (malicious_ips)
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, RemoteIP, RemotePort, RemoteUrl
| order by Timestamp desc

HQ-11: General — All Known IOC Domains (Consolidated)

// Sweep for DNS lookups or HTTP connections to all known malicious domains
let malicious_domains = dynamic([
    "wellnessmedcare.org",
    "wellnesscaremed.com",
    "freefoodaid.com",
    "longsauce.com",
    "cryptoinfo-news.com",
    "odyssey1.to",
    "barbermoo.xyz"
]);
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteUrl has_any (malicious_domains)
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, RemoteUrl, RemoteIP
| order by Timestamp desc

Detection Rules (High Fidelity KQL)

These rules are designed for low false-positive rate. They require validated, stable behavioral indicators rather than broad string matches. Tune thresholds for your environment before production deployment.

DR-01: APT28 PRISMEX — In-Memory .NET Payload from Image File

Logic: PrismexLoader executes .NET payloads loaded entirely in-memory. This rule detects .NET runtime loading initiated from within an image-rendering or Office process, which is anomalous.

// High-fidelity: .NET CLR loaded by Office/image processes — PRISMEX PrismexLoader indicator
DeviceImageLoadEvents
| where Timestamp > ago(24h)
| where FileName in~ ("clr.dll", "clrjit.dll", "mscorwks.dll")
| where InitiatingProcessFileName in~ (
    "excel.exe", "winword.exe", "powerpnt.exe",
    "mspaint.exe", "photos.exe", "Windows.Photos.exe"
)
| where InitiatingProcessCommandLine !has "-embedding"
| summarize
    LoadCount = count(),
    DistinctDLLs = dcount(FileName),
    DLLList = make_set(FileName)
    by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, bin(Timestamp, 1h)
| where LoadCount >= 2
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, LoadCount, DLLList
| order by Timestamp desc

DR-02: APT28 PRISMEX — COM Hijack + Scheduled Task Combo

Logic: The simultaneous creation of a scheduled task named "OneDriveHealth" AND registration/loading of adwapi64.dll on the same host within a 30-minute window is a near-certain PRISMEX indicator.

// High-fidelity: PRISMEX persistence — scheduled task + DLL combo within 30 min window
let sched_tasks = DeviceProcessEvents
| where Timestamp > ago(24h)
| where ProcessCommandLine has "OneDriveHealth" and ProcessCommandLine has "schtasks"
| project DeviceName, TaskTime = Timestamp;
let com_hijack = DeviceImageLoadEvents
| where Timestamp > ago(24h)
| where FileName =~ "adwapi64.dll"
| project DeviceName, DLLTime = Timestamp;
sched_tasks
| join kind=inner com_hijack on DeviceName
| where abs(datetime_diff('minute', TaskTime, DLLTime)) <= 30
| project DeviceName, TaskTime, DLLTime, TimeDiffMinutes = abs(datetime_diff('minute', TaskTime, DLLTime))
| order by TaskTime desc

DR-03: Ivanti EPMM — Exploitation Chain Detection

Logic: Exploitation of CVE-2026-1340 results in HTTP requests to /mifs/c/aftstore/fob/ from external IPs. Legitimate internal MDM clients do not typically hit this endpoint from internet-facing addresses.

// High-fidelity: Ivanti EPMM CVE-2026-1340 exploitation — external IP hitting vulnerable path
CommonSecurityLog
| where TimeGenerated > ago(24h)
| where RequestURL has "/mifs/c/aftstore/fob/"
| where ipv4_is_private(SourceIP) == false  // External source only
| summarize
    RequestCount = count(),
    Methods = make_set(RequestMethod),
    ResponseCodes = make_set(EventOutcome),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
    by SourceIP, DestinationHostName
| where RequestCount >= 1
| extend GeoInfo = geo_info_from_ip_address(SourceIP)
| project FirstSeen, LastSeen, SourceIP, DestinationHostName, RequestCount, Methods, ResponseCodes, GeoInfo
| order by FirstSeen desc

DR-04: npm Supply Chain — Dev Host C2 Beaconing Post-Package Install

Logic: A developer workstation connecting to 144.31.107.231 combined with a recent npm install event on the same host is near-certain compromise.

// High-fidelity: npm supply chain C2 beacon — network + process correlation
let c2_ip = "144.31.107.231";
let c2_connections = DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteIP == c2_ip
| project DeviceName, C2Time = Timestamp, RemoteIP, RemotePort, InitiatingProcessFileName;
let npm_installs = DeviceProcessEvents
| where Timestamp > ago(24h)
| where ProcessCommandLine has_any ("npm install", "npm i ", "npm ci")
| project DeviceName, NpmTime = Timestamp, ProcessCommandLine;
c2_connections
| join kind=inner npm_installs on DeviceName
| where C2Time > NpmTime and datetime_diff('hour', C2Time, NpmTime) <= 2
| project DeviceName, NpmTime, C2Time, ProcessCommandLine, RemoteIP, RemotePort
| order by C2Time desc

DR-05: ClickFix macOS — AppleScript URL Scheme Abuse

Logic: Execution of osascript spawned from a browser process, followed by an outbound curl, is the precise AMOS ClickFix delivery chain.

// High-fidelity: ClickFix macOS delivery chain — browser spawns osascript, then curl
let script_exec = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ ("osascript", "Script Editor", "ScriptEditor")
| where InitiatingProcessFileName in~ ("Google Chrome", "Safari", "Firefox", "Brave Browser", "Arc")
| project DeviceName, ScriptTime = Timestamp, AccountName, InitiatingProcessFileName;
let curl_exec = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName =~ "curl"
    and ProcessCommandLine has "zsh"
| project DeviceName, CurlTime = Timestamp, ProcessCommandLine;
script_exec
| join kind=inner curl_exec on DeviceName
| where CurlTime > ScriptTime and datetime_diff('minute', CurlTime, ScriptTime) <= 10
| project DeviceName, AccountName, ScriptTime, CurlTime, InitiatingProcessFileName, ProcessCommandLine
| order by ScriptTime desc

DR-06: ClickFix — Outbound Connection to Known Atomic Stealer C2

// High-fidelity: Direct C2 connection to confirmed Atomic Stealer infrastructure
let amos_ips = dynamic(["83.222.190.214"]);
let amos_domains = dynamic(["cryptoinfo-news.com", "odyssey1.to", "barbermoo.xyz"]);
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteIP in (amos_ips) or RemoteUrl has_any (amos_domains)
| summarize
    ConnectionCount = count(),
    Processes = make_set(InitiatingProcessFileName),
    Ports = make_set(RemotePort)
    by DeviceName, AccountName, RemoteIP, RemoteUrl
| project DeviceName, AccountName, RemoteIP, RemoteUrl, ConnectionCount, Processes, Ports
| order by ConnectionCount desc

DR-07: CVE-2026-33032 nginx-ui — Unauthenticated MCP Endpoint Exploitation

Logic: The vulnerability is triggered via unauthenticated requests to the nginx-ui MCP endpoint from external hosts. A successful 200 response to an unauthenticated request on this path is a confirmed exploitation indicator.

// High-fidelity: nginx-ui CVE-2026-33032 exploitation — unauthenticated MCP access
CommonSecurityLog
| where TimeGenerated > ago(24h)
| where RequestURL has "/api/nginx"
    or RequestURL has "/api/pty"
    or RequestURL has "/api/config"
| where ipv4_is_private(SourceIP) == false
| where EventOutcome == "200"  // Successful unauthorized access
| where isempty(RequestContext) or RequestContext !has "Bearer"  // No auth token
| summarize
    SuccessfulHits = count(),
    TargetPaths = make_set(RequestURL),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
    by SourceIP, DestinationHostName
| where SuccessfulHits >= 1
| project FirstSeen, LastSeen, SourceIP, DestinationHostName, SuccessfulHits, TargetPaths
| order by FirstSeen desc

Recommended Immediate Actions

  1. APT28/PRISMEX — Block all four PRISMEX delivery domains at DNS/proxy tier. Alert on Filen.io outbound from non-approved processes. Patch CVE-2026-21509 and CVE-2026-21513 immediately.
  2. Ivanti EPMM — Apply Ivanti EPMM patches. Search Apache access logs for /mifs/c/aftstore/fob/ hits with 200 response codes. Hunt for Behinder web shell key 45e329feb5d925b in memory.
  3. npm Supply Chain — Audit build pipelines for strapi-plugin-* packages installed from the four sock puppet accounts. Block egress to 144.31.107.231.
  4. SharePoint / nginx-ui — Apply April 2026 Patch Tuesday updates. Restrict internet exposure of nginx-ui instances (Shodan shows 2,689 exposed).
  5. Atomic Stealer — Block ClickFix C2 domains and IP at perimeter. Alert EDR teams to AMOS signatures. Educate macOS users on applescript:// social engineering lures.

Sources: The Hacker News — APT28 PRISMEX | Trellix Research | Unit 42 — Ivanti EPMM | Rapid7 ETR | The Hacker News — npm Supply Chain | SafeDep | Security Boulevard — Patch Tuesday | The Hacker News — nginx-ui | Jamf Threat Labs — ClickFix macOS | BleepingComputer