
Cloud security company Wiz says an automated campaign it calls Gheist is using stolen GitHub tokens to push a small workflow file into every repository the token can write to. The workflow prints the repository’s secrets into the GitHub Actions log, the attackers download the log through GitHub’s API, and then they delete the run seconds later. Because the secrets leave through GitHub itself, there is no attacker server or outbound connection for a firewall to block. Wiz has tracked the campaign since September 15 and recovered more than 13,500 planted branches from more than 850 compromised accounts, ranging from personal projects to private repositories of enterprise organisations. Wiz’s analysis does not say how many organisations had secrets exposed.
The payload prints the job’s environment and every secret it can read, encoded in base32. GitHub masks secrets in logs, but its documentation says that masking is not guaranteed once a value has been encoded, and Wiz says the base32 text no longer matches the original secret, so it prints in full. GitHub has held workflow runs it identifies as potentially malicious for approval since July 28, and every public Gheist run Wiz checked was still waiting for approval, so its payload never ran. GitHub says the hold currently applies to public repositories on github.com only, so it does not cover private repositories or GitHub Enterprise Server, where Wiz says the attacks succeeded. Wiz says Gheist is distinct from GhostAction, which uses different workflow files.
How to check if you’re affected
Affected products are GitHub repositories, especially private ones and those on GitHub Enterprise Server, that a stolen personal access token or other token could write to. Wiz’s indicators:
- A branch named
ci-sync-followed by six random characters, containing one commit with the messageci: sync configthat adds only.github/workflows/sync-check.yml. The commit is unsigned and carries the token owner’s name. - In GitHub audit logs, workflow runs on those branches that finish and are then deleted by the user agent
gheist. - In AWS CloudTrail, role assumptions or token exchanges whose subject includes a
ci-sync-branch, which shows Actions ran on an attacker branch. - On self-hosted runners, the files
.gdmp_pat,.gdmp_patgand.gdmp_sweep, or the stringgdmp-pivotin job logs. Wiz says to treat such a host and its instance role as compromised.
If you find a ci-sync- branch, Wiz says deleting the branch or the run does not undo the exposure. Rotate every repository, organisation and environment secret available to that repository, revoke the token that pushed the commits and check its owner’s devices for infostealers, and do not approve held sync-check runs.
