Skip to content

Response, New York. Noah Park: Check Point Patches Actively Exploited Management Server Path Traversal. Detection, Dallas. Ava Okello: Report Finds Nearly Half of Deployed Detections Need Attention Before SOCs Can Trust Them.

SOCtember

Always First. Fast SOC News.

Wiz's cover graphic for its Gheist research, a Wiz Threat Update card reading Gheist, Attempted Scaled Abuse of Stolen GitHub Tokens Stumbles, with a cartoon worm breaking through the page, in pink and blue on a dark background.
Image: Wiz, cover graphic for "Gheist: Attempted Scaled Abuse of Stolen GitHub Tokens Stumbles," Oct. 25, 2026 (fair use).

Detection

Wiz Says a Campaign Called Gheist Used Stolen GitHub Tokens to Plant Secret-Dumping Workflows on More Than 13,500 Branches, and the Runs Got Through in Private Repositories GitHub's New Approval Hold Does Not Cover

The planted workflow base32-encodes a repository's secrets so GitHub's log masking misses them, then the tool downloads the log and deletes the run seconds later, leaving no attacker server to block. Wiz traced the campaign to more than 850 compromised accounts and says cloud audit logs can expose it even where GitHub logs are not collected.

Ava Okello, DetectionLondon6 min read

LONDON - The commit looks like housekeeping. A new branch named ci-sync followed by a few random characters, one file at .github/workflows/sync-check.yml and the message "ci: sync config." According to Wiz, it is the calling card of an automated campaign that has been turning stolen GitHub tokens into a way to read the secrets stored in every repository those tokens can reach.

In research published Oct. 25, Wiz researchers Rami McCarthy and Hila Ramati say they have tracked the campaign since Sept. 15 and named it Gheist, after the user agent its tool sends with every request to GitHub's API. They write that they have recovered more than 13,500 planted branches from more than 850 compromised accounts, ranging from personal projects to the private repositories of enterprise organizations. As of Oct. 24, they say, the attack was still running and still changing.

Secrets in plain sight, then gone

The method is short. For each repository a token can reach, the tool creates the branch, commits the workflow as the token's owner without a signature, and lets the push trigger it. The workflow prints the runner's environment and the repository's secrets into its own log, both run through base32. The tool then downloads the log through GitHub's API and deletes the run seconds later.

Screenshot of the sync-check workflow Wiz recovered, which runs on push with empty permissions on ubuntu-latest and pipes env and toJSON(secrets) through base32 -w 120, followed by Wiz's three-point explanation of why it works.
Screenshot: Wiz, "Gheist: Attempted Scaled Abuse of Stolen GitHub Tokens Stumbles," Oct. 25, 2026 (fair use).The planted workflow and Wiz's explanation of why it works.

Wiz says three details make it work. GitHub masks secret values in logs only when they appear verbatim, so a base32-encoded secret prints in full. The workflow's empty permissions block limits the job's own GITHUB_TOKEN, which the attacker does not need, but does nothing to the secrets context. And when a repository has deployment environments, the tool lists them in a job matrix so that environment-scoped secrets, often production credentials, are printed too.

Because the secrets leave through GitHub's own API, Wiz notes, there is no attacker domain or outbound connection to block. In enterprise organizations, the researchers say they saw the tool cycle through the tokens of several users and automation accounts within minutes, clone private repositories before planting the workflow and, hours later, use cloud credentials from the same organization to enumerate AWS Secrets Manager.

A second job aimed at self-hosted runners

Wiz describes two variants running in parallel, told apart by their branch names. Tool A uses a hexadecimal suffix and the plain payload. Tool B uses a base36 suffix, and within hours of its first run on Sept. 28 added a six-minute timeout and the environment matrix.

On Oct. 19, Tool B began pushing a second job, sync-host, apparently only to repositories with a registered self-hosted runner. Wiz says it searches the machine for 31 token formats, including keys for AI providers such as Anthropic, Hugging Face, Groq and NVIDIA, along with private keys, .env files, Terraform state and shell history. It also reads the environment of every process, uses the Docker socket to mount the host's root filesystem in a container and repeat the search there, and goes after AWS instance-role credentials, runner credential files and the Kubernetes service account token.

