Detection rules › Panther
Panther rules: shai
| Rule | Severity |
|---|---|
| Sha1-Hulud V2 Filenames Added to Repository |
Sha1-Hulud V2 Filenames Added to Repository
#This saved query detects filenames associated with the Sha1-Hulud worm 2.0 campaign, where malicious JS files are inserted into GitHub repositories to exfiltrate secrets. Attack details: - GitHub repositories get compromised via vulnerable workflows - Attackers are able to push their malicious code, contained in filenames "setup_bun.js" and "bun_environment.js" - These files are responsible for exfiltrating cloud credentials, secrets and tokens.
Rule specification
AnalysisType: saved_query
QueryName: Sha1-Hulud V2 Filenames Added to Repository
Description: |
This saved query detects filenames associated with the Sha1-Hulud worm 2.0 campaign,
where malicious JS files are inserted into GitHub repositories to exfiltrate secrets.
Attack details:
- GitHub repositories get compromised via vulnerable workflows
- Attackers are able to push their malicious code, contained in
filenames "setup_bun.js" and "bun_environment.js"
- These files are responsible for exfiltrating cloud credentials, secrets and tokens.
Tags:
- GitHub
- Supply Chain
- Suspicious Files
- Code Injection
SnowflakeQuery: |
SELECT
github_webhook.*,
all_commits.value AS commit_data,
added_files.value AS added_file
FROM panther_logs.public.github_webhook,
TABLE(FLATTEN(input => commits, outer => true)) all_commits,
TABLE(FLATTEN(input => all_commits.value:added, outer => true)) added_files
WHERE p_event_time >= TIMESTAMP '2025-11-24 03:00:00'
AND (
added_files.value::STRING IN ('setup_bun.js', 'bun_environment.js')
OR ARRAY_CONTAINS('setup_bun.js'::VARIANT, head_commit:added)
OR ARRAY_CONTAINS('bun_environment.js'::VARIANT, head_commit:added)
)
ORDER BY p_event_time DESC
DatabricksQuery: |
SELECT
github_webhook.*,
commit_value AS commit_data,
added_file_value AS added_file
FROM panther_logs.github_webhook
LATERAL VIEW OUTER EXPLODE(
from_json(TO_JSON(commits), 'ARRAY<STRUCT<added: ARRAY<STRING>>>')
) commits_exploded AS commit_value
LATERAL VIEW OUTER EXPLODE(commit_value.added) added_exploded AS added_file_value
WHERE p_event_time >= TIMESTAMP '2025-11-24 03:00:00'
AND (
added_file_value IN ('setup_bun.js', 'bun_environment.js')
OR ARRAY_CONTAINS(from_json(TO_JSON(head_commit), 'STRUCT<added: ARRAY<STRING>>').added, 'setup_bun.js')
OR ARRAY_CONTAINS(from_json(TO_JSON(head_commit), 'STRUCT<added: ARRAY<STRING>>').added, 'bun_environment.js')
)
ORDER BY p_event_time DESC
Stages and Predicates
Stage 1: source
Stage 2: filter
p_event_timeis at least2025-11-24 03:00:00added_files.valueis one ofsetup_bun.js,bun_environment.js
This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
added_files.value | in |
| field:"added_files.value" kind:in |
p_event_time | ge |
| field:"p_event_time" kind:ge value:"2025-11-24 03:00:00" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field | Source |
|---|---|
github_webhook . * | |
commit_data | all_commits.value |
added_file | added_files.value |