top of page

Someone Swapped OVHcloud's CLI Downloads and Their Checksums. A Pinned Hash in One CI Job Caught It.

Writer: Patrick Duggan
Patrick Duggan
2 hours ago
4 min read

On October 19, for about 25 minutes, someone replaced the downloadable binaries of OVHcloud's command-line tool on GitHub with a malicious build, and replaced the checksums file next to them so the hashes still matched. The releases were weeks old. No code was pushed and no build pipeline ran. It was caught because one user's CI job had pinned the SHA-256 of the archive it downloaded before, and the hash changed. If you install developer tools from GitHub release pages, this is the attack to plan for.





What happened


The details come from the reporter's GitHub issue on the ovhcloud-cli repository and from OpenSourceMalware's analysis.


  • Between about 12:47 and 13:12 UTC on October 19, the release assets for v0.13.0, v0.14.0 and v0.15.0 were replaced: the macOS, Linux x86_64 and arm64, and Windows x86_64 archives, plus checksums.txt. OpenSourceMalware's release data suggests v0.11.0 and v0.12.0 were touched too.

  • The uploads came from a contributor account through the GitHub Releases API. No tag moved and no workflow ran. The replacement binary was a plain local build marked as built from a modified checkout, missing the version string the real release process stamps in.

  • At 13:50 a user opened an issue because their CI's SHA-256 check on the v0.15.0 Linux arm64 archive failed. At 14:21 OVHcloud deleted the replaced files. Later that day it shipped v0.16.0, built by a service account and published as an immutable release, which GitHub will not let anyone edit.

  • Anyone who installed through the install script, the Homebrew cask or a direct download during the window got the bad binary. Per OVHcloud's public statements it looks for secrets on disk. Building from source with go install and the Docker image were not affected. How many people downloaded it has not been published.


The GlassWorm link, and how strong it is


OpenSourceMalware attributes this to GlassWorm with moderate confidence, and they are careful about it. The same contributor account force-pushed its own personal repositories back in March, adding a preinstall.js loader that hides code in invisible Unicode characters, decrypts a second stage and then reads the address of its next stage from the memo of a Solana wallet transaction. That wallet appears in public GlassWorm indicator lists. A blockchain memo is a dead drop nobody can take down, which is why we keep writing about it. But the link between the March activity and the October swap is the shared account, not direct observation, and the researchers say they cannot prove it was the same actor. How the account was compromised is unknown; stolen tokens or an infostealer are the likely paths, and that is unproven too.



Why the checksum file didn't help


This is the part to take away. The attacker replaced checksums.txt along with the binaries. Anyone who downloaded a binary and checked it against the checksums file in the same release got a match. The install script doesn't check hashes at all, and the Homebrew cask downloads the same release URL. A checksum fetched from the same place as the file only proves the two arrived together.


What caught it was a hash pinned somewhere else, earlier: a value recorded in a CI config from a previous download. A release published weeks ago changing under you is something only a pinned hash will notice.



What to do


If you installed ovhcloud-cli between October 19 and the v0.16.0 release, assume the machine's secrets were read. From a different machine, rotate OVH API keys and the ovh.conf credentials, cloud credentials, SSH keys, package-registry tokens, Kubernetes configs and anything in .env files. Then remove the binary and install v0.16.0 or later.


For any tool you pull from GitHub releases:


  1. Pin the SHA-256 of every downloaded release asset in your CI or Dockerfile, and treat a mismatch as an incident, not a flaky download.

  2. Prefer releases that carry build attestations, and verify them with gh attestation verify. v0.16.0 has them; earlier versions did not.

  3. If you maintain a project: turn on immutable releases, publish from a service account in CI rather than from a person's account, and limit who can write release assets.

  4. Build hosts rarely need to talk to Solana RPC endpoints. If yours don't, block them; it breaks this family's dead drop.


What our feed has


We ingested the three SHA-256 hashes the researchers published today: the trojanized v0.15.0 Linux arm64 archive, the preinstall.js loader and the decrypted second stage, at confidence 85 and attributed to GlassWorm with the attribution caveat in the record. None was held before. The Solana wallet and the hijacked account are in the record descriptions, not in a blocklist, because neither is something a firewall can block. No IPs or domains have been published for this one. If follow-up research names where the stolen secrets went, those go in the feed the same day.


The free key that pulls the feed is at https://analytics.dugganusa.com/stix/register?utm_source=blog&utm_campaign=ovhcloud-cli-release-swap


If this was useful, or if it wasn't, the rating widget below takes ten seconds and is the only way we know.




Every indicator in this post is in the feed. Free.

1.58M+ IOCs, STIX 2.1 / TAXII, 88% novel vs ThreatFox, exploited-CVE leads ahead of CISA. No credit card — a free API key in 30 seconds, and you can audit every claim above against the live endpoints.



Was this useful? Thirty seconds, no cookies, no tracking, no third parties, your address hashed and never stored. If the box below does not load, the same question lives at https://analytics.dugganusa.com/nps.html?post=someone-swapped-ovhcloud-s-cli-downloads-and-their-checksums-a-pinned-hash-in-one-ci-job-caught-it



Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page