Four concurrent OTX pulses published on 2026-10-07/08 reveal a maturing, multi-front credential-theft ecosystem in which stolen secrets are the primary commodity — harvested at network edge, in the browser, in developer toolchains, and validated in the cloud.
The four campaign threads:
-
FortiBleed (FortiGate/SSL VPN mass compromise) — 86,644+ compromised devices across 194 countries. Attackers exploit reused/leaked credentials and legacy SHA-256 password storage on internet-facing FortiGate firewalls, then crack harvested hashes at scale using distributed GPU clusters (Hashtopolis-style infrastructure). Verified compromises are reportedly feeding initial access broker (IAB) pipelines with ties to INC/Lynx ransomware staging and victim lockouts. The IC3 has published a joint CSA (261006.pdf), elevating this to federal-advisory severity.
-
Malicious Firefox crypto-wallet extensions — 16 extensions impersonating Rabby Wallet (cloned as "Raabby WaIIet" using homoglyph substitution) and OKX Wallet intercept seed phrases and private keys during wallet import flows, exfiltrating via Cloudflare Workers endpoints that blend into legitimate CDN traffic.
-
TensorLake npm SDK compromise (ChainDrop / Shai-Hulud) — version 0.5.144 of a package with ~12,000 weekly downloads was poisoned with obfuscated credential-harvesting code targeting npm tokens, GitHub tokens, AWS credentials, HashiCorp Vault, Kubernetes configs, SSH keys, and AI development tooling. Shai-Hulud is a self-propagating worm: stolen npm tokens are used to publish malicious versions of other packages owned by the victim, creating exponential supply-chain spread.
-
AWS Bedrock credential validation ("token-jacking") — harvesting platforms such as KMON_NOC systematically test stolen AWS keys:
GetCallerIdentityfor validation, thenListFoundationModels/Conversecalls against Amazon Bedrock to determine whether keys unlock paid LLM inference — for crypto-jacking-style LLM abuse, data extraction via model endpoints, or resale of "AI-capable" keys on dark web markets.
The collective picture: credential material is being harvested at every layer — perimeter VPN, browser, CI/CD, and cloud — then industrially validated, cracked, brokered, and monetized. A single leaked secret now has a fully automated downstream pipeline from theft to ransomware deployment.
Threat Actor / Malware Profile
FortiBleed (Attribution: Unknown; IAB ecosystem feeding INC/Lynx)
- Distribution / Access: Exploitation of internet-facing FortiGate SSL VPN gateways using credential reuse from prior breach corpora; abuse of legacy SHA-256 (unsalted/weakly hashed) credential stores on unpatched firmware.
- Payload behavior: Mass extraction of VPN user databases and session tokens; offline cracking via distributed GPU rigs (Hashtopolis orchestration); validated admin-level creds resold or used directly.
- Post-compromise: VPN account lockouts reported (likely password-spray side effects or deliberate denial during extortion), followed by INC/Lynx ransomware staging in some victim environments.
- Anti-analysis: Activity rides legitimate SSL VPN management plane traffic, making network detection difficult without behavioral baselining.
Shai-Hulud / ChainDrop npm Worm (TensorLake SDK 0.5.144)
- Distribution: Compromised maintainer publish flow on the npm registry; malicious postinstall hooks in a trusted package.
- Payload behavior: Obfuscated JavaScript harvests
~/.npmrctokens,~/.aws/credentials, GitHub tokens (env vars,ghCLI config), kubeconfig files, SSH private keys (~/.ssh), HashiCorp Vault tokens, and AI-tool credentials. - Persistence / Propagation: Uses stolen npm tokens to self-publish trojanized versions of the victim's other packages — true worm behavior across the registry.
- Anti-analysis: Heavy string obfuscation and multi-stage payload reveal; execution gated to install-time hooks to evade sandbox detonation.
Firefox Wallet Stealers
- Distribution: Mozilla Add-ons store listings using homoglyph brand impersonation ("Raabby WaIIet" with capital-I substitution).
- Payload behavior: Content scripts hook wallet import/recovery flows, capturing seed phrases and private keys at the DOM level before encryption.
- C2: Exfiltration to Cloudflare Workers domains — serverless, ephemeral, and reputation-laundered.
KMON_NOC / Bedrock Key Validators
- Behavior: Automated
sts:GetCallerIdentityvalidation followed bybedrock:ListFoundationModelsandbedrock:Converse/InvokeModelprobes (including Anthropic Claude models) to grade key value for resale. - Detection opportunity: These API calls from unfamiliar principals are high-fidelity signals in CloudTrail.
IOC Analysis
The pulse set contains three indicator classes with distinct operationalization paths:
| Type | Count (sampled) | Source pulse | Operationalization |
|---|---|---|---|
| IPv4 (scanner/C2/exfil) | 8 + 8 sampled | FortiBleed, Bedrock validators | Block at perimeter/proxy; retro-hunt VPN auth logs & netflow for 30–90 days |
| FileHash-SHA256 | 8 + 2 + 2 sampled | Firefox extensions, TensorLake packages | EDR blocklists; hunt package caches, node_modules, browser extension stores |
| Behavioral (API patterns) | n/a | Bedrock, Shai-Hulud | CloudTrail analytics; npm audit; egress DNS to Cloudflare Workers |
SOC guidance:
- IPs such as
103.27.186.156,154.202.59.169,45.154.12.132,80.75.212.113(FortiBleed) and112.78.151.90,78.109.78.211,83.194.172.248(validator infrastructure) should be pushed to firewall/proxy blocklists and cross-matched against VPN authentication and outbound connection logs. Expect high churn — prioritize retro-hunting over pure blocking. - SHA256 hashes for the malicious Firefox extensions should be swept across managed browser extension inventories (via
Get-Itemon extension XPIs, or MDM browser policies). The TensorLake hashes should be checked against build artifacts and CI caches. - Tooling: Decode/npm-audit the obfuscated SDK payload with
deobfuscate.ioorbox-js; verify extension hashes against the Socket.dev research; pivot on IPs in OTX, AbuseIPDB, and GreyNoise to distinguish scanner vs. C2 roles.
Detection Engineering
---
title: Shai-Hulud npm Supply Chain Credential Harvesting - Postinstall Execution
id: 7f3a1b2c-9e4d-4c1a-a8f2-3d5e6b7c8d9e
status: experimental
description: Detects Node.js/npm child processes spawned during package install accessing credential stores (AWS, SSH, kubeconfig, npmrc), consistent with Shai-Hulud/ChainDrop worm behavior
references:
- https://socket.dev/blog/tensorlake-compromise
author: Security Arsenal Threat Intel
date: 2026/10/08
tags:
- attack.credential_access
- attack.t1552
- attack.t1552.001
- attack.t1195.002
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\node.exe'
- '\npm.exe'
- '\npm.cmd'
selection_access:
CommandLine|contains:
- '.npmrc'
- '.aws\credentials'
- '\.ssh\'
- 'kubeconfig'
- '.kube\config'
- 'vault'
- 'id_rsa'
condition: selection_parent and selection_access
falsepositives:
- Legitimate dev tooling reading configs (rare during install hooks)
level: high
---
title: FortiBleed - Suspicious FortiGate SSL VPN Authentication From Known Malicious Infrastructure
id: 2b8c4d5e-1a6f-4e2b-b3c7-8d9e0f1a2b3c
status: experimental
description: Detects network connections to or from FortiBleed-associated IPv4 indicators used for credential harvesting against FortiGate SSL VPN gateways
references:
- https://www.ic3.gov/CSA/2026/261006.pdf
author: Security Arsenal Threat Intel
date: 2026/10/08
tags:
- attack.initial_access
- attack.t1078
- attack.t1110
logsource:
category: network_connection
product: windows
detection:
selection_dst:
DestinationIp:
- '103.27.186.156'
- '154.202.59.169'
- '45.154.12.132'
- '80.75.212.113'
- '85.11.187.8'
- '193.8.187.2'
- '45.227.254.210'
- '77.91.118.10'
selection_src:
SourceIp:
- '103.27.186.156'
- '154.202.59.169'
- '45.154.12.132'
- '80.75.212.113'
- '85.11.187.8'
- '193.8.187.2'
- '45.227.254.210'
- '77.91.118.10'
condition: 1 of selection_*
falsepositives:
- Unlikely; indicators are pulse-verified malicious
level: critical
---
title: AWS Bedrock Credential Validation - Token-Jacking Probe Pattern
id: 9d1e2f3a-4b5c-6d7e-8f9a-0b1c2d3e4f5a
status: experimental
description: Detects the KMON_NOC-style validation sequence where a principal calls GetCallerIdentity followed by Bedrock model enumeration, indicative of stolen AWS key testing
references:
- https://securitylabs.datadoghq.com/articles/beyond-valid-credentials-how-exposed-aws-keys-are-tested-for-amazon-bedrock-access
author: Security Arsenal Threat Intel
date: 2026/10/08
tags:
- attack.discovery
- attack.t1580
- attack.t1078.004
logsource:
product: aws
service: cloudtrail
detection:
selection_validate:
eventSource: 'sts.amazonaws.com'
eventName: 'GetCallerIdentity'
selection_bedrock:
eventSource: 'bedrock.amazonaws.com'
eventName:
- 'ListFoundationModels'
- 'Converse'
- 'InvokeModel'
condition: selection_validate and selection_bedrock
timeframe: 10m
falsepositives:
- Legitimate AI/ML application bootstrap sequences; tune by known IAM roles and CI/CD principals
level: high
// FortiBleed IOC retro-hunt + suspicious credential-store access (Microsoft Sentinel / Defender)
let FortiBleedIPs = dynamic(["103.27.186.156","154.202.59.169","45.154.12.132","80.75.212.113","85.11.187.8","193.8.187.2","45.227.254.210","77.91.118.10"]);
let BedrockValidatorIPs = dynamic(["112.78.151.90","78.109.78.211","83.194.172.248","103.160.185.100","109.146.93.39","115.138.247.83"]);
union isfuzzy=true
(DeviceNetworkEvents
| where TimeGenerated > ago(30d)
| where RemoteIP in~ (FortiBleedIPs) or RemoteIP in~ (BedrockValidatorIPs)
| summarize Connections=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated),
Ports=make_set(RemotePort) by DeviceName, RemoteIP, InitiatingProcessFileName
| extend HuntContext="OTX_IOC_Network_Match"),
(DeviceProcessEvents
| where TimeGenerated > ago(14d)
| where InitiatingProcessFileName in~ ("node.exe","npm.exe","cmd.exe","powershell.exe")
| where ProcessCommandLine has_any (".npmrc","id_rsa",".kube","kubeconfig","credentials","vault")
| where FileName in~ ("powershell.exe","cmd.exe","node.exe","cat.exe","type.exe","findstr.exe")
| summarize Hits=count(), Commands=make_set(ProcessCommandLine, 10) by DeviceName, InitiatingProcessFileName, bin(TimeGenerated, 1h)
| extend HuntContext="ShaiHulud_CredStore_Access")
| order by HuntContext asc, Connections desc
# Security Arsenal - FortiBleed / Shai-Hulud / Wallet-Stealer IOC Hunt Script
# Run elevated on endpoints and build servers. Outputs findings to CSV.
$ErrorActionPreference = 'SilentlyContinue'
$findings = @()
# --- 1. Check for malicious TensorLake npm package version in node_modules / lockfiles ---
$searchRoots = @("$env:USERPROFILE","C:\projects","C:\src","D:\")
foreach ($root in $searchRoots) {
if (Test-Path $root) {
Get-ChildItem -Path $root -Recurse -Filter "package-lock.json" -Depth 6 | ForEach-Object {
$content = Get-Content $_.FullName -Raw
if ($content -match '"tensorlake"[^}]*"0\.5\.144"' -or $content -match 'tensorlake.*0\.5\.144') {
$findings += [pscustomobject]@{Type="SHAI-HULUD_PACKAGE"; Path=$_.FullName; Detail="Malicious tensorlake 0.5.144 in lockfile"}
}
}
}
}
# --- 2. Hash-sweep Firefox extension XPIs against OTX malicious SHA256 list ---
$badHashes = @(
"7d9d7e80ed52350616be0215a7ded10aaeb9aaa64e34ff8af7f9177c8c855799",
"da447fe02e4577da97144a4d92b395078954fde1ff196746413837e1e4a20bcd",
"be246ca5cb1372394e0443df45454f88ca39eb4a8dcfc4a99cb8865100fb4897",
"c550f0860012e0dfab14ed65a9425961e22025e0ab23fd9d69d294a8aa34db2f",
"eb134bbf73046800c8177383754cf754b8776ec30cf5cc8a13655d259e49a4bf",
"2f9270269e631bc4fd634d741afcfc3df8f54e43e40b16f38660fe8ce6c26f51",
"25a0735d0db7dc40e5d45ce42d9c106067e6a66e184d967cfecfab17c3bcb5ef",
"b50a00900399ba99fb6ce1fc151519cb99d44320ef2a631f2237e1aea0ad6fec"
)
$ffExt = "$env:APPDATA\Mozilla\Firefox\Profiles"
if (Test-Path $ffExt) {
Get-ChildItem $ffExt -Recurse -Include "*.xpi" | ForEach-Object {
$h = (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower()
if ($badHashes -contains $h) {
$findings += [pscustomobject]@{Type="MALICIOUS_FF_EXT"; Path=$_.FullName; Detail="SHA256 match: $h"}
}
}
}
# --- 3. Detect recent suspicious access to credential stores (Shai-Hulud behavior artifact) ---
$credPaths = @("$env:USERPROFILE\.npmrc","$env:USERPROFILE\.aws\credentials","$env:USERPROFILE\.kube\config","$env:USERPROFILE\.ssh\id_rsa","$env:USERPROFILE\.vault-token")
foreach ($p in $credPaths) {
if (Test-Path $p) {
$f = Get-Item $p
if ($f.LastAccessTime -gt (Get-Date).AddDays(-3)) {
$findings += [pscustomobject]@{Type="CREDSTORE_RECENT_ACCESS"; Path=$p; Detail="LastAccess: $($f.LastAccessTime) - validate against known activity"}
}
}
}
# --- 4. Active/recent connections to FortiBleed & validator IPs ---
$badIPs = @("103.27.186.156","154.202.59.169","45.154.12.132","80.75.212.113","85.11.187.8","193.8.187.2","45.227.254.210","77.91.118.10","112.78.151.90","78.109.78.211","83.194.172.248","103.160.185.100","109.146.93.39","115.138.247.83")
Get-NetTCPConnection | Where-Object { $badIPs -contains $_.RemoteAddress } | ForEach-Object {
$findings += [pscustomobject]@{Type="MALICIOUS_CONNECTION"; Path=$_.RemoteAddress; Detail="State: $($_.State) | OwningPID: $($_.OwningProcess)"}
}
$findings | Format-Table -AutoSize
$findings | Export-Csv -Path ".\otx_hunt_$(Get-Date -Format 'yyyyMMdd_HHmm').csv" -NoTypeInformation
Write-Host "[+] Hunt complete. $($findings.Count) findings." -ForegroundColor Cyan
Response Priorities
Immediate (0–4 hours):
- Push all FortiBleed and validator IPv4 indicators to perimeter firewalls, proxies, and DNS sinkholes; enable alerting on any historical match over a 90-day retro window.
- Audit npm dependency trees org-wide for
tensorlake@0.5.144; if present, treat as an active incident — rotate all npm, GitHub, AWS, Vault, and SSH credentials present on affected build systems and developer workstations. - Force-reset credentials on all internet-facing FortiGate SSL VPN accounts; verify firmware is current and disable legacy SHA-256 credential storage where configurable.
- Query CloudTrail for
GetCallerIdentity+ListFoundationModelssequences from human-user access keys in the last 90 days.
24 hours (identity & access blast radius):
- Rotate any AWS access keys found in code repos, CI logs, or developer environments; enable Bedrock-specific SCPs denying
bedrock:InvokeModel/Converseexcept to approved roles. - Invalidate active FortiGate VPN sessions; review auth logs for successful logins from OTX-listed IPs and impossible-travel patterns; enforce MFA on all VPN accounts.
- Audit managed browsers for the 16 malicious extensions (Rabby/OKX impersonators); for any hit, assume full wallet compromise and assist users with fund migration to new seed phrases.
- If Shai-Hulud exposure is confirmed, audit npm registry publish history for all packages owned by affected maintainers — the worm self-propagates.
1 week (architectural hardening):
- Migrate FortiGate authentication to MFA-only with certificate-based device posture checks; remove legacy password-hash storage; consider VPN-less ZTNA for administrative access.
- Implement npm provenance/Sigstore verification and CI-based dependency pinning with hash validation; block postinstall script execution in build pipelines (
npm ci --ignore-scripts) where feasible. - Deploy CloudTrail anomaly detection on Bedrock APIs; scope IAM keys to least privilege and eliminate long-lived static access keys in favor of OIDC/roles.
- Enforce enterprise browser extension allowlisting via MDM to prevent unvetted add-on installation.
Related Resources
Security Arsenal Incident Response Managed SOC & MDR Services AlertMonitor Threat Detection From The Dark Side Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.