GemStuffer Campaign Abuses RubyGems as Exfiltration Channel Targeting UK Local Government
The GemStuffer campaign leverages the RubyGems package registry as an unconventional data exfiltration channel. Threat actors deploy Ruby scripts that scrape UK local government portals, package the harvested data into valid .gem archives, and push them to RubyGems using hardcoded API keys. The malware demonstrates defense evasion by overriding the HOME environment variable to a /tmp directory to isolate its credential environment, or by bypassing the gem CLI entirely to perform direct API POST requests.
Authors: Joseph Edwards
Source:Socket
- filename/tmp/gemhome/.gem/credentialsFabricated credentials file containing hardcoded RubyGems API key
- sha256239440c830e17530dda0a8a06ed2708860998750a1e3ed2239e919465dc59420Hash of payload.rb script used in the campaign
- sha256c2d6bcacc88177e0f2c8c262726f86f37e671b1692c8bc135bac4b610ddcf31aHash of script.rb used in the campaign
- urlhxxps://democracy[.]wandsworth[.]gov[.]uk/mgCalendarMonthView.aspx?M=1&Y=2026&GL=1&bcr=1Targeted scraping URL for Wandsworth council portal
- urlhxxps://moderngov[.]lambeth[.]gov[.]uk/mgCalendarMonthView.aspx?M=1&Y=2026&GL=1&bcr=1Targeted scraping URL for Lambeth council portal
- urlhxxps://moderngov[.]southwark[.]gov[.]uk/mgCalendarMonthView.aspx?M=1&Y=2026&GL=1&bcr=1Targeted scraping URL for Southwark council portal
Detection / HunterGoogle
What Happened
A new cyber campaign called GemStuffer is misusing the RubyGems software registry to store data scraped from UK local government websites. The attackers use automated scripts to collect public meeting and calendar data from councils like Lambeth, Wandsworth, and Southwark. They then hide this data inside software packages and upload them to the public registry. This shows how attackers can abuse trusted developer tools to sneak data out of networks. Organizations should check their systems for these unauthorized scripts and block unnecessary uploads to package registries.
Key Takeaways
- The GemStuffer campaign abuses the RubyGems registry as a data exfiltration channel rather than a malware distribution method.
- Threat actors scrape public data from UK local government portals (Lambeth, Wandsworth, Southwark) and package it into .gem archives.
- Exfiltration is achieved by pushing the malicious gems to rubygems.org using hardcoded API keys.
- The malware isolates its execution by overriding the HOME environment variable to a temporary directory (/tmp/gemhome) to inject its own credentials.
- A variant of the malware bypasses the 'gem' CLI entirely, using direct API POST requests to exfiltrate data, reducing its forensic footprint.
Affected Systems
- UK local government portals running ModernGov software
- Ruby environments
- CI/CD pipelines
Attack Chain
The attacker deploys a Ruby script onto a target system, which fetches and scrapes calendar and agenda pages from UK local government portals. The script packages the scraped HTML responses into a valid .gem archive, either staging it in a temporary directory or keeping it in memory. It then overrides the HOME environment variable to point to a fabricated /tmp/gemhome directory containing injected RubyGems API credentials. Finally, the script exfiltrates the packaged data by pushing the gem to rubygems.org using the 'gem push' CLI command or a direct API POST request.
Detection Availability
- YARA Rules: No
- Sigma Rules: No
- Snort/Suricata Rules: No
- KQL Queries: No
- Splunk SPL Queries: No
- EQL Queries: No
- Other Detection Logic: No
The article does not provide ready-to-use detection rules, but suggests behavioral monitoring for HOME environment variable manipulation and network egress filtering.
Detection Engineering Assessment
EDR Visibility: Medium — EDR can detect process execution of 'gem push' and file writes to /tmp, but the direct API POST variant runs entirely within the Ruby process memory, reducing process-level visibility. Network Visibility: Medium — Network monitoring can spot the anomalous short User-Agent and outbound POSTs to rubygems.org, but the payload is TLS-encrypted and gzip-compressed, blinding standard DLP. Detection Difficulty: Moderate — The exfiltration blends in with legitimate developer activity (pushing gems). Detecting the direct API variant requires deep inspection or runtime application self-protection (RASP).
Required Log Sources
- Process Creation (Event ID 4688 / Sysmon 1)
- File Creation (Sysmon 11)
- Network Connections (Sysmon 3)
Hunting Hypotheses
| Hypothesis | Telemetry | ATT&CK Stage | FP Risk |
|---|---|---|---|
| Consider hunting for Ruby processes that modify the HOME environment variable to point to a /tmp directory. | Process execution logs, EDR runtime telemetry (eBPF/Falco) | Execution / Defense Evasion | Low |
| Consider hunting for unexpected outbound network connections to rubygems.org/api/v1/gems originating from non-developer or production servers. | Network flow logs, Proxy logs | Exfiltration | Medium |
| Consider hunting for file creation events in /tmp matching the pattern /tmp/gemhome/.gem/credentials. | File creation logs (Sysmon Event ID 11) | Credential Access / Defense Evasion | Low |
Control Gaps
- Standard DLP tools cannot inspect the gzip-compressed tar archive inside the TLS session to rubygems.org.
Key Behavioral Indicators
- HOME environment variable overridden to /tmp
- Short User-Agent 'Mozilla/5.0' in HTTP requests
- Creation of /tmp/gemhome/.gem/credentials
False Positive Assessment
- Low for the specific file paths and HOME variable overrides to /tmp, but Medium for general 'gem push' activity in developer environments.
Recommendations
Immediate Mitigation
- Verify against your organization's incident response runbook and team escalation paths before acting.
- Audit /tmp directories on potentially affected machines for suspicious patterns like /tmp/gemhome/ or /tmp/rubydocran_*.
- If applicable, yank any identified malicious gem packages from your internal registries or caches.
Infrastructure Hardening
- Evaluate whether to block outbound HTTPS POST requests to rubygems.org/api/v1/gems in CI pipelines that do not legitimately publish gems.
- For CI pipelines that do publish gems, consider restricting allowed gem names to an explicit allowlist.
User Protection
- Consider implementing runtime security tooling (e.g., Falco) to detect abnormal putenv/setenv calls that redirect HOME out of standard user directories.
- Audit Bundler configuration files and CI pipeline definitions for unauthorized script references (e.g., evil.rb, payload.rb).
Security Awareness
- Educate development teams on the risks of supply chain attacks and the importance of monitoring CI/CD pipeline egress traffic.
MITRE ATT&CK Mapping
- T1119 - Automated Collection
- T1567 - Exfiltration Over Web Service
- T1074.001 - Local Data Staging
- T1564 - Hide Artifacts
- T1078 - Valid Accounts
Additional IOCs
- File Hashes:
81c34eea9c853c5ec13a3b3cd4a2228b(MD5) - Hash of payload.rb5f924c0454f1fb6b2299d658c3bb4e75ce3d0b66(SHA1) - Hash of payload.rb9211506ae02c9e4e75aeadfebeb4883c(MD5) - Hash of script.rbdb9827ae2c004a4dc6009be2d009477bff5249df(SHA1) - Hash of script.rb
- File Paths:
/tmp/gemhome/- Temporary home directory for gem execution/tmp/rubydocran_*- Temporary directory pattern used by the malware/tmp/<package><epoch_timestamp><pid>/lib/result.txt- Exfiltrated data staging file/tmp/<package><epoch_timestamp><pid>/x.gemspec- Staged gemspec file
- Command Lines:
- Purpose: Builds the malicious gem archive locally containing the scraped data. | Tools:
gem| Stage: Collection |gem build - Purpose: Pushes the exfiltrated data disguised as a gem to the RubyGems registry. | Tools:
gem| Stage: Exfiltration |gem push
- Purpose: Builds the malicious gem archive locally containing the scraped data. | Tools:
- Other:
rubygems_9feada...054a57- Partial RubyGems API Key used for exfiltrationrubygems_fb4e1b...6aec9dd- Partial RubyGems API Key used for exfiltrationrubygems_d8e875...503a533- Partial RubyGems API Key used for exfiltrationevil.rb- Associated malicious filenameyardload.rb- Associated malicious filenameyard_plugin.rb- Associated malicious filenameexploit.rb- Associated malicious filenameextconf.rb- Associated malicious filenamefetcher.rb- Associated malicious filenameMozilla/5.0- Anomalous short User-Agent string used during scraping