Class: Rex::Post::Meterpreter::Ui::Console::CommandDispatcher::Core

Inherits:
Object
  • Object
show all
Includes:
Rex::Post::Meterpreter::Ui::Console::CommandDispatcher
Defined in:
lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb

Overview

Core meterpreter client commands that provide only the required set of commands for having a functional meterpreter client<->server instance.

Constant Summary collapse

@@load_opts =
Rex::Parser::Arguments.new(
"-l" => [ false, "List all available extensions" ],
"-h" => [ false, "Help menu."                    ])
@@channel_opts =

Displays information about active channels

Rex::Parser::Arguments.new(
"-c" => [ true,  "Close the given channel." ],
"-k" => [ true,  "Close the given channel." ],
"-i" => [ true,  "Interact with the given channel." ],
"-l" => [ false, "List active channels." ],
"-r" => [ true,  "Read from the given channel." ],
"-w" => [ true,  "Write to the given channel." ],
"-h" => [ false, "Help menu." ])
@@write_opts =

Writes data to a channel.

Rex::Parser::Arguments.new(
"-f" => [ true,  "Write the contents of a file on disk" ],
"-h" => [ false, "Help menu."                           ])
@@client_extension_search_paths =
[ ::File.join(Rex::Root, "post", "meterpreter", "ui", "console", "command_dispatcher") ]

Instance Attribute Summary

Attributes included from Ui::Text::DispatcherShell::CommandDispatcher

#shell, #tab_complete_items

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Rex::Post::Meterpreter::Ui::Console::CommandDispatcher

check_hash, #client, #log_error, #msf_loaded?, set_hash

Methods included from Ui::Text::DispatcherShell::CommandDispatcher

#cmd_help, #cmd_help_help, #cmd_help_tabs, #deprecated_cmd, #deprecated_commands, #deprecated_help, #help_to_s, #print, #print_error, #print_good, #print_line, #print_status, #print_warning, #tab_complete_filenames, #update_prompt

Constructor Details

#initialize(shell) ⇒ Core

Initializes an instance of the core command set using the supplied shell for interactivity.


24
25
26
27
28
29
30
31
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 24

def initialize(shell)
  super

  self.extensions = []
  self.bgjobs     = []
  self.bgjob_id   = 0

end

Class Method Details

.add_client_extension_search_path(path) ⇒ Object


846
847
848
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 846

def self.add_client_extension_search_path(path)
  @@client_extension_search_paths << path unless @@client_extension_search_paths.include?(path)
end

.client_extension_search_pathsObject


849
850
851
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 849

def self.client_extension_search_paths
  @@client_extension_search_paths
end

Instance Method Details

#cmd_backgroundObject


96
97
98
99
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 96

def cmd_background
  print_status "Backgrounding session #{client.name}..."
  client.interacting = false
end

#cmd_background_helpObject


89
90
91
92
93
94
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 89

def cmd_background_help
  print_line "Usage: background"
  print_line
  print_line "Stop interacting with this session and return to the parent prompt"
  print_line
end

#cmd_bgkill(*args) ⇒ Object

Kill a background job


638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 638

def cmd_bgkill(*args)
  if args.length == 0
    print_line("Usage: bgkill [id]")
    return
  end

  args.each do |jid|
    jid = jid.to_i
    if self.bgjobs[jid]
      print_status("Killing background job #{jid}...")
      self.bgjobs[jid].kill
      self.bgjobs[jid] = nil
    else
      print_error("Job #{jid} was not running")
    end
  end
end

#cmd_bglist(*args) ⇒ Object

List background jobs


659
660
661
662
663
664
665
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 659

def cmd_bglist(*args)
  self.bgjobs.each_index do |jid|
    if self.bgjobs[jid]
      print_status("Job #{jid}: #{self.bgjobs[jid][:args].inspect}")
    end
  end
end

#cmd_bgrun(*args) ⇒ Object

Executes a script in the context of the meterpreter session in the background


599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 599

