Skip to content

Instantly share code, notes, and snippets.

@SamStudio8
Last active November 28, 2025 13:18
Show Gist options
  • Select an option

  • Save SamStudio8/059921f4b9bbdcda19d8cd869838ba32 to your computer and use it in GitHub Desktop.

Select an option

Save SamStudio8/059921f4b9bbdcda19d8cd869838ba32 to your computer and use it in GitHub Desktop.
A simple Sandworm summoner
#!/usr/bin/env python
import argparse
import base64
import json
import os
import re
import sys
from github import Github, Auth
from github.GithubException import GithubException
__author__ = "@samstudio8"
__version__ = "0.0.2"
"""
0.0.2 2025-11-28: Don't keep exposed users in suspense for the repo list. May as well run findall.
0.0.1 2025-11-28: Threw this together in case it is useful.
"""
parser = argparse.ArgumentParser()
parser.add_argument("--files", nargs="+", help="File paths in detected repos to double base64 decode and check", default=["environment.json"])
parser.add_argument("--words", required=True, nargs="+", help="Words to search for in decoded files (case insensitive)")
parser.add_argument("--token", help="Token may be provided via the GITHUB_TOKEN environment variable, or this arg.")
args = parser.parse_args()
token = args.token or os.getenv("GITHUB_TOKEN")
if token:
auth = Auth.Token(token)
else:
auth = None
sys.stderr.write("No GITHUB_TOKEN, will use anonymous API but may incur rate limiting.\n")
sys.stderr.write(f"Searching files: {args.files}\n")
sys.stderr.write(f"Searching words: {args.words}\n")
PATTERN = re.compile("|".join(args.words), re.IGNORECASE)
g = Github(auth=auth)
query = '\"Sha1-Hulud: The Second Coming.\" in:description'
results = g.search_repositories(query=query)
sys.stderr.write(f"{results.totalCount} repositories found, investigating...\n")
repos_read = 0
files_decoded = 0
repos_detected = 0
for repo in results:
repos_read += 1
for filename in args.files:
try:
f = repo.get_contents(filename)
except GithubException as e:
if e.status == 404:
continue
try:
content = base64.b64decode(f.content)
shai_halud_payload = base64.b64decode(base64.b64decode(content)).decode("utf-8", "ignore")
files_decoded += 1
matches = set(PATTERN.findall(shai_halud_payload))
if matches:
for m in matches:
sys.stdout.write(f"{repo.full_name},{m}\n")
repos_detected += 1
break
except Exception as e:
sys.stderr.write(f"{e}\n")
if repos_read % 10 == 0 and repos_read > 0:
sys.stderr.write(f"{repos_read} repos checked, {repos_detected} repo detections so far...\n")
if repos_detected > 0:
sys.stderr.write(f"! Checked {repos_read} repos and {files_decoded} files, and unfortunately at least one of your search words was detected in {repos_detected} repos.\n")
sys.exit(1)
else:
sys.stderr.write(f"Checked {repos_read} repos and {files_decoded} files, and you're looking good.\n")
@SamStudio8
Copy link
Author

I've tested this briefly with some repos I can see are exposed and get the messages I expect. Things will likely fall apart if the number of public exposed repos becomes greater than the maximum API response of 1000 repositories. I've also (clearly) not tested a wider range of potential HTTP failure modes. If you're using an anonymous token you're on your own.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment