Skip to main content
Blog

BETA DETECTION: Mini Shai-Hulud gh-token-monitor Persistence Service Registration Analytic

  • May 14, 2026
  • 0 replies
  • 4 views
Aaron Beardslee
Forum|alt.badge.img
name: Mini Shai-Hulud gh-token-monitor Persistence Service Registration Analytic
category: 'Persistence'
threatname: 'Boot or Logon Autostart Execution: Systemd Service'
functionality: 'Endpoint Management Systems'
description: |
Detects the installation of the gh-token-monitor persistence service deployed by the Mini
Shai-Hulud npm worm (TeamPCP). After stealing credentials from an npm install context, the
worm's Payload 1 installs a platform-native service that continuously monitors for newly
available GitHub tokens and re-exfiltrates them on every reboot. The service name
gh-token-monitor is campaign-specific and has no known legitimate use.
On Linux: ~/.config/systemd/user/gh-token-monitor.service via systemctl --user enable
On macOS: ~/Library/LaunchAgents/com.user.gh-token-monitor.plist via launchctl load

DEPLOYMENT SCOPE: Developer workstations ONLY.
This rule has no value on CI runners of any type. GitHub managed runners are ephemeral
VMs with no endpoint visibility. Self-hosted CI runners, while org-owned and instrumented,
are also treated as stateless — each job runs in a clean environment, any service
registered during a job is destroyed when that environment resets, and the runner host
is not a machine where developers have persistent authenticated sessions. The
gh-token-monitor service is specifically designed to re-collect credentials across reboots
on machines with long-lived developer sessions — that describes a workstation, not a
runner. Deploy exclusively against your developer workstation fleet via Sysmon For Linux.
Sysmon For Linux EVID 1 is the required telemetry source.
reference:
- https://www.stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem
- https://github.com/fluffybunnies-h4x/FT-Linux-Sysmon-Config
labels:
- attack.persistence
- attack.t1543.002
- attack.t1543
- Mini_Shai_Hulud
- TeamPCP
- Supply_Chain
logsource:
category: process_creation
product: linux
detection:
selection_systemctl_linux:
Image|endswith:
- '/systemctl'
CommandLine|contains|all:
- '--user'
- 'gh-token-monitor'
CommandLine|contains:
- 'enable'
- 'start'
selection_launchctl_macos:
Image|endswith:
- '/launchctl'
CommandLine|contains|all:
- 'load'
- 'gh-token-monitor'
selection_service_file_reference:
# Catches direct script installs referencing the service files by path
CommandLine|contains:
- 'com.user.gh-token-monitor'
- 'gh-token-monitor.service'
- 'gh-token-monitor.plist'
condition: selection_systemctl_linux or selection_launchctl_macos or selection_service_file_reference
criticality: High
saveasthreat: false

violation_summary:
grouping_attribute: 'accountname'
level2_attribute: 'devicehostname'
level2_metadata_attributes:

TECHNICAL DETAILS


    DEPLOYMENT SCOPE
    ----------------
    Target systems:  Developer workstations ONLY
    Do NOT deploy:   GitHub managed runners (no endpoint visibility)
                     Self-hosted CI runners (ephemeral job environments — runner jobs
                     start clean per execution, any service registered mid-job is
                     wiped when the environment resets; no persistent developer
                     session to re-collect credentials from anyway)
    Rationale:       The gh-token-monitor service re-collects credentials on every
                     reboot. This only matters on machines with persistent state where
                     a developer is authenticated to npm, GitHub, cloud providers, and
                     IDE tools between sessions. That is a workstation, not a runner.

    PERSISTENCE ARTIFACT DETAILS
    ----------------------------
    Payload 1 (payload_1.sh) installer logic (decrypted from AES-256-GCM layer):

      SCRIPT_NAME="gh-token-monitor"
      PLIST_LABEL="com.user.${SCRIPT_NAME}"
      PLIST_PATH="${HOME}/Library/LaunchAgents/${PLIST_LABEL}.plist"
      SERVICE_PATH="${HOME}/.config/systemd/user/${SCRIPT_NAME}.service"

      # Linux: register and start via systemd user session
      systemctl --user enable gh-token-monitor
      systemctl --user start gh-token-monitor

      # macOS: register via LaunchAgent (fires on login)
      launchctl load ${PLIST_PATH}

    Persistence artifacts for retroactive file-existence hunt:
      ~/.config/systemd/user/gh-token-monitor.service
      ~/Library/LaunchAgents/com.user.gh-token-monitor.plist
      ~/.local/bin/gh-token-monitor.sh     (monitor script binary)
      ~/.config/gh-token-monitor/token     (stores stolen token between runs)

    Removal commands:
      systemctl --user stop gh-token-monitor
      systemctl --user disable gh-token-monitor
      rm -f ~/.config/systemd/user/gh-token-monitor.service
      launchctl unload ~/Library/LaunchAgents/com.user.gh-token-monitor.plist
      rm -f ~/Library/LaunchAgents/com.user.gh-token-monitor.plist
      rm -rf ~/.config/gh-token-monitor ~/.local/bin/gh-token-monitor.sh

    False Positives: None expected. The service name is campaign-specific.


Policy building walkthrough can be found in this previous post:

 

https://connect.securonix.com/threat%2Dresearch%2Dintelligence%2D62/beta%2Ddetection%2Dtelnyx%2Dteampcp%2Dcredential%2Dexfiltration%2D241

 


Sysmon For Linux is CRITICAL for this detection to work

 

Here is the github repo I co-maintain to help security professionals who haven’t installed or worked with Sysmon For Linux get it up and running:

https://github.com/fluffybunnies-h4x/FT-Linux-Sysmon-Config