Detection rules › Sigma

Dynamic .NET Compilation Via Csc.EXE

Status
test
Severity
medium
Log source
product windows, category process_creation
Author
Florian Roth (Nextron Systems), X__Junior (Nextron Systems)
Source
github.com/SigmaHQ/sigma

Detects execution of "csc.exe" to compile .NET code. Attackers often leverage this to compile code on the fly and use it in other stages.

MITRE ATT&CK coverage

Event coverage

ProviderEventTitle
SysmonEvent ID 1Process creation

Rule body yaml

title: Dynamic .NET Compilation Via Csc.EXE
id: dcaa3f04-70c3-427a-80b4-b870d73c94c4
status: test
description: Detects execution of "csc.exe" to compile .NET code. Attackers often leverage this to compile code on the fly and use it in other stages.
references:
    - https://securityboulevard.com/2019/08/agent-tesla-evading-edr-by-removing-api-hooks/
    - https://www.clearskysec.com/wp-content/uploads/2018/11/MuddyWater-Operations-in-Lebanon-and-Oman.pdf
    - https://app.any.run/tasks/c6993447-d1d8-414e-b856-675325e5aa09/
    - https://twitter.com/gN3mes1s/status/1206874118282448897
    - https://github.com/redcanaryco/atomic-red-team/blob/b27a3cb25025161d49ac861cb216db68c46a3537/atomics/T1027.004/T1027.004.md#atomic-test-1---compile-after-delivery-using-cscexe
author: Florian Roth (Nextron Systems), X__Junior (Nextron Systems)
date: 2019-08-24
modified: 2026-03-23
tags:
    - attack.stealth
    - attack.t1027.004
logsource:
    category: process_creation
    product: windows
detection:
    selection_img:
        Image|endswith: '\csc.exe'
    selection_susp_location_1:
        CommandLine|contains:
            - ':\Perflogs\'
            - ':\Users\Public\'
            - '\AppData\Local\Temp\' # User execution
            - '\Temporary Internet'
            - '\Windows\Temp\' # Admin execution
    selection_susp_location_2:
        - CommandLine|contains|all:
              - ':\Users\'
              - '\Favorites\'
        - CommandLine|contains|all:
              - ':\Users\'
              - '\Favourites\'
        - CommandLine|contains|all:
              - ':\Users\'
              - '\Contacts\'
        - CommandLine|contains|all:
              - ':\Users\'
              - '\Pictures\'
    selection_susp_location_3:
        CommandLine|re: '(?:[Pp]rogram[Dd]ata|%(?:[Ll]ocal)?[Aa]pp[Dd]ata%|\\[Aa]pp[Dd]ata\\(?:[Ll]ocal(?:[Ll]ow)?|[Rr]oaming))\\[^\\]{1,256}$'
    filter_main_programfiles:
        # Note: this is a generic filter. You could baseline execution in your env for a more robust rule
        ParentImage|startswith:
            - 'C:\Program Files (x86)\' # https://twitter.com/gN3mes1s/status/1206874118282448897
            - 'C:\Program Files\' # https://twitter.com/gN3mes1s/status/1206874118282448897
    filter_main_sdiagnhost:
        ParentImage: 'C:\Windows\System32\sdiagnhost.exe' # https://twitter.com/gN3mes1s/status/1206874118282448897
    filter_main_w3p:
        ParentImage: 'C:\Windows\System32\inetsrv\w3wp.exe' # https://twitter.com/gabriele_pippi/status/1206907900268072962
    filter_optional_chocolatey:
        ParentImage: # Chocolatey https://chocolatey.org/
            - 'C:\ProgramData\chocolatey\choco.exe'
            - 'C:\ProgramData\chocolatey\tools\shimgen.exe'
    filter_optional_defender:
        ParentCommandLine|contains: '\ProgramData\Microsoft\Windows Defender Advanced Threat Protection'
    filter_optional_ansible:
        # Note: As ansible is widely used we exclude it with this generic filter.
        # A better option would be to filter based on script content basis or other marker while hunting
        ParentCommandLine|contains:
            # '{"failed":true,"msg":"Ansible requires PowerShell v3.0 or newer"}'
            - 'JwB7ACIAZgBhAGkAbABlAGQAIgA6AHQAcgB1AGUALAAiAG0AcwBnACIAOgAiAEEAbgBzAGkAYgBsAGUAIAByAGUAcQB1AGkAcgBlAHMAIABQAG8AdwBlAHIAUwBoAGUAbABsACAAdgAzAC4AMAAgAG8AcgAgAG4AZQB3AGUAcgAiAH0AJw'
            - 'cAewAiAGYAYQBpAGwAZQBkACIAOgB0AHIAdQBlACwAIgBtAHMAZwAiADoAIgBBAG4AcwBpAGIAbABlACAAcgBlAHEAdQBpAHIAZQBzACAAUABvAHcAZQByAFMAaABlAGwAbAAgAHYAMwAuADAAIABvAHIAIABuAGUAdwBlAHIAIgB9ACcA'
            - 'nAHsAIgBmAGEAaQBsAGUAZAAiADoAdAByAHUAZQAsACIAbQBzAGcAIgA6ACIAQQBuAHMAaQBiAGwAZQAgAHIAZQBxAHUAaQByAGUAcwAgAFAAbwB3AGUAcgBTAGgAZQBsAGwAIAB2ADMALgAwACAAbwByACAAbgBlAHcAZQByACIAfQAnA'
    condition: selection_img and 1 of selection_susp_location_* and not 1 of filter_main_* and not 1 of filter_optional_*
