# RubyGems wgkit wave 2 - 24 DeFi/MEV/wallet/NFT crypto gems at `0.9.1` drop a direct `/bin/sh` reverse shell to `45.138.12.177:8089` from `extconf.rb`, same operator as the 2026-10-05 wgkit cluster

> OpenSSF/Amazon Inspector flagged **24 fresh malicious RubyGems** on 2026-10-11 (ingested 2026-10-12) - all v`0.9.1`, all shipping an `ext/<name>/extconf.rb` base64-decoded Ruby payload that double-forks, sleeps 20-40 min, and pipes a TCP socket to `/bin/sh` against `45.138.12.177:8089`. Same C2 IP, same evasion gates, same `bitcoin_rpc_lite_native` cover extension as the 2026-10-05 wgkit cluster - **this is wave 2 of the same operator**, now targeting DeFi/MEV/wallet-HD/NFT/TRC20/jetton verticals.

- Published: 2026-10-12
- Severity: high
- Kind: Malicious package - A package that was malicious from its first publish under its own name - a fake tool, a lure used in a social-engineering campaign, or a trojanised utility - rather than a copy of an existing name.
- Ecosystems: RubyGems
- Scope: 24 packages, 24 compromised versions
- Tags: credential-theft, infostealer, crypto-wallet-drain, obfuscation
- Also known as: wgkit RubyGems crypto wave 2, 45.138.12.177:8089 RubyGems DeFi reverse-shell burst, bitcoin_rpc_lite_native extconf.rb RubyGems wave 2
- Detected by: OpenSSF malicious-packages, Amazon Inspector, GitHub Advisory Database
- Incident ID: rubygems-2026-10-12-wgkit-wave-2-crypto-defi-cluster

