# Gheist: Automated Campaign Abusing Stolen GitHub Tokens to Plant Secret-Exfiltrating Workflows

> Wiz Research tracks 'Gheist', an automated campaign that uses compromised GitHub tokens to push ci-sync-[6 chars] branches containing .github/workflows/sync-check.yml, which dumps repository secrets and environment variables base32-encoded to bypass log masking. Wiz recovered 13,500+ planted branches across 850+ compromised accounts; GitHub's approval hold on public-repo workflow runs (since 2026-07-28) blocked execution, but private repositories and GitHub Enterprise Server are not covered.

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

## Description

Gheist is an automated campaign, tracked by Wiz Research since 2026-09-15, that abuses stolen GitHub tokens (sourced primarily from infostealer logs and earlier supply-chain compromises such as the March 2026 Trivy incident and the May 2026 Megalodon campaign) to push unsigned commits authored as the token owner. Each commit has the message 'ci: sync config', lands on a branch matching ^ci-sync-[0-9a-z]{6}$ (hexadecimal suffix in the earlier 'Tool A', base36 in 'Tool B'), and adds a single file, .github/workflows/sync-check.yml. The API activity carries the user agent 'gheist'.

The workflow triggers on push and runs 'env | base32 -w 120' and 'echo -n ${{ toJSON(secrets) }} | base32 -w 120'. Base32 encoding defeats GitHub's log secret masking, and the operator retrieves the logs through the GitHub API. The workflow run and the branch are then deleted within seconds, leaving a short-lived audit trail. Tool B adds a 6-minute timeout, a matrix across deployment environments to capture environment-scoped secrets, and (from 2026-10-19) '=====  gdmp-pivot: <stage> =====' and 'LAFA====' separator markers. No attacker C2 domains or IPs were identified: exfiltration relies on GitHub's own infrastructure and API.

On 2026-10-19 Tool B gained a second job, 'sync-host', that runs on self-hosted runners. It collects host details and crontab, searches home, workspace and system paths for 31 token formats (including Anthropic, Hugging Face, Groq and NVIDIA AI provider keys, private keys, .env files, Terraform state and shell history), enumerates /proc/*/environ, abuses the Docker socket to mount the host root filesystem, queries AWS instance-role, GCP and Azure metadata, and collects GitHub Actions/GitLab runner credential files and Kubernetes service-account tokens. Wiz notes bugs in this job (wrong runner key path, broken URL-credential regex, incomplete GCP/Azure token collection). It leaves .gdmp_pat, .gdmp_patg and .gdmp_sweep marker files.

Scale: Wiz recovered 13,500+ planted branches across 850+ compromised accounts, ranging from personal projects to enterprise private repositories; about two-thirds of the implicated accounts had been removed by 2026-10-24. GitHub's 2026-07-28 control, which holds potentially malicious workflow runs in public repositories for collaborator approval, stopped payload execution in every public-repository case Wiz tested. The hold does not apply to private repositories or GitHub Enterprise Server, and CloudTrail evidence shows successful execution in private repositories (OIDC role assumptions from ci-sync-* branches).

The same accounts show related abuse: on 2026-10-06, 391 accounts renamed ~1,461 repositories to cracked-software lures (wiping 610 ci-sync branches as a side effect); on 2026-10-18, 25 accounts created 'Windows RDP Runner' repositories within nine minutes (free-compute abuse); and between 2026-10-19 and 2026-10-20 three victims had Gheist commits re-pushed with a PolinRider JavaScript loader appended to vite.config.js. 57 first-phase accounts were also Megalodon victims. GhostAction is described as a distinct campaign.

## MITRE ATT&CK

- T1078 Valid Accounts
- T1195.002 Compromise Software Supply Chain
- T1059.004 Unix Shell
- T1027.013 Encrypted/Encoded File
- T1036 Masquerading
- T1528 Steal Application Access Token
- T1552.001 Credentials In Files
- T1552.003 Shell History
- T1552.004 Private Keys
- T1552.005 Cloud Instance Metadata API
- T1552.007 Container API
- T1057 Process Discovery
- T1082 System Information Discovery
- T1611 Escape to Host
- T1213.003 Code Repositories
- T1567 Exfiltration Over Web Service
- T1496.001 Compute Hijacking

## Sources

- [Gheist: Attempted Scaled Abuse of Stolen GitHub Tokens Stumbles (Wiz Research)](https://www.wiz.io/blog/gheist-attempted-scaled-abuse-of-stolen-github-tokens-stumbles)
- [Megalodon: Mass CI/CD Pipeline Poisoning via GitHub Actions (CSA Research Note)](https://labs.cloudsecurityalliance.org/research/csa-research-note-megalodon-github-actions-cicd-supply-chain)
- [Megalodon: Mass GitHub Repo Backdooring via CI Workflows (SafeDep)](https://safedep.io/megalodon-mass-github-repo-backdooring-ci-workflows/)
- [Trivy GitHub Actions Supply Chain Compromise: How TeamPCP Turned a Security Scanner Into a Credential Stealer (Phoenix Security)](https://phoenix.security/trivy-supply-chain-attack-team-pcp/)
- [Trivy Supply Chain Attack: What You Need to Know (Aqua Security)](https://www.aquasec.com/blog/trivy-supply-chain-attack-what-you-need-to-know)
- [GhostAction Campaign: 3,325 Secrets Stolen (GitGuardian)](https://blog.gitguardian.com/ghostaction-campaign-3-325-secrets-stolen/)
- [GhostAction Campaign (StepSecurity)](https://www.stepsecurity.io/blog/ghostaction-campaign-over-3-000-secrets-stolen-through-malicious-github-workflows)
- [GhostAction Campaign (Wiz Cloud Threat Landscape)](https://threats.wiz.io/all-incidents/ghostaction-campaign)

## 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-4423