falsepositives:
    - Legitimate software from program files - https://twitter.com/gN3mes1s/status/1206874118282448897
    - Legitimate Microsoft software - https://twitter.com/gabriele_pippi/status/1206907900268072962
    - Ansible
level: medium

Stages and Predicates

Stage 0: condition

selection_img and 1 of selection_susp_location_* and not 1 of filter_main_* and not 1 of filter_optional_*

Stage 1: selection_img

selection_img:
    Image|endswith: '\csc.exe'

Stage 2: selection_susp_location_1

selection_susp_location_1:
    CommandLine|contains:
        - ':\Perflogs\'
        - ':\Users\Public\'
        - '\AppData\Local\Temp\'
        - '\Temporary Internet'
        - '\Windows\Temp\'

Stage 3: selection_susp_location_2

selection_susp_location_2:
    - CommandLine|contains|all:
          - ':\Users\'
          - '\Favorites\'
    - CommandLine|contains|all:
          - ':\Users\'
          - '\Favourites\'
    - CommandLine|contains|all:
          - ':\Users\'
          - '\Contacts\'
    - CommandLine|contains|all:
          - ':\Users\'
          - '\Pictures\'

Stage 4: selection_susp_location_3

selection_susp_location_3:
    CommandLine|re: '(?:[Pp]rogram[Dd]ata|%(?:[Ll]ocal)?[Aa]pp[Dd]ata%|\\[Aa]pp[Dd]ata\\(?:[Ll]ocal(?:[Ll]ow)?|[Rr]oaming))\\[^\\]{1,256}$'

Stage 5: not filter_main_*

filter_main_programfiles:
    ParentImage|startswith:
        - 'C:\Program Files (x86)\'
        - 'C:\Program Files\'
filter_main_sdiagnhost:
    ParentImage: 'C:\Windows\System32\sdiagnhost.exe'
filter_main_w3p:
    ParentImage: 'C:\Windows\System32\inetsrv\w3wp.exe'

Stage 6: not filter_optional_*

filter_optional_chocolatey:
    ParentImage:
        - 'C:\ProgramData\chocolatey\choco.exe'
        - 'C:\ProgramData\chocolatey\tools\shimgen.exe'
filter_optional_defender:
    ParentCommandLine|contains: '\ProgramData\Microsoft\Windows Defender Advanced Threat Protection'
