Security Arsenal has identified an active automated campaign designated Gheist that leverages compromised GitHub tokens for large-scale supply chain attacks. Since September 15, 2026, the adversary has systematically abused stolen authentication tokens to commit malicious workflow files—named sync-check—to every accessible repository.
The attack chain is straightforward but highly effective: once a token is compromised, the threat actor uses it to push a GitHub Actions workflow that prints all repository secrets into workflow logs. These logs are then accessed via GitHub's API, the secrets exfiltrated, and the logs deleted within seconds to minimize forensic traces. The scale is significant—over 13,500 planted branches across more than 850 compromised organizations indicate a highly automated, industrialized credential harvesting operation.
The campaign is associated with the PolinRider malware family, which appears to be the tooling used to orchestrate token abuse and secret exfiltration. The objective is clear: mass harvesting of CI/CD secrets, API keys, cloud credentials, and other sensitive tokens stored in GitHub repositories for downstream exploitation, resale, or lateral movement into victim infrastructure.
Threat Actor / Malware Profile
Malware Family: PolinRider
Campaign Name: Gheist
Threat Actor: Unknown (attribution pending)
First Observed: September 15, 2026
Target: GitHub repositories with exposed or compromised personal access tokens (PATs)
Distribution Method
PolinRider is not distributed via traditional phishing or drive-by download. Instead, it operates as a post-compromise tool, activated after GitHub tokens are obtained through other means—likely credential stuffing, infostealer logs, exposed .env files, or compromised developer workstations.
Payload Behavior
Once a valid GitHub token is acquired, PolinRider:
- Enumerates all repositories accessible to the token
- Creates a new branch (naming pattern consistent across victims)
- Commits a workflow file named
sync-check.ymlto.github/workflows/ - The workflow is configured to trigger on push and executes commands to print all repository secrets to workflow logs using
echo $SECRET_NAMEor similar - The workflow logs are immediately retrieved via GitHub API
- Logs are deleted within seconds to reduce detection window
C2 Communication
PolinRider communicates with GitHub's legitimate API (api.github.com) using stolen tokens, blending malicious activity with legitimate API traffic. This makes detection based solely on network indicators challenging. Exfiltrated secrets are likely staged to attacker-controlled infrastructure, though OTX indicators do not yet include C2 IPs or domains.
Persistence Mechanism
Persistence is achieved through the malicious workflow file itself. As long as the workflow remains in the repository, it can be re-triggered manually or via automated events. Additionally, if the compromised token is not revoked, the attacker retains persistent access to the repository and can re-plant workflows at will.
Anti-Analysis Techniques
- Rapid log deletion: Workflow logs are deleted seconds after execution, reducing forensic evidence
- Living off the land: Uses legitimate GitHub API and Actions infrastructure, avoiding custom malware artifacts on endpoint
- Token rotation: May cycle through multiple compromised tokens to avoid rate limiting and detection
IOC Analysis
The OTX pulse provides five indicators:
- CVE-2026-111497: A vulnerability identifier associated with this campaign. Details on this CVE are not yet public, but it may relate to a GitHub token leakage vector or a flaw in a third-party tool that exposes tokens.
- FileHash-SHA1 (x4): Four SHA1 hashes likely correspond to samples of the
sync-check.ymlworkflow file or PolinRider tooling. These should be added to blocklists and scanned against code repositories and endpoint file systems.
Operationalization Guidance
SOC teams should:
- Ingest the SHA1 hashes into EDR/XDR platforms and scan for matching files across endpoints and repositories
- Query GitHub audit logs for any workflow files matching the provided hashes or the
sync-checkfilename - Monitor for the presence of
.github/workflows/sync-check.ymlin any repository - Hunt for GitHub API calls with unusual patterns (mass repository enumeration, rapid workflow creation, log access)
Tooling:
- GitHub Advanced Security / Secret Scanning
- YARA rules for hash matching
- Sigma rules for GitHub API abuse patterns (see Detection Engineering)
Detection Engineering
---
title: Suspicious GitHub Workflow File Creation - Gheist Campaign
id: 9f4e2a1b-8c3d-4e5f-9a1b-2c3d4e5f6a7b
status: experimental
description: Detects creation of sync-check workflow file associated with Gheist campaign and PolinRider malware
references:
- https://www.wiz.io/blog/gheist-attempted-scaled-abuse-of-stolen-github-tokens-stumbles
author: Security Arsenal
date: 2026/10/27
tags:
- attack.credential_access
- attack.t1552.001
logsource:
category: file_event
product: github
detection:
selection:
file_path|endswith: '.github/workflows/sync-check.yml'
condition: selection
falsepositives:
- Legitimate sync-check workflows (rare)
level: high
---
title: GitHub Actions Workflow Secret Exfiltration Pattern
id: 1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
status: experimental
description: Detects GitHub Actions workflows that print secrets to logs, indicative of Gheist campaign
references:
- https://www.wiz.io/blog/gheist-attempted-scaled-abuse-of-stolen-github-tokens-stumbles
author: Security Arsenal
date: 2026/10/27
tags:
- attack.credential_access
- attack.t1552
logsource:
category: process_creation
product: github
detection:
selection:
workflow_command|contains:
- 'echo $'
- 'printenv'
- 'env |'
filter:
workflow_name: 'sync-check'
condition: selection and filter
falsepositives:
- Debug workflows in test repositories
level: critical
---
title: Mass GitHub Repository Access via API - Potential Token Abuse
id: 7f8e9d0c-1b2a-3c4d-5e6f-7a8b9c0d1e2f
status: experimental
description: Detects anomalous volume of repository access via GitHub API, potentially indicating token abuse
references:
- https://www.wiz.io/blog/gheist-attempted-scaled-abuse-of-stolen-github-tokens-stumbles
author: Security Arsenal
date: 2026/10/27
tags:
- attack.discovery
- attack.t1087
logsource:
category: webserver
product: github
detection:
selection:
http_method: 'GET'
uri_path|contains: '/repos/'
timeframe: 5m
condition: selection | count() by src_ip > 50
falsepositives:
- Legitimate automation or CI/CD pipelines
level: medium
// Microsoft Sentinel KQL Hunt - Gheist Campaign GitHub Token Abuse
// Hunt for suspicious GitHub API activity and workflow file creation
let SuspiciousWorkflow = "sync-check.yml";
let TimeRange = 7d;
// Hunt 1: File creation events for sync-check workflow
DeviceFileEvents
| where TimeGenerated > ago(TimeRange)
| where FileName == SuspiciousWorkflow
| where FolderPath contains ".github/workflows"
| project TimeGenerated, DeviceName, FileName, FolderPath, SHA1, InitiatingProcessAccountName
| join kind=leftouter (
DeviceProcessEvents
| where TimeGenerated > ago(TimeRange)
| project TimeGenerated, DeviceName, ProcessCommandLine, AccountName
) on DeviceName, $left.TimeGenerated == $right.TimeGenerated
;
// Hunt 2: Network connections to GitHub API from non-standard processes
DeviceNetworkEvents
| where TimeGenerated > ago(TimeRange)
| where RemoteUrl contains "api.github.com"
| where InitiatingProcessName !in ("git.exe", "githubdesktop.exe", "code.exe", "curl.exe")
| project TimeGenerated, DeviceName, InitiatingProcessName, RemoteUrl, RemoteIP
| summarize APIHits = count() by DeviceName, InitiatingProcessName, RemoteIP
| where APIHits > 100
| order by APIHits desc;
# PowerShell IOC Hunt Script - Gheist Campaign / PolinRider
# Checks for presence of sync-check workflow file and associated hashes
$TargetHashes = @(
"1dc5af9cce950aad1eb1546ecce8565b117540c4",
"c665b778b2d822453293003e7ca0bbb2cb08e39d",
"d09535857a741bbb976bdc084a9a021713133291",
"f3da2b8b357dcda02fd455d314be2a95007516a6"
)
$SuspiciousFileName = "sync-check.yml"
$SearchPaths = @("C:\Users", "C:\Repos", "C:\Projects", "D:\")
Write-Host "[+] Starting Gheist Campaign IOC Hunt..." -ForegroundColor Green
# Check for sync-check.yml files
foreach ($Path in $SearchPaths) {
if (Test-Path $Path) {
Write-Host "[+] Searching $Path for $SuspiciousFileName..." -ForegroundColor Yellow
$Files = Get-ChildItem -Path $Path -Recurse -Filter $SuspiciousFileName -ErrorAction SilentlyContinue
foreach ($File in $Files) {
Write-Host "[!] FOUND: $($File.FullName)" -ForegroundColor Red
$FileHash = Get-FileHash -Path $File.FullName -Algorithm SHA1
if ($TargetHashes -contains $FileHash.Hash) {
Write-Host "[!] MATCH: Hash $($FileHash.Hash) matches known IOC!" -ForegroundColor Red
}
}
}
}
# Check for suspicious network connections to GitHub API
Write-Host "[+] Checking for suspicious GitHub API connections..." -ForegroundColor Yellow
$Connections = Get-NetTCPConnection | Where-Object { $_.RemotePort -eq 443 -and $_.State -eq "Established" }
foreach ($Conn in $Connections) {
$Process = Get-Process -Id $Conn.OwningProcess -ErrorAction SilentlyContinue
if ($Process -and $Process.ProcessName -notin @("git", "chrome", "firefox", "msedge")) {
$RemoteHost = (Resolve-DnsName -Name $Conn.RemoteAddress -ErrorAction SilentlyContinue).NameHost
if ($RemoteHost -like "*github*") {
Write-Host "[!] Suspicious connection: $($Process.ProcessName) -> $RemoteHost" -ForegroundColor Red
}
}
}
Write-Host "[+] Hunt complete. Review findings above." -ForegroundColor Green
Response Priorities
Immediate (0-24 hours)
- Block IOCs: Add SHA1 hashes to EDR/XDR blocklists and scan all endpoints
- Audit GitHub: Search all repositories for
.github/workflows/sync-check.ymland remove immediately - Token Inventory: Identify all GitHub personal access tokens (PATs) in use across the organization
- Revoke Suspicious Tokens: Revoke any tokens with unusual activity or those not actively monitored
24 Hours
- Credential Rotation: Rotate ALL secrets stored in GitHub repositories (assume compromise)
- Identity Verification: Verify all recent commits and workflow runs were legitimate
- Access Review: Audit GitHub organization access logs for unusual API activity
- Developer Awareness: Alert development teams to the threat and require verification of any unexpected workflow files
1 Week
- Architecture Hardening: Implement GitHub Advanced Security with secret scanning and push protection
- Token Policy: Enforce use of fine-grained PATs with minimal scope and short expiration
- Workflow Approval: Require manual approval for all new GitHub Actions workflows before execution
- Network Segmentation: Restrict GitHub API access from developer workstations to approved IP ranges
- Detection Tuning: Deploy Sigma rules and KQL queries to production SIEM/SOAR platforms
Related Resources
Security Arsenal Incident Response Managed SOC & MDR Services AlertMonitor Threat Detection From The Dark Side Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.