Detection: PowerShell Download from Code Hosting Service

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.

 1`powershell` EventCode=4104 ScriptBlockText IN ("*.DownloadFile(*", "*.DownloadData(*", "*.DownloadString(*", "*Invoke-WebRequest*", "*Invoke-RestMethod*", "*Start-BitsTransfer*", "*iwr *", "*irm *", "*curl *", "*wget *")
 2
 3| where match(
 4    ScriptBlockText,
 5    "(?ix)
 6        (?:
 7            \.Download(?:File
 8|Data
 9|String)\s*\(\s*['\"]?
10            
11|
12            (?:Invoke-WebRequest
13|Invoke-RestMethod
14|iwr
15|irm)
16            (?:\s+(?:-Uri\s+)?
17|\b[^;\r\n]{0,200}?\s-Uri\s+)['\"]?
18            
19|
20            Start-BitsTransfer\b[^;\r\n]{0,200}?-Source\s+['\"]?
21            
22|
23            (?:curl
24|wget)\s+(?:-Uri\s+)?['\"]?
25        )
26        https?://
27        (?:
28            raw\.githubusercontent\.com/[^/\s'\"]+/[^/\s'\"]+/[^/\s'\"]+(?:/[^/\s'\"]+)*
29            
30|
31            (?:github
32|gitlab)\.com/[^/\s'\"]+/[^/\s'\"]+/(?:-/)?raw/(?:refs/(?:heads
33|tags)/)?[^/\s'\"]+(?:/[^/\s'\"]+)*
34            
35|
36            codeberg\.org/[^/\s'\"]+/[^/\s'\"]+/raw/(?:branch/)?[^/\s'\"]+(?:/[^/\s'\"]+)*
37        )
38        \.(?:bat
39|cmd
40|ps1
41|js
42|vbs
43|vbe
44|py
45|zip
46|7z
47|rar
48|tar
49|gz
50|exe
51|dll
52|msi)
53        (?:[?#][^\s'\"]*)?
54        (?=['\"\s),;]
55|$)"
56)
57
58| fillnull
59
60| stats count min(_time) as firstTime max(_time) as lastTime
61    by dest signature signature_id user_id vendor_product EventID Guid Opcode Name Path ProcessID ScriptBlockId ScriptBlockText
62
63| `security_content_ctime(firstTime)`
64
65| `security_content_ctime(lastTime)`
66
67| `powershell_download_from_code_hosting_service_filter`

Data Source

Name Platform Sourcetype Source
Powershell Script Block Logging 4104 Windows icon Windows 'XmlWinEventLog' 'XmlWinEventLog:Microsoft-Windows-PowerShell/Operational'

Macros Used

Name Value
security_content_ctime convert timeformat="%Y-%m-%dT%H:%M:%S" ctime($field$)
powershell_download_from_code_hosting_service_filter search *
powershell_download_from_code_hosting_service_filter is an empty macro by default. It allows the user to filter out any results (false positives) without editing the SPL.

Annotations

Default Configuration

This detection is configured by default in Splunk Enterprise Security to run with the following settings:

Setting Value
Disabled true
Cron Schedule 0 * * * *
Earliest Time -70m@m
Latest Time -10m@m
Schedule Window auto
Creates Finding (Notable) No
Creates Intermediate Finding (Risk Event) Yes
Anomaly detections generate Intermediate Findings (Risk Events). They do not generate a Finding (Notable) directly.

Implementation

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.

Associated Analytic Story

Intermediate Findings

Message Entity Field Entity Type Risk Score
A PowerShell script on [$dest$] invoked a download method with a raw code-hosting URL in ScriptBlockText with ScriptBlockId [$ScriptBlockId$]. dest system 20

References

Detection Testing

Test Type Status Dataset Source Sourcetype
Validation ✅ Passing N/A N/A N/A
Unit ✅ Passing Dataset XmlWinEventLog:Microsoft-Windows-PowerShell/Operational XmlWinEventLog
Integration ✅ Passing Dataset XmlWinEventLog:Microsoft-Windows-PowerShell/Operational XmlWinEventLog

Replay any dataset to Splunk Enterprise by using our replay.py tool or the UI. Alternatively you can replay a dataset into a Splunk Attack Range


Source: GitHub |

Version: 1