AnalysisType: rule
Filename: github_shai_hulud_repo_created.py
RuleID: "GitHub.Webhook.Sha1HuludRepoCreated"
DisplayName: "GitHub Sha1-Hulud Malicious Repository Created"
Enabled: true
LogTypes:
- GitHub.Webhook
Reports:
MITRE ATT&CK:
- TA0001:T1195.002 # Supply Chain Compromise: Compromise Software Supply Chain
Tags:
- GitHub
- Supply Chain
- Threat Intelligence
Severity: High
Description: >
Detects when a repository is created with the description "Sha1-Hulud: The Second Coming.",
which is a known indicator of compromise associated with the Sha1-Hulud 2.0 campaign. Repos
created with this description are typically indicators of an exfiltration attempt by the worm.
Runbook: |
1. Immediately investigate the repository and its creator
2. Review the repository owner's account for signs of compromise
3. Check if any code has been pushed to the repository
4. Review organization access and permissions for the user who created the repository
5. Consider immediately archiving or deleting the repository
6. Report the repository and user to GitHub Trust & Safety
7. Review recent activity from the same user across all repositories
8. Check for any downstream impacts if the repository was forked or cloned
9. Notify security team and relevant stakeholders immediately
Reference: https://www.wiz.io/blog/shai-hulud-2-0-ongoing-supply-chain-attack
Tests:
- Name: Sha1-Hulud Repository Created
ExpectedResult: true
Log:
{
"action": "created",
"repository": {
"id": 1104055056,
"node_id": "R_kgDOQc6LEA",
"name": "wuhhsdknjf",
"full_name": "Owner/wuhhsdknjf",
"private": true,
"owner": {
"login": "Owner",
"id": 123456789,
"type": "Organization"
},
"html_url": "https://github.com/Owner/wuhhsdknjf",
"description": "Sha1-Hulud: The Second Coming.",
"created_at": "2025-11-25T17:32:12Z",
"clone_url": "https://github.com/Owner/wuhhsdknjf.git",
"visibility": "private"
},
"organization": {
"login": "Owner",
"id": 123456789
},
"sender": {
"login": "Owner",
"id": 123456789,
"type": "User",
"html_url": "https://github.com/Owner"
},
"p_log_type": "GitHub.Webhook"
}
- Name: Normal Repository Created
ExpectedResult: false
Log:
{
"action": "created",
"repository": {
"id": 123456789,
"name": "my-project",
"full_name": "myorg/my-project",
"private": false,
"owner": {
"login": "myorg",
"id": 987654321,
"type": "Organization"
},
"html_url": "https://github.com/myorg/my-project",
"description": "A legitimate project for data analysis",
"created_at": "2025-11-25T10:00:00Z"
},
"sender": {
"login": "developer",
"id": 111222333,
"type": "User"
},
"p_log_type": "GitHub.Webhook"
}
- Name: Different Event Action
ExpectedResult: false
Log:
{
"action": "deleted",
"repository": {
"id": 1104055056,
"name": "wuhhsdknjf",
"full_name": "Owner/wuhhsdknjf",
"description": "Sha1-Hulud: The Second Coming.",
"html_url": "https://github.com/Owner/wuhhsdknjf"
},
"sender": {
"login": "giredeops",
"id": 123456789,
"type": "User"
},
"p_log_type": "GitHub.Webhook"
}
# ------ paired body: github_shai_hulud_repo_created.py ------
from panther_github_helpers import github_webhook_alert_context
def rule(event):
if event.get("action") != "created":
return False
# Check if the repository description matches the Shai-Hulud indicator
description = event.deep_get("repository", "description", default="")
return description == "Sha1-Hulud: The Second Coming."
def title(event):
repo_name = event.deep_get("repository", "full_name", default="<UNKNOWN_REPO>")
user = event.deep_get("sender", "login", default="<UNKNOWN_USER>")
return f"Sha1-Hulud malicious repository [{repo_name}] created by compromised user [{user}]"
def alert_context(event):
context = github_webhook_alert_context(event)
return context