Script derives a cryptographic key from a machine identifier
Environmental keying is a burst of discovery followed by a decryption whose key is derived from what the discovery found, and the count-over-a-window part of AN1305 has no Sigma construct, so this rule requires the two halves that do fit inside a single script block — a read of a machine-identifying value and a call into a cryptographic primitive that could turn that value into a key. The corpus rule for the parent technique T1480 matches the conditional form of a guardrail on a process command line, an identity read next to a comparison operator; this one matches the cryptographic form in script text, so the two cover different halves of the behaviour rather than repeating each other. The brief's PowerShell log source spans EventID 4103 through 4106 and this rule is written in the 4104 vocabulary, gating on that EventID because ScriptBlockText exists only there — 4103 carries Payload and ContextInfo instead and would need a field mapping before it could feed the same logic. Script Block Logging is off in a default install and in the vendor and CIS baselines, so unless it has been enabled there is no 4104 at all and this returns zero rows while appearing healthy. Treat a match as a hunting lead, not an alert: co-occurrence of the two vocabularies in one block is textually identical whether an operator is deriving a key to unlock a payload or an ops script is protecting a secret with the machine's own DPAPI store, and nothing else in a 4104 event separates them. The level is set to what the first false positive below supports, not to the severity of the technique. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0474, 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 derives a cryptographic key from a machine identifierid: 66d66665-7a21-47d5-8d0c-657971167355status: experimentaldescription: | Environmental keying is a burst of discovery followed by a decryption whose key is derived from what the discovery found, and the count-over-a-window part of AN1305 has no Sigma construct, so this rule requires the two halves that do fit inside a single script block — a read of a machine-identifying value and a call into a cryptographic primitive that could turn that value into a key. The corpus rule for the parent technique T1480 matches the conditional form of a guardrail on a process command line, an identity read next to a comparison operator; this one matches the cryptographic form in script text, so the two cover different halves of the behaviour rather than repeating each other. The brief's PowerShell log source spans EventID 4103 through 4106 and this rule is written in the 4104 vocabulary, gating on that EventID because ScriptBlockText exists only there — 4103 carries Payload and ContextInfo instead and would need a field mapping before it could feed the same logic. Script Block Logging is off in a default install and in the vendor and CIS baselines, so unless it has been enabled there is no 4104 at all and this returns zero rows while appearing healthy. Treat a match as a hunting lead, not an alert: co-occurrence of the two vocabularies in one block is textually identical whether an operator is deriving a key to unlock a payload or an ops script is protecting a secret with the machine's own DPAPI store, and nothing else in a 4104 event separates them. The level is set to what the first false positive below supports, not to the severity of the technique. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0474, 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/T1480/001 - https://attack.mitre.org/detectionstrategies/DET0474author: Siemphony pipeline (machine-derived from MITRE ATT&CK v19.2)date: 2026-08-16tags: - attack.defense-evasion - attack.t1480.001logsource: product: windows service: powershelldetection: selection_event: EventID: 4104 selection_identity: ScriptBlockText|contains: - 'env:COMPUTERNAME' - 'env:USERDOMAIN' - 'env:USERDNSDOMAIN' - 'env:LOGONSERVER' - 'Win32_ComputerSystemProduct' - 'Win32_BIOS' - 'Win32_NetworkAdapterConfiguration' - 'MachineGuid' - 'GetHostByName' - 'Get-ADDomain' selection_crypto: ScriptBlockText|contains: - 'System.Security.Cryptography' - 'AesManaged' - 'AesCryptoServiceProvider' - 'RijndaelManaged' - 'CreateDecryptor' - 'DeriveBytes' - 'ComputeHash' - 'ConvertTo-SecureString' condition: selection_event and selection_identity and selection_cryptofalsepositives: - "Plain DPAPI secret handling — ConvertTo-SecureString -AsPlainText piped into ConvertFrom-SecureString with no -Key — which is the default and ubiquitous way to store a credential on a Windows host. Any such script that also logs or stamps the computer name or the domain in the same block matches, and this is the most common PowerShell idiom the rule will ever see." - "Software inventory, licensing and device-enrolment scripts, which build a machine fingerprint by hashing the hardware UUID, the machine GUID or the computer name. Where such a script runs on a schedule it recurs on every host in the estate." - "Configuration management and packaging frameworks that protect a secret with a machine-bound key. Desired State Configuration, installer wrappers and deployment scripts routinely call ConvertTo-SecureString or a key-derivation routine in the same script block that reads the computer name or the domain." - "Backup, endpoint-protection and remote-management agents shipping PowerShell modules that checksum collected system information before uploading it, which reads as an identity value flowing into a hash." - "Administrators writing an ad-hoc script that queries the hardware details and hashes the result to produce a per-host identifier for an asset register or a licence check."level: lowSentinel · KQL
Run this as a search.
Event| where ((EventID == 4104 and (ScriptBlockText contains "env:COMPUTERNAME" or ScriptBlockText contains "env:USERDOMAIN" or ScriptBlockText contains "env:USERDNSDOMAIN" or ScriptBlockText contains "env:LOGONSERVER" or ScriptBlockText contains "Win32_ComputerSystemProduct" or ScriptBlockText contains "Win32_BIOS" or ScriptBlockText contains "Win32_NetworkAdapterConfiguration" or ScriptBlockText contains "MachineGuid" or ScriptBlockText contains "GetHostByName" or ScriptBlockText contains "Get-ADDomain")) and (ScriptBlockText contains "System.Security.Cryptography" or ScriptBlockText contains "AesManaged" or ScriptBlockText contains "AesCryptoServiceProvider" or ScriptBlockText contains "RijndaelManaged" or ScriptBlockText contains "CreateDecryptor" or ScriptBlockText contains "DeriveBytes" or ScriptBlockText contains "ComputeHash" or ScriptBlockText contains "ConvertTo-SecureString"))
Splunk · SPL
Run this as a search.
index=* ((EventID="4104" AND (ScriptBlockText="*env:COMPUTERNAME*" OR ScriptBlockText="*env:USERDOMAIN*" OR ScriptBlockText="*env:USERDNSDOMAIN*" OR ScriptBlockText="*env:LOGONSERVER*" OR ScriptBlockText="*Win32_ComputerSystemProduct*" OR ScriptBlockText="*Win32_BIOS*" OR ScriptBlockText="*Win32_NetworkAdapterConfiguration*" OR ScriptBlockText="*MachineGuid*" OR ScriptBlockText="*GetHostByName*" OR ScriptBlockText="*Get-ADDomain*")) AND (ScriptBlockText="*System.Security.Cryptography*" OR ScriptBlockText="*AesManaged*" OR ScriptBlockText="*AesCryptoServiceProvider*" OR ScriptBlockText="*RijndaelManaged*" OR ScriptBlockText="*CreateDecryptor*" OR ScriptBlockText="*DeriveBytes*" OR ScriptBlockText="*ComputeHash*" OR ScriptBlockText="*ConvertTo-SecureString*"))Elastic · ES|QL
Run this as a search.
FROM logs-*| WHERE ((event.code == 4104 AND (TO_LOWER(powershell.file.script_block_text) LIKE "*env:computername*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*env:userdomain*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*env:userdnsdomain*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*env:logonserver*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*win32_computersystemproduct*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*win32_bios*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*win32_networkadapterconfiguration*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*machineguid*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*gethostbyname*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*get-addomain*")) AND (TO_LOWER(powershell.file.script_block_text) LIKE "*system.security.cryptography*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*aesmanaged*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*aescryptoserviceprovider*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*rijndaelmanaged*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*createdecryptor*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*derivebytes*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*computehash*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*convertto-securestring*"))
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="5"> <!-- 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)(env:COMPUTERNAME|env:USERDOMAIN|env:USERDNSDOMAIN|env:LOGONSERVER|Win32_ComputerSystemProduct|Win32_BIOS|Win32_NetworkAdapterConfiguration|MachineGuid|GetHostByName|Get-ADDomain)</field> <field name="ScriptBlockText" type="pcre2">(?i)(System\.Security\.Cryptography|AesManaged|AesCryptoServiceProvider|RijndaelManaged|CreateDecryptor|DeriveBytes|ComputeHash|ConvertTo-SecureString)</field> <description>Script derives a cryptographic key from a machine identifier</description> <mitre> <id>T1480.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.