Name:PowerShell Download from Code Hosting Service id:3ffbd4d4-84a7-453e-9e06-8e9cd0350366 version:1 date:None author:Teoderick Contreras, Splunk status:production type:Anomaly Description:This analytic detects PowerShell Script Block Logging (Event ID 4104) events that use common download methods to retrieve files directly from raw-content URLs on GitHub, GitLab, or Codeberg.
These code hosting services can be abused to stage payloads, but administrators and developers also download files from them.
A match identifies a download attempt; it does not establish that the file was successfully retrieved or executed. Review the full script block, destination path, process ancestry, and related endpoint activity. Data_source:
how_to_implement:To implement this analytic, enable PowerShell Script Block Logging and ingest Event ID 4104 events with the `ScriptBlockText` field extracted.
Confirm that the `powershell` macro scopes the search to the correct PowerShell Operational logs in your environment. known_false_positives:Administrators, developers, and software deployment tools may download legitimate files from GitHub, GitLab, and Codeberg.
Review repository ownership, the downloaded file, destination path, signer where applicable, process ancestry, and subsequent execution before taking action. References: -https://www.splunk.com/en_us/blog/security/cracking-braodo-stealer-analyzing-python-malware-and-its-obfuscated-loader.html -https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_logging_windows?view=powershell-7.6 drilldown_searches: name:'View the detection results for - "$dest$"' search:'%original_detection_search% | search dest = "$dest$"' earliest_offset:'$info_min_time$' latest_offset:'$info_max_time$' name:'View risk events for the last 7 days for - "$dest$"' search:'| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$") | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset:'7d' latest_offset:'0' analytic_story:['Braodo Stealer']