def cmd_bgrun(*args)
  if args.length == 0
    print_line(
      "Usage: bgrun <script> [arguments]\n\n" +
      "Executes a ruby script in the context of the meterpreter session.")
    return true
  end

  jid = self.bgjob_id
  self.bgjob_id += 1

  # Get the script name
  self.bgjobs[jid] = Rex::ThreadFactory.spawn("MeterpreterBGRun(#{args[0]})-#{jid}", false, jid, args) do |myjid,xargs|
    ::Thread.current[:args] = xargs.dup
    begin
      # the rest of the arguments get passed in through the binding
      client.execute_script(args.shift, args)
    rescue ::Exception
      print_error("Error in script: #{$!.class} #{$!}")
      elog("Error in script: #{$!.class} #{$!}")
      dlog("Callstack: #{[email protected].join("\n")}")
    end
    self.bgjobs[myjid] = nil
    print_status("Background script with Job ID #{myjid} has completed (#{::Thread.current[:args].inspect})")
  end

  print_status("Executed Meterpreter with Job ID #{jid}")
end

#cmd_bgrun_tabs(*args) ⇒ Object

Map this to the normal run command tab completion


631
632
633
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 631

def cmd_bgrun_tabs(*args)
  cmd_run_tabs(*args)
end

#cmd_channel(*args) ⇒ Object

Performs operations on the supplied channel.


123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 123

def cmd_channel(*args)
  if args.empty? or args.include?("-h") or args.include?("--help")
    cmd_channel_help
    return
  end

  mode = nil
  chan = nil

  # Parse options
  @@channel_opts.parse(args) { |opt, idx, val|
    case opt
    when "-l"
      mode = :list
    when "-c", "-k"
      mode = :close
      chan = val
    when "-i"
      mode = :interact
      chan = val
    when "-r"
      mode = :read
      chan = val
    when "-w"
      mode = :write
      chan = val
    end
    if @@channel_opts.arg_required?(opt)
      unless chan
        print_error("Channel ID required")
        return
      end
    end
  }

  case mode
  when :list
    tbl = Rex::Ui::Text::Table.new(
      'Indent'  => 4,
      'Columns' =>
        [
          'Id',
          'Class',
          'Type'
        ])
    items = 0

    client.channels.each_pair { |cid, channel|
      tbl << [ cid, channel.class.cls, channel.type ]
      items += 1
    }

    if (items == 0)
      print_line("No active channels.")
    else
      print("\n" + tbl.to_s + "\n")
    end
  when :close
    cmd_close(chan)
  when :interact
    cmd_interact(chan)
  when :read
    cmd_read(chan)
  when :write
    cmd_write(chan)
  else
    # No mode, no service.
    return true
  end
end

#cmd_channel_helpObject


113
114
115
116
117
118
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 113

def cmd_channel_help
  print_line "Usage: channel [options]"
  print_line
  print_line "Displays information about active channels."
  print_line @@channel_opts.usage
end

#cmd_channel_tabs(str, words) ⇒ Object


194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 194

def cmd_channel_tabs(str, words)
  case words.length
  when 1
    @@channel_opts.fmt.keys
  when 2
    case words[1]
    when "-k", "-c", "-i", "-r", "-w"
      tab_complete_channels
    else
      []
    end
  else
    []
  end
end

#cmd_close(*args) ⇒ Object

Closes a supplied channel.


220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 220

def cmd_close(*args)
  if (args.length == 0)
    cmd_close_help
    return true
  end

  cid     = args[0].to_i
  channel = client.find_channel(cid)

  if (!channel)
    print_error("Invalid channel identifier specified.")
    return true
  else
    channel._close # Issue #410

    print_status("Closed channel #{cid}.")
  end
end

#cmd_close_helpObject


210
211
212
213
214
215
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 210

def cmd_close_help
  print_line "Usage: close <channel_id>"
  print_line
  print_line "Closes the supplied channel."
  print_line
end

#cmd_close_tabs(str, words) ⇒ Object Also known as: cmd_interact_tabs, cmd_read_tabs


239
240
241
242
243
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 239

def cmd_close_tabs(str, words)
  return [] if words.length > 1

  return tab_complete_channels
end

