Detection rules › Sigma

Windows Suspicious Child Process from Node.js - React2Shell

Status
experimental
Severity
high
Log source
category process_creation, product windows
Author
Swachchhanda Shrawan Poudel (Nextron Systems), Nasreddine Bencherchali
Source
github.com/SigmaHQ/sigma

Detects suspicious child processes started by Node.js server processes on Windows, which may indicate exploitation of vulnerabilities like CVE-2025-55182 (React2Shell). Attackers can abuse the Node.js 'child_process' module to run system commands or scripts using methods such as spawn(), exec(), execFile(), fork(), or execSync(). If execSync() or exec() is used in the exploit, the command line often shows a shell (e.g., cmd.exe /d /s /c ...) running a suspicious command unless other shells are explicitly invoked. For other methods, the spawned process appears directly in the Image field unless a shell is explicitly used.

MITRE ATT&CK coverage

Telemetry coverage

ProviderRecord / event type
SysmonEvent ID 1: Process creation

Rule body

title: Windows Suspicious Child Process from Node.js - React2Shell
id: 271de298-cc0e-4842-acd8-079a0a99ea65
related:
    - id: c70834fa-fb9d-4aa0-9e7d-45ceed36f3f7
      type: similar
status: experimental
description: |
    Detects suspicious child processes started by Node.js server processes on Windows, which may indicate exploitation of vulnerabilities like CVE-2025-55182 (React2Shell).
    Attackers can abuse the Node.js 'child_process' module to run system commands or scripts using methods such as spawn(), exec(), execFile(), fork(), or execSync().
    If execSync() or exec() is used in the exploit, the command line often shows a shell (e.g., cmd.exe /d /s /c ...) running a suspicious command unless other shells are explicitly invoked.
    For other methods, the spawned process appears directly in the Image field unless a shell is explicitly used.
references:
    - https://github.com/msanft/CVE-2025-55182
    - https://nodejs.org/api/child_process.html#class-childprocess
    - https://gist.github.com/swachchhanda000/a0228130f86a2dedfbcebb415b47f870
    - https://github.com/nasbench/Misc-Research/blob/2f651ede832ab34027a7ba005b63bb78f1ade378/Other/React-Next-Child-Processes-Notes.md
author: Swachchhanda Shrawan Poudel (Nextron Systems), Nasreddine Bencherchali
date: 2025-12-05
tags:
    - attack.execution
    - attack.t1059
    - attack.initial-access
    - attack.t1190
    - detection.emerging-threats
    - cve.2025-55182
logsource:
    category: process_creation
    product: windows
detection:
    selection_parent:
        ParentImage|endswith: '\node.exe'
        ParentCommandLine|contains:
            - '--experimental-https'
            - '--experimental-next-config-strip-types'
            - '\node_modules\next'
            - 'next dev'
            - 'next start'
            - 'next" start'
            - 'node_modules\\.bin\\\\..\\next' # We escape every backslash to avoid confusion
            - 'react-scripts start'
            - 'start-server.js'
    selection_generic_child_img:
        # Observed when child_process.spawn(), child_process.exec(), child_process.execFile(), or child_process.fork() method  is used to spawn suspicious processes
        - Image|endswith:
              - '\bash.exe'
              - '\bitsadmin.exe'
              - '\certutil.exe'
              - '\cscript.exe'
              - '\curl.exe'
              - '\ipconfig.exe'
              - '\mshta.exe'
              - '\net.exe'
              - '\net1.exe'
              - '\netsh.exe'
              - '\nslookup.exe'
              - '\OpenConsole.exe'
              - '\perl.exe'
              - '\ping.exe'
              - '\powershell.exe'
              - '\pwsh.exe'
              - '\py.exe'
              - '\python.exe'
              - '\pythonw.exe'
              - '\pyw.exe'
              - '\reg.exe'
              - '\regsvr32.exe'
              - '\rundll32.exe'
              - '\sc.exe'
              - '\sh.exe'
              - '\systeminfo.exe'
              - '\wget.exe'
              - '\whoami.exe'
              - '\wmic.exe'
              - '\wscript.exe'
              - '\wt.exe'
        - Image|contains: '\python'
    selection_generic_child_cli_susp_pattern:
        # Observed when child_process.execSync() is used to spawn suspicious processes
        # Reference: https://nodejs.org/api/child_process.html#child_processexecsynccommand-options
        # In default, the cli will look something like `C:\WINDOWS\System32\cmd.exe /d /s /c "...susp..cli...."`
        CommandLine|contains:
            - '\net'
            - 'bitsadmin'
            - 'certutil '
            - 'conhost --headless'
            - 'cscript '
            - 'curl'
            - 'ipconfig'
            - 'java'
            - 'lua'
            - 'mshta'
            - 'netsh'
            - 'nslookup '
            - 'perl'
            - 'ping '
            - 'powershell'
            - 'pwsh'
            - 'python'
            - 'reg '
            - 'reg.exe'
            - 'regsvr32'
            - 'ruby'
            - 'rundll32'
            - 'sc.exe'
            - 'systeminfo'
            - 'wget'
            - 'whoami'
            - 'wmic'
            - 'wscript'
    selection_specific_cmd:
        Image|endswith: '\cmd.exe'
    selection_specific_cli:
        CommandLine|contains: '/d /s /c '
    filter_main_default_shell_flag:
        CommandLine|contains: '/d /s /c '
    filter_main_cli_git:
        CommandLine|contains: 'git config --local --get remote.origin.url'
    filter_main_cli_netstat:
        CommandLine|contains|all:
            - 'netstat -ano | findstr /C:'
            - ' | findstr LISTENING'
    filter_main_cli_mkcert_install:
        CommandLine|contains|all:
            - '\mkcert\'
            - ' -install '
    filter_main_cli_mkcert_caroot:
        CommandLine|contains|all:
            - '\mkcert\'
            - ' -CAROOT'
    condition:
        selection_parent and
        (
            1 of selection_generic_*
            or
            (selection_specific_cmd and not filter_main_default_shell_flag)
            or
            (all of selection_specific_* and not 1 of filter_main_cli_*)
        )