Screenshot of Wiz's How the payload evolved section, describing Tool A and Tool B, the Oct. 19 separator and sync-host job for self-hosted runners, the .gdmp helper files and gdmp-pivot log headers, and a seven-step list of what the job searches, ending with Wiz's note that the job is buggy.
Screenshot: Wiz, "Gheist: Attempted Scaled Abuse of Stolen GitHub Tokens Stumbles," Oct. 25, 2026 (fair use).How the payload changed, including the self-hosted runner job.

That job is buggy, according to Wiz: it looks for the wrong runner key file, its regular expression for credentials in URLs is broken, and it does not collect Google Cloud or Azure tokens.

Where GitHub's control stopped it, and where it did not

Wiz's title says the campaign "stumbles," and the reason is a GitHub change. Since July 28, GitHub has held potentially malicious workflow runs in public repositories until a collaborator approves them. Every public Gheist run Wiz checked, across all variants, sits waiting for that approval. "The control worked, and the malicious payloads never ran," the researchers write.

The hold does not apply to private repositories or GitHub Enterprise Server. There, Wiz says, GitHub audit logs show runs on ci-sync branches completing and then being deleted by the gheist user agent, and AWS CloudTrail shows the organizations' own workflows running on those branches and assuming AWS roles.

Roughly two-thirds of the implicated accounts are no longer available on GitHub, which Wiz says likely reflects response activity after it reported the campaign to GitHub.

The same stolen accounts, other crews

The tokens appear to come from a shared pool. Wiz traced credential sources to infostealer logs and to tokens exposed in earlier supply-chain compromises, such as the Trivy compromise in March, and it found the same accounts in other operations. On Oct. 6, 391 accounts renamed about 1,461 repositories to cracked-software lures, wiping 610 ci-sync branches as a side effect; 166 of those accounts never appear in Gheist activity. On Oct. 18, 25 Gheist accounts each created a "Windows RDP Runner" repository within nine minutes in an apparent attempt to use GitHub Actions for free computing. Some victims also appear to be infected with PolinRider, the malware Wiz describes as linked to North Korea, and 57 accounts from Gheist's first phase were also victims of a campaign called Megalodon in May.

Wiz says Gheist is distinct from GhostAction, which uses different workflow files and sends secrets to 193[.]32[.]204[.]199.

Screenshot of Wiz's Which actions should security teams take section, with Hunt, Respond and Harden guidance, followed by the Indicators of compromise list: the gheist user agent, the ci-sync branch pattern, the ci: sync config commit message, gdmp markers and helper files, and four workflow blob hashes.
Screenshot: Wiz, "Gheist: Attempted Scaled Abuse of Stolen GitHub Tokens Stumbles," Oct. 25, 2026 (fair use).Wiz's hunting, response and hardening guidance and indicators.

What detection teams can hunt for

  • Branches matching ci-sync- plus six lowercase letters or digits, where the only change is a new .github/workflows/sync-check.yml committed with the message "ci: sync config."
  • In GitHub audit logs, workflow runs on ci-sync branches that were deleted within a minute of completing, and any API activity with the user agent gheist.
  • If workflows reach the cloud through OIDC, cloud audit log role assumptions or token exchanges whose subject includes a ci-sync branch. Wiz says this finds Gheist even without GitHub logs.
  • On self-hosted runners, the files .gdmp_pat, .gdmp_patg and .gdmp_sweep, and the string gdmp-pivot in job logs.
  • Workflow blob hashes published by Wiz: f3da2b8b357dcda02fd455d314be2a95007516a6 (plain), d09535857a741bbb976bdc084a9a021713133291 (timeout), 1dc5af9cce950aad1eb1546ecce8565b117540c4 (separator) and c665b778b2d822453293003e7ca0bbb2cb08e39d (self-hosted job).

For response, Wiz advises rotating every repository, organization and environment secret available to an affected repository, noting that deleting the run or the branch does not undo the exposure. It also recommends revoking the tokens that pushed the commits, checking their owners' devices for infostealers, treating any self-hosted runner that ran a ci-sync branch as compromised along with its instance role, and never approving held sync-check runs.

Sources:


Ava Okello covers detection engineering, EDR telemetry and SOC hunting for SOCtember from London.

Related stories

Detection desk