#cmd_detach(*args) ⇒ Object

Disconnects the session


271
272
273
274
275
276
277
278
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 271

def cmd_detach(*args)
  if not client.passive_service
    print_error("Detach is only possible for non-stream sessions (http/https)")
    return
  end
  client.shutdown_passive_dispatcher
  shell.stop
end

#cmd_detach_helpObject


257
258
259
260
261
262
263
264
265
266
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 257

def cmd_detach_help
  print_line "Detach from the victim. Only possible for non-stream sessions (http/https)"
  print_line
  print_line "The victim will continue to attempt to call back to the handler until it"
  print_line "successfully connects (which may happen immediately if you have a handler"
  print_line "running in the background), or reaches its expiration."
  print_line
  print_line "This session may #{client.passive_service ? "" : "NOT"} be detached."
  print_line
end

#cmd_disable_unicode_encodingObject


839
840
841
842
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 839

def cmd_disable_unicode_encoding
  client.encode_unicode = false
  print_status("Unicode encoding is disabled")
end

#cmd_enable_unicode_encodingObject


834
835
836
837
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 834

def cmd_enable_unicode_encoding
  client.encode_unicode = true
  print_status("Unicode encoding is enabled")
end

#cmd_exit(*args) ⇒ Object Also known as: cmd_quit

Terminates the meterpreter session.


248
249
250
251
252
253
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 248

def cmd_exit(*args)
  print_status("Shutting down Meterpreter...")
  client.core.shutdown rescue nil
  client.shutdown_passive_dispatcher
  shell.stop
end

#cmd_info(*args) ⇒ Object

Show info for a given Post module.

See also cmd_info in lib/msf/ui/console/command_dispatcher/core.rb


679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 679

def cmd_info(*args)
  return unless msf_loaded?

  if args.length != 1 or args.include?("-h")
    cmd_info_help
    return
  end

  module_name = args.shift
  mod = client.framework.modules.create(module_name);

  if mod.nil?
    print_error 'Invalid module: ' << module_name
  end

  if (mod)
    print_line(::Msf::Serializer::ReadableText.dump_module(mod))
    mod_opt = ::Msf::Serializer::ReadableText.dump_options(mod, '   ')
    print_line("\nModule options (#{mod.fullname}):\n\n#{mod_opt}") if (mod_opt and mod_opt.length > 0)
  end
end

#cmd_info_helpObject


667
668
669
670
671
672
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 667

def cmd_info_help
  print_line 'Usage: info <module>'
  print_line
  print_line 'Prints information about a post-exploitation module'
  print_line
end

#cmd_info_tabs(*args) ⇒ Object


701
702
703
704
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 701

def cmd_info_tabs(*args)
  return unless msf_loaded?
  tab_complete_postmods
end

#cmd_interact(*args) ⇒ Object

Interacts with a channel.


290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 290

def cmd_interact(*args)
  if (args.length == 0)
    cmd_info_help
    return true
  end

  cid     = args[0].to_i
  channel = client.find_channel(cid)

  if (channel)
    print_line("Interacting with channel #{cid}...\n")

    shell.interact_with_channel(channel)
  else
    print_error("Invalid channel identifier specified.")
  end
end

#cmd_interact_helpObject


280
281
282
283
284
285
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 280

def cmd_interact_help
  print_line "Usage: interact <channel_id>"
  print_line
  print_line "Interacts with the supplied channel."
  print_line
end

#cmd_irb(*args) ⇒ Object

Runs the IRB scripting shell


313
314
315
316
317
318
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 313

def cmd_irb(*args)
  print_status("Starting IRB shell")
  print_status("The 'client' variable holds the meterpreter client\n")

  Rex::Ui::Text::IrbShell.new(binding).run
end

#cmd_load(*args) ⇒ Object

Loads one or more meterpreter extensions.


409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 409