falsepositives:
    - Unknown
level: high
regression_tests_path: regression_data/rules-emerging-threats/2025/Exploits/CVE-2025-55182/proc_creation_win_exploit_cve_2025_55182_susp_nodejs_server_child_process/info.yml

Stages and Predicates

Stage 1: selection_parent

selection_parent:
    ParentImage|endswith: '\node.exe'
    ParentCommandLine|contains:
        - '--experimental-https'
        - '--experimental-next-config-strip-types'
        - '\node_modules\next'
        - 'next dev'
        - 'next start'
        - 'next" start'
        - 'node_modules\\.bin\\\\..\\next'
        - 'react-scripts start'
        - 'start-server.js'

Stage 2: selection_generic_child_img

selection_generic_child_img:
    - Image|endswith:
          - '\bash.exe'
          - '\bitsadmin.exe'
          - '\certutil.exe'
          - '\cscript.exe'
          - '\curl.exe'
          - '\ipconfig.exe'
          - '\mshta.exe'
          - '\net.exe'
          - '\net1.exe'
          - '\netsh.exe'
          - '\nslookup.exe'
          - '\OpenConsole.exe'
          - '\perl.exe'
          - '\ping.exe'
          - '\powershell.exe'
          - '\pwsh.exe'
          - '\py.exe'
          - '\python.exe'
          - '\pythonw.exe'
          - '\pyw.exe'
          - '\reg.exe'
          - '\regsvr32.exe'
          - '\rundll32.exe'
          - '\sc.exe'
          - '\sh.exe'
          - '\systeminfo.exe'
          - '\wget.exe'
          - '\whoami.exe'
          - '\wmic.exe'
          - '\wscript.exe'
          - '\wt.exe'
    - Image|contains: '\python'

Stage 3: selection_generic_child_cli_susp_pattern

selection_generic_child_cli_susp_pattern:
    CommandLine|contains:
        - '\net'
        - 'bitsadmin'
        - 'certutil '
        - 'conhost --headless'
        - 'cscript '
        - 'curl'
        - 'ipconfig'
        - 'java'
        - 'lua'
        - 'mshta'
        - 'netsh'
        - 'nslookup '
        - 'perl'
        - 'ping '
        - 'powershell'
        - 'pwsh'
        - 'python'
        - 'reg '
        - 'reg.exe'
        - 'regsvr32'
        - 'ruby'
        - 'rundll32'
        - 'sc.exe'
        - 'systeminfo'
        - 'wget'
        - 'whoami'
        - 'wmic'
        - 'wscript'

Stage 4: selection_specific_cmd

selection_specific_cmd:
    Image|endswith: '\cmd.exe'

Stage 5: not filter_main_default_shell_flag

filter_main_default_shell_flag:
    CommandLine|contains: '/d /s /c '

Stage 6: selection_specific_cmd

selection_specific_cmd:
    Image|endswith: '\cmd.exe'

Stage 7: selection_specific_cli

selection_specific_cli:
    CommandLine|contains: '/d /s /c '

Stage 8: not filter_main_cli_*

filter_main_cli_git:
    CommandLine|contains: 'git config --local --get remote.origin.url'
