Detection rules › Sigma

Linux Suspicious Child Process from Node.js - React2Shell

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

Detects suspicious child processes spawned from Node.js server processes on Linux systems, potentially indicating remote code execution exploitation such as CVE-2025-55182 (React2Shell). This rule particularly looks for exploitation of vulnerability on Node.js Servers where attackers abuse Node.js child_process module to execute arbitrary system commands. When execSync() or exec() is used, the command line often includes a shell invocation followed by suspicious commands or scripts (e.g., /bin/sh -c <malicious-command>). For other methods, the Image field will show the spawned process directly.

MITRE ATT&CK coverage

Event coverage

Rule body yaml

title: Linux Suspicious Child Process from Node.js - React2Shell
id: c70834fa-fb9d-4aa0-9e7d-45ceed36f3f7
related:
    - id: 271de298-cc0e-4842-acd8-079a0a99ea65
      type: similar
status: experimental
description: |
    Detects suspicious child processes spawned from Node.js server processes on Linux systems, potentially indicating remote code execution exploitation such as CVE-2025-55182 (React2Shell).
    This rule particularly looks for exploitation of vulnerability on Node.js Servers where attackers abuse Node.js child_process module to execute arbitrary system commands.
    When execSync() or exec() is used, the command line often includes a shell invocation followed by suspicious commands or scripts (e.g., /bin/sh -c <malicious-command>).
    For other methods, the Image field will show the spawned process directly.
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: linux
detection:
    selection_parent:
        ParentImage|endswith: '/node'
        ParentCommandLine|contains:
            - '--experimental-https'
            - '--experimental-next-config-strip-types'
            - '/node_modules/next'
            - 'next dev'
            - 'next start'
            - 'node_modules/.bin'
            - '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 in exploit
        - Image|endswith:
              - '/busybox'
              - '/cat'
              - '/curl'
              - '/dash'
              - '/dig'
              - '/head'
              - '/id'
              - '/ifconfig'
              - '/ip'
              - '/java'
              - '/less'
              - '/lua'
              - '/more'
              - '/nc'
              - '/ncat'
              - '/netcat'
              - '/netstat'
              - '/nslookup'
              - '/perl'
              - '/ping'
              - '/python'
              - '/python2'
              - '/ruby'
              - '/socat'
              - '/tail'
              - '/wget'
              - '/whoami'
        - Image|contains: '/python'
    selection_generic_child_cli:
        # Observed when child_process.execSync() is used to spawn suspicious processes
        # Reference: https://nodejs.org/api/child_process.html#child_processexecsynccommand-options
        # By default, the cli will look something like `/bin/sh -c .......`
        CommandLine|contains:
            - '/dev/tcp/'
            - '/dev/udp/'
            - '/etc/hosts'
            - '/etc/passwd'
            - '/etc/shadow'
            - 'base64'
            - 'cat '
            - 'curl'
            - 'dig'
            - 'ifconfig'
            - 'IO::Socket::INET'
            - 'java'
            - 'less '
            - 'lua'
            - 'mkfifo '
            - 'more'
            - 'nc '
            - 'ncat'
            - 'netcat'
            - 'netstat'
            - 'nslookup'
            - 'perl'
            - 'php'
            - 'ping'
            - 'ps -ef'
            - 'ps aux'
            - 'python'
            - 'rcat'
            - 'ruby'
            - 'sh -i 2>&1'
            - '-c id'
            - 'socat'
            - 'uname'
            - 'wget'
            - 'whoami'
    selection_specific_sh:
        Image|endswith: '/sh'
    selection_specific_cli:
        Image|endswith: '-c'
    filter_main_default_shell_flag:
        Image|endswith: '-c'
    condition:
        selection_parent and
        (
            1 of selection_generic_*
            or
            (selection_specific_sh and not filter_main_default_shell_flag)
            or
            (all of selection_specific_* and selection_generic_child_cli)
        )
falsepositives:
    - Unknown
level: high

Stages and Predicates

Stage 1: selection_parent

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

Stage 2: selection_generic_child_img

