Skip to content

Siemphony is in beta and still being built. How a rule earns its badge.

Siemphony’s repertoire

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 description

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: medium

Sentinel · 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.

Log in to react
Not yet reported on

Nobody has run this in a real environment and said what happened.

Verdicts from engineers who deployed it

0 cast

No 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.