def cmd_load(*args)
  if (args.length == 0)
    args.unshift("-h")
  end

  @@load_opts.parse(args) { |opt, idx, val|
    case opt
      when "-l"
        exts = []
        path = ::File.join(Msf::Config.data_directory, 'meterpreter')
        ::Dir.entries(path).each { |f|
          if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
            exts.push($1)
          end
        }
        print(exts.sort.join("\n") + "\n")

        return true
      when "-h"
        cmd_load_help
        return true
    end
  }

  # Load each of the modules
  args.each { |m|
    md = m.downcase

    if (extensions.include?(md))
      print_error("The '#{md}' extension has already been loaded.")
      next
    end

    print("Loading extension #{md}...")

    begin
      # Use the remote side, then load the client-side
      if (client.core.use(md) == true)
        add_extension_client(md)
      end
    rescue
      print_line
      log_error("Failed to load extension: #{$!}")
      next
    end

    print_line("success.")
  }

  return true
end

#cmd_load_helpObject Also known as: cmd_use_help


399
400
401
402
403
404
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 399

def cmd_load_help
  print_line("Usage: load ext1 ext2 ext3 ...")
  print_line
  print_line "Loads a meterpreter extension module or modules."
  print_line @@load_opts.usage
end

#cmd_load_tabs(str, words) ⇒ Object Also known as: cmd_use_tabs


461
462
463
464
465
466
467
468
469
470
471
472
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 461

def cmd_load_tabs(str, words)
  tabs = []
  path = ::File.join(Msf::Config.data_directory, 'meterpreter')
  ::Dir.entries(path).each { |f|
    if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
      if (not extensions.include?($1))
        tabs.push($1)
      end
    end
  }
  return tabs
end

#cmd_migrate(*args) ⇒ void

This method returns an undefined value.

Migrates the server to the supplied process identifier.

Parameters:

  • args (Array<String>)

    Commandline arguments, only -h or a pid


333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 333

def cmd_migrate(*args)
  if ( args.length == 0 or args.include?("-h") )
    cmd_migrate_help
    return true
  end

  pid = args[0].to_i
  if(pid == 0)
    print_error("A process ID must be specified, not a process name")
    return
  end

  begin
    server = client.sys.process.open
  rescue TimeoutError => e
    elog(e.to_s)
  rescue RequestError => e
    elog(e.to_s)
  end

  service = client.pfservice

  # If we have any open port forwards, we need to close them down
  # otherwise we'll end up with local listeners which aren't connected
  # to valid channels in the migrated meterpreter instance.
  existing_relays = []

  if service
    service.each_tcp_relay do |lhost, lport, rhost, rport, opts|
      next unless opts['MeterpreterRelay']
      if existing_relays.empty?
        print_status("Removing existing TCP relays...")
      end
      if (service.stop_tcp_relay(lport, lhost))
        print_status("Successfully stopped TCP relay on #{lhost || '0.0.0.0'}:#{lport}")
        existing_relays << {
          :lport => lport,
          :opts => opts
        }
      else
        print_error("Failed to stop TCP relay on #{lhost || '0.0.0.0'}:#{lport}")
        next
      end
    end
    unless existing_relays.empty?
      print_status("#{existing_relays.length} TCP relay(s) removed.")
    end
  end

  server ? print_status("Migrating from #{server.pid} to #{pid}...") : print_status("Migrating to #{pid}")

  # Do this thang.
  client.core.migrate(pid)

  print_status("Migration completed successfully.")

  unless existing_relays.empty?
    print_status("Recreating TCP relay(s)...")
    existing_relays.each do |r|
      client.pfservice.start_tcp_relay(r[:lport], r[:opts])
      print_status("Local TCP relay recreated: #{r[:opts]['LocalHost'] || '0.0.0.0'}:#{r[:lport]} <-> #{r[:opts]['PeerHost']}:#{r[:opts]['PeerPort']}")
    end
  end

end

#cmd_migrate_helpObject


320
321
322
323
324
325
326
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 320

def cmd_migrate_help
  print_line "Usage: migrate <pid>"
  print_line
  print_line "Migrates the server instance to another process."
  print_line "NOTE: Any open channels or other dynamic state will be lost."
  print_line
end

#cmd_read(*args) ⇒ Object

Reads data from a channel.


491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 491

