Security Affairs' Malware Newsletter Round 115 aggregates several active research threads, but two stand out for immediate defensive action: a malicious Twitch browser extension that exposed roughly 30,000 users' OAuth tokens to a Russian-operated bot, and an ongoing multinational campaign exploiting an n-day vulnerability in self-hosted Gitea instances that culminates in deployment of a previously undocumented Linux rootkit. A third thread — the "Gray Rabbits" research into a one-click unauthorized access mechanism — reinforces a theme we've been hammering on in client engagements all year: session tokens and identity artifacts are now the primary target, not passwords.
Neither campaign relies on exotic zero-days. Both succeed because of gaps we see in nearly every environment we assess: unmanaged browser extensions with excessive permission scopes, and internet-exposed development infrastructure (Gitea, GitLab, Jenkins) that lags months behind upstream patches. If your SOC isn't hunting for token exfiltration from browsers and kernel-level persistence on Linux servers, you're blind to both of these campaigns.
Threat 1: Malicious Twitch Browser Extension — OAuth Token Theft at Scale
What Happened
A browser extension marketed to Twitch users — the kind that promises channel analytics, viewer tools, or QoL features — was found siphoning OAuth tokens from approximately 30,000 users and funneling them to infrastructure controlled by a Russian-speaking operator, reportedly via a Telegram bot exfiltration channel. OAuth tokens for Twitch (and frequently the broader session cookies the extension can access) grant API access without the password and, critically, bypass MFA entirely because they represent an already-authenticated session.
Why This Matters to Enterprise Defenders
You may be tempted to file this under "consumer problem." Don't. The same tradecraft is actively used against corporate identities:
- Extensions request broad permissions (
cookies,webRequest,<all_urls>host access) and silently harvest session tokens for Microsoft 365, Google Workspace, Slack, and Okta. - Stolen tokens are replayed from attacker infrastructure, defeating MFA and most conditional access policies that aren't token-binding aware.
- Extension updates can turn a previously benign install malicious overnight — the extension supply chain is a persistent problem because post-install behavior changes don't trigger re-review.
In our incident response work, browser-extension token theft is now a top-three initial access vector for session hijacking cases, right behind infostealers and phishing-as-a-service kits.
Threat 2: Gitea N-Day Exploitation and a New Linux Rootkit
What Happened
Researchers tracking the "Red Heron" activity cluster documented a multinational campaign in which attackers exploited an already-patched (n-day) vulnerability in self-hosted Gitea instances — lightweight, self-hosted Git services that are enormously popular in DevOps environments and frequently internet-exposed for collaboration. Post-exploitation, the actors deployed a new Linux rootkit providing kernel-level concealment of processes, files, and network connections.
The Attack Chain (Defender's View)
- Reconnaissance: Scanning for internet-reachable Gitea instances, fingerprinting version banners (Gitea discloses version information in page footers and API responses by default).
- Exploitation: Abusing a known, patched Gitea flaw on unpatched servers — classic n-day exploitation where the patch exists but the fleet lags.
- Post-exploitation: The Gitea process (typically running as the
gituser) spawns unexpected child processes — shells, downloaders pulling second-stage payloads via curl/wget. - Privilege escalation & persistence: Deployment of a kernel-mode rootkit via loadable kernel module (LKM) insertion (
insmod/modprobe), followed by concealment of attacker processes, cron/systemd persistence, and outbound C2.
Why Linux Rootkits Change Your IR Calculus
Once an LKM rootkit is loaded, userland tools lie to you. ps, netstat, ls, and even EDR agents relying solely on userland hooks can be deceived. Detection has to come from kernel telemetry (eBPF-based sensors, auditd), memory forensics, or out-of-band network monitoring. If your Linux coverage strategy is "we forward syslog to the SIEM," a rootkit can suppress the very logs you're counting on.
Detection & Response
The detections below target the observable behaviors common to both campaigns: suspicious extension installation/persistence on endpoints, token exfiltration patterns, and kernel module loading plus web-service-spawned shells on Linux servers.
Sigma Rules
---
title: Browser Extension Force-Installed or Sideloaded via Registry Policy
id: 3f7a91c2-8e54-4b61-9d03-2c6a5e8f1a47
status: experimental
description: Detects browser extensions being installed or force-installed via Windows registry policy keys, a common persistence and distribution mechanism for malicious extensions that harvest session tokens.
references:
- https://attack.mitre.org/techniques/T1176/
- https://securityaffairs.com/199409/malware/security-affairs-malware-newsletter-round-115.html
author: Security Arsenal
date: 2026/04/06
tags:
- attack.persistence
- attack.t1176
logsource:
category: registry_set
product: windows
detection:
selection:
TargetObject|contains:
- '\Policies\Google\Chrome\ExtensionInstallForcelist'
- '\Policies\Microsoft\Edge\ExtensionInstallForcelist'
- '\Software\Google\Chrome\Extensions'
- '\Software\Microsoft\Edge\Extensions'
filter_known_updaters:
Image|endswith:
- '\GoogleUpdate.exe'
- '\MicrosoftEdgeUpdate.exe'
condition: selection and not filter_known_updaters
falsepositives:
- Enterprise extension deployments via GPO or MDM (baseline approved extension IDs)
level: medium
---
title: Linux Kernel Module Load by Non-Package-Manager Process
id: 8c2d5e19-4a73-4f08-b651-9d3e7c2a6b58
status: experimental
description: Detects loading of kernel modules via insmod or modprobe from non-standard paths or by non-package-management parents, consistent with LKM rootkit installation observed in the Gitea compromise campaign.
references:
- https://attack.mitre.org/techniques/T1547/006/
- https://attack.mitre.org/techniques/T1014/
- https://securityaffairs.com/199409/malware/security-affairs-malware-newsletter-round-115.html
author: Security Arsenal
date: 2026/04/06
tags:
- attack.persistence
- attack.defense_evasion
- attack.t1547.006
- attack.t1014
logsource:
category: process_creation
product: linux
detection:
selection_tool:
Image|endswith:
- '/insmod'
- '/modprobe'
selection_suspicious_args:
CommandLine|contains:
- '/tmp/'
- '/dev/shm/'
- '/var/tmp/'
- '/home/'
filter_legit:
ParentImage|endswith:
- '/dpkg'
- '/apt'
- '/yum'
- '/dnf'
- '/systemd'
condition: selection_tool and (selection_suspicious_args or not filter_legit)
falsepositives:
- Legitimate driver installation by administrators; tune the parent-process filter to your fleet's configuration management tooling
level: high
---
title: Gitea or Git Service Process Spawning Shell or Downloader
id: 5b1e8d42-7c36-4a92-8f14-3d9a2e7c5b06
status: experimental
description: Detects the Gitea server process spawning shells, interpreters, or download utilities, a strong post-exploitation indicator following n-day exploitation of the web application.
references:
- https://attack.mitre.org/techniques/T1190/
- https://attack.mitre.org/techniques/T1059/
- https://securityaffairs.com/199409/malware/security-affairs-malware-newsletter-round-115.html
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.execution
- attack.t1190
- attack.t1059.004
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/gitea'
selection_child:
Image|endswith:
- '/bash'
- '/sh'
- '/dash'
- '/curl'
- '/wget'
- '/python'
- '/python3'
- '/perl'
- '/nc'
- '/ncat'
condition: selection_parent and selection_child
falsepositives:
- Gitea hooks and CI integrations that legitimately invoke shells; baseline hook scripts per repository and alert on deviations
level: high
KQL (Microsoft Sentinel / Defender)
This query hunts Linux Syslog/audit data for kernel module loads and suspicious process lineage from Git services — the rootkit and post-exploitation side of the campaign:
let suspiciousParents = dynamic(["gitea", "gitlab", "nginx", "apache", "httpd"]);
let suspiciousChildren = dynamic(["bash", "sh", "dash", "curl", "wget", "insmod", "modprobe", "python", "perl"]);
union isfuzzy=true
(Syslog
| where Facility =~ "auth" or Facility =~ "kern" or SyslogMessage has_any ("insmod", "modprobe")
| where SyslogMessage has_any (suspiciousChildren)
| extend ParsedCmd = SyslogMessage
| project TimeGenerated, Computer, HostIP, ParsedCmd, SeverityLevel),
(DeviceProcessEvents
| where InitiatingProcessFileName has_any (suspiciousParents)
| where FileName has_any (suspiciousChildren)
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName)
| sort by TimeGenerated desc
For the browser-extension token theft angle, this Defender query surfaces Chromium-based browsers making network connections to messaging-platform API endpoints — the reported exfiltration channel pattern — which has essentially no legitimate business use from a browser process in most environments:
DeviceNetworkEvents
| where InitiatingProcessFileName in~ ("chrome.exe", "msedge.exe", "firefox.exe", "brave.exe")
| where RemoteUrl has_any ("api.telegram.org", "t.me") or RemoteUrl endswith ".onion.site"
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteUrl, RemoteIP, RemotePort
| summarize ConnectionCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by DeviceName, RemoteUrl, RemoteIP
| sort by ConnectionCount desc
Velociraptor VQL
This artifact hunts Linux endpoints for the classic rootkit-adjacent anomalies: processes whose executable has been deleted from disk (in-memory resident payloads) and recently loaded kernel modules outside the distribution's standard module trees:
-- Hunt for processes running deleted executables and modules loaded from suspicious paths
SELECT Pid,
Name,
Exe,
CommandLine,
Username,
CreateTime
FROM pslist()
WHERE Exe =~ '(deleted)'
OR Exe =~ '/tmp/|/dev/shm/|/var/tmp/'
OR CommandLine =~ 'insmod|modprobe'
On Windows endpoints, enumerate installed browser extensions across user profiles to inventory what's actually running in your environment — the first step in finding the malicious one:
-- Enumerate Chromium extension manifests across all user profiles
SELECT FullPath,
Data.name AS ExtensionName,
Data.version AS ExtensionVersion,
Data.permissions AS Permissions,
Mtime AS LastModified
FROM glob(globs='C:/Users/*/AppData/Local/*/User Data/Default/Extensions/*/*/manifest.json')
WHERE Permissions =~ 'cookies|webRequest|<all_urls>|tabs'
Remediation & Verification Script
For Linux servers — audit recently loaded kernel modules, check Gitea's running version against the latest upstream release, and look for common persistence hooks:
#!/bin/bash
# Rootkit and Gitea post-exploitation audit — run as root
echo "=== Recently loaded kernel modules (non-standard paths) ==="
lsmod | awk '{print $1}' | while read mod; do
path=$(modinfo -n "$mod" 2>/dev/null)
if [ -n "$path" ] && [[ "$path" != /lib/modules/* ]]; then
echo "[!] $mod loaded from non-standard path: $path"
fi
done
echo ""
echo "=== Module load events in audit logs (last 7 days) ==="
ausearch -ts recent -k modules 2>/dev/null || grep -E "insmod|modprobe" /var/log/auth.log /var/log/syslog 2>/dev/null | tail -50
echo ""
echo "=== Gitea version check ==="
if command -v gitea &>/dev/null; then
gitea --version
echo "Compare against latest release: https://dl.gitea.com/gitea/ and https://github.com/go-gitea/gitea/security/advisories"
else
sudo -u git /usr/local/bin/gitea --version 2>/dev/null || echo "Gitea binary not found in PATH — check your install location"
fi
echo ""
echo "=== Processes with deleted executables (possible rootkit activity) ==="
for pid in $(ls /proc | grep -E '^[0-9]+$'); do
exe=$(readlink /proc/$pid/exe 2>/dev/null)
if [[ "$exe" == *"(deleted)"* ]]; then
echo "[!] PID $pid ($(cat /proc/$pid/comm 2>/dev/null)) running deleted binary: $exe"
fi
done
echo ""
echo "=== Persistence check: systemd units and cron modified in last 14 days ==="
find /etc/systemd/system /etc/cron.d /var/spool/cron -type f -mtime -14 2>/dev/null
echo ""
echo "=== Gitea-spawned shell processes right now ==="
ps auxf | grep -A2 -i gitea | grep -E "bash|sh |curl|wget|python" || echo "None found"
For Windows endpoints — inventory force-installed and sideloaded browser extensions:
# Browser extension audit — force-installed via policy and user-installed with risky permissions
$policyPaths = @(
'HKLM:\\\SOFTWARE\\Policies\\Google\\Chrome\\ExtensionInstallForcelist',
'HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge\\ExtensionInstallForcelist',
'HKCU:\\SOFTWARE\\Google\\Chrome\\Extensions',
'HKCU:\\SOFTWARE\\Microsoft\\Edge\\Extensions'
)
foreach ($path in $policyPaths) {
if (Test-Path $path) {
Write-Host "[+] Entries under $path" -ForegroundColor Yellow
Get-ChildItem $path -ErrorAction SilentlyContinue | ForEach-Object { $_.PSChildName }
(Get-ItemProperty $path -ErrorAction SilentlyContinue).PSObject.Properties |
Where-Object { $_.Name -notmatch '^PS' } | ForEach-Object { "$($_.Name) = $($_.Value)" }
}
}
# Enumerate installed Chromium extensions and flag high-risk permission scopes
$extRoot = "$env:LOCALAPPDATA\\Google\\Chrome\\User Data\\Default\\Extensions"
$riskyPerms = 'cookies|webRequest|webRequestBlocking|<all_urls>|debugger|nativeMessaging'
if (Test-Path $extRoot) {
Get-ChildItem $extRoot -Directory | ForEach-Object {
$manifest = Get-ChildItem $_.FullName -Recurse -Filter 'manifest.json' -ErrorAction SilentlyContinue | Select-Object -First 1
if ($manifest) {
$json = Get-Content $manifest.FullName -Raw | ConvertFrom-Json -ErrorAction SilentlyContinue
$perms = ($json.permissions + $json.host_permissions) -join ','
if ($perms -match $riskyPerms) {
Write-Host "[!] $($json.name) ($($_.Name)) — permissions: $perms" -ForegroundColor Red
}
}
}
}
Remediation Recommendations
For the Browser Extension Threat
- Establish an extension allowlist. Use Chrome/Edge enterprise policy (
ExtensionInstallAllowlist/ExtensionInstallBlocklist) to block all extensions by default and permit only business-approved IDs. This is the single highest-value control against malicious extensions. - Revoke and rotate. Any user who installed the malicious Twitch extension must revoke the affected OAuth grants (Twitch connections page), invalidate all active sessions, and rotate credentials. Assume downstream accounts sharing session context are exposed.
- Move to phishing-resistant, token-bound authentication where possible: passkeys/FIDO2, and for Microsoft 365, enable token protection in Conditional Access to bind tokens to devices — this directly defeats token replay.
- Monitor for token replay via impossible-travel and anomalous-ASN detections on SaaS sign-in logs; stolen tokens are almost always replayed from hosting-provider infrastructure, not residential ISPs.
For the Gitea Campaign
- Patch immediately. Identify every Gitea instance in your environment (scan for the Gitea version banner on ports 3000 and 443), and upgrade to the latest upstream release. Review all published Gitea security advisories at the project's GitHub security page — the n-day being exploited has a fix; unpatched instances are being actively scanned for.
- Reduce exposure. Self-hosted Git services should not be internet-facing without a compensating control. Put Gitea behind VPN, SSO with device posture, or an authenticated reverse proxy at minimum.
- Assume breach on unpatched, internet-exposed instances. If your instance was reachable and unpatched during the campaign window, treat it as compromised: collect memory before reboot (kernel rootkits survive in memory and their on-disk artifacts are designed to evade detection), image the host, and rebuild from known-good.
- Deploy kernel-visibility tooling. eBPF-based monitoring or at minimum auditd rules logging
insmod,modprobe, andinit_module/finit_modulesyscalls. Centralize logs off-host so a rootkit cannot tamper with the evidence trail. - Protect the software supply chain downstream. A compromised Git server means potentially compromised source code. Audit recent commits, tags, and CI/CD secrets for any repository hosted on an affected instance — rotate any credentials stored in CI variables.
Final Assessment
Neither campaign in this roundup succeeds against a hardened environment — and that's precisely the point. N-day exploitation of internet-facing dev tools and unvetted browser extensions are hygiene failures, not sophisticated zero-day operations. The organizations getting hit are the ones without an extension allowlist, without a patch SLA on exposed services, and without kernel-level visibility on Linux. Close those three gaps and both campaigns become non-events.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.