Detection rules › Sigma

Windows Suspicious Child Process from Node.js - React2Shell

Status
experimental
Severity
high
Log source
product windows, category process_creation
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

Event coverage

ProviderEventTitle
SysmonEvent ID 1Process creation

Rule body yaml

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

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

FieldKindExcluded values
CommandLinematch/d /s /c
CommandLinematch -CAROOT
CommandLinematch\mkcert\
CommandLinematch -install
CommandLinematch\mkcert\
CommandLinematch | findstr LISTENING
CommandLinematchnetstat -ano | findstr /C:
CommandLinematchgit config --local --get remote.origin.url

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
  • /d /s /c corpus 2 (sigma 1, splunk 1)
  • \net
  • bitsadmin corpus 10 (sigma 10)
  • certutil
  • conhost --headless
  • cscript
  • curl corpus 17 (sigma 14, elastic 2, splunk 1)
  • ipconfig corpus 4 (sigma 3, kusto 1)
  • java corpus 2 (sigma 2)
  • lua corpus 2 (sigma 2)
  • mshta corpus 14 (sigma 14)
  • netsh corpus 9 (sigma 9)
  • nslookup
  • perl corpus 2 (sigma 2)
  • ping
  • powershell corpus 25 (sigma 24, chronicle 1)
  • pwsh corpus 7 (sigma 7)
  • python corpus 4 (sigma 4)
  • reg corpus 5 (sigma 5)
  • reg.exe corpus 2 (sigma 2)
  • regsvr32 corpus 15 (sigma 15)
  • ruby corpus 2 (sigma 2)
  • rundll32 corpus 26 (sigma 23, chronicle 2, kusto 1)
  • sc.exe
  • systeminfo corpus 6 (sigma 4, splunk 1, kusto 1)
  • wget corpus 11 (sigma 8, elastic 1, splunk 1, kusto 1)
  • whoami corpus 13 (sigma 9, splunk 2, elastic 1, kusto 1)
  • wmic corpus 6 (sigma 6)
  • wscript corpus 16 (sigma 16)
Imageends_with
  • \OpenConsole.exe corpus 2 (sigma 2)
  • \bash.exe corpus 22 (sigma 22)
  • \bitsadmin.exe corpus 29 (sigma 29)
  • \certutil.exe corpus 43 (sigma 43)
  • \cmd.exe corpus 130 (sigma 130)
  • \cscript.exe corpus 73 (sigma 73)
  • \curl.exe corpus 30 (sigma 30)
  • \ipconfig.exe corpus 5 (sigma 5)
  • \mshta.exe corpus 67 (sigma 67)
  • \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 7 (sigma 7)
  • \powershell.exe corpus 182 (sigma 182)
  • \pwsh.exe corpus 168 (sigma 168)
  • \py.exe
  • \python.exe corpus 5 (sigma 5)
  • \pythonw.exe
  • \pyw.exe
  • \reg.exe corpus 58 (sigma 58)
  • \regsvr32.exe corpus 65 (sigma 65)
  • \rundll32.exe corpus 95 (sigma 95)
  • \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 60 (sigma 60)
  • \wscript.exe corpus 75 (sigma 75)
  • \wt.exe corpus 5 (sigma 5)
Imagematch
  • \python corpus 3 (sigma 3)
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)
ParentImageends_with
  • \node.exe corpus 4 (sigma 4)