filter_main_cli_netstat:
    CommandLine|contains|all:
        - 'netstat -ano | findstr /C:'
        - ' | findstr LISTENING'
filter_main_cli_mkcert_install:
    CommandLine|contains|all:
        - '\mkcert\'
        - ' -install '
filter_main_cli_mkcert_caroot:
    CommandLine|contains|all:
        - '\mkcert\'
        - ' -CAROOT'

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
CommandLinematch
  • /d /s /c corpus 2 (sigma 1, splunk 1)
  • \net
  • bitsadmin corpus 10 (sigma 10)
  • certutil
  • conhost --headless
  • cscript
  • curl corpus 19 (sigma 14, elastic 4, splunk 1)
  • ipconfig corpus 4 (sigma 3, kusto 1)
  • java corpus 2 (sigma 2)
  • lua corpus 3 (sigma 2, elastic 1)
  • mshta corpus 14 (sigma 14)
  • netsh corpus 9 (sigma 9)
  • nslookup
  • perl corpus 3 (sigma 2, elastic 1)
  • ping
  • powershell corpus 25 (sigma 24, chronicle 1)
  • pwsh corpus 7 (sigma 7)
  • python corpus 6 (sigma 4, elastic 2)
  • reg corpus 5 (sigma 5)
  • reg.exe corpus 2 (sigma 2)
  • regsvr32 corpus 15 (sigma 15)
  • ruby corpus 3 (sigma 2, elastic 1)
  • rundll32 corpus 26 (sigma 23, chronicle 2, kusto 1)
  • sc.exe
  • systeminfo corpus 6 (sigma 4, splunk 1, kusto 1)
  • wget corpus 13 (sigma 8, elastic 3, splunk 1, kusto 1)
  • whoami corpus 16 (sigma 9, elastic 4, splunk 2, kusto 1)
  • wmic corpus 6 (sigma 6)
  • wscript corpus 16 (sigma 16)
field:"CommandLine" kind:match
Imageends_with
  • \OpenConsole.exe corpus 2 (sigma 2)
  • \bash.exe corpus 21 (sigma 21)
  • \bitsadmin.exe corpus 29 (sigma 29)
  • \certutil.exe corpus 44 (sigma 43, kusto 1)
  • \cmd.exe corpus 130 (sigma 130)
  • \cscript.exe corpus 72 (sigma 72)
  • \curl.exe corpus 31 (sigma 31)
  • \ipconfig.exe corpus 5 (sigma 5)
  • \mshta.exe corpus 66 (sigma 66)
  • \net.exe corpus 49 (sigma 49)
  • \net1.exe corpus 47 (sigma 47)
  • \netsh.exe corpus 28 (sigma 28)
  • \nslookup.exe corpus 5 (sigma 5)
  • \perl.exe corpus 2 (sigma 2)
  • \ping.exe corpus 6 (sigma 6)
  • \powershell.exe corpus 179 (sigma 178, kusto 1)
  • \pwsh.exe corpus 165 (sigma 164, kusto 1)
  • \py.exe
  • \python.exe corpus 4 (sigma 4)
  • \pythonw.exe
  • \pyw.exe
  • \reg.exe corpus 58 (sigma 58)
  • \regsvr32.exe corpus 64 (sigma 64)
  • \rundll32.exe corpus 94 (sigma 94)
  • \sc.exe corpus 30 (sigma 30)
  • \sh.exe corpus 16 (sigma 16)
  • \systeminfo.exe corpus 11 (sigma 11)
  • \wget.exe corpus 9 (sigma 9)
  • \whoami.exe corpus 19 (sigma 19)
  • \wmic.exe corpus 62 (sigma 62)
  • \wscript.exe corpus 74 (sigma 74)
  • \wt.exe corpus 5 (sigma 5)
field:"Image" kind:ends_with
Imagematch
  • \python corpus 3 (sigma 3)
field:"Image" kind:match value:"\python"
ParentCommandLinematch
  • --experimental-https corpus 3 (sigma 2, elastic 1)
  • --experimental-next-config-strip-types corpus 2 (sigma 2)
  • \node_modules\next
  • next dev corpus 3 (sigma 2, elastic 1)
  • next start corpus 3 (sigma 2, elastic 1)
  • next" start
  • node_modules\\.bin\\\\..\\next
  • react-scripts start corpus 3 (sigma 2, elastic 1)
  • start-server.js corpus 3 (sigma 2, elastic 1)
field:"ParentCommandLine" kind:match
ParentImageends_with
  • \node.exe corpus 4 (sigma 4)
field:"ParentImage" kind:ends_with value:"\node.exe"