Script block that encodes data and then sends it outbound
Matches a PowerShell script block that both calls a standard encoder or compressor and, in the same block, reaches the network. MITRE's AN0345 describes a chain — encode, then egress within a tunable TimeWindow — which Sigma cannot join across events, so the chain is collapsed into a single 4104 record where the two halves appear together; a script that encodes in one block and uploads in another will not match. EventID is matched explicitly because the logsource is the raw PowerShell channel, whose other event IDs do not carry ScriptBlockText. The B64LengthThreshold, PayloadEntropyThreshold and BytesOutToInRatio knobs are all thresholds over payload or flow data that a script-block event does not contain, so none of them are encoded here. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0124, not hand-written and not tested by its author. Any lab result is on this rule's own page.Full descriptionShow less
The detection
The 4 SIEM queries below are previews produced by Siemphony’s own translator, not pySigma, and none has been executed against a real backend — review before you deploy.
detection.yml
title: Script block that encodes data and then sends it outboundid: 2d6b83f5-41ae-4c09-8e73-b5a1f9207cd4status: experimentaldescription: | Matches a PowerShell script block that both calls a standard encoder or compressor and, in the same block, reaches the network. MITRE's AN0345 describes a chain — encode, then egress within a tunable TimeWindow — which Sigma cannot join across events, so the chain is collapsed into a single 4104 record where the two halves appear together; a script that encodes in one block and uploads in another will not match. EventID is matched explicitly because the logsource is the raw PowerShell channel, whose other event IDs do not carry ScriptBlockText. The B64LengthThreshold, PayloadEntropyThreshold and BytesOutToInRatio knobs are all thresholds over payload or flow data that a script-block event does not contain, so none of them are encoded here. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0124, not hand-written and not tested by its author. Any lab result is on this rule's own page.references: - https://attack.mitre.org/techniques/T1132/001 - https://attack.mitre.org/detectionstrategies/DET0124author: Siemphony pipeline (machine-derived from MITRE ATT&CK v19.2)date: 2026-08-16tags: - attack.command-and-control - attack.t1132.001logsource: product: windows service: powershelldetection: selection_encoder: EventID: 4104 ScriptBlockText|contains: - 'ToBase64String' - 'FromBase64String' - 'ToBase64Transform' - 'FromBase64Transform' - 'ToBase64CharArray' - 'FromBase64CharArray' - 'EncodedCommand' - 'BitConverter]::ToString' - 'GZipStream' - 'DeflateStream' selection_egress: ScriptBlockText|contains: - 'Net.WebClient' - 'UploadString' - 'UploadData' - 'UploadFile' - 'Invoke-WebRequest' - 'Invoke-RestMethod' - 'HttpWebRequest' - 'Net.Http.HttpClient' - 'Net.Sockets.TcpClient' - 'Resolve-DnsName' condition: selection_encoder and selection_egressfalsepositives: - "API automation that builds an HTTP Basic authorization header with `[Convert]::ToBase64String` and then calls Invoke-RestMethod. This is structurally the same logic the rule looks for and is the single largest source of noise; it is what MITRE's KnownAdminTools knob is for, and the allowlist has to be by script path or signing certificate, not by keyword." - "Backup, telemetry and log-shipping scripts that compress with GZipStream or DeflateStream before an UploadData call. MITRE separates these from C2 with the BytesOutToInRatio and PayloadEntropyThreshold knobs, neither of which is available in a script-block event, so they cannot be filtered out here." - "Deployment and configuration tooling that fetches content with Invoke-WebRequest and unpacks an embedded base64 blob — a certificate, a licence file, a settings bundle — with FromBase64String in the same block." - "Nested-quoting workarounds where an administrative script launches a child PowerShell with -EncodedCommand and also performs a web call, encoding for convenience rather than evasion."level: mediumSentinel · KQL
Run this as a search.
Event| where ((EventID == 4104 and (ScriptBlockText contains "ToBase64String" or ScriptBlockText contains "FromBase64String" or ScriptBlockText contains "ToBase64Transform" or ScriptBlockText contains "FromBase64Transform" or ScriptBlockText contains "ToBase64CharArray" or ScriptBlockText contains "FromBase64CharArray" or ScriptBlockText contains "EncodedCommand" or ScriptBlockText contains "BitConverter]::ToString" or ScriptBlockText contains "GZipStream" or ScriptBlockText contains "DeflateStream")) and (ScriptBlockText contains "Net.WebClient" or ScriptBlockText contains "UploadString" or ScriptBlockText contains "UploadData" or ScriptBlockText contains "UploadFile" or ScriptBlockText contains "Invoke-WebRequest" or ScriptBlockText contains "Invoke-RestMethod" or ScriptBlockText contains "HttpWebRequest" or ScriptBlockText contains "Net.Http.HttpClient" or ScriptBlockText contains "Net.Sockets.TcpClient" or ScriptBlockText contains "Resolve-DnsName"))
Splunk · SPL
Run this as a search.
index=* ((EventID="4104" AND (ScriptBlockText="*ToBase64String*" OR ScriptBlockText="*FromBase64String*" OR ScriptBlockText="*ToBase64Transform*" OR ScriptBlockText="*FromBase64Transform*" OR ScriptBlockText="*ToBase64CharArray*" OR ScriptBlockText="*FromBase64CharArray*" OR ScriptBlockText="*EncodedCommand*" OR ScriptBlockText="*BitConverter]::ToString*" OR ScriptBlockText="*GZipStream*" OR ScriptBlockText="*DeflateStream*")) AND (ScriptBlockText="*Net.WebClient*" OR ScriptBlockText="*UploadString*" OR ScriptBlockText="*UploadData*" OR ScriptBlockText="*UploadFile*" OR ScriptBlockText="*Invoke-WebRequest*" OR ScriptBlockText="*Invoke-RestMethod*" OR ScriptBlockText="*HttpWebRequest*" OR ScriptBlockText="*Net.Http.HttpClient*" OR ScriptBlockText="*Net.Sockets.TcpClient*" OR ScriptBlockText="*Resolve-DnsName*"))Elastic · ES|QL
Run this as a search.
FROM logs-*| WHERE ((event.code == 4104 AND (TO_LOWER(powershell.file.script_block_text) LIKE "*tobase64string*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*frombase64string*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*tobase64transform*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*frombase64transform*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*tobase64chararray*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*frombase64chararray*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*encodedcommand*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*bitconverter]::tostring*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*gzipstream*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*deflatestream*")) AND (TO_LOWER(powershell.file.script_block_text) LIKE "*net.webclient*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*uploadstring*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*uploaddata*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*uploadfile*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*invoke-webrequest*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*invoke-restmethod*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*httpwebrequest*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*net.http.httpclient*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*net.sockets.tcpclient*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*resolve-dnsname*"))
Wazuh · XML rule
Deploy to your manager — this is a rule, not a search.
<group name="sigma,windows,"> <!-- Rule ids must be unique on your manager; 100000+ is the user range. --> <rule id="100000" level="7"> <!-- Set <if_sid> to the decoder/base rule for windows so this only evaluates relevant events. --> <field name="EventID" type="pcre2">(?i)^4104$</field> <field name="ScriptBlockText" type="pcre2">(?i)(ToBase64String|FromBase64String|ToBase64Transform|FromBase64Transform|ToBase64CharArray|FromBase64CharArray|EncodedCommand|BitConverter\]::ToString|GZipStream|DeflateStream)</field> <field name="ScriptBlockText" type="pcre2">(?i)(Net\.WebClient|UploadString|UploadData|UploadFile|Invoke-WebRequest|Invoke-RestMethod|HttpWebRequest|Net\.Http\.HttpClient|Net\.Sockets\.TcpClient|Resolve-DnsName)</field> <description>Script block that encodes data and then sends it outbound</description> <mitre> <id>T1132.001</id> </mitre> </rule></group>
Verdicts · reactions · comments
Community
Verdicts from engineers who actually deployed it, and the conversation around it.
Nobody has run this in a real environment and said what happened.
Verdicts from engineers who deployed it
0 castNo verdicts reported yet. The first one is worth more than the tenth — say what you ran it against.
Log in to report a verdict.
Log in to join the discussion.
No comments yet. Someone who deploys this will have something to say about it.