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.
| Tier | Threats |
|---|---|
| Critical | APT28/PRISMEX (nation-state), Ivanti EPMM RCE chain |
| High | npm Strapi supply-chain, CVE-2026-33032 nginx-ui, CVE-2026-32201 SharePoint |
| Medium | ClickFix 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).
| Component | Function |
|---|---|
| PrismexSheet | Excel dropper with VBA steganography, initial payload delivery |
| PrismexDrop | Native dropper; COM hijacking via adwapi64.dll (CLSID {68DDBB56-9D1D-4FD9-89C5-C0DA2A625392}); persistence via scheduled task "OneDriveHealth" |
| PrismexLoader | Proxy DLL extracting payloads from PNG images using steganography; executes payload in-memory via .NET runtime loading |
| PrismexStager | Covenant 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.
| CVE | Type | CVSS | Vector |
|---|---|---|---|
| CVE-2026-1281 | Auth bypass | Critical | Unauthenticated HTTP |
| CVE-2026-1340 | Code injection | Critical | HTTP 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)
- CVSS: 6.5
- Exploited in the wild as a zero-day; publicly disclosed April 2026 Patch Tuesday (167 CVEs patched total)
- Allows unauthenticated network-based content spoofing / interface impersonation
- Exploit PoC "BlueHammer" published to GitHub on April 3 by researcher "Chaotic Eclipse"
CVE-2026-33032 — nginx-ui Authentication Bypass (Actively Exploited)
- CVSS: 9.8
- Allows complete unauthenticated takeover of the Nginx service
- Chained with CVE-2026-27944 (information leak) in observed wild exploitation
- Approximately 2,689 exposed internet-facing instances (Shodan)
- Exploitation confirmed by Recorded Future (April 13, 2026) and PurpleOps (April 16, 2026)
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
- 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.
- 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 key45e329feb5d925bin memory. - npm Supply Chain — Audit build pipelines for
strapi-plugin-*packages installed from the four sock puppet accounts. Block egress to144.31.107.231. - SharePoint / nginx-ui — Apply April 2026 Patch Tuesday updates. Restrict internet exposure of nginx-ui instances (Shodan shows 2,689 exposed).
- 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