Malicious Twitch Extension Steals OAuth Tokens from 30,000 Users
Detection stack
- AIDR
- Alert
- ETL
- Query
Summary
A malicious browser extension called Twitch Enhanced Viewer | JeetBot targets Chrome and Firefox users to steal Twitch OAuth session tokens. The extension routes network requests through attacker-controlled proxy servers and appends the victim’s authentication token as a cleartext query parameter. This enables the operator to hijack Twitch accounts and potentially access chat, whispers, and account settings.
Investigation
Socket researchers identified the extension across major browser marketplaces and examined its JavaScript source code. Analysis showed that a content script captures the Authorization header while a background worker forwards it to attacker-controlled proxy infrastructure. Researchers also uncovered a hardcoded allowlist of Russian streamer channels excluded from token exfiltration, suggesting a specific targeting pattern or operational preference.
Mitigation
Users should immediately remove the Twitch Enhanced Viewer | JeetBot extension and terminate all active Twitch sessions to invalidate potentially stolen tokens. Security teams should block the identified malicious infrastructure and monitor endpoints for unauthorized browser extensions. Developers should also avoid routing authenticated traffic through third-party proxies without first removing credentials.
Response
If the malicious extension is detected, administrators should identify all endpoints containing its extension IDs and isolate affected user sessions. OAuth tokens associated with compromised Twitch accounts should be revoked immediately. Organizations should also enforce strict browser extension policies to prevent installation of unapproved or high-risk third-party add-ons.
Attack Flow
We are still updating this part.
Detections
Suspicious Command and Control by Unusual Top Level Domain (TLD) DNS Request (via dns)
Possible Data Infiltration / Exfiltration / C2 via Third Party Services / Tools (via proxy)
Possible Data Infiltration / Exfiltration / C2 via Third Party Services / Tools (via dns)
IOCs (HashSha256) to detect: Malicious Twitch Browser Extension Exposes 30,000 Users’ OAuth Tokens to Russian Bot Service
IOCs (SourceIP) to detect: Malicious Twitch Browser Extension Exposes 30,000 Users’ OAuth Tokens to Russian Bot Service
IOCs (DestinationIP) to detect: Malicious Twitch Browser Extension Exposes 30,000 Users’ OAuth Tokens to Russian Bot Service
Malicious Twitch Browser Extension Exposes OAuth Tokens [Webserver]
Simulation Execution
-
Attack Narrative & Commands: The adversary has successfully installed a malicious browser extension on the victim’s machine. The extension’s primary goal is to hijack Twitch sessions to gain access to premium features or user data. To do this, the extension scrapes the user’s OAuth token from the browser’s local storage. To exfiltrate this token or validate it through a proxy, the extension constructs a GET request to
usher.ttvnw.net. It appends the stolen token using the&auth=parameter. The simulation will trigger a mock event log with the requiredEventID(5678) and the malicious URL to ensure the detection rule’scondition(selection_url AND selection_browser_events) is met. -
Regression Test Script:
import requests import json import datetime # Simulation Parameters target_url = "https://usher.ttvnw.net/api/get_playlist?user_id=12345&auth=STOLEN_OAUTH_TOKEN_XYZ_789" mock_event_id = 5678 print(f"[*] Starting Simulation: Malicious Twitch Extension Exfiltration") print(f"[*] Target URL: {target_url}") print(f"[*] Mock Event ID: {mock_event_id}") # In a real scenario, the proxy log is generated by the network traffic. # To simulate the log entry appearing in the SIEM for this test: simulation_log = { "timestamp": datetime.datetime.utcnow().isoformat(), "url": target_url, "EventID": mock_event_id, "category": "proxy", "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "action": "allowed" } print(f"[+] Generating simulated log entry for SIEM ingestion...") print(json.dumps(simulation_log, indent=4)) # Perform the actual request to ensure network-level telemetry is generated try: response = requests.get(target_url) print(f"[+] Request sent. Status Code: {response.status_code}") except Exception as e: print(f"[-] Request failed (this is expected if the URL is invalid): {e}") print("[*] Simulation Complete.") -
Cleanup Commands:
# No persistent changes made to the system during this simulation. # If browser history was manually modified, clear browser cache/history. echo "[*] Cleanup complete. No artifacts left on host."