# SleeperGem Supply-Chain Campaign Uses Three Malicious RubyGems Packages to Backdoor Developer Machines

> The SleeperGem campaign hijacked two long-dormant RubyGems maintainer accounts and used them to publish trojanized releases of git_credential_manager (impersonating Microsoft's official tool), Dendreo, and fastlane-plugin-run_tests_firebase_testlab. Each malicious release is a loader that fetches a second-stage deploy.sh and native daemon from an attacker-controlled Forgejo instance, deliberately skips execution on ~30 recognized CI/CD environment variables to avoid disposable build runners, and installs dual persistence (systemd user service + cron) plus a setuid root shell backdoor on genuine developer laptops.

- **Published:** 2026-07-20T00:00:00Z
- **Last reviewed:** 2026-07-20T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-1575
- **Card image:** https://intel.threadlinqs.com/og/threat/threat-intel-sleepergem-rubygems-dormant-accounts-tl-2026-1575.webp?v=06a55967 (Threadlinqs threat intel: SleeperGem Malicious RubyGems Backdoor: Detection & IOCs (TL-2026-1575) — High severity, 21 IOCs, 9 detection rules.)
- **ID:** TL-2026-1575
- **Severity:** HIGH (CVSS 8.1)
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Detections:** 9 (1 shown free below) · **IOCs:** 21 (1 shown free below)

## Description

Between July 18 and July 19, 2026, threat actors published malicious versions of three RubyGems packages to the public RubyGems.org registry in a coordinated software supply-chain attack that researchers at Aikido Security named SleeperGem. The name reflects the campaign's core tradecraft: rather than typosquatting or registering new packages, the attackers hijacked two ordinary RubyGems maintainer accounts that had gone quiet for six to seven years -- accounts that "looked harmless enough to hijack without anyone noticing," per Aikido researcher Charlie Eriksen. Once in control, the attackers pushed new releases of Dendreo (v1.1.3, v1.1.4, last legitimately updated 2020) and fastlane-plugin-run_tests_firebase_testlab (v0.3.2, last legitimately updated 2019), and separately published four new versions of a package named git_credential_manager (v2.8.0-2.8.3) that impersonates Microsoft's official Git Credential Manager tool. The git_credential_manager releases shipped within roughly nine hours across two working sessions: a 24-minute gap between v2.8.0 and v2.8.1, an 8-hour sleep, then a 17-minute gap between v2.8.2 and the final v2.8.3 activation release -- behavior consistent with an operator iterating live against telemetry. The malicious gem was also added as a dependency to at least five downstream packages (Dendreo, fastlane-plugin-run_tests_firebase_testlab, slackHtmlToMarkdown, seo_optimizer, array_fast_methods), and fastlane-plugin-run_tests_firebase_testlab alone carried a total download count of 574,661, giving the campaign a substantial installed footprint despite the packages' age. On require, each trojanized gem spawns a child Ruby process that shells out to an install script. The script disables TLS verification (OpenSSL::SSL::VERIFY_NONE) and issues an HTTPS request with a 'Git' User-Agent to an attacker-controlled Forgejo instance at git.disroot.org under the repository namespace 'git-ecosystem', using the URL pattern https://git.disroot.org/git-ecosystem/#{product}/raw/branch/main. Before doing anything further, the script performs a skip_install check that enumerates roughly 30 environment variables associated with CI/CD platforms -- including GITHUB_ACTIONS, GITLAB_CI, CIRCLECI, plus Travis, Jenkins, and Vercel indicators -- and silently exits if any are present. This is a deliberate anti-analysis and targeting control: the operators want persistent footholds on human-operated developer laptops and long-lived build hosts, not disposable, ephemeral CI runners that would be destroyed at job completion and yield no lasting access. On a genuine developer machine, the loader downloads a second-stage shell script (deploy.sh) and a native binary masquerading as a Git Credential Manager helper (Windows delivery uses PowerShell with -ExecutionPolicy bypass; Unix delivery uses /bin/sh). The binary is copied to ~/.local/share/gcm/git-credential-manager with an accompanying ~/.local/share/gcm/.env configuration file, marked executable, and launched as a resident daemon. Persistence is installed twice -- via a systemd user service and a cron entry, both deliberately labeled 'git-credential-manager' so that removing one persistence mechanism leaves the other intact and silently respawns the daemon on reboot or session start. The malware then probes group membership for sudo or wheel; where passwordless sudo is available it re-executes as root and plants a setuid (mode 6777) copy of the system shell disguised as a networking utility at /usr/local/sbin/ping6, providing a durable, camouflaged root escalation path independent of the original daemon. StepSecurity, running the malicious releases inside their Harden-Runner sandboxing tool, captured and confirmed the full kill chain end-to-end. No CVE or GHSA identifier has been assigned to this campaign as of the current reporting; RubyGems.org and downstream mirrors are the primary distribution vector. Affected users are advised to treat any machine that installed the trojanized gems -- and every credential and secret that touched that machine -- as fully compromised, remove the daemon directory and both persistence mechanisms, hunt for the setuid shell at /usr/local/sbin/ping6, and rotate all credentials.

## MITRE ATT&CK

- T1586 Compromise Accounts
- T1583.004 Server
- T1608.001 Upload Malware
- T1195.002 Compromise Software Supply Chain
- T1199 Trusted Relationship
- T1059.004 Unix Shell
- T1059.001 PowerShell
- T1204.003 Malicious Image
- T1053.003 Cron
- T1543.002 Systemd Service
- T1548.001 Setuid and Setgid
- T1548.001 Setuid and Setgid
- T1053.003 Cron
- T1548.003 Sudo and Sudo Caching
- T1497.001 System Checks
- T1036.005 Match Legitimate Resource Name or Location
- T1036.003 Rename Legitimate Utilities
- T1564.001 Hidden Files and Directories
- T1685 Disable or Modify Tools
- T1082 System Information Discovery
- T1069.001 Local Groups
- T1518 Software Discovery
- T1552.001 Credentials In Files
- T1071.001 Web Protocols
- T1105 Ingress Tool Transfer
- T1102 Web Service
- T1486 Data Encrypted for Impact

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**SleeperGem — Ruby Gem Require-Time Child Process Spawns Installer Shell** (`TL-2026-1575-SPL-001`)

Detects a Ruby process (bundler/gem require hook) spawning a child shell or PowerShell process immediately after `bundle install`/`gem install`, with no CI/CD environment markers present — consistent with the SleeperGem trojanized-gem loader (git_credential_manager, Dendreo, fastlane-plugin-run_tests_firebase_testlab) executing its install-time payload on a genuine developer workstation.

- **Languages:** Splunk SPL, Microsoft KQL, Sigma
- **ATT&CK:** T1204.003, T1059.001, T1059.004
- **Data sources:** sysmon, windows_security, edr_process_telemetry
- **Severity:** high
- **Confidence:** high

### Splunk SPL

```spl
index=edr sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" OR sourcetype="linux:sysmon" EventCode=1
| eval parent_is_ruby=if(match(lower(ParentImage), "/ruby(\.exe)?$"), 1, 0)
| where parent_is_ruby=1
| eval child_is_shell=if(match(lower(Image), "(powershell\.exe|cmd\.exe|/bin/sh|/bin/bash)$"), 1, 0)
| where child_is_shell=1
| lookup ci_cd_env_allowlist envvar_present OUTPUT is_ci_runner
| where isnull(is_ci_runner) OR is_ci_runner=0
| stats count min(_time) as first_seen max(_time) as last_seen by host, User, ParentImage, Image, CommandLine
| where count > 0
| sort -last_seen
```

### Microsoft KQL

```kql
DeviceProcessEvents
| where Timestamp > ago(24h)
| where InitiatingProcessFileName has_any ("ruby", "ruby.exe")
| where FileName has_any ("powershell.exe", "cmd.exe", "sh", "bash")
| where isempty(tostring(parse_json(InitiatingProcessCommandLine)))
| extend CI_Marker = iff(ProcessCommandLine has_any ("GITHUB_ACTIONS","GITLAB_CI","CIRCLECI","JENKINS_URL","VERCEL"), true, false)
| where CI_Marker == false
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| order by Timestamp desc
```

### Sigma

```yaml
title: RubyGems Require-Time Child Process Spawning Installer Shell (SleeperGem)
id: 3a2c1e40-6b8d-4a2f-9c1e-tl2026sig001
status: experimental
description: Detects a Ruby process spawning a shell/PowerShell child immediately after gem install, consistent with the SleeperGem trojanized-gem loader executing its second-stage installer on a developer workstation.
references:
    - https://www.aikido.dev/blog/sleepergem-rubygems-supply-chain-attack
    - https://www.stepsecurity.io/blog/sleepergem-compromised-rubygems-drop-persistent-backdoor
author: AII-Detector — ThreadLinqs Intelligence
date: 2026-07-20
tags:
    - attack.execution
    - attack.t1204.003
    - attack.t1059
    - attack.t1059.001
    - attack.t1059.004
    - attack.tool.sleepergem
logsource:
    category: process_creation
    product: windows
detection:
    selection_parent:
        ParentImage|endswith:
            - '\ruby.exe'
            - '/ruby'
    selection_child:
        Image|endswith:
            - '\powershell.exe'
            - '\cmd.exe'
            - '/bin/sh'
            - '/bin/bash'
    filter_ci:
        CommandLine|contains:
            - 'GITHUB_ACTIONS'
            - 'GITLAB_CI'
            - 'CIRCLECI'
            - 'JENKINS_URL'
            - 'VERCEL'
    condition: selection_parent and selection_child and not filter_ci
falsepositives:
    - Legitimate Ruby gem post-install hooks that intentionally shell out (rare; validate against known-good gem publishers)
    - Developer tooling wrappers written in Ruby that launch a shell for interactive setup
level: high
```

**Known false positives:**

- Legitimate Ruby gem post-install hooks that shell out for compilation or asset builds

**Tuning notes:** Build and maintain a CI/CD environment-variable allowlist lookup so genuine ephemeral build agents are excluded; extend the parent-image match list to cover jruby/truffleruby if present in the environment.

### 8 more detection rules (Splunk SPL, Microsoft KQL, Sigma), unlock with TL Creds

- SleeperGem — Dual Persistence: Identically-Named systemd User Service + Cron Entry (locked: unlock with TL Creds)
- SleeperGem — Setuid Root Shell Backdoor Masquerading as ping6 ([indicator]) (locked: unlock with TL Creds)
- SleeperGem — Sudo/Wheel Group Discovery Immediately Followed by Root Re-Execution (locked: unlock with TL Creds)
- SleeperGem — Ruby Process TLS-Verification-Disabled Fetch to Forgejo C2 ([indicator]) (locked: unlock with TL Creds)
- SleeperGem — GCM-Impersonating Daemon Artifact Drop at ~/.local/share/gcm/ (locked: unlock with TL Creds)
- SleeperGem — Dormant RubyGems Maintainer Account Publishes New Release Impersonating Known Vendor Tool (locked: unlock with TL Creds)
- SleeperGem — skip_install CI/CD Environment Fingerprint Enumeration (locked: unlock with TL Creds)
- SleeperGem — PowerShell ExecutionPolicy Bypass Fetching GCM-Named Payload (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sample indicators (1 of 21)

Defanged, TLP:CLEAR.

- Domain: `git[.]disroot[.]org`

Full set of 21 indicators unlocks with TL Creds: https://threadlinqs.com/tl-creds

## Sources

- [SleeperGem Uses Three Malicious RubyGems Packages to Backdoor Developer Machines](https://thehackernews.com/2026/07/sleepergem-uses-three-malicious.html)
- [SleeperGem: Compromised git_credential_manager, Dendreo, and fastlane RubyGems Drop a Persistent Backdoor](https://www.stepsecurity.io/blog/sleepergem-compromised-rubygems-drop-persistent-backdoor)
- [SleeperGem: RubyGems supply chain attack targets dormant maintainer accounts](https://www.aikido.dev/blog/sleepergem-rubygems-supply-chain-attack)
- [SleeperGem RubyGems attack evades CI to hit developer laptops](https://www.developer-tech.com/news/sleepergem-rubygems-attack-evades-ci-to-hit-developer-laptops/)
- [SleeperGem attack targets Ruby ecosystem with malicious gems](https://www.scworld.com/brief/sleepergem-attack-targets-ruby-ecosystem-with-malicious-gems)
- [Supply Chain Vulnerability in RubyGems Highlights Growing Software Security Risks](https://www.tipranks.com/news/private-companies/supply-chain-vulnerability-in-rubygems-highlights-growing-software-security-risks)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-1575