## Affected packages (24)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [airdrop-eligibility-check](https://dependencywatch.io/package/rubygems/airdrop-eligibility-check) | RubyGems | 0.9.1 |
| [block-explorer-api](https://dependencywatch.io/package/rubygems/block-explorer-api) | RubyGems | 0.9.1 |
| [btc-fee-estimator](https://dependencywatch.io/package/rubygems/btc-fee-estimator) | RubyGems | 0.9.1 |
| [crypto-tax-export](https://dependencywatch.io/package/rubygems/crypto-tax-export) | RubyGems | 0.9.1 |
| [defi-yield-calculator](https://dependencywatch.io/package/rubygems/defi-yield-calculator) | RubyGems | 0.9.1 |
| [dex-router-abis](https://dependencywatch.io/package/rubygems/dex-router-abis) | RubyGems | 0.9.1 |
| [erc20-approve-audit](https://dependencywatch.io/package/rubygems/erc20-approve-audit) | RubyGems | 0.9.1 |
| [eth-gas-oracle](https://dependencywatch.io/package/rubygems/eth-gas-oracle) | RubyGems | 0.9.1 |
| [evm-tx-decoder](https://dependencywatch.io/package/rubygems/evm-tx-decoder) | RubyGems | 0.9.1 |
| [gas-refuel-bridge](https://dependencywatch.io/package/rubygems/gas-refuel-bridge) | RubyGems | 0.9.1 |
| [hd-wallet-generator](https://dependencywatch.io/package/rubygems/hd-wallet-generator) | RubyGems | 0.9.1 |
| [mev-sandwich-detect](https://dependencywatch.io/package/rubygems/mev-sandwich-detect) | RubyGems | 0.9.1 |
| [multichain-rpc](https://dependencywatch.io/package/rubygems/multichain-rpc) | RubyGems | 0.9.1 |
| [nft-metadata-resolver](https://dependencywatch.io/package/rubygems/nft-metadata-resolver) | RubyGems | 0.9.1 |
| [perp-funding-rates](https://dependencywatch.io/package/rubygems/perp-funding-rates) | RubyGems | 0.9.1 |
| [seed-phrase-validator](https://dependencywatch.io/package/rubygems/seed-phrase-validator) | RubyGems | 0.9.1 |
| [sol-mint-utils](https://dependencywatch.io/package/rubygems/sol-mint-utils) | RubyGems | 0.9.1 |
| [staking-apr-fetcher](https://dependencywatch.io/package/rubygems/staking-apr-fetcher) | RubyGems | 0.9.1 |
| [ton-jetton-tools](https://dependencywatch.io/package/rubygems/ton-jetton-tools) | RubyGems | 0.9.1 |
| [tron-trc20-utils](https://dependencywatch.io/package/rubygems/tron-trc20-utils) | RubyGems | 0.9.1 |
| [wallet-balance-scanner](https://dependencywatch.io/package/rubygems/wallet-balance-scanner) | RubyGems | 0.9.1 |
| [wallet-hd-derive](https://dependencywatch.io/package/rubygems/wallet-hd-derive) | RubyGems | 0.9.1 |
| [web3-signer-kit](https://dependencywatch.io/package/rubygems/web3-signer-kit) | RubyGems | 0.9.1 |
| [xrp-ledger-utils](https://dependencywatch.io/package/rubygems/xrp-ledger-utils) | RubyGems | 0.9.1 |

## What happened

Between 2026-10-10 11:42 UTC (the OSSF `malicious-packages` cutoff of yesterday`s sweep) and 2026-10-12 06:11 UTC (today`s ingest-window start), the GitHub Advisory Database and OpenSSF `malicious-packages` published **24 fresh RubyGems malware advisories**, every one of them pointing at the same C2 and sharing the operator fingerprint of the [2026-10-05 wgkit crypto cluster](https://dependencywatch.io/incident/rubygems-2026-10-05-eth-crypto-wgkit-cluster).

## Operator continuity vs. the 2026-10-05 wave

| Signal | 2026-10-05 wgkit wave 1 (25 gems) | 2026-10-11 wgkit wave 2 (24 gems - this file) |
|---|---|---|
| C2 subnet | `45.138.0.0/16` (`.12.177`, `.17.70`, `.17.177`, `.122.177`, `.127.77`, `.172.177`) | `45.138.12.177:8089` (one of the wave-1 endpoints) |
| Payload delivery | Base64/XOR fetch of `wgkit.tar.gz` -> `/tmp/.w1/wg_install.sh` second stage | **Direct `/bin/sh` reverse shell** via TCP socket pipe to C2 |
| Package version | `1.0.0` across all 25 | **`0.9.1` across all 24** |
| Native-ext file | `ext/<name>/extconf.rb` with base64 payload | `ext/<name>/extconf.rb` with base64 payload (same technique) |
| Native-ext name | `bitcoin_rpc_lite_native` on multiple slugs | `bitcoin_rpc_lite_native` on **every** slug |
| Evasion gates | CI env + path prefix + hostname regex + developer-artefact presence + uptime > 1800 s + 20-40 min jitter | **Identical set** |
| Vertical | Ethereum / Bitcoin / Lightning / BIP32-BIP39 / TRON basics | **DeFi / MEV / airdrop / NFT / stablecoin / cross-chain** (the un-covered half of the Web3 attack surface) |
| Disclosure path | OSSF Amazon Inspector -> `malicious-packages` -> GHSA | OSSF Amazon Inspector -> `malicious-packages` -> GHSA |

The shared C2 IP (`45.138.12.177:8089` is one of the wave-1 ports verbatim), the shared native-extension cover name across unrelated slugs, the shared evasion-gate list, and the shared verbatim OSV submission template argue for one operator shipping a second production wave against the un-covered half of the Web3 vertical.

## Package inventory (all v0.9.1, all pointing at 45.138.12.177:8089)

| Package | GHSA | OSV/MAL |
|---|---|---|
| `airdrop-eligibility-check` | GHSA-qmg2-cxmc-2xm5 | MAL-2026-17779 |
| `block-explorer-api` | GHSA-hg3j-6p9h-76jm | MAL-2026-17780 |
| `btc-fee-estimator` | GHSA-4264-cr8p-9wh7 | MAL-2026-17781 |
| `crypto-tax-export` | GHSA-7qmm-9mrq-vf4q | MAL-2026-17782 |
| `defi-yield-calculator` | GHSA-qchc-hrjm-3rwv | MAL-2026-17783 |
| `dex-router-abis` | GHSA-j34r-6fqr-vh5p | MAL-2026-17784 |
| `erc20-approve-audit` | GHSA-mq54-cvw7-j5m5 | MAL-2026-17785 |
| `eth-gas-oracle` | GHSA-3h65-764h-38gg | MAL-2026-17786 |
| `evm-tx-decoder` | GHSA-9f63-cxjq-v6f8 | MAL-2026-17787 |
| `gas-refuel-bridge` | GHSA-vpf2-wcf3-pq8j | MAL-2026-17788 |
| `hd-wallet-generator` | GHSA-539m-69r6-rw3m | MAL-2026-17789 |
| `mev-sandwich-detect` | GHSA-pcpf-mq97-v8pp | MAL-2026-17790 |
| `multichain-rpc` | GHSA-hh53-qgqp-j52v | MAL-2026-17791 |
| `nft-metadata-resolver` | GHSA-9f8r-f7cw-6pv8 | MAL-2026-17792 |
| `perp-funding-rates` | GHSA-rpp6-g37v-xmgh | MAL-2026-17793 |
| `seed-phrase-validator` | GHSA-vfwp-3q5f-qqrh | MAL-2026-17794 |
| `sol-mint-utils` | GHSA-3xwh-c3gj-3f29 | MAL-2026-17795 |
| `staking-apr-fetcher` | GHSA-5wxm-jv9m-mw2r | MAL-2026-17796 |
| `ton-jetton-tools` | GHSA-xqg7-h4h5-x6pf | MAL-2026-17797 |
| `tron-trc20-utils` | GHSA-94vm-385v-mjfj | MAL-2026-17798 |
| `wallet-balance-scanner` | GHSA-g92c-g6pm-wf38 | MAL-2026-17799 |
| `wallet-hd-derive` | GHSA-9grv-7vv7-5ppj | MAL-2026-17800 |
| `web3-signer-kit` | GHSA-m6qx-67h3-wwrh | MAL-2026-17801 |
| `xrp-ledger-utils` | GHSA-p4hf-p5fc-85p7 | MAL-2026-17802 |

**Classification**: `malicious-package` (24 fresh brand-adjacent lures published for this wave; none hijacks a legitimate upstream, so this is not a `compromise`). **Severity**: `high` - confirmed install-time RCE and persistent interactive shell on developer workstations with crypto credentials, but reach is limited to developers who `gem install` a lure, exactly matching the wave-1 severity call.

## Discovery

OpenSSF `malicious-packages` (ingested via Amazon Inspector`s IN-MAL feed), published to GitHub Advisory Database on 2026-10-11.

## Impact

- **One operator - continuation of the 2026-10-05 "wgkit" RubyGems crypto cluster**. Every one of today`s 24 gems shares with the earlier 25-gem wave: (a) C2 at `45.138.12.177:8089` on the same `45.138.0.0/16` superblock, (b) the `bitcoin-rpc-lite` README cover text and `bitcoin_rpc_lite_native` native-extension name across unrelated package slugs, (c) the identical evasion gating list (`~/.ssh`, `~/.gitconfig`, `~/.npmrc`, `~/.gem/credentials`, `~/.bundle` presence; uptime > 1800 s; CI / `GITHUB_ACTIONS` / `TRAVIS` / `JENKINS` / `GITLAB_CI` / `CODESPACES` env skips; `uvm`/`firecracker`/`sandbox`/`vagrant` hostname skips; `/opt/rubygems`/`/tmp`/`/var/tmp`/`/workspace` path skips), (d) the 20-40 minute jittered sleep inside a double-forked setsid detached child, (e) the Amazon Inspector-first disclosure path with OSSF `malicious-packages` MAL-2026-177XX IDs
- **Payload family shift from wave 1**: the 2026-10-05 wave fetched `wgkit.tar.gz` from the `45.138.*.*` subnet and ran `/tmp/.w1/wg_install.sh` as a staged second-stage installer; today`s wave 2 skips the staged dropper and goes straight to **TCP socket piped to `/bin/sh`** in an infinite reconnect loop. On every single wave-2 gem the sink is `45.138.12.177:8089`, exactly matching the port reused on `bitcoin-rpc-lite` and `web3-eth-utils` in wave 1
- **Target vertical shift from wave 1**: wave 1`s 25 gems were Ethereum / Bitcoin / Lightning Network / BIP39 / BIP32 / TRON basics (`eth-keystore-utils`, `btc-wallet-tools`, `keccak` typos, `ethereum.rb` typos, `tron-rb`). Wave 2`s 24 gems cover the **DeFi / MEV / airdrop / NFT / stablecoin / cross-chain** space that the first wave did not: Solana (`sol-mint-utils`), XRP Ledger (`xrp-ledger-utils`), TRON TRC-20 (`tron-trc20-utils`), TON jettons (`ton-jetton-tools`), MEV sandwich detection (`mev-sandwich-detect`), DEX router ABIs (`dex-router-abis`), perp funding rates (`perp-funding-rates`), airdrop eligibility (`airdrop-eligibility-check`), ERC-20 approvals auditing (`erc20-approve-audit`), gas estimation (`btc-fee-estimator`, `eth-gas-oracle`), tax export (`crypto-tax-export`), yield (`defi-yield-calculator`), bridges (`gas-refuel-bridge`), NFT metadata (`nft-metadata-resolver`), block explorers (`block-explorer-api`), multi-chain RPC (`multichain-rpc`), EVM tx decoding (`evm-tx-decoder`), staking APR (`staking-apr-fetcher`), balance scanning (`wallet-balance-scanner`), HD derivation (`hd-wallet-generator`, `wallet-hd-derive`), seed phrase validation (`seed-phrase-validator`), Web3 signing (`web3-signer-kit`). None of the 24 names is a strict single-char typosquat; all are brand-adjacent lures manufactured fresh for the wave to look like plausible utility gems a DeFi/Web3 Rubyist would try first
- **Target victim profile remains "developer workstation with crypto credentials"**: the same six developer-signal files (`~/.ssh`, `~/.gitconfig`, `~/.npmrc`, `~/.gem/credentials`, `~/.bundle`, `~/.ethereum/keystore`) must be present for the payload to fire, and the shell is `/bin/sh` with the installer user`s privileges. On any hit, treat SSH private keys, GitHub/GitLab/Codeberg PATs, RubyGems API key (`~/.gem/credentials`), npm authToken (`~/.npmrc`), Bundler config (`~/.bundle/config`), any `~/.ethereum/keystore/*` **and the seed phrases those encrypt**, hardware-wallet companion secrets, DeFi exchange CLI credentials, MetaMask browser-profile data, Phantom and Solana wallet state, hot wallets of ANY chain accessible from the user profile, and - if the installer user was privileged - `~/.aws/credentials` and `~/.config/gcloud` as fully compromised
- **Install-time native-extension abuse mechanism (unchanged from wave 1)**: every gem declares `ext/<name>/extconf.rb` in its gemspec`s `require_paths` with a native-extension name of `bitcoin_rpc_lite_native` (independent of the slug - a hint that the operator ships one wave-2 payload template and only rebrands the gemspec `summary`, `description`, and `homepage`). `gem install` auto-runs `extconf.rb` to generate a `Makefile`. Here the `extconf.rb` IS the payload: it base64-decodes an embedded Ruby string with `Base64.decode64` and runs it under `eval` from inside a double-fork setsid detached child. There is no shipped C source and no real native extension to build. The gem`s `lib/<name>.rb` is a two-method stub (`build_id = "ok"`, `healthy? = true`) that lets `require` succeed if a confused developer actually tries to use it, and the README text copy-pastes `bitcoin-rpc-lite` tagline across every slug regardless of the actual gem name

## What to do

1. `grep -nE "(wallet-balance-scanner|xrp-ledger-utils|staking-apr-fetcher|wallet-hd-derive|web3-signer-kit|tron-trc20-utils|ton-jetton-tools|crypto-tax-export|gas-refuel-bridge|btc-fee-estimator|evm-tx-decoder|hd-wallet-generator|sol-mint-utils|defi-yield-calculator|block-explorer-api|perp-funding-rates|airdrop-eligibility-check|erc20-approve-audit|nft-metadata-resolver|eth-gas-oracle|dex-router-abis|mev-sandwich-detect|multichain-rpc|seed-phrase-validator)" Gemfile Gemfile.lock *.gemspec` across every Rails/Sinatra/Jekyll/crypto-tooling repo. On any hit: `gem uninstall <name>`, delete `Gemfile.lock`, invalidate any Docker image layer that ran `bundle install` after 2026-10-11, rebuild from scratch
2. **Host-level hunt on any workstation or CI runner that ran `gem install` or `bundle install` against any of the 24 slugs since 2026-10-11**: audit outbound connections to `45.138.12.177:8089`, orphan long-lived `ruby` processes in session leader state (`ps -eo pid,ppid,sid,user,command | grep -i ruby | grep -v grep` - the double-forked payload is a session leader detached from any shell), suspicious `/bin/sh` descendants of a `ruby` parent, and `extconf.rb` under `~/.gem/ruby/*/gems/<name>-0.9.1/ext/`. **Any single hit means image the host** - the shell is interactive and the operator can have dropped anything the installer user could reach
3. **Rotate on any confirmed hit** (and on strong suspicion): SSH keys (`~/.ssh/*`), Git tokens (`~/.gitconfig`, `~/.config/gh`, `~/.config/glab`, GitHub/GitLab PATs), RubyGems API key (log in to rubygems.org, revoke old key, issue new one), npm authToken (`~/.npmrc`), Bundler config (`~/.bundle/config`), any `~/.ethereum/keystore/*` (**treat the seed phrases these encrypt as exposed** - rotate the wallets to fresh seeds, not just the config), MetaMask and Phantom browser profiles, hardware-wallet companion-app secrets, exchange CLI credentials. On a developer who runs `gem install` as a privileged user, assume `~/.aws/credentials`, `~/.config/gcloud`, and any `kubectl` kubeconfig under `~/.kube/` are reachable - rotate those too
4. **Egress blocklist additions** for CI, build hosts, and corporate developer egress proxies: deny outbound TCP to `45.138.12.177:8089` immediately. Extend to the full `45.138.0.0/16` superblock if your proxy supports it (keeps the standing wave-1 denylist of `45.138.12.0/24`, `45.138.17.0/24`, `45.138.122.0/24`, `45.138.127.0/24`, `45.138.172.0/24` in force). Deny outbound plain HTTP from CI by default; whitelist specific HTTPS mirrors instead
5. **Developer education**: there are no mainstream Ruby gems for DEX router ABIs, MEV sandwich detection, perp funding rates, airdrop eligibility, TON jettons, TRC-20 operations, EVM tx decoding, or multichain RPC - the Ruby ecosystem has `ethereum.rb` and that is largely it. Any gem that advertises Web3/DeFi/NFT functionality at `0.9.1` with no release history, an `ext/<name>/extconf.rb` whose native-extension name is `bitcoin_rpc_lite_native` across unrelated packages, and a `lib/<name>.rb` that only exports `build_id` and `healthy?` methods is a tarball-inspection-in-a-sandbox job before any `gem install` or any `bundle install`

## References

- [GitHub Advisory Database - recent RubyGems malware advisories](https://github.com/advisories?query=type%3Amalware+ecosystem%3Arubygems&sort=published-desc) - GitHub
- [GHSA-qmg2-cxmc-2xm5 - rubygems airdrop-eligibility-check](https://github.com/advisories/GHSA-qmg2-cxmc-2xm5) - GitHub
- [GHSA-hg3j-6p9h-76jm - rubygems block-explorer-api](https://github.com/advisories/GHSA-hg3j-6p9h-76jm) - GitHub
- [GHSA-4264-cr8p-9wh7 - rubygems btc-fee-estimator](https://github.com/advisories/GHSA-4264-cr8p-9wh7) - GitHub
- [GHSA-7qmm-9mrq-vf4q - rubygems crypto-tax-export](https://github.com/advisories/GHSA-7qmm-9mrq-vf4q) - GitHub
- [GHSA-qchc-hrjm-3rwv - rubygems defi-yield-calculator](https://github.com/advisories/GHSA-qchc-hrjm-3rwv) - GitHub
- [GHSA-j34r-6fqr-vh5p - rubygems dex-router-abis](https://github.com/advisories/GHSA-j34r-6fqr-vh5p) - GitHub
- [GHSA-mq54-cvw7-j5m5 - rubygems erc20-approve-audit](https://github.com/advisories/GHSA-mq54-cvw7-j5m5) - GitHub
- [GHSA-3h65-764h-38gg - rubygems eth-gas-oracle](https://github.com/advisories/GHSA-3h65-764h-38gg) - GitHub
- [GHSA-9f63-cxjq-v6f8 - rubygems evm-tx-decoder](https://github.com/advisories/GHSA-9f63-cxjq-v6f8) - GitHub
- [GHSA-vpf2-wcf3-pq8j - rubygems gas-refuel-bridge](https://github.com/advisories/GHSA-vpf2-wcf3-pq8j) - GitHub
- [GHSA-539m-69r6-rw3m - rubygems hd-wallet-generator](https://github.com/advisories/GHSA-539m-69r6-rw3m) - GitHub
- [GHSA-pcpf-mq97-v8pp - rubygems mev-sandwich-detect](https://github.com/advisories/GHSA-pcpf-mq97-v8pp) - GitHub
- [GHSA-hh53-qgqp-j52v - rubygems multichain-rpc](https://github.com/advisories/GHSA-hh53-qgqp-j52v) - GitHub
- [GHSA-9f8r-f7cw-6pv8 - rubygems nft-metadata-resolver](https://github.com/advisories/GHSA-9f8r-f7cw-6pv8) - GitHub
- [GHSA-rpp6-g37v-xmgh - rubygems perp-funding-rates](https://github.com/advisories/GHSA-rpp6-g37v-xmgh) - GitHub
- [GHSA-vfwp-3q5f-qqrh - rubygems seed-phrase-validator](https://github.com/advisories/GHSA-vfwp-3q5f-qqrh) - GitHub
- [GHSA-3xwh-c3gj-3f29 - rubygems sol-mint-utils](https://github.com/advisories/GHSA-3xwh-c3gj-3f29) - GitHub
- [GHSA-5wxm-jv9m-mw2r - rubygems staking-apr-fetcher](https://github.com/advisories/GHSA-5wxm-jv9m-mw2r) - GitHub
- [GHSA-xqg7-h4h5-x6pf - rubygems ton-jetton-tools](https://github.com/advisories/GHSA-xqg7-h4h5-x6pf) - GitHub
- [GHSA-94vm-385v-mjfj - rubygems tron-trc20-utils](https://github.com/advisories/GHSA-94vm-385v-mjfj) - GitHub
- [GHSA-g92c-g6pm-wf38 - rubygems wallet-balance-scanner](https://github.com/advisories/GHSA-g92c-g6pm-wf38) - GitHub
- [GHSA-9grv-7vv7-5ppj - rubygems wallet-hd-derive](https://github.com/advisories/GHSA-9grv-7vv7-5ppj) - GitHub
- [GHSA-m6qx-67h3-wwrh - rubygems web3-signer-kit](https://github.com/advisories/GHSA-m6qx-67h3-wwrh) - GitHub
- [GHSA-p4hf-p5fc-85p7 - rubygems xrp-ledger-utils](https://github.com/advisories/GHSA-p4hf-p5fc-85p7) - GitHub
- [DependencyWatch: 2026-10-05 wgkit wave 1 (prior wave of the same operator)](https://dependencywatch.io/incident/rubygems-2026-10-05-eth-crypto-wgkit-cluster)

---

Canonical page: https://dependencywatch.io/incident/rubygems-2026-10-12-wgkit-wave-2-crypto-defi-cluster
Markdown version: https://dependencywatch.io/incident/rubygems-2026-10-12-wgkit-wave-2-crypto-defi-cluster.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
