This is a booby-trapped flashlight in an old incident-response kit, not a burglar opening your front door
CVE-2026-28704 is a classic DLL search-order hijack in EmoCheck, JPCERT/CC's Windows utility for checking Emotet infection. Per JVN and the CVE record, all versions are affected: if an attacker can place a crafted DLL in the same directory as the EmoCheck executable and then get a user to run the tool from there, Windows may load the attacker DLL and execute code with the privileges of the user who launched EmoCheck.
The vendor's HIGH 7.8 score is technically defensible in a vacuum because successful execution yields full code execution in the caller's context. In the real world, it is overstated: this is local, user-assisted, non-automatable, tied to a discontinued one-off utility, and has essentially no internet-exposed attack surface. That combination crushes the reachable population and keeps this out of the normal urgent enterprise patch queue.
4 steps from start to impact.
Stage a rogue DLL next to EmoCheck*.exe
- Target still has a copy of EmoCheck or can be convinced to download one
- Attacker can write into the directory where EmoCheck will be executed
- DLL architecture and naming must match what the loader will request
- EmoCheck is not a resident service; it is an ad hoc responder tool, so there is no standing foothold to hit at scale
- AppLocker/WDAC or MOTW-aware controls can block unsigned DLLs from user-writable paths
- The attacker must know or test the correct DLL name and exports
Downloads, temp paths, or analyst tooling folders.Trigger execution through user action
- A human must execute EmoCheck
- The user must run it from the directory containing the rogue DLL
- JVN explicitly notes user direction is required
- JPCERT/CC ended distribution and told users to stop using EmoCheck, which sharply reduces the remaining execution population
- Many enterprises no longer use EmoCheck at all because Emotet activity subsided
EmoCheck*.exe executions from nonstandard paths, download directories, or ZIP extraction folders; this is good EDR hunting material but poor VM scanner material.Windows loader resolves the attacker DLL first
- The crafted DLL must satisfy the target load request closely enough to be loaded
- The operating system must not block the library via policy
- Broken export tables, wrong bitness, or missing dependencies will crash or reveal the attempt
- Image-load telemetry can expose the sideload even if the initial file delivery was missed
Payload inherits the caller's token
- The invoking user has a live security token
- Post-load payload behavior is not separately blocked by EDR
- This vulnerability does not itself provide privilege escalation
- Blast radius is usually one workstation and one user context unless the victim is highly privileged
The supporting signals.
| In-the-wild status | No active exploitation evidence found in the reviewed primary sources. The CISA ADP enrichment on the CVE record marks exploitation as none; CISA KEV does not list this CVE in the catalog reviewed for this assessment. Sources: NVD, CISA KEV |
|---|---|
| PoC availability | No authoritative public exploit repo was identified in the reviewed sources. The vulnerability appears straightforward to reproduce for anyone who can build a DLL, but that is not the same as broad commoditized exploitation. Research credit appears to go to Powder Keg Technologies. |
| EPSS | User-provided EPSS is 0.00015, which is extremely low and consistent with a narrow, local, user-assisted bug. EPSS framework reference: FIRST EPSS |
| KEV status | Not KEV-listed. That matters here because this CVE has no evidence of broad operational use and no exposed network service to drive rapid weaponization. Source: CISA KEV catalog |
| CVSS vector reality check | CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H is telling you the truth in miniature: local, no privileges required, user interaction required. The vendor score prices in worst-case impact after code runs, but not the tiny number of enterprise hosts where this chain is actually reachable. Sources: JVN, NVD |
| Affected versions | All versions of EmoCheck are affected per the JVN advisory and CVE record. Sources: JVN, NVD |
| Fixed version | No patched version was published in the reviewed sources. JPCERT/CC instead announced on 2026-04-10 that distribution ended and users should stop using EmoCheck immediately. Sources: JPCERT/CC press release, GitHub repo README |
| Exposure / scan surface | No meaningful internet-exposed surface. EmoCheck is described as a Windows Emotet detection tool, not a daemon, listener, or managed agent. That makes Shodan/Censys/FOFA style exposure effectively not applicable except where teams have manually copied the binary around. Sources: GitHub repo, JVN |
| Disclosure date | 2026-04-10. Both JVN and the JPCERT/CC press release were published on that date. Sources: JVN, JPCERT/CC press release |
| Research / reporting | The vendor advisory references the issue, while external reporting attributes discovery to Powder Keg Technologies. Use that as tentative attribution unless JPCERT/CC later publishes formal credit language. Source: Powder Keg Technologies |
noisgate verdict.
The decisive factor is reachability: this bug requires a local file-placement condition plus a human launching a discontinued utility from the compromised directory. That makes it a narrow post-delivery execution opportunity, not a scalable enterprise-wide intrusion path.
Why this verdict
- Start at vendor 7.8, then cut for attacker position: this is
AV:LandUI:R, so the attacker is not reaching in over the network; they need local placement conditions and a user to run the binary. - Subtract again for exposure population: EmoCheck is a niche responder utility, not a broadly installed service or agent, and JPCERT/CC ended distribution on 2026-04-10.
- Subtract again for operational evidence: no KEV listing, no active exploitation evidence in the reviewed sources, and the user-provided EPSS is extremely low at
0.00015.
Why not higher?
There is no remote pre-auth path, no server-side listener, and no indication of wormable or automated exploitation. The chain assumes prior delivery success plus user execution of a discontinued tool, which is exactly the kind of compounding friction that drags a CVSS-high local bug down in patch priority.
Why not lower?
This is still real code execution, not a cosmetic bug. If a privileged analyst or admin runs EmoCheck from a writable folder or tainted ZIP extraction path, the DLL executes in that user's context and could turn into a meaningful workstation compromise.
What to do — in priority order.
- Remove EmoCheck wherever it still exists — Because no fixed version is published and the vendor says to stop using it, the cleanest control is retirement. For a LOW noisgate verdict there is no SLA; treat removal as backlog hygiene and close it during your next software-rationalization cycle.
- Block execution from user-writable folders — Use WDAC, AppLocker, ASR, or equivalent to reduce executable and DLL loading from
Downloads,%TEMP%, desktop extraction folders, and ad hoc shares. This is broadly useful beyond this CVE and meaningfully cuts the same-directory sideload condition; for LOW, fold it into normal hardening work with no formal SLA. - Hunt for analyst copies and ZIP-based tooling kits — Search responder laptops, admin jump boxes, shared IR folders, and archived incident kits for
EmoCheck*.exe. The highest-risk cases are copies sitting in writable directories next to miscellaneous DLLs; again, for LOW, handle in the normal hygiene queue. - Alert on unsigned DLL loads next to rare utilities — If you already collect image-load telemetry, create lightweight detections for rare binaries launching from user paths and loading unsigned same-directory DLLs. This does not replace removal, but it gives you a net for residual copies without creating a fire drill.
- A WAF does nothing; there is no web transaction to inspect.
- Perimeter network scanning does nothing; EmoCheck is not an exposed network service.
- MFA does not meaningfully help; the execution point is local DLL sideload after file delivery and user launch.
Crowdsourced verification payload.
Run this on the target Windows endpoint or via your EDR/live-response shell. Invoke it as powershell -ExecutionPolicy Bypass -File .\Find-EmoCheck-CVE-2026-28704.ps1 from an elevated session for best coverage across C:\Users, C:\Program Files, and shared tooling directories; standard user rights will work but may return UNKNOWN for protected paths.
# Find-EmoCheck-CVE-2026-28704.ps1
# Detects presence of EmoCheck binaries. All known versions are affected and no fixed version is published.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
[CmdletBinding()]
param(
[string[]]$SearchRoots = @(
'C:\Users',
'C:\Program Files',
'C:\Program Files (x86)',
'C:\Tools',
'C:\Temp'
)
)
$ErrorActionPreference = 'Continue'
$found = @()
$hadErrors = $false
function Add-FoundFile {
param([System.IO.FileInfo]$File)
$version = $null
try {
$version = $File.VersionInfo.FileVersion
} catch {
$version = $null
}
$found += [pscustomobject]@{
Path = $File.FullName
Version = if ($version) { $version } else { '' }
LastWriteTime = $File.LastWriteTime.ToString('s')
}
}
foreach ($root in $SearchRoots) {
if (-not (Test-Path -LiteralPath $root)) { continue }
try {
Get-ChildItem -LiteralPath $root -Recurse -File -ErrorAction Stop |
Where-Object {
$_.Name -match '^EmoCheck.*\.exe$' -or
$_.Name -match '^emocheck.*\.exe$'
} |
ForEach-Object { Add-FoundFile -File $_ }
} catch {
Write-Warning ("Could not fully search root: {0} :: {1}" -f $root, $_.Exception.Message)
$hadErrors = $true
# Best-effort shallow fallback
try {
Get-ChildItem -LiteralPath $root -File -ErrorAction SilentlyContinue |
Where-Object {
$_.Name -match '^EmoCheck.*\.exe$' -or
$_.Name -match '^emocheck.*\.exe$'
} |
ForEach-Object { Add-FoundFile -File $_ }
} catch {
$hadErrors = $true
}
}
}
# Deduplicate
$found = $found | Sort-Object Path -Unique
if ($found.Count -gt 0) {
Write-Output 'VULNERABLE'
Write-Output 'Detected EmoCheck binaries (all known versions affected; vendor advises discontinuation):'
$found | ForEach-Object {
Write-Output ("Path={0}; Version={1}; LastWriteTime={2}" -f $_.Path, $_.Version, $_.LastWriteTime)
}
exit 1
}
if ($hadErrors) {
Write-Output 'UNKNOWN'
Write-Output 'No EmoCheck binary found in searched paths, but one or more locations could not be fully scanned.'
exit 2
}
Write-Output 'PATCHED'
Write-Output 'No EmoCheck binary found in the searched paths. Since no fixed version is published, absence is the safe state.'
exit 0
If you remember one thing.
EmoCheck*.exe copies on analyst workstations, jump boxes, and shared IR folders, and fold WDAC/AppLocker user-path hardening into normal platform hygiene; for a LOW verdict there is no noisgate mitigation SLA and no noisgate remediation SLA—treat it as backlog hygiene, document any residual exceptions, and clean it up in your next regular rationalization cycle rather than burning urgent patch capacity.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.