remove PolinRider malware scan workflow

This workflow scans for PolinRider malware signatures, checks git history for suspicious patterns, and enforces a clean-scan gate to block deployments if malware is detected.
This commit is contained in:
Sennay
2026-06-16 23:25:21 +03:00
committed by GitHub
parent 9329e6ca57
commit fd49d904a8

View File

@@ -1,243 +1 @@
name: PolinRider Malware Scan
# ── Triggers ──────────────────────────────────────────────────────────────────
# Runs on every push and every PR targeting main/master/develop.
# Also available as a manual trigger (workflow_dispatch) and on a nightly
# schedule so dormant infections in older branches are caught too.
on:
push:
branches: ["**"]
pull_request:
branches: ["**"]
schedule:
# Nightly full-repo scan at 02:00 UTC
- cron: "0 2 * * *"
workflow_dispatch:
# ── Permissions ───────────────────────────────────────────────────────────────
permissions:
contents: read # checkout
security-events: write # upload SARIF to GitHub Security tab
actions: read
checks: write # annotate PRs with scan findings
# ── Deployment gate ───────────────────────────────────────────────────────────
# All other jobs (build, test, deploy) should list this job under `needs:`.
# If this job fails (exit code 1 from the scanner), the whole workflow stops.
jobs:
polinrider-scan:
name: "PolinRider / Famous Chollima Scan"
runs-on: ubuntu-latest
# Prevent CI from being disabled by any workflow override
if: always()
steps:
# ── 1. Checkout full history ─────────────────────────────────────────────
# Full depth so we can inspect recent commits for temp_auto_push.bat traces
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
# ── 2. Detect suspicious force-push patterns in git history ──────────────
- name: Check git history for force-push and timestamp manipulation
id: git-check
shell: bash
run: |
echo "=== Checking for suspicious git history patterns ==="
# Check for .gitignore entries hiding known malware artifacts
GITIGNORE_HITS=0
if [ -f .gitignore ]; then
for pattern in "branch_structure.json" "temp_auto_push.bat" "temp_interactive_push.bat"; do
if grep -qF "$pattern" .gitignore 2>/dev/null; then
echo "::warning file=.gitignore::SUSPICIOUS: .gitignore hides known PolinRider artifact: $pattern"
GITIGNORE_HITS=$((GITIGNORE_HITS + 1))
fi
done
fi
# Check if malware persistence artifacts exist anywhere in the tree
ARTIFACTS_FOUND=0
for artifact in "temp_auto_push.bat" "temp_interactive_push.bat" "branch_structure.json"; do
FOUND=$(find . -name "$artifact" -not -path "./.git/*" 2>/dev/null)
if [ -n "$FOUND" ]; then
echo "::error ::CRITICAL: PolinRider persistence artifact found: $artifact"
echo "$FOUND"
ARTIFACTS_FOUND=$((ARTIFACTS_FOUND + 1))
fi
done
# Scan recent commit messages for --no-verify (used by temp_auto_push.bat)
NO_VERIFY_COMMITS=$(git log --oneline -50 --format="%H %s" 2>/dev/null | grep -i "no.verify\|force.*push\|amend" || true)
if [ -n "$NO_VERIFY_COMMITS" ]; then
echo "::warning ::Recent commits with suspicious metadata (--no-verify / force amend patterns):"
echo "$NO_VERIFY_COMMITS"
fi
# Check for .woff2 files with unusually large sizes (>50KB is suspicious)
find . -name "*.woff2" -not -path "./.git/*" -size +50k 2>/dev/null | while read f; do
SIZE=$(stat -c%s "$f" 2>/dev/null || echo 0)
echo "::warning file=$f::Oversized .woff2 font file ($SIZE bytes) — may contain embedded payload"
done
echo "GITIGNORE_HITS=$GITIGNORE_HITS" >> "$GITHUB_OUTPUT"
echo "ARTIFACTS_FOUND=$ARTIFACTS_FOUND" >> "$GITHUB_OUTPUT"
# ── 3. Run the JavaScript malware scanner ────────────────────────────────
- name: Run PolinRider malware scanner
id: scanner
shell: bash
run: |
echo "=== Running PolinRider IOC scanner ==="
# The scanner is zero-dependency — just needs Node.js (always present on ubuntu-latest)
node .github/scripts/scan.js \
--json \
--output scan-report.json \
.
SCANNER_EXIT=$?
echo "SCANNER_EXIT=$SCANNER_EXIT" >> "$GITHUB_OUTPUT"
# Also emit a human-readable summary to the Actions log
node .github/scripts/scan.js . || true
exit $SCANNER_EXIT
# ── 4. Upload scan report as artifact ────────────────────────────────────
# - name: Upload scan report
# if: always()
# uses: actions/upload-artifact@v4
# with:
# name: polinrider-scan-report
# path: scan-report.json
# retention-days: 90
# # ── 5. Convert to SARIF and upload to GitHub Security tab ─────────────
# - name: Convert scan results to SARIF
# if: always()
# shell: bash
# run: |
# node - << 'SCRIPT'
# const fs = require('fs');
# let report;
# try {
# report = JSON.parse(fs.readFileSync('scan-report.json', 'utf8'));
# } catch {
# // No report = no findings, write empty SARIF
# report = { results: [] };
# }
# const severityMap = {
# CRITICAL: 'error',
# HIGH: 'warning',
# MEDIUM: 'note',
# };
# const sarif = {
# version: '2.1.0',
# $schema: 'https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json',
# runs: [{
# tool: {
# driver: {
# name: 'PolinRider Malware Scanner',
# version: '1.0.0',
# informationUri: 'https://github.com/your-org/your-repo',
# rules: [
# { id: 'POLINRIDER-001', name: 'StringShufflerVariable',
# shortDescription: { text: 'PolinRider _$_1e42 shuffler variable' },
# helpUri: 'https://safedep.io/astro-config-blockchain-c2-supply-chain/' },
# { id: 'POLINRIDER-002', name: 'CampaignMarkerAssignment',
# shortDescription: { text: "global['!'] campaign marker" } },
# { id: 'POLINRIDER-003', name: 'ShufflerSeedString',
# shortDescription: { text: 'rmcej%otb% seed string' } },
# { id: 'POLINRIDER-004', name: 'KnownC2IP',
# shortDescription: { text: 'Known PolinRider C2 IP address' } },
# { id: 'POLINRIDER-005', name: 'TRONWallet',
# shortDescription: { text: 'Known TRON dead-drop wallet' } },
# { id: 'POLINRIDER-006', name: 'AptosAddress',
# shortDescription: { text: 'Known Aptos dead-drop address' } },
# { id: 'POLINRIDER-007', name: 'XORKey',
# shortDescription: { text: 'Known XOR decryption key' } },
# { id: 'POLINRIDER-008', name: 'KnownMalwareHash',
# shortDescription: { text: 'SHA-256 matches known malware sample' } },
# { id: 'POLINRIDER-009', name: 'BlockchainC2Contact',
# shortDescription: { text: 'Blockchain RPC dead-drop infrastructure' } },
# { id: 'POLINRIDER-010', name: 'HiddenProcessSpawn',
# shortDescription: { text: 'windowsHide:true hidden process spawn' } },
# { id: 'POLINRIDER-011', name: 'DuplicateCreateRequire',
# shortDescription: { text: 'Duplicate createRequire injection' } },
# { id: 'POLINRIDER-012', name: 'HorizontalWhitespacePadding',
# shortDescription: { text: 'Hidden payload via horizontal whitespace' } },
# { id: 'POLINRIDER-013', name: 'ConfigFileSizeAnomaly',
# shortDescription: { text: 'Config file size anomaly' } },
# { id: 'POLINRIDER-014', name: 'PersistenceArtifact',
# shortDescription: { text: 'PolinRider persistence artifact present' } },
# { id: 'POLINRIDER-015', name: 'CampaignMarkerPattern',
# shortDescription: { text: 'Numeric campaign marker pattern' } },
# { id: 'POLINRIDER-016', name: 'SfLObfuscationFunction',
# shortDescription: { text: 'sfL obfuscation function' } },
# { id: 'POLINRIDER-017', name: 'GlobalRequireInjection',
# shortDescription: { text: 'global require/module injection' } },
# ],
# },
# },
# results: (report.results || []).flatMap(file =>
# (file.findings || []).map(finding => ({
# ruleId: finding.id,
# level: severityMap[finding.severity] || 'warning',
# message: { text: finding.description + ' — ' + finding.matches.join('; ') },
# locations: [{
# physicalLocation: {
# artifactLocation: { uri: file.filePath.replace(/^\.\//,''), uriBaseId: '%SRCROOT%' },
# region: { startLine: 1 },
# },
# }],
# }))
# ),
# }],
# };
# fs.writeFileSync('scan-results.sarif', JSON.stringify(sarif, null, 2));
# console.log('SARIF written.');
# SCRIPT
# - name: Upload SARIF to GitHub Security tab
# if: always()
# uses: github/codeql-action/upload-sarif@v3
# with:
# sarif_file: scan-results.sarif
# category: polinrider-malware-scan
# ── 6. Block deployment if infected ──────────────────────────────────────
- name: Enforce clean-scan gate
if: steps.scanner.outputs.SCANNER_EXIT == '1' || steps.git-check.outputs.ARTIFACTS_FOUND != '0'
shell: bash
run: |
echo ""
echo "╔══════════════════════════════════════════════════════════════════╗"
echo "║ DEPLOYMENT BLOCKED — PolinRider malware signatures detected ║"
echo "║ ║"
echo "║ This repository contains code signatures consistent with the ║"
echo "║ PolinRider supply-chain campaign (DPRK / Famous Chollima). ║"
echo "║ ║"
echo "║ DO NOT run npm install, build, or deploy until remediated. ║"
echo "║ ║"
echo "║ See scan-report.json artifact for full details. ║"
echo "╚══════════════════════════════════════════════════════════════════╝"
exit 1
# ── Dependent jobs — add `needs: polinrider-scan` to block on clean scan ─────
# Example: your existing build/deploy jobs should look like this:
#
# build:
# needs: polinrider-scan
# runs-on: ubuntu-latest
# steps:
# ...
#
# deploy:
# needs: [polinrider-scan, build]
# ...