def cmd_read(*args)
  if (args.length == 0)
    cmd_read_help
    return true
  end

  cid     = args[0].to_i
  length  = (args.length >= 2) ? args[1].to_i : 16384
  channel = client.find_channel(cid)

  if (!channel)
    print_error("Channel #{cid} is not valid.")
    return true
  end

  data = channel.read(length)

  if (data and data.length)
    print("Read #{data.length} bytes from #{cid}:\n\n#{data}\n")
  else
    print_error("No data was returned.")
  end

  return true
end

#cmd_read_helpObject


481
482
483
484
485
486
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 481

def cmd_read_help
  print_line "Usage: read <channel_id> [length]"
  print_line
  print_line "Reads data from the supplied channel."
  print_line
end

#cmd_resource(*args) ⇒ Object


796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 796

def cmd_resource(*args)
  if args.empty?
    return false
  end
  args.each do |glob|
    files = ::Dir.glob(::File.expand_path(glob))
    if files.empty?
      print_error("No such file #{glob}")
      next
    end
    files.each do |filename|
      print_status("Reading #{filename}")
      if (not ::File.readable?(filename))
        print_error("Could not read file #{filename}")
        next
      else
        ::File.open(filename, "r").each_line do |line|
          next if line.strip.length < 1
          next if line[0,1] == "#"
          begin
            print_status("Running #{line}")
            client.console.run_single(line)
          rescue ::Exception => e
            print_error("Error Running Command #{line}: #{e.class} #{e}")
          end

        end
      end
    end
  end
end

#cmd_resource_helpObject


789
790
791
792
793
794
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 789

def cmd_resource_help
  print_line "Usage: resource <path1> [path2 ...]"
  print_line
  print_line "Run the commands stored in the supplied files."
  print_line
end

#cmd_resource_tabs(str, words) ⇒ Object


828
829
830
831
832
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 828

def cmd_resource_tabs(str, words)
  return [] if words.length > 1

  tab_complete_filenames(str, words)
end

#cmd_run(*args) ⇒ Object

Executes a script in the context of the meterpreter session.


531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 531

def cmd_run(*args)
  if args.length == 0
    cmd_run_help
    return true
  end

  # Get the script name
  begin
    script_name = args.shift
    # First try it as a Post module if we have access to the Metasploit
    # Framework instance.  If we don't, or if no such module exists,
    # fall back to using the scripting interface.
    if (msf_loaded? and mod = client.framework.modules.create(script_name))
      original_mod = mod
      reloaded_mod = client.framework.modules.reload_module(original_mod)

      unless reloaded_mod
        error = client.framework.modules.module_load_error_by_path[original_mod.file_path]
        print_error("Failed to reload module: #{error}")

        return
      end

      opts = (args + [ "SESSION=#{client.sid}" ]).join(',')
      reloaded_mod.run_simple(
        #'RunAsJob' => true,
        'LocalInput'  => shell.input,
        'LocalOutput' => shell.output,
        'OptionStr'   => opts
      )
    else
      # the rest of the arguments get passed in through the binding
      client.execute_script(script_name, args)
    end
  rescue
    print_error("Error in script: #{$!.class} #{$!}")
    elog("Error in script: #{$!.class} #{$!}")
    dlog("Callstack: #{[email protected].join("\n")}")
  end
end

#cmd_run_helpObject


519
520
521
522
523
524
525
526
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 519

def cmd_run_help
  print_line "Usage: run <script> [arguments]"
  print_line
  print_line "Executes a ruby script or Metasploit Post module in the context of the"
  print_line "meterpreter session.  Post modules can take arguments in var=val format."
  print_line "Example: run post/foo/bar BAZ=abcd"
  print_line
end

#cmd_run_tabs(str, words) ⇒ Object


572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 572

