Last active
November 28, 2025 13:18
-
-
Save SamStudio8/059921f4b9bbdcda19d8cd869838ba32 to your computer and use it in GitHub Desktop.
A simple Sandworm summoner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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") |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.