Wiz Research has recovered more than 13,500 planted branches from 850+ compromised GitHub accounts, the work of a campaign it calls Gheist, after the user agent the tool sends with its GitHub API requests. The tool takes a stolen token, finds every repository that token can open, and plants a workflow in each one. The workflow prints the repository’s secrets into a log, and the attacker downloads it.

GitHub token abuse

The exposure is in private repositories. A GitHub safeguard blocks the attack in public ones, but Wiz has seen the workflows run in private repositories. The secrets at risk there include environment-scoped credentials, which are often production credentials.

How it works

Once the tool has a stolen token, it walks through every repository that token can reach. In each one it creates a branch named ci-sync- plus six random characters and commits a small workflow file called sync-check. Pushing the branch starts the workflow automatically, and the workflow does one job: it prints the repository’s secrets into its run log.

GitHub normally hides secrets in logs, but it only catches a secret that appears exactly as stored. The workflow scrambles each one into base32, a text encoding, so the masking misses it and the secrets print in full. The tool then downloads the log through the GitHub API and deletes the run seconds later.

No attacker server is involved. The secrets leave through GitHub’s API, so a security team has no outside domain or connection to block.

One of the two variants added a second job on October 19 that goes after self-hosted runners. It searches the host for tokens and keys and uses Docker to reach the host’s files.

Where the block stops

Since July 28, GitHub has held potentially malicious workflow runs in public repositories until a collaborator approves them.

“Unfortunately, that hold doesn’t apply to private repositories or GitHub Enterprise Server. There, GitHub audit logs show runs on ci-sync-* branches completing and then being deleted by the gheist user agent. CloudTrail shows the organizations’ own workflows running on those branches and assuming AWS roles, which proves Actions executed without approval,” Wiz researchers wrote.

In enterprise organizations, the tool cycled through tokens of several users and automation accounts within minutes and cloned private repositories before planting the workflow. Hours later, cloud credentials from the same organization were used to enumerate AWS Secrets Manager. Wiz does not say how those credentials were obtained.

Same accounts, other crews

Other actors use the same accounts. On October 6, 391 accounts renamed about 1,461 repositories to cracked-software lures, and 166 of those accounts never appear in Gheist activity. On October 18, 25 Gheist accounts each created a “Windows RDP Runner” repository within nine minutes.

What you should check

If your workflows authenticate to the cloud with OIDC, search cloud audit logs for role assumptions whose subject includes a ci-sync- branch. That shows Actions ran on an attacker branch even if you collect no GitHub logs. Also look in GitHub audit logs for the gheist user agent.

Deleted runs and branches do not undo the exposure. Wiz’s advice is to rotate every repository, organization and environment secret available to an affected repository, and to revoke the tokens that pushed the commits.