def cmd_run_tabs(str, words)
  tabs = []
  if(not words[1] or not words[1].match(/^\//))
    begin
      if (msf_loaded?)
        tabs += tab_complete_postmods
      end
      [
        ::Msf::Sessions::Meterpreter.script_base,
        ::Msf::Sessions::Meterpreter.user_script_base
      ].each do |dir|
        next if not ::File.exist? dir
        tabs += ::Dir.new(dir).find_all { |e|
          path = dir + ::File::SEPARATOR + e
          ::File.file?(path) and ::File.readable?(path)
        }
      end
    rescue Exception
    end
  end
  return tabs.map { |e| e.sub(/\.rb$/, '') }
end

#cmd_use(*args) ⇒ Object


474
475
476
477
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 474

def cmd_use(*args)
  #print_error("Warning: The 'use' command is deprecated in favor of 'load'")
  cmd_load(*args)
end

#cmd_write(*args) ⇒ Object


720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 720

def cmd_write(*args)
  if (args.length == 0 or args.include?("-h"))
    cmd_write_help
    return
  end

  src_file = nil
  cid      = nil

  @@write_opts.parse(args) { |opt, idx, val|
    case opt
      when "-f"
        src_file = val
      else
        cid = val.to_i
    end
  }

  # Find the channel associated with this cid, assuming the cid is valid.
  if ((!cid) or (!(channel = client.find_channel(cid))))
    print_error("Invalid channel identifier specified.")
    return true
  end

  # If they supplied a source file, read in its contents and write it to
  # the channel
  if (src_file)
    begin
      data = ''

      ::File.open(src_file, 'rb') { |f|
        data = f.read(f.stat.size)
      }

    rescue Errno::ENOENT
      print_error("Invalid source file specified: #{src_file}")
      return true
    end

    if (data and data.length > 0)
      channel.write(data)
      print_status("Wrote #{data.length} bytes to channel #{cid}.")
    else
      print_error("No data to send from file #{src_file}")
      return true
    end
  # Otherwise, read from the input descriptor until we're good to go.
  else
    print("Enter data followed by a '.' on an empty line:\n\n")

    data = ''

    # Keep truckin'
    while (s = shell.input.gets)
      break if (s =~ /^\.\r?\n?$/)
      data += s
    end

    if (!data or data.length == 0)
      print_error("No data to send.")
    else
      channel.write(data)
      print_status("Wrote #{data.length} bytes to channel #{cid}.")
    end
  end

  return true
end

#cmd_write_helpObject


713
714
715
716
717
718
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 713

def cmd_write_help
  print_line "Usage: write [options] channel_id"
  print_line
  print_line "Writes data to the supplied channel."
  print_line @@write_opts.usage
end

#commandsObject

List of supported commands.


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
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 40

def commands
  c = {
    "?"          => "Help menu",
    "background" => "Backgrounds the current session",
    "close"      => "Closes a channel",
    "channel"    => "Displays information about active channels",
    "exit"       => "Terminate the meterpreter session",
    "help"       => "Help menu",
    "interact"   => "Interacts with a channel",
    "irb"        => "Drop into irb scripting mode",
    "use"        => "Deprecated alias for 'load'",
    "load"       => "Load one or more meterpreter extensions",
    "quit"       => "Terminate the meterpreter session",
    "resource"   => "Run the commands stored in a file",
    "read"       => "Reads data from a channel",
    "run"        => "Executes a meterpreter script or Post module",
    "bgrun"      => "Executes a meterpreter script as a background thread",
    "bgkill"     => "Kills a background meterpreter script",
    "bglist"     => "Lists running background scripts",
    "write"      => "Writes data to a channel",
    "enable_unicode_encoding"  => "Enables encoding of unicode strings",
    "disable_unicode_encoding" => "Disables encoding of unicode strings"
  }

  if client.passive_service
    c["detach"] = "Detach the meterpreter session (for http/https)"
  end
  # The only meterp that implements this right now is native Windows and for
  # whatever reason it is not adding core_migrate to its list of commands.
  # Use a dumb platform til it gets sorted.
  #if client.commands.include? "core_migrate"
  if client.platform =~ /win/
    c["migrate"] = "Migrate the server to another process"
  end

  if (msf_loaded?)
    c["info"] = "Displays information about a Post module"
  end

  c
end

#nameObject

Core baby.


85
86
87
# File 'lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb', line 85

def name
  "Core"
end