filter_optional_ansible:
    ParentCommandLine|contains:
        - 'JwB7ACIAZgBhAGkAbABlAGQAIgA6AHQAcgB1AGUALAAiAG0AcwBnACIAOgAiAEEAbgBzAGkAYgBsAGUAIAByAGUAcQB1AGkAcgBlAHMAIABQAG8AdwBlAHIAUwBoAGUAbABsACAAdgAzAC4AMAAgAG8AcgAgAG4AZQB3AGUAcgAiAH0AJw'
        - 'cAewAiAGYAYQBpAGwAZQBkACIAOgB0AHIAdQBlACwAIgBtAHMAZwAiADoAIgBBAG4AcwBpAGIAbABlACAAcgBlAHEAdQBpAHIAZQBzACAAUABvAHcAZQByAFMAaABlAGwAbAAgAHYAMwAuADAAIABvAHIAIABuAGUAdwBlAHIAIgB9ACcA'
        - 'nAHsAIgBmAGEAaQBsAGUAZAAiADoAdAByAHUAZQAsACIAbQBzAGcAIgA6ACIAQQBuAHMAaQBiAGwAZQAgAHIAZQBxAHUAaQByAGUAcwAgAFAAbwB3AGUAcgBTAGgAZQBsAGwAIAB2ADMALgAwACAAbwByACAAbgBlAHcAZQByACIAfQAnA'

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
ParentImageeqC:\Windows\System32\inetsrv\w3wp.exe
ParentImageeqC:\Windows\System32\sdiagnhost.exe
ParentImagestarts_withC:\Program Files (x86)\
ParentImagestarts_withC:\Program Files\
ParentCommandLinematchJwB7ACIAZgBhAGkAbABlAGQAIgA6AHQAcgB1AGUALAAiAG0AcwBnACIAOgAiAEEAbgBzAGkAYgBsAGUAIAByAGUAcQB1AGkAcgBlAHMAIABQAG8AdwBlAHIAUwBoAGUAbABsACAAdgAzAC4AMAAgAG8AcgAgAG4AZQB3AGUAcgAiAH0AJw
ParentCommandLinematch\ProgramData\Microsoft\Windows Defender Advanced Threat Protection
ParentCommandLinematchcAewAiAGYAYQBpAGwAZQBkACIAOgB0AHIAdQBlACwAIgBtAHMAZwAiADoAIgBBAG4AcwBpAGIAbABlACAAcgBlAHEAdQBpAHIAZQBzACAAUABvAHcAZQByAFMAaABlAGwAbAAgAHYAMwAuADAAIABvAHIAIABuAGUAdwBlAHIAIgB9ACcA
ParentCommandLinematchnAHsAIgBmAGEAaQBsAGUAZAAiADoAdAByAHUAZQAsACIAbQBzAGcAIgA6ACIAQQBuAHMAaQBiAGwAZQAgAHIAZQBxAHUAaQByAGUAcwAgAFAAbwB3AGUAcgBTAGgAZQBsAGwAIAB2ADMALgAwACAAbwByACAAbgBlAHcAZQByACIAfQAnA
ParentImageeqC:\ProgramData\chocolatey\choco.exe
ParentImageeqC:\ProgramData\chocolatey\tools\shimgen.exe

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
CommandLinematch
  • :\Perflogs\ corpus 11 (sigma 11)
  • :\Users\ corpus 6 (sigma 6)
  • :\Users\Public\ corpus 18 (sigma 18)
  • \AppData\Local\Temp\ corpus 26 (sigma 26)
  • \Contacts\ corpus 6 (sigma 6)
  • \Favorites\ corpus 6 (sigma 6)
  • \Favourites\ corpus 6 (sigma 6)
  • \Pictures\ corpus 4 (sigma 4)
  • \Temporary Internet corpus 7 (sigma 7)
  • \Windows\Temp\ corpus 12 (sigma 12)
CommandLineregex_match
  • (?:[Pp]rogram[Dd]ata|%(?:[Ll]ocal)?[Aa]pp[Dd]ata%|\[Aa]pp[Dd]ata\(?:[Ll]ocal(?:[Ll]ow)?|[Rr]oaming))\[^\]{1,256}$
Imageends_with
  • \csc.exe corpus 9 (sigma 9)