selection_generic_child_img:
    - Image|endswith:
          - '/busybox'
          - '/cat'
          - '/curl'
          - '/dash'
          - '/dig'
          - '/head'
          - '/id'
          - '/ifconfig'
          - '/ip'
          - '/java'
          - '/less'
          - '/lua'
          - '/more'
          - '/nc'
          - '/ncat'
          - '/netcat'
          - '/netstat'
          - '/nslookup'
          - '/perl'
          - '/ping'
          - '/python'
          - '/python2'
          - '/ruby'
          - '/socat'
          - '/tail'
          - '/wget'
          - '/whoami'
    - Image|contains: '/python'

Stage 3: selection_generic_child_cli

selection_generic_child_cli:
    CommandLine|contains:
        - '/dev/tcp/'
        - '/dev/udp/'
        - '/etc/hosts'
        - '/etc/passwd'
        - '/etc/shadow'
        - 'base64'
        - 'cat '
        - 'curl'
        - 'dig'
        - 'ifconfig'
        - 'IO::Socket::INET'
        - 'java'
        - 'less '
        - 'lua'
        - 'mkfifo '
        - 'more'
        - 'nc '
        - 'ncat'
        - 'netcat'
        - 'netstat'
        - 'nslookup'
        - 'perl'
        - 'php'
        - 'ping'
        - 'ps -ef'
        - 'ps aux'
        - 'python'
        - 'rcat'
        - 'ruby'
        - 'sh -i 2>&1'
        - '-c id'
        - 'socat'
        - 'uname'
        - 'wget'
        - 'whoami'

Stage 4: selection_specific_sh

selection_specific_sh:
    Image|endswith: '/sh'

Stage 5: not filter_main_default_shell_flag

filter_main_default_shell_flag:
    Image|endswith: '-c'

Stage 6: selection_specific_sh

selection_specific_sh:
    Image|endswith: '/sh'

Stage 7: selection_specific_cli

selection_specific_cli:
    Image|endswith: '-c'

Stage 8: selection_generic_child_cli

selection_generic_child_cli:
    CommandLine|contains:
        - '/dev/tcp/'
        - '/dev/udp/'
        - '/etc/hosts'
        - '/etc/passwd'
        - '/etc/shadow'
        - 'base64'
        - 'cat '
        - 'curl'
        - 'dig'
        - 'ifconfig'
        - 'IO::Socket::INET'
        - 'java'
        - 'less '
        - 'lua'
        - 'mkfifo '
        - 'more'
        - 'nc '
        - 'ncat'
        - 'netcat'
        - 'netstat'
        - 'nslookup'
        - 'perl'
        - 'php'
        - 'ping'
        - 'ps -ef'
        - 'ps aux'
        - 'python'
        - 'rcat'
        - 'ruby'
        - 'sh -i 2>&1'
        - '-c id'
        - 'socat'
        - 'uname'
        - 'wget'
        - 'whoami'

Exclusions

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

FieldKindExcluded values
Imageends_with-c

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
  • -c id
  • /dev/tcp/
  • /dev/udp/
  • /etc/hosts
  • /etc/passwd
  • /etc/shadow
  • IO::Socket::INET
  • base64
  • cat
  • curl
  • dig
  • ifconfig
  • java
  • less
  • lua
  • mkfifo
  • more
  • nc
  • ncat
  • netcat
  • netstat
  • nslookup
  • perl
  • php
  • ping
  • ps -ef
  • ps aux
  • python
  • rcat
  • ruby
  • sh -i 2>&1
  • socat
  • uname
  • wget
  • whoami
Imageends_with
  • -c
  • /busybox
  • /cat
  • /curl
  • /dash
  • /dig
  • /head
  • /id
  • /ifconfig
  • /ip
  • /java
  • /less
  • /lua
  • /more
  • /nc
  • /ncat
  • /netcat
  • /netstat
  • /nslookup
  • /perl
  • /ping
  • /python
  • /python2
  • /ruby
  • /sh
  • /socat
  • /tail
  • /wget
  • /whoami
Imagematch
  • /python
ParentCommandLinematch
  • --experimental-https
  • --experimental-next-config-strip-types
  • /node_modules/next
  • next dev
  • next start
  • node_modules/.bin
  • react-scripts start
  • start-server.js
ParentImageends_with
  • /node