UAC-0099 — LUNCHPOKE / BURNYBEAR via Notepad++ Plugin Loading
Executive Summary
What happened, why it defeats ordinary controls, and what a hunter should actually go looking for.
CERT-UA published advisory 6318634 on 2026-07-21 describing a change in tradecraft for the threat cluster it tracks as UAC-0099 — a Russia-aligned actor active since at least mid-2022, previously known for weaponising WinRAR flaws to deliver LONEPAGE and for the MATCHBOIL / MATCHWOK / DRAGSTARE toolset, and reported to have provided initial access for APT44 (Sandworm). The new chain replaces exploitation with abuse of a completely legitimate feature.
The victim receives a phishing email whose image attachment carries the hyperlink. Clicking it walks a URL
shortener out to a consumer file-transfer service, which serves a ZIP. Inside is a VBScript padded with a long run of
spaces before its real .vbs extension so the file list shows a PDF. Running it opens a decoy PDF in the
foreground while, in the background, it pulls a second archive, Evernote.zip, containing a
complete, unmodified copy of Notepad++ 8.8.3, a rogue NppExport.dll in the
plugins\NppExport\ directory, a password-protected updater.rar, and a legitimate
winrar.exe. The script unpacks that into a randomly named directory under the public profile and starts
Notepad++. Notepad++ loads the plugin because that is what Notepad++ does.
From there the chain is entirely living-off-its-own-bundle:
- LUNCHPOKE (
NppExport.dll) creates a working directory under%PUBLIC%\Libraries\, uses the bundled WinRAR to unpackupdater.rarwith a password, dropsRemoteLibUpdater.exeandInitTest.dll, copiesschtasks.exeto%PUBLIC%\Wallpapers\Background.exe, and registers a scheduled task that runs the loader with the argumentssetup nodisplayevery three minutes. - BURNYBEAR (
RemoteLibUpdater.exe) exists only to loadInitTest.dll. Run it with no arguments and it deliberately burns RAM and CPU instead — a combined anti-analysis and sandbox-detection trick, since automated detonation usually launches a binary bare. - MATCHBOIL.V2 (
InitTest.dll) is a C#-based stager that creates further scheduled tasks, rotates its C2 configuration, downloads follow-on payloads and now unpacks them with WinRAR — fetching WinRAR from Dropbox if the host does not have it.
%PUBLIC%, a plugin DLL written somewhere no
installer would write, a copy of the Task Scheduler binary under a wallpapers folder, and a task firing every three
minutes.REPLACE_WITH_
placeholders. Every detection below is behavioural or path-based by design, not by omission. The directory name
fFthY3-Ytrevc3w-ab3 and the task name W1n3r-U09oTy-Ap5 are the values CERT-UA observed and
are documented as rotating per victim — hunt the shape, use the literals only as confirmation.Hunt priority
| Priority | Hunt | Why it is first |
|---|---|---|
| P1 | Notepad++ executing from a user-writable directory (Q1) | Single highest-signal event in the chain. A managed estate installs Notepad++ to Program Files; this campaign cannot work without running it from a staging directory. |
| P1 | Scheduled task with a minute-level interval pointing into %PUBLIC% (Q3) |
The three-minute persistence beacon is the most durable artefact and survives reboot and process kill. |
| P1 | Renamed Task Scheduler binary (Q5) | Background.exe is schtasks.exe. Any non-schtasks image issuing schtasks create syntax is a masquerade. |
| P2 | Notepad++ spawning children (Q6) and rogue plugin writes (Q2) | Confirms the side-load rather than merely the staging. |
| P2 | Double-extension VBS execution (Q7) | Catches the delivery stage and generalises well beyond this actor. |
Source Review & Web-Hunter Notes
Every source below was fetched on 2026-07-25 and its page text saved verbatim to
UAC0099-LunchPoke-Notepad-Hunt-sources/. The provenance gate traces each atomic indicator in this pack back
to that saved text.
| Tier | Source | Snapshot | Key contribution | Carry forward |
|---|---|---|---|---|
| Tier 1 | CERT-UA advisory 6318634 — "UAC-0099: LUNCHPOKE, BURNYBEAR, оновлений MATCHBOIL.V2 та використання Notepad++ 8.8.3", published 2026-07-21 | 01-cert-ua-6318634.txt |
Originating advisory. Establishes actor attribution, malware naming and the 2026-07-21 publication date. | Partial |
| Tier 2 | The Hacker News — Fake Notepad++ Plugin Delivers MATCHBOIL.V2 in UAC-0099 Attacks (2026-07-24) | 02-thehackernews.txt |
Full chain narrative, archive contents, three-minute task, BURNYBEAR resource-exhaustion fallback, prior-toolset lineage. | Yes |
| Tier 2 | BleepingComputer — Hackers abuse Notepad++ plugins to stealthily install malware (2026-07-23) | 03-bleepingcomputer.txt |
APT44 / Sandworm initial-access link, randomly named install directory, MATCHBOIL.V2 second task and C2 rotation, CVE-2025-56383 dispute, vendor version guidance. | Yes |
| Tier 2 | Security Affairs — UAC-0099 Is Now Hiding Malware Inside a Fake Notepad++ Plugin (2026-07-24) | 04-securityaffairs.txt |
Directly quotes the CERT-UA advisory text, giving the exact working directory, the renamed schtasks path, the task name, the setup nodisplay arguments and the /plugins/NppExport/ layout. |
Yes |
| Tier 3 | Cybersecurity Help — UAC-0099 espionage cluster uses legitimate Notepad++ software (2026-07-23) | 05-cybersecurity-help.txt |
Independent confirmation of the MATCHBOIL.V2 WinRAR-plus-Dropbox behaviour and of CERT-UA's stated reason for citing CVE-2025-56383 only as a search aid. | Yes |
| Tier 3 | Cyber Press — Hackers Weaponize Notepad++ 8.8.3 to Silently Install MATCHBOIL.V2 (2026-07-24) | 06-cyberpress.txt |
The %PUBLIC%\Libs_ staging-directory prefix, the double-extension space-padding mechanic, Dropbox fallback for WinRAR. |
Yes |
| Tier 3 | GBHackers — Hackers Weaponize Notepad++ Plugins to Silently Infect Windows Systems (2026-07-24) | 07-gbhackers.txt |
Consolidated artefact table: staging directory template, working directory, renamed schtasks path, task name, command-line arguments, task frequency. | Yes |
cert.gov.ua/article/<id> is an Angular single-page application. A non-browser client receives a
2,380-byte JavaScript shell and no article body, and the site exposes no per-article JSON endpoint (eight candidate paths
were probed; all returned 404). The advisory's existence, exact title, URL and 2026-07-21 publication date were therefore
confirmed straight from CERT-UA's own /api/articles/rss and /api/articles/all endpoints, and
that verbatim output is what snapshot 01 holds. No atomic indicator in this pack rests on that
snapshot. The artefact-level detail is carried by snapshots 04 and 07, which quote the advisory directly and
agree with each other on every value.Intel gaps carried into the hunt
- No hashes. Not one source publishes a SHA256, SHA1 or MD5 for LUNCHPOKE, BURNYBEAR or MATCHBOIL.V2.
- No C2. MATCHBOIL.V2's command-and-control infrastructure is described functionally but never named.
- No final payload. BleepingComputer notes explicitly that CERT-UA does not disclose what MATCHBOIL.V2 ultimately delivers, the campaign's objective, or the victim set.
- Rotating literals. CERT-UA states the working-directory name changes; the reporting implies the task name and staging directory do too. Treat all three as samples of a pattern.
- Archive lure names are localised. Ukrainian-language lure filenames were reported. They are useful context but are poor detection anchors outside a Ukrainian-language estate.
Hunt Brief & Attack Chain
| # | Step | Artefact / behaviour | Falcon telemetry | Hunt angle |
|---|---|---|---|---|
| 1 | Phishing email carrying an image attachment | Hyperlink is on the image, not on visible text | Email gateway (not EDR) | Gateway hunt: inbound mail whose only clickable element is an image linking to a shortener. |
| 2 | URL shortener → consumer file-transfer service | e.g. easysend[.]co (legitimate service, abused) | DnsRequest, proxy logs |
Shortener resolution followed within seconds by a file-transfer domain, from a mail-reading host. |
| 3 | ZIP delivered containing a space-padded VBS | Zavodskyi rayon.pdf .vbs |
ZipFileWritten, ProcessRollup2 |
Q7 — wscript/cscript command line containing a document extension followed by whitespace then .vbs. |
| 4 | VBS drops decoy PDF and fetches Evernote.zip |
Decoy opens in the foreground as cover | ProcessRollup2, DnsRequest |
Script host writing an archive then immediately launching a GUI application. |
| 5 | Archive extracted to a randomly named public directory | %PUBLIC%\Libs_<random>\Notepad\ |
PeFileWritten, ZipFileWritten |
Q2 — a plugin DLL written under a public or temp path. |
| 6 | Legitimate notepad++.exe launched from that directory |
Signed, unmodified Notepad++ 8.8.3 | ProcessRollup2 |
Q1 — highest-signal event in the whole chain. |
| 7 | Notepad++ side-loads NppExport.dll (LUNCHPOKE) |
Loaded via documented plugin mechanism, no exploit | Module-load telemetry — see coverage gap G1 | Q6 — infer from the children Notepad++ then spawns. |
| 8 | Bundled WinRAR unpacks password-protected updater.rar |
Drops RemoteLibUpdater.exe + InitTest.dll into %PUBLIC%\Libraries\<random>\ |
ProcessRollup2, PeFileWritten |
Q8 — WinRAR run from a user-writable path with a password switch. |
| 9 | schtasks.exe copied to %PUBLIC%\Wallpapers\Background.exe |
Masquerade of a Microsoft-signed binary | PeFileWritten, ProcessRollup2 |
Q5 — task-create syntax issued by a process not named schtasks.exe. |
| 10 | Scheduled task registered, three-minute interval | \W1n3r-U09oTy-Ap5\Updates runs RemoteLibUpdater.exe setup nodisplay |
ScheduledTaskRegistered |
Q3 — the most durable artefact in the chain. |
| 11 | BURNYBEAR loads MATCHBOIL.V2 | No arguments → deliberate RAM/CPU exhaustion instead | ProcessRollup2 |
Q4 — direct execution hunt on the loader. |
| 12 | MATCHBOIL.V2 stages follow-on payloads | New tasks, C2 config rotation, WinRAR extraction, Dropbox fallback for WinRAR | DnsRequest, NetworkConnectIP4, ScheduledTaskRegistered |
Q9 / Q10 — execution from the working directory, and Dropbox resolution by a non-browser process. |
Hunt hypotheses
| ID | Hypothesis | MITRE | Confidence | Expected FP source |
|---|---|---|---|---|
| H1 | A signed text editor is executing from a user-writable staging directory rather than an installed location. | T1574.001 | High | Portable-app users; software packaging and test hosts. |
| H2 | A DLL named like a Notepad++ plugin has been written outside any legitimate Notepad++ installation path. | T1574.001, T1036.005 | High | Developers building plugins; portable installs. |
| H3 | A scheduled task with a minute-level repetition interval points at an executable under the public profile. | T1053.005 | High | Some RMM and monitoring agents use minute-level tasks — but not from %PUBLIC%. |
| H4 | A process that is not schtasks.exe is issuing Task Scheduler create syntax. | T1036.003, T1053.005 | High | Installer bundles that ship their own renamed utilities. |
| H5 | Notepad++ has spawned a shell, script host, archiver or task-scheduler child. | T1574.001, T1059 | Medium | Notepad++ "Run" menu and NppExec plugin used legitimately by developers. |
| H6 | A script host is executing a file whose name contains a document extension followed by padding whitespace and a real .vbs extension. | T1036.007, T1204.002 | High | Essentially none; this pattern is deceptive by construction. |
| H7 | An archiver is being run from a user-writable directory with a password switch. | T1560.001, T1140 | Medium | Legitimate use of portable archivers and backup scripting. |
| H8 | Processes are executing from %PUBLIC%\Libraries\, a directory no supported installer writes executables to. | T1036, T1074.001 | High | Rare. Some poorly written LOB installers stage here. |
| H9 | A non-browser process is resolving a consumer cloud-storage domain in order to retrieve a utility. | T1105 | Medium | Sync clients, updaters and CI agents legitimately reach cloud storage. |
Consolidated IOC Table
NppExport.dll — is a real Notepad++ plugin
name. That is the entire point of the masquerade. Blocking on those filenames will break legitimate installs and
will not stop this actor, who can rename at will. They are listed for context and for path-scoped hunting only.| Type | Value | Role | Conf. | Action | Sources |
|---|---|---|---|---|---|
| Filename | RemoteLibUpdater.exe | BURNYBEAR loader; run with setup nodisplay | High | Detect | 02, 03, 04, 06, 07 |
| Filename | InitTest.dll | MATCHBOIL.V2 C#-based stager | High | Detect | 02, 03, 04, 06, 07 |
| Filename | updater.rar | Password-protected payload archive | High | Detect | 02, 03, 04, 06, 07 |
| Filename | Evernote.zip | Second-stage archive carrying the Notepad++ bundle | High | Detect | 02, 03, 04, 06, 07 |
| Filename | Background.exe | Renamed copy of schtasks.exe under %PUBLIC%\Wallpapers\ | High | Detect | 04, 07 |
| Scheduled task | W1n3r-U09oTy-Ap5 (task \W1n3r-U09oTy-Ap5\Updates) | Three-minute persistence trigger | Med — rotates | Detect | 04, 07 |
| Directory | fFthY3-Ytrevc3w-ab3 (under %PUBLIC%\Libraries\) | LUNCHPOKE working directory | Med — CERT-UA states it rotates | Detect | 04, 07 |
| Path template | %PUBLIC%\Libs_ + random digits + \Notepad\ | Staging directory for the Notepad++ bundle | High | Hunt | 06, 07 |
| Command line | setup nodisplay | Required BURNYBEAR arguments; absent them it self-sabotages | High | Detect | 04, 07 |
| Filename | NppExport.dll | LUNCHPOKE — also a genuine Notepad++ plugin name | High | Context only — never block on name | 02, 03, 04, 05, 06, 07 |
| Filename | notepad++.exe | Legitimate signed host process for the side-load | n/a | Context only | 06, 07 |
| Filename | winrar.exe / schtasks.exe | Legitimate binaries bundled or abused | n/a | Context only | 02, 04, 05, 06, 07 |
| Domain | easysend[.]co | Consumer file-transfer service used to stage the first ZIP | Med | Do not block — legitimate service; monitor only | 02, 04 |
| Lure filename | Ukrainian-language document names padded with spaces before .vbs | Double-extension delivery | High | Hunt (pattern) | 04, 06, 07 |
| CVE reference | CVE-2025-56383 | Referenced by CERT-UA only as a search aid; Notepad++ disputes it is a vulnerability | n/a | Do not treat as the root cause | 03, 05, 06 |
| SHA256 ×3 | REPLACE_WITH_… | LUNCHPOKE / BURNYBEAR / MATCHBOIL.V2 | — | Placeholder — no hash published in any reviewed source | — |
| C2 domain | REPLACE_WITH_… | MATCHBOIL.V2 command-and-control | — | Placeholder — never disclosed | — |
REPLACE_WITH_ placeholders and the corresponding detection weight
was moved into the behavioural queries (Q1, Q3, Q5, Q9). Fill the placeholders from your own sample or from a CERT-UA
follow-up before enabling any block action.Affected Surface & Telemetry Matrix
| Surface | Exposure | Required telemetry | Priority | Gap risk if missing |
|---|---|---|---|---|
| Windows workstations (user-facing, email-enabled) | Primary. Whole chain runs in user context; no admin rights needed. | ProcessRollup2, SyntheticProcessRollup2 | Critical | Total. Q1, Q4, Q5, Q6, Q7, Q8, Q9 all blind. |
| Scheduled Task subsystem | Persistence anchor; three-minute interval | ScheduledTaskRegistered + Windows Event ID 4698 | Critical | Persistence survives eradication of the running process. |
| Filesystem — public profile and temp | Staging and working directories | PeFileWritten, ZipFileWritten | High | Q2 blind; drop-time detection lost, only execution-time remains. |
| Module / image load | The actual side-load moment | Module-load telemetry (tenant dependent) | Medium | Known gap G1 — compensated by process-lineage queries Q1 and Q6. |
| DNS and egress | Shortener, file-transfer service, C2, Dropbox fallback | DnsRequest, NetworkConnectIP4 | Medium | Q10 blind; no C2 indicators exist to hunt on anyway. |
| Email gateway | Delivery — image-borne hyperlink | Gateway / message-trace logs (outside Falcon) | Medium | Known gap G2 — earliest interdiction point is lost. |
| Servers and domain controllers | Not directly targeted, but UAC-0099 is an access broker for APT44 | Standard EDR coverage | Medium | Follow-on lateral movement unmonitored. |
| macOS / Linux | Not applicable — Windows-only chain | — | n/a | None. |
ATT&CK Mapping
| Tactic | Technique | ID | Observed behaviour | Covered by |
|---|---|---|---|---|
| Initial Access | Phishing: Spearphishing Link | T1566.002 | Image attachment carrying a shortened hyperlink to a file-transfer service | Gateway hunt (gap G2) |
| Execution | User Execution: Malicious File | T1204.002 | Victim double-clicks a VBS that appears to be a PDF | Q7 |
| Execution | Command and Scripting Interpreter: Visual Basic | T1059.005 | VBScript unpacks the bundle and launches Notepad++ | Q7, Q6 |
| Defense Evasion | Masquerading: Match Legitimate Name or Location | T1036.005 | Rogue DLL named after a real Notepad++ plugin | Q2 |
| Defense Evasion | Masquerading: Rename System Utilities | T1036.003 | schtasks.exe copied to Background.exe | Q5 |
| Defense Evasion | Masquerading: Double File Extension | T1036.007 | Space-padded .pdf … .vbs | Q7 |
| Defense Evasion / Persistence | Hijack Execution Flow: DLL Search Order Hijacking | T1574.001 | Notepad++ loads an attacker DLL through its plugin mechanism | Q1, Q2, Q6 |
| Defense Evasion | Deobfuscate/Decode Files or Information | T1140 | Password-protected RAR unpacked at runtime | Q8 |
| Defense Evasion | Impair Defenses / anti-analysis | T1562 | BURNYBEAR exhausts RAM and CPU when launched without arguments | Gap G3 (behavioural note) |
| Persistence / Execution | Scheduled Task/Job: Scheduled Task | T1053.005 | Task firing every three minutes; MATCHBOIL.V2 registers more | Q3, Q5 |
| Collection / Staging | Data Staged: Local Data Staging | T1074.001 | Working directory under %PUBLIC%\Libraries\ | Q9 |
| Command and Control | Ingress Tool Transfer | T1105 | MATCHBOIL.V2 downloads payloads and fetches WinRAR from Dropbox | Q10 |
| Command and Control | Web Service | T1102 | Consumer file-transfer and cloud-storage services used as delivery infrastructure | Q10 |
Native Audit-Log Hunts
Checks that need no EDR — run these on any Windows host you cannot reach with Falcon, and use them to corroborate an EDR hit before declaring an incident.
7.1 — Scheduled tasks with a minute-level repetition interval
# PowerShell. Any task repeating faster than 5 minutes is unusual outside monitoring agents.
Get-ScheduledTask | ForEach-Object {
$t = $_
$t.Triggers | Where-Object { $_.Repetition.Interval -match '^PT[1-5]M$' } |
ForEach-Object {
[pscustomobject]@{
TaskPath = $t.TaskPath
TaskName = $t.TaskName
Interval = $_.Repetition.Interval
Action = ($t.Actions.Execute -join '; ')
Args = ($t.Actions.Arguments -join '; ')
}
}
} | Format-Table -AutoSize
7.2 — Any scheduled-task action pointing into the public profile
# The single strongest native check for this campaign. Expect zero rows on a clean host.
Get-ScheduledTask | Where-Object {
$_.Actions.Execute -like "$env:PUBLIC*"
} | Select-Object TaskPath, TaskName, @{n='Exec';e={$_.Actions.Execute}},
@{n='Args';e={$_.Actions.Arguments}} | Format-List
7.3 — Executables and DLLs staged under the public profile
# Staging directories observed: %PUBLIC%\Libs_<random>\Notepad\ and %PUBLIC%\Libraries\<random>\
Get-ChildItem -Path $env:PUBLIC -Recurse -Include *.exe,*.dll,*.rar,*.zip -ErrorAction SilentlyContinue |
Select-Object FullName, Length, CreationTimeUtc, LastWriteTimeUtc |
Sort-Object CreationTimeUtc -Descending | Format-Table -AutoSize
7.4 — Copies of schtasks.exe living outside System32
# Compares file version metadata rather than name, so a rename cannot hide it.
Get-ChildItem -Path $env:PUBLIC, $env:APPDATA, $env:ProgramData -Recurse -Include *.exe -ErrorAction SilentlyContinue |
Where-Object { $_.VersionInfo.OriginalFilename -eq 'schtasks.exe' } |
Select-Object FullName, @{n='OriginalName';e={$_.VersionInfo.OriginalFilename}}, CreationTimeUtc
7.5 — Security event log: task registration
# Event ID 4698 = a scheduled task was created. Requires "Audit Other Object Access Events" (Success).
Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4698 } -MaxEvents 400 -ErrorAction SilentlyContinue |
Where-Object { $_.Message -match 'Public|Libraries|Wallpapers|Libs_' } |
Select-Object TimeCreated, Id, Message | Format-List
7.6 — Notepad++ installations outside Program Files
# A managed estate should return only the packaged install path, if any.
Get-ChildItem -Path C:\Users, $env:ProgramData -Recurse -Filter 'notepad++.exe' -ErrorAction SilentlyContinue |
Select-Object FullName, CreationTimeUtc,
@{n='PluginDlls';e={ (Get-ChildItem (Join-Path $_.DirectoryName 'plugins') -Recurse -Filter *.dll -ErrorAction SilentlyContinue).FullName -join '; ' }} |
Format-List
CrowdStrike LogScale CQL Hunt Queries
@timestamp >= (now() - N) is not valid CQL — the right side of a filter comparison must be a literal —
and putting one on line 1 silently kills the whole query.// HUNT: Notepad++ running from %PUBLIC%, ProgramData, AppData or Windows\Temp
// MITRE: T1574.001, T1036 | CONF: high FP: low COST: low
// REQUIRES: ProcessRollup2 / SyntheticProcessRollup2 process telemetry
// FALSE POSITIVES: portable Notepad++ builds run from a share, a USB stick or a developer sandbox
// TUNING: exclude your software-packaging and build hosts by ComputerName, and any
// approved portable-app share path, before promoting this to a Scheduled Search
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| FileName=/^notepad\+\+\.exe$/i
| ImageFileName=/\\Users\\Public\\|\\ProgramData\\|\\AppData\\|\\Windows\\Temp\\/i
| table([ComputerName, UserName, FileName, ImageFileName, CommandLine, ParentBaseFileName, TargetProcessId, ProcessStartTime])
// HUNT: NppExport.dll (or any plugin DLL) dropped under a public/temp path
// MITRE: T1574.001, T1036.005 | CONF: high FP: low COST: low
// REQUIRES: PeFileWritten file-write telemetry
// FALSE POSITIVES: plugin developers; portable Notepad++ unpacked to a user directory
// NOTE: NppExport.dll is a GENUINE Notepad++ plugin name -- the write LOCATION is the signal,
// never the filename on its own. Do not turn this into a filename block.
// TUNING: exclude known developer workstations, and any approved portable-app staging share,
// by ComputerName before alerting
#event_simpleName=/^PeFileWritten$/
| TargetFileName=/\\plugins\\/i
| TargetFileName=/\.dll$/i
| TargetFileName=/\\Users\\Public\\|\\ProgramData\\|\\AppData\\|\\Windows\\Temp\\/i
| table([ComputerName, UserName, TargetFileName, FileName, ImageFileName, ParentBaseFileName, TargetProcessId])
// HUNT: task registration whose action executes from %PUBLIC% / ProgramData / AppData
// MITRE: T1053.005 | CONF: high FP: low-med COST: low
// REQUIRES: ScheduledTaskRegistered telemetry (Windows Event 4698 equivalent)
// FALSE POSITIVES: a small number of RMM, patching and telemetry agents stage under ProgramData
// TUNING: exclude your RMM and patch-agent TaskAuthor values and their ProgramData vendor
// subdirectories; %PUBLIC% itself should stay in scope with no exclusions at all
#event_simpleName=/^ScheduledTaskRegistered$/
| TaskExecutable=/\\Users\\Public\\|\\ProgramData\\|\\AppData\\/i
| table([ComputerName, UserName, TaskName, TaskExecutable, TaskAuthor, ProcessStartTime])
// HUNT: RemoteLibUpdater.exe, or any process invoked with the BURNYBEAR argument pair
// MITRE: T1204.002, T1053.005 | CONF: high FP: low COST: low
// REQUIRES: ProcessRollup2 / SyntheticProcessRollup2
// FALSE POSITIVES: none expected -- neither the filename nor the argument pair is a known product
// TUNING: if a legitimate internal tool shares this name, pin the exclusion to its signed
// install path via ImageFileName rather than removing the FileName clause
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| FileName=/^RemoteLibUpdater\.exe$/i OR CommandLine=/\bsetup\s+nodisplay\b/i
| table([ComputerName, UserName, FileName, ImageFileName, CommandLine, ParentBaseFileName, GrandparentBaseFileName, TargetProcessId])
// HUNT: schtasks.exe copied and renamed (observed as %PUBLIC%\Wallpapers\Background.exe)
// MITRE: T1036.003, T1053.005 | CONF: high FP: low COST: low
// REQUIRES: ProcessRollup2 with full command line
// FALSE POSITIVES: installer bundles that ship a renamed copy of a Microsoft utility
// TUNING: exclude signed vendor installers by ImageFileName path; do NOT relax the
// FileName negation itself, that clause is the entire detection
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| CommandLine=/\bcreate\b.*\btn\b.*\bsc\b\s+minute/i
| FileName!=/^schtasks\.exe$/i
| table([ComputerName, UserName, FileName, ImageFileName, CommandLine, ParentBaseFileName, TargetProcessId])
// HUNT: process-lineage proxy for the plugin side-load, which module-load telemetry may not show
// MITRE: T1574.001, T1059 | CONF: medium FP: medium COST: low
// REQUIRES: ProcessRollup2 with ParentBaseFileName populated
// FALSE POSITIVES: the Notepad++ Run menu and the NppExec plugin legitimately spawn shells;
// developers do this routinely
// TUNING: exclude your developer workstation group by ComputerName, then triage what remains
// by ImageFileName -- a Notepad++ under Program Files spawning cmd.exe is far less
// interesting than one under %PUBLIC% spawning an archiver
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| ParentBaseFileName=/^notepad\+\+\.exe$/i
| FileName=/^(cmd\.exe|powershell\.exe|pwsh\.exe|wscript\.exe|cscript\.exe|mshta\.exe|schtasks\.exe|winrar\.exe|rar\.exe|unrar\.exe|Background\.exe)$/i
| table([ComputerName, UserName, FileName, ImageFileName, CommandLine, ParentBaseFileName, TargetProcessId, ParentProcessId])
// HUNT: wscript/cscript invoked on a file whose name shows a document extension,
// then padding whitespace, then the real .vbs extension
// MITRE: T1036.007, T1204.002, T1059.005 | CONF: high FP: low COST: low
// REQUIRES: ProcessRollup2 with full command line
// FALSE POSITIVES: essentially none -- this filename shape exists only to deceive
// TUNING: if a legacy in-house script genuinely carries a doubled extension, exclude that
// one exact filename rather than loosening the whitespace-padding pattern
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| FileName=/^(wscript\.exe|cscript\.exe)$/i
| CommandLine=/\.(pdf|doc|docx|xls|xlsx|jpg|png|txt)\s{2,}[^\\]*\.vbs/i
| table([ComputerName, UserName, FileName, CommandLine, ParentBaseFileName, TargetProcessId, ProcessStartTime])
// HUNT: WinRAR/RAR run from a user-writable directory with a password switch
// MITRE: T1560.001, T1140 | CONF: medium FP: medium COST: low
// REQUIRES: ProcessRollup2 with full command line
// FALSE POSITIVES: backup scripts, portable archivers, and legitimate password-protected
// transfers between users
// TUNING: exclude your backup and file-transfer service accounts by UserName, and any
// approved portable-archiver path by ImageFileName; keep %PUBLIC% unexcluded
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| FileName=/^(winrar\.exe|rar\.exe|unrar\.exe|7z\.exe|7zg\.exe)$/i
| ImageFileName=/\\Users\\Public\\|\\ProgramData\\|\\AppData\\|\\Windows\\Temp\\/i
| CommandLine=/\s-p/i
| table([ComputerName, UserName, FileName, ImageFileName, CommandLine, ParentBaseFileName, TargetProcessId])
// HUNT: the CERT-UA-named artefacts, plus execution from the LUNCHPOKE working directory
// MITRE: T1074.001, T1036, T1053.005 | CONF: high FP: low COST: low
// REQUIRES: ProcessRollup2 and PeFileWritten
// FALSE POSITIVES: low -- but %PUBLIC%\Libraries is occasionally abused by sloppy LOB installers
// NOTE: the directory literal fFthY3-Ytrevc3w-ab3 and the task literal W1n3r-U09oTy-Ap5 are
// documented by CERT-UA as ROTATING per victim. They confirm a hit; they do not find one.
// The %PUBLIC%\Libraries and Libs_ path clauses are what actually carries this query.
// TUNING: exclude any approved LOB installer that stages under %PUBLIC%\Libraries by
// ParentBaseFileName before scheduling
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2|PeFileWritten|ZipFileWritten)$/
| FileName=/^(RemoteLibUpdater\.exe|InitTest\.dll|Background\.exe|updater\.rar|Evernote\.zip)$/i OR TargetFileName=/\\(RemoteLibUpdater\.exe|InitTest\.dll|Background\.exe|updater\.rar|Evernote\.zip)$/i OR ImageFileName=/\\Users\\Public\\(Libraries|Libs_|Wallpapers)/i
| table([ComputerName, UserName, FileName, TargetFileName, ImageFileName, CommandLine, ParentBaseFileName, TargetProcessId])
// HUNT: MATCHBOIL.V2 retrieving WinRAR from Dropbox when the host has no archiver
// MITRE: T1105, T1102 | CONF: medium FP: medium COST: low
// REQUIRES: DnsRequest with ContextBaseFileName populated
// FALSE POSITIVES: the Dropbox sync client, browsers, updaters and CI agents all resolve
// cloud-storage domains constantly
// TUNING: exclude your sanctioned sync client and browser images by ContextBaseFileName;
// what should remain is script hosts, unsigned loaders and anything under %PUBLIC%
#event_simpleName=/^DnsRequest$/
| DomainName=/dropbox|easysend|mediafire|mega\.nz|files\.fm/i
| ContextBaseFileName=/^(RemoteLibUpdater\.exe|notepad\+\+\.exe|wscript\.exe|cscript\.exe|Background\.exe|InitTest\.dll)$/i
| table([ComputerName, UserName, DomainName, ContextBaseFileName, ContextProcessId])
Query quality review
| Query | Fields verified | CONF | FP | COST | Reviewer note |
|---|---|---|---|---|---|
| Q1 | Yes | High | Low | Low | Best single query in the pack. Promote first. |
| Q2 | Yes | High | Low | Low | Location-scoped, not name-scoped — deliberately so. |
| Q3 | Yes | High | Low-med | Low | Baseline your RMM task authors once, then it stays quiet. |
| Q4 | Yes | High | Low | Low | Argument clause keeps it alive after a filename change. |
| Q5 | Yes | High | Low | Low | Generalises far beyond UAC-0099; worth keeping permanently. |
| Q6 | Yes | Medium | Medium | Low | Noisy on developer estates. Hunt-only until baselined. |
| Q7 | Yes | High | Low | Low | Near-zero FP by construction. Strong IOA candidate. |
| Q8 | Yes | Medium | Medium | Low | The -p switch is the weak link; scope by path. |
| Q9 | Yes | High | Low | Low | Path clauses carry it; the literals only confirm. |
| Q10 | Yes | Medium | Medium | Low | Weakest query — no real C2 exists to hunt. Exploratory. |
CrowdStrike Custom IOA Recommendations
| IOA | Type | Pattern | Action | Severity | Rationale |
|---|---|---|---|---|---|
| IOA-1 — Text editor from public profile | Process Creation | Image filename notepad++.exe AND image path matches \Users\Public\ |
Detect | High | The chain's load-bearing step. Cannot be renamed away without breaking the side-load. |
| IOA-2 — Task action in public profile | Process Creation | Command line matches create + sc minute AND references \Users\Public\ |
Detect | High | Catches the persistence step regardless of which binary registers it. |
| IOA-3 — Renamed schtasks | Process Creation | Command line carries schtasks create syntax AND image filename is not schtasks.exe |
Detect | High | Durable, actor-agnostic masquerade detection. |
| IOA-4 — BURNYBEAR arguments | Process Creation | Command line matches setup nodisplay from a non-Program-Files path |
Detect | Critical | Argument pair is unique to this loader across all reviewed reporting. |
| IOA-5 — Double-extension script | Process Creation | wscript.exe/cscript.exe with a document extension, whitespace padding, then .vbs |
Detect | High | Deceptive by construction; safe to alert on immediately. |
| IOA-6 — Plugin DLL write to public profile | File Creation | Target path matches \plugins\ AND \Users\Public\ AND extension .dll |
Detect | High | Drop-time coverage that fires before Notepad++ is ever launched. |
| — | Hash IOC | REPLACE_WITH_… |
Not deployable | — | No hash exists in any reviewed source. Do not fabricate one to fill the row. |
Alert package — IOA-1 / Q1
| Scheduled Search | DETECT — Notepad++ from public profile (UAC-0099 LUNCHPOKE) |
|---|---|
| Description | Fires when the Notepad++ editor executes from %PUBLIC%, ProgramData, AppData or Windows\Temp. UAC-0099 ships a complete legitimate Notepad++ 8.8.3 to the victim so its plugin loader will side-load LUNCHPOKE; running it from a staging directory is unavoidable for that chain. |
| Email subject | [HIGH] Detection: UAC-0099 LUNCHPOKE — Notepad++ executing from public profile |
| Body | What fired: a signed copy of Notepad++ started from a user-writable directory rather than an installed location. Why it matters: this is the side-load host in the UAC-0099 LUNCHPOKE chain. Notepad++ loads any DLL sitting in its plugins folder — no exploit involved, so signature and reputation checks pass cleanly. Immediate actions: network-contain the host; enumerate %PUBLIC% for the Notepad++ bundle and any plugins\NppExport\ directory; list scheduled tasks with minute-level intervals; preserve the DLL before deleting anything.Escalate: if a matching scheduled task or RemoteLibUpdater.exe is present, treat as a confirmed intrusion and escalate to IR — UAC-0099 is an access broker for APT44/Sandworm. |
L1 triage checklist
- Record the full
ImageFileName. Is it under%PUBLIC%? If it is under Program Files, this is likely a portable-app FP — note and close. - List the directory. A full Notepad++ 8.8.3 tree plus
updater.rarpluswinrar.exealongside it is conclusive. - Check for
plugins\NppExport\NppExport.dllinside that tree and preserve a copy before any removal. - Run Q3 host-scoped. Any task pointing into
%PUBLIC%, especially at a three-minute interval, escalates immediately. - Run Q4 host-scoped for
RemoteLibUpdater.exeor thesetup nodisplayarguments. - Check
%PUBLIC%\Wallpapers\for an executable whose version metadata saysschtasks.exe(native hunt 7.4). - Identify the parent. A script host parent confirms the VBS delivery stage; pull the original email and the source URL.
- Sweep the estate with Q1 and Q9 for the same user, the same sender, and the same staging path shape.
Pivot queries
// Host-scoped: everything this host did around the hit. Replace the placeholder, // then set the time window to the two hours either side in the console. #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ComputerName=/^REPLACE_WITH_HOSTNAME$/i | ImageFileName=/\\Users\\Public\\/i | table([ComputerName, UserName, FileName, ImageFileName, CommandLine, ParentBaseFileName, ProcessStartTime]) // Estate-wide: which hosts have ANY executable content staged under the public profile #event_simpleName=/^(PeFileWritten|ZipFileWritten)$/ | TargetFileName=/\\Users\\Public\\/i | groupBy([ComputerName, UserName], function=count(as=Writes)) | sort(Writes, order=desc, limit=100)
Machine-Readable IOC Appendix
Grouped quick-copy. The CSV is shaped for Falcon IOC Management import; the placeholder rows are intentional and must be filled from your own sample before they will import.
type,value,action,severity,platform,description filename,RemoteLibUpdater.exe,detect,high,windows,BURNYBEAR loader unpacked from updater.rar filename,InitTest.dll,detect,high,windows,MATCHBOIL.V2 C# stager loaded by BURNYBEAR filename,updater.rar,detect,medium,windows,Password-protected payload archive unpacked by LUNCHPOKE filename,Evernote.zip,detect,medium,windows,Second-stage archive carrying Notepad++ 8.8.3 and the rogue plugin filename,Background.exe,detect,medium,windows,Renamed copy of schtasks.exe used to register the persistence task scheduled_task,W1n3r-U09oTy-Ap5,detect,high,windows,Persistence task container observed by CERT-UA - name rotates per victim directory,fFthY3-Ytrevc3w-ab3,detect,high,windows,LUNCHPOKE working directory under the public Libraries folder - name rotates sha256,REPLACE_WITH_LUNCHPOKE_NPPEXPORT_SHA256,detect,critical,windows,No hash published in any reviewed source sha256,REPLACE_WITH_BURNYBEAR_REMOTELIBUPDATER_SHA256,detect,critical,windows,No hash published in any reviewed source sha256,REPLACE_WITH_MATCHBOIL_V2_INITTEST_SHA256,detect,critical,windows,No hash published in any reviewed source domain,REPLACE_WITH_MATCHBOIL_V2_C2_DOMAIN,detect,critical,windows,MATCHBOIL.V2 C2 never disclosed by CERT-UA # CONTEXT ONLY - DO NOT IMPORT AS INDICATORS: # NppExport.dll is a genuine Notepad++ plugin name. Hunt it by write location only. # notepad++.exe / winrar.exe / schtasks.exe are legitimate signed binaries. # easysend[.]co is a legitimate consumer file-transfer service that was abused. Monitor - do not block.
%PUBLIC%\Libs_<random digits>\Notepad\ staging directory for the Notepad++ 8.8.3 bundle %PUBLIC%\Libraries\<random>\ LUNCHPOKE working directory (observed: fFthY3-Ytrevc3w-ab3) %PUBLIC%\Wallpapers\Background.exe renamed copy of schtasks.exe <staging>\plugins\NppExport\NppExport.dll LUNCHPOKE, side-loaded by notepad++.exe <working>\RemoteLibUpdater.exe BURNYBEAR <working>\InitTest.dll MATCHBOIL.V2 \W1n3r-U09oTy-Ap5\Updates scheduled task, runs every 3 minutes setup nodisplay required BURNYBEAR arguments
B1 notepad++.exe executing from %PUBLIC% / ProgramData / AppData / Windows\Temp
B2 a .dll written into any *\plugins\* directory beneath a user-writable path
B3 scheduled task whose action path is under %PUBLIC%
B4 scheduled task repetition interval of 5 minutes or less
B5 a process that is NOT schtasks.exe issuing schtasks create syntax
B6 notepad++.exe as the parent of cmd / powershell / wscript / cscript / an archiver
B7 wscript/cscript command line: document extension + padding whitespace + .vbs
B8 an archiver executing from a user-writable path with a password switch
B9 any process executing from %PUBLIC%\Libraries or %PUBLIC%\Libs_*
B10 a non-browser, non-sync-client process resolving consumer cloud-storage domains
B11 sudden sustained RAM and CPU exhaustion by an unsigned binary run with no arguments
(BURNYBEAR's deliberate anti-analysis fallback)
{
"pack": "UAC-0099 LUNCHPOKE / BURNYBEAR / MATCHBOIL.V2",
"version": "0.1",
"generated": "2026-07-25",
"actor": { "primary": "UAC-0099", "relationship": "initial access for APT44 / Sandworm" },
"malware": ["LUNCHPOKE", "BURNYBEAR", "MATCHBOIL.V2"],
"targeting": "Ukrainian organisations",
"atomic_iocs": {
"filenames": ["RemoteLibUpdater.exe", "InitTest.dll", "updater.rar",
"Evernote.zip", "Background.exe"],
"scheduled_task": "W1n3r-U09oTy-Ap5",
"directory": "fFthY3-Ytrevc3w-ab3",
"hashes": [],
"c2": []
},
"context_only_do_not_block": ["NppExport.dll", "notepad++.exe",
"winrar.exe", "schtasks.exe", "easysend[.]co"],
"attack": ["T1566.002", "T1204.002", "T1059.005", "T1036.003", "T1036.005",
"T1036.007", "T1574.001", "T1140", "T1053.005", "T1074.001",
"T1105", "T1102", "T1562"],
"queries": 10,
"ioa_candidates": 6,
"known_gaps": ["module-load telemetry", "email gateway", "resource-exhaustion fallback"]
}
Detection Validation Gates
Do not mark this pack deployed until every gate below has an owner and a date. Gates 1 to 4 are build-time; gates 5 to 8 are tenant-time and only you can close them.
| # | Gate | How it is proven | Status |
|---|---|---|---|
| G1 | Structural — gold HuntPack layout | verify_huntpack.py exits 0 | Passed at build |
| G2 | Field names are real Falcon data-model fields | lint_cql_fields.py exits 0 | Passed at build |
| G3 | CQL parses — no known breaking constructs | lint_cql_syntax.py exits 0 | Passed at build |
| G4 | Every atomic indicator traces to a saved source snapshot | check_ioc_provenance.py exits 0 against UAC0099-LunchPoke-Notepad-Hunt-sources/ | Passed at build |
| G5 | Each query returns rows in your tenant when it should | Run Q1 with a deliberately staged, benign copy of Notepad++ under %PUBLIC% on one test host. If Q1 returns nothing, your process telemetry or field mapping is wrong, not the query. | Open |
| G6 | Baseline established for the medium-FP queries | Run Q6, Q8 and Q10 over 7 days. Record the benign population, then write the exclusions named in each // TUNING: line before scheduling. | Open |
| G7 | ScheduledTaskRegistered is actually flowing | Create a throwaway task on a test host and confirm Q3 sees it. Many estates find this event missing and never notice until a hunt returns a false clean. | Open |
| G8 | Deep-links land correctly on a non-US-1 cloud | Switch the selector above to US-2, click any "Open in Falcon", confirm the URL contains /investigate/search? and the query autoruns. | Open |
Hardening — Tiered
Every control below is anchored to the specific step in this chain that it breaks. The chain has no exploit in it, so patching is hygiene rather than remediation — the controls that actually stop it are execution location, script handling and task-creation policy.
| Control | Breaks which step | Authority | Verify |
|---|---|---|---|
Block executable content from email client and webmail (Microsoft ASR rule BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550), enabled in Block mode. |
Steps 1–3 — the delivered ZIP and the VBS inside it. | M1040 Behavior Prevention on Endpoint; Microsoft Defender ASR baseline. | (Get-MpPreference).AttackSurfaceReductionRules_Ids |
Block JavaScript/VBScript from launching downloaded executable content (ASR D3E037E1-3EB8-44C8-A917-57927947596D). |
Step 4 — the VBS fetching and launching the second stage. | M1040; MS Security Baseline for Windows. | Same as above; confirm the rule ID reports 1 (Block). |
Block execution of potentially obfuscated scripts (ASR 5BEB7EFE-FD9A-4556-801D-275E5FFC04CC). |
Step 3 — space-padded, deliberately deceptive script files. | M1040. | As above. |
Disable Windows Script Host for standard users, or at minimum re-associate .vbs, .vbe, .js, .jse, .wsf and .wsh to open in Notepad instead of executing. |
Step 3 — kills the delivery stage outright. This is the single highest-leverage control in the list. | M1042 Disable or Remove Feature or Program; CIS Microsoft Windows Benchmark. | Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings' -Name Enabled |
| Turn off "Hide extensions for known file types" estate-wide via GPO. | Step 3 — the double-extension lure depends on the extension being hidden or scrolled off. | M1017 User Training (technical enforcement of); CIS Benchmark. | Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -Name HideFileExt |
| Enable "Audit Other Object Access Events" (Success) so task creation writes Event ID 4698. | Step 10 — without this, native hunt 7.5 and half of your forensic timeline do not exist. | M1047 Audit; MS Security Baseline. | auditpol /get /subcategory:"Other Object Access Events" |
| Quarantine inbound archives containing script files at the mail gateway, and rewrite or block URL-shortener links. | Steps 1–3 — the earliest and cheapest interdiction point. | M1054 Software Configuration; M1021 Restrict Web-Based Content. | Send a test archive containing a benign .vbs from an external account. |
| Control | Breaks which step | Authority | Verify |
|---|---|---|---|
AppLocker or WDAC deny rules for %PUBLIC%, %TEMP% and user-writable AppData paths, audit mode first. |
Steps 5–11 — every executable in this chain runs from a user-writable directory. | M1038 Execution Prevention; CIS Microsoft Windows Benchmark; MS WDAC guidance. | Get-AppLockerPolicy -Effective -Xml, then review AppLocker EXE/DLL audit events. |
| Update Notepad++ to 8.9.7, WinRAR to 7.23, 7-Zip to 26.02 and remove unmanaged portable copies. | Not this chain directly — CERT-UA's own guidance, aimed at the known flaws used in follow-on stages. Note the bundled WinRAR means the chain does not depend on a vulnerable local copy. | CERT-UA advisory 6318634; M1051 Update Software. | Software inventory query for versions below those baselines. |
| Restrict scheduled-task creation by standard users where the business allows, and alert on any task with a repetition interval of 5 minutes or less. | Step 10 — removes the persistence anchor. | M1018 User Account Management; M1047 Audit. | Native hunt 7.1 should return only your known monitoring agents. |
| Constrain Notepad++ plugin loading — where Notepad++ is genuinely needed, deploy it as a managed package under Program Files and use a WDAC policy that permits DLL load only from that signed directory. | Step 7 — makes the side-load fail even if the bundle lands on disk. | M1038; M1045 Code Signing. | Attempt to load an unsigned test DLL from a plugins folder outside Program Files; it must be denied. |
| Egress and DNS category filtering for URL shorteners and consumer file-transfer services, with an allowlist for the ones the business genuinely uses. | Steps 2 and 12 — both delivery and the Dropbox tool-transfer fallback. | M1021 Restrict Web-Based Content; M1037 Filter Network Traffic. | Resolve a shortener domain from a workstation and confirm the block. |
| Control | Breaks which step | Authority | Verify |
|---|---|---|---|
| Enterprise application allowlisting (WDAC) in enforce mode, covering DLLs and not only EXEs. | The entire chain. DLL-level enforcement is what makes plugin side-loading structurally impossible. | M1038 Execution Prevention; NIST SP 800-167; CIS Benchmark. | WDAC event log shows blocked DLL loads from non-allowlisted paths. |
| Retire Windows Script Host from the standard build and migrate any surviving legacy scripts to signed PowerShell under Constrained Language Mode. | Step 3, permanently. | M1042; M1045 Code Signing. | WSH disabled in the golden image; verified at build validation. |
| Formal software-provenance policy: users must not be able to obtain or run application bundles from consumer file-transfer services. | Steps 2–6. The chain's premise is that a user can receive and run a whole application bundle. | M1017 User Training; M1021; M1038. | Policy attestation plus a periodic estate scan for unmanaged application trees under user-writable paths. |
| Phishing simulation using image-only hyperlinks and space-padded double extensions, measured for click-through rather than report rate alone. | Step 1. | M1017 User Training. Best practice — no formal benchmark | Simulation results trending down quarter on quarter. |
Deployable Playbooks
13.1 — Disable Windows Script Host (M1042)
# Run elevated. Sets both the 64-bit and 32-bit WSH policy keys. # Reversible: set Enabled back to 1. $keys = @( 'HKLM:\SOFTWARE\Microsoft\Windows Script Host\Settings', 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows Script Host\Settings' ) foreach ($k in $keys) { if (-not (Test-Path $k)) { New-Item -Path $k -Force | Out-Null } New-ItemProperty -Path $k -Name 'Enabled' -Value 0 -PropertyType DWord -Force | Out-Null Write-Host "WSH disabled at $k" } # Verify Get-ItemProperty -Path $keys[0] -Name Enabled | Select-Object Enabled
13.2 — Enable the three relevant ASR rules in Block mode (M1040)
# Run elevated on a pilot ring. Use AuditMode (value 2) first if you are unsure. $rules = @{ 'BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550' = 'Block executable content from email client and webmail' 'D3E037E1-3EB8-44C8-A917-57927947596D' = 'Block JS/VBScript from launching downloaded executable content' '5BEB7EFE-FD9A-4556-801D-275E5FFC04CC' = 'Block execution of potentially obfuscated scripts' } foreach ($id in $rules.Keys) { Add-MpPreference -AttackSurfaceReductionRules_Ids $id -AttackSurfaceReductionRules_Actions Enabled Write-Host ("Enabled: {0} -- {1}" -f $id, $rules[$id]) } # Verify: Ids and Actions are positionally paired; 1 = Block, 2 = Audit $p = Get-MpPreference for ($i = 0; $i -lt $p.AttackSurfaceReductionRules_Ids.Count; $i++) { "{0} = {1}" -f $p.AttackSurfaceReductionRules_Ids[$i], $p.AttackSurfaceReductionRules_Actions[$i] }
13.3 — Show file extensions estate-wide (defeats the double-extension lure)
# Deploy per-user via GPO preference or logon script. HideFileExt = 0 shows extensions. $path = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' New-ItemProperty -Path $path -Name 'HideFileExt' -Value 0 -PropertyType DWord -Force | Out-Null Stop-Process -Name explorer -Force # restarts Explorer to apply # Note: this shows the extension but does NOT collapse the padding whitespace. # A name padded with 40 spaces still reads as a PDF in a narrow column. Pair this # with ASR and WSH controls -- on its own it is not sufficient.
13.4 — AppLocker deny rules for user-writable execution paths (M1038)
<!-- Import in AUDIT mode first: Set-AppLockerPolicy -XmlPolicy .\deny-public.xml
Review 8003/8006 events for a week before switching EnforcementMode to Enabled. -->
<AppLockerPolicy Version="1">
<RuleCollection Type="Exe" EnforcementMode="AuditOnly">
<FilePathRule Id="a1b2c3d4-0001-0000-0000-000000000001"
Name="Deny EXE from Public profile"
Description="UAC-0099 LUNCHPOKE stages the whole chain under %PUBLIC%"
UserOrGroupSid="S-1-1-0" Action="Deny">
<Conditions><FilePathCondition Path="%OSDRIVE%\Users\Public\*"/></Conditions>
</FilePathRule>
</RuleCollection>
<RuleCollection Type="Dll" EnforcementMode="AuditOnly">
<FilePathRule Id="a1b2c3d4-0002-0000-0000-000000000002"
Name="Deny DLL load from Public profile"
Description="Blocks the NppExport.dll plugin side-load at its source"
UserOrGroupSid="S-1-1-0" Action="Deny">
<Conditions><FilePathCondition Path="%OSDRIVE%\Users\Public\*"/></Conditions>
</FilePathRule>
</RuleCollection>
</AppLockerPolicy>
13.5 — Enable task-creation auditing (M1047)
# Produces Security Event ID 4698 on task creation. Feed it to your SIEM. auditpol /set /subcategory:"Other Object Access Events" /success:enable /failure:enable # Verify auditpol /get /subcategory:"Other Object Access Events"
13.6 — Post-deployment CQL spot-check
// After the AppLocker and WSH rollout, this should trend to zero.
// A flat, non-zero line means the policy did not apply to that host group.
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| ImageFileName=/\\Users\\Public\\/i
| groupBy([ComputerName], function=count(as=Executions))
| sort(Executions, order=desc, limit=200)
Containment Runbook
Phase 1 — Isolate (0 to 15 minutes)
- Network-contain the host in Falcon. Do not power it off — BURNYBEAR's resource-exhaustion fallback and the three-minute task both leave volatile evidence.
- Disable the user's account sessions if the mail account is implicated, and force a token revocation.
- Preserve, in this order, before touching anything: running process list, the full
%PUBLIC%tree, and the scheduled-task export (schtasks /query /xml ONE). - Open the incident with the sender address, the shortener URL and the file-transfer domain from the original email.
Phase 2 — Scope (15 to 90 minutes)
- Run Q1 and Q9 estate-wide. These two answer "is this one host or a campaign" faster than anything else in the pack.
- Run Q3 estate-wide for tasks pointing into
%PUBLIC%, then native hunt 7.1 for minute-level intervals on any host EDR cannot reach. - Pull the mail gateway for every recipient of the same sender, subject or attachment hash. Image-borne links mean URL-rewrite logs may be the only record of who clicked.
- Run Q7 estate-wide — other victims may still be at the delivery stage and not yet detonated.
- Check for lateral movement. UAC-0099 hands access to APT44/Sandworm; treat a confirmed hit as a potential precursor to destructive activity, not as commodity malware.
Phase 3 — Eradicate
- Delete the scheduled task first, before removing files — otherwise it re-launches the loader every three minutes while you work.
schtasks /delete /tn "\W1n3r-U09oTy-Ap5\Updates" /f, substituting the task name you actually observed. - Terminate
RemoteLibUpdater.exeand anynotepad++.exerunning from a staging path. - Collect, then remove: the
%PUBLIC%\Libs_*staging tree, the%PUBLIC%\Libraries\*working directory, and%PUBLIC%\Wallpapers\Background.exe. - Sweep for additional tasks — MATCHBOIL.V2 registers its own, so removing only the LUNCHPOKE task is not sufficient.
- Submit the recovered
NppExport.dll,RemoteLibUpdater.exeandInitTest.dllfor analysis. Populate the hash placeholders in this pack from those samples — you will be the first source of them your organisation has.
Phase 4 — Recover and improve
- Reimage rather than clean, if MATCHBOIL.V2 executed at all. Its stated purpose is fetching arbitrary follow-on payloads and none of them are documented.
- Reset the user's credentials and any credentials cached on the host.
- Deploy the Immediate hardening tier estate-wide if it is not already in place; the WSH control alone breaks this chain.
- Promote Q1, Q3, Q5 and Q7 to Scheduled Searches with the alert package from section 9.
- Re-run gates G5 to G8 and record the closure dates in section 11.
Detection Coverage Map
| Chain step | Technique | Coverage | Query | Confidence |
|---|---|---|---|---|
| 1. Phishing email, image-borne link | T1566.002 | Gap G2 | Gateway only | — |
| 2. Shortener to file-transfer service | T1102 | Partial | Q10 | Low |
| 3. Double-extension VBS delivered | T1036.007 | Covered | Q7 | High |
| 4. VBS fetches Evernote.zip | T1204.002, T1059.005 | Covered | Q7, Q9 | High |
| 5. Bundle extracted to public profile | T1074.001 | Covered | Q2, Q9 | High |
| 6. notepad++.exe launched from staging dir | T1574.001 | Covered | Q1 | High |
| 7. NppExport.dll side-loaded | T1574.001 | Gap G1 — inferred | Q6 (lineage proxy) | Medium |
| 8. updater.rar unpacked with a password | T1140, T1560.001 | Covered | Q8 | Medium |
| 9. schtasks.exe copied to Background.exe | T1036.003 | Covered | Q5, Q9 | High |
| 10. Three-minute scheduled task registered | T1053.005 | Covered | Q3 | High |
| 11. BURNYBEAR loads MATCHBOIL.V2 | T1204.002 | Covered | Q4 | High |
| 11b. BURNYBEAR resource-exhaustion fallback | T1562 | Gap G3 | — | — |
| 12. MATCHBOIL.V2 stages payloads / C2 | T1105, T1102 | Partial | Q9, Q10 | Low |
Declared gaps
| ID | Gap | Why it exists | Compensating control |
|---|---|---|---|
| G1 | The plugin side-load itself is not directly observed | Module/image-load telemetry is tenant-dependent and frequently not retained at the volume a DLL-load hunt needs. | Q1 catches the host process in the wrong place; Q6 catches what it spawns afterwards; Q2 catches the DLL at write time. Between them the step is bracketed on both sides. |
| G2 | Delivery is invisible to EDR | The link lives on an image attachment and resolution happens in the mail client and browser, before any endpoint process is created. | Mail gateway hunting plus the Immediate-tier gateway controls. Q7 picks the chain back up one step later. |
| G3 | BURNYBEAR's resource-exhaustion fallback is not detected | It is a performance symptom, not a process or file event. CQL over EDR telemetry is the wrong instrument. | Behavioural signature B11 in section 10, routed to whatever performance monitoring you already run. Q4 catches the same binary on the path that matters more. |
| G4 | No hash or C2 coverage at all | No reviewed source published any. Fabricating them would have been worse than declaring the gap. | Ten behavioural and path-based queries. Fill the REPLACE_WITH_ rows the moment you or CERT-UA produce a sample. |
Hunt Summary Ticket
HUNT TICKET — UAC-0099 LUNCHPOKE / BURNYBEAR / MATCHBOIL.V2
VERSION: v0.1 (Draft) - 2026-07-25
AUTHOR: HuntPack
THREAT: UAC-0099 abusing Notepad++ 8.8.3 plugin loading
MALWARE: LUNCHPOKE (NppExport.dll) / BURNYBEAR (RemoteLibUpdater.exe)
/ MATCHBOIL.V2 (InitTest.dll)
ORIGIN: CERT-UA advisory 6318634, published 2026-07-21
ATTRIBUTION: Russia-aligned; prior initial-access provider for APT44 / Sandworm
TARGETING: Ukrainian organisations
PLATFORM: Windows endpoint (user context - no privilege escalation required)
HYPOTHESIS: An adversary delivered a complete legitimate Notepad++ 8.8.3 bundle to
an endpoint and used the editor's own plugin loader to execute a
malicious DLL, then persisted via a scheduled task firing every
three minutes from the public profile.
QUERIES: 10 CQL (6 IOA candidates, 4 hunt-only)
Q1 Notepad++ from user-writable path CONF high FP low
Q2 Plugin DLL written to public/temp CONF high FP low
Q3 Task action under public profile CONF high FP low-med
Q4 BURNYBEAR execution / arguments CONF high FP low
Q5 Renamed Task Scheduler binary CONF high FP low
Q6 Notepad++ spawning shells/archivers CONF med FP med
Q7 Double-extension VBS execution CONF high FP low
Q8 Archiver with password switch CONF med FP med
Q9 Campaign artefact sweep CONF high FP low
Q10 Cloud-storage tool transfer CONF med FP med
ATOMIC IOCS: 7 shipped, all traced to saved source snapshots
5 filenames + 1 scheduled-task name + 1 directory name
0 hashes, 0 IPs, 0 C2 domains - none published in any source
4 REPLACE_WITH_ placeholders shipped in their place
DO NOT BLOCK: NppExport.dll (genuine Notepad++ plugin name)
notepad++.exe / winrar.exe / schtasks.exe (legitimate signed binaries)
easysend[.]co (legitimate file-transfer service, abused)
GAPS: G1 module-load telemetry (side-load inferred, not observed)
G2 email delivery outside EDR
G3 resource-exhaustion fallback not detectable in CQL
G4 no hash or C2 coverage - intel does not exist
TOP CONTROL: Disable Windows Script Host. It breaks the chain at step 3, before
any of the rest of it can happen.
NEXT ACTION: 1. Run Q1 and Q3 estate-wide today.
2. Close validation gates G5 and G7 - prove the queries CAN fire.
3. Baseline Q6/Q8/Q10 for 7 days, then apply the TUNING exclusions.
4. Promote Q1/Q3/Q5/Q7 to Scheduled Searches at Detect.
5. Fill the hash placeholders from any recovered sample.
STATUS: Ready to hunt - not yet validated in tenant
Changelog
REPLACE_WITH_ placeholders because no reviewed source publishes them. NppExport.dll, notepad++.exe, winrar.exe, schtasks.exe and easysend[.]co deliberately excluded from the import CSV as legitimate artefacts.References
- CERT-UA — advisory 6318634, "UAC-0099: LUNCHPOKE, BURNYBEAR, оновлений MATCHBOIL.V2 та використання Notepad++ 8.8.3", 2026-07-21. cert.gov.ua/article/6318634 — snapshot
01-cert-ua-6318634.txt(metadata from CERT-UA's own RSS and articles API; body is behind an Angular SPA). - The Hacker News — Fake Notepad++ Plugin Delivers MATCHBOIL.V2 in UAC-0099 Attacks, 2026-07-24. thehackernews.com — snapshot
02-thehackernews.txt. - BleepingComputer — Hackers abuse Notepad++ plugins to stealthily install malware, 2026-07-23. bleepingcomputer.com — snapshot
03-bleepingcomputer.txt. - Security Affairs — UAC-0099 Is Now Hiding Malware Inside a Fake Notepad++ Plugin to Target Ukrainian Organizations, 2026-07-24. securityaffairs.com — snapshot
04-securityaffairs.txt. - Cybersecurity Help — UAC-0099 espionage cluster uses legitimate Notepad++ software to hide malicious code, 2026-07-23. cybersecurity-help.cz — snapshot
05-cybersecurity-help.txt. - Cyber Press — Hackers Weaponize Notepad++ 8.8.3 to Silently Install MATCHBOIL.V2 Malware, 2026-07-24. cyberpress.org — snapshot
06-cyberpress.txt. - GBHackers — Hackers Weaponize Notepad++ Plugins to Silently Infect Windows Systems, 2026-07-24. gbhackers.com — snapshot
07-gbhackers.txt. - MITRE ATT&CK — T1574.001 Hijack Execution Flow: DLL, T1053.005 Scheduled Task, T1036.003/.005/.007 Masquerading, T1204.002 User Execution, T1105 Ingress Tool Transfer. attack.mitre.org
- MITRE ATT&CK Mitigations — M1038 Execution Prevention, M1040 Behavior Prevention on Endpoint, M1042 Disable or Remove Feature, M1045 Code Signing, M1047 Audit, M1051 Update Software, M1021 Restrict Web-Based Content.
- Microsoft — Attack Surface Reduction rules reference (rule GUIDs used in playbook 13.2) and Windows Security Baselines.
- CIS Microsoft Windows Benchmark — Windows Script Host, file-extension display, and audit-policy settings.
UAC0099-LunchPoke-Notepad-Hunt-sources/. They are treated strictly as untrusted data. No fetched page
contained instructions aimed at an automated agent, and nothing in any of them altered how this pack was built.