Class: Rex::Post::HWBridge::Ui::Console::CommandDispatcher::Core
- Inherits:
-
Object
- Object
- Rex::Post::HWBridge::Ui::Console::CommandDispatcher::Core
- Defined in:
- lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb
Overview
Core hwbridge client commands that provide only the required set of commands for having a functional hwbridge client<->hardware instance.
Constant Summary collapse
- CommDispatcher =
Console::CommandDispatcher
- @@irb_opts =
Rex::Parser::Arguments.new( "-h" => [ false, "Help banner." ], "-e" => [ true, "Expression to evaluate." ])
- @@load_opts =
Rex::Parser::Arguments.new( "-h" => [ false, "Help menu." ])
- @@client_extension_search_paths =
[ ::File.join(Rex::Root, "post", "hwbridge", "ui", "console", "command_dispatcher") ]
Instance Attribute Summary collapse
-
#bgjob_id ⇒ Object
protected
:nodoc:.
-
#bgjobs ⇒ Object
protected
:nodoc:.
-
#extensions ⇒ Object
protected
:nodoc:.
Attributes included from Ui::Text::DispatcherShell::CommandDispatcher
Class Method Summary collapse
Instance Method Summary collapse
-
#add_extension_client(mod) ⇒ Object
protected
Loads the client extension specified in mod.
- #cmd_background ⇒ Object
- #cmd_background_help ⇒ Object
-
#cmd_bgkill(*args) ⇒ Object
Kill a background job.
-
#cmd_bglist(*args) ⇒ Object
List background jobs.
-
#cmd_bgrun(*args) ⇒ Object
Executes a script in the context of the hardware bridge session in the background.
-
#cmd_bgrun_tabs(*args) ⇒ Object
Map this to the normal run command tab completion.
-
#cmd_exit(*args) ⇒ Object
(also: #cmd_quit)
Terminates the hwbridge.
-
#cmd_info(*args) ⇒ Object
Show info for a given Post module.
- #cmd_info_help ⇒ Object
- #cmd_info_tabs(*args) ⇒ Object
-
#cmd_irb(*args) ⇒ Object
Runs the IRB scripting shell.
- #cmd_irb_help ⇒ Object
-
#cmd_load(*args) ⇒ Object
Loads one or more meterpreter extensions.
-
#cmd_load_custom_methods(*args) ⇒ Object
Loads custom methods if any exist.
- #cmd_load_custom_methods_help ⇒ Object
- #cmd_load_help ⇒ Object
-
#cmd_reboot(*args) ⇒ Object
Perform a device reboot.
- #cmd_reboot_help ⇒ Object
-
#cmd_reset(*args) ⇒ Object
Performs a device reset or factory reset.
- #cmd_reset_help ⇒ Object
-
#cmd_run(*args) ⇒ Object
Executes a script in the context of the hwbridge session.
- #cmd_run_help ⇒ Object
- #cmd_run_tabs(str, words) ⇒ Object
- #cmd_sessions(*args) ⇒ Object
- #cmd_sessions_help ⇒ Object
-
#cmd_specialty(*args) ⇒ Object
Get the Hardware specialty.
- #cmd_specialty_help ⇒ Object
-
#cmd_status(*args) ⇒ Object
Get the HW bridge devices status.
- #cmd_status_help ⇒ Object
-
#commands ⇒ Object
List of supported commands.
-
#initialize(shell) ⇒ Core
constructor
Initializes an instance of the core command set using the supplied shell for interactivity.
- #name ⇒ Object
- #tab_complete_postmods ⇒ Object protected
Methods included from Rex::Post::HWBridge::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, #docs_dir, #help_to_s, included, #print, #print_error, #print_good, #print_line, #print_status, #print_warning, #tab_complete_directory, #tab_complete_filenames, #tab_complete_generic, #tab_complete_source_address, #unknown_command, #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 32 33 34 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 24 def initialize(shell) super self.extensions = [] self.bgjobs = [] self.bgjob_id = 0 # keep a lookup table to refer to transports by index @transport_map = {} end |
Instance Attribute Details
#bgjob_id ⇒ Object (protected)
:nodoc:
524 525 526 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 524 def bgjob_id @bgjob_id end |
#bgjobs ⇒ Object (protected)
:nodoc:
524 525 526 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 524 def bgjobs @bgjobs end |
#extensions ⇒ Object (protected)
:nodoc:
523 524 525 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 523 def extensions @extensions end |
Class Method Details
.add_client_extension_search_path(path) ⇒ Object
514 515 516 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 514 def self.add_client_extension_search_path(path) @@client_extension_search_paths << path unless @@client_extension_search_paths.include?(path) end |
.client_extension_search_paths ⇒ Object
517 518 519 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 517 def self.client_extension_search_paths @@client_extension_search_paths end |
Instance Method Details
#add_extension_client(mod) ⇒ Object (protected)
Loads the client extension specified in mod
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 571 572 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 531 def add_extension_client(mod) loaded = false klass = nil self.class.client_extension_search_paths.each do |path| path = ::File.join(path, "#{mod}.rb") klass = CommDispatcher.check_hash(path) if klass.nil? old = CommDispatcher.constants next unless ::File.exist? path if require(path) new = CommDispatcher.constants diff = new - old next if diff.empty? klass = CommDispatcher.const_get(diff[0]) CommDispatcher.set_hash(path, klass) loaded = true break else print_error("Failed to load client script file: #{path}") return false end else # the klass is already loaded, from a previous invocation loaded = true break end end unless loaded print_error("Failed to load client portion of #{mod}.") return false end # Enstack the dispatcher self.shell.enstack_dispatcher(klass) # Insert the module into the list of extensions self.extensions << mod end |
#cmd_background ⇒ Object
106 107 108 109 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 106 def cmd_background print_status "Backgrounding session #{client.name}..." client.interacting = false end |
#cmd_background_help ⇒ Object
99 100 101 102 103 104 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 99 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
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 475 def cmd_bgkill(*args) if args.length.zero? 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
496 497 498 499 500 501 502 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 496 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 hardware bridge session in the background
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 436 def cmd_bgrun(*args) if args.length.zero? print_line( "Usage: bgrun <script> [arguments]\n\n" + "Executes a ruby script in the context of the hardware bridge session.") return true end jid = self.bgjob_id self.bgjob_id += 1 # Get the script name self.bgjobs[jid] = Rex::ThreadFactory.spawn("HWBridgeBGRun(#{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 script_name = args.shift client.execute_script(script_name, args) rescue ::Exception => e print_error("Error in script: #{script_name}") elog("Error in script #{script_name}", error: e) end self.bgjobs[myjid] = nil print_status("Background script with Job ID #{myjid} has completed (#{::Thread.current[:args].inspect})") end print_status("Executed HWBridge with Job ID #{jid}") end |
#cmd_bgrun_tabs(*args) ⇒ Object
Map this to the normal run command tab completion
468 469 470 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 468 def cmd_bgrun_tabs(*args) cmd_run_tabs(*args) end |
#cmd_exit(*args) ⇒ Object Also known as: cmd_quit
Terminates the hwbridge
114 115 116 117 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 114 def cmd_exit(*args) print_status("Shutting down the hardware bridge...") 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
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 169 def cmd_info(*args) return unless msf_loaded? if args.length != 1 || 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.(mod, ' ') print_line("\nModule options (#{mod.fullname}):\n\n#{mod_opt}") if mod_opt && mod_opt.length > 0 end end |
#cmd_info_help ⇒ Object
157 158 159 160 161 162 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 157 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
191 192 193 194 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 191 def cmd_info_tabs(*args) return unless msf_loaded? tab_complete_postmods end |
#cmd_irb(*args) ⇒ Object
Runs the IRB scripting shell
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 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 131 def cmd_irb(*args) expressions = [] # Parse the command options @@irb_opts.parse(args) do |opt, idx, val| case opt when '-e' expressions << val when '-h' return cmd_irb_help end end session = client framework = client.framework if expressions.empty? print_status("Starting IRB shell") print_status("The 'client' variable holds the hwbridge client\n") Rex::Ui::Text::IrbShell.new(binding).run else expressions.each { |expression| eval(expression, binding) } end end |
#cmd_irb_help ⇒ Object
121 122 123 124 125 126 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 121 def cmd_irb_help print_line "Usage: irb" print_line print_line "Execute commands in a Ruby environment" print @@irb_opts.usage end |
#cmd_load(*args) ⇒ Object
Loads one or more meterpreter extensions.
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 316 def cmd_load(*args) if args.length.zero? args.unshift("-h") end @@load_opts.parse(args) { |opt, idx, val| case opt 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) client.add_extension(md) # NOTE: Doesn't work, going to use core instead add_extension_client(md) #end rescue print_line log_error("Failed to load extension: #{$!}") next end print_line("success.") } return true end |
#cmd_load_custom_methods(*args) ⇒ Object
Loads custom methods if any exist
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 287 def cmd_load_custom_methods(*args) if args.length > 0 cmd_load_custom_methods_help return true end res = client.get_custom_methods if res.has_key? 'Methods' cmd_load("custom_methods") self.shell.dispatcher_stack.each do |dispatcher| if dispatcher.name =~ /custom methods/i dispatcher.load_methods(res['Methods']) end end print_status("Loaded #{res['Methods'].size} method(s)") else print_status("Not supported") end end |
#cmd_load_custom_methods_help ⇒ Object
277 278 279 280 281 282 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 277 def cmd_load_custom_methods_help print_line("Usage: load_custom_methods") print_line print_line "Checks to see if there are any custom HW commands and loads as" print_line "interactive commands in your session." end |
#cmd_load_help ⇒ Object
306 307 308 309 310 311 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 306 def cmd_load_help print_line("Usage: load ext1 ext2 ext3 ...") print_line print_line "Loads a hardware extension module or modules." print_line @@load_opts.usage end |
#cmd_reboot(*args) ⇒ Object
Perform a device reboot
269 270 271 272 273 274 275 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 269 def cmd_reboot(*args) if args.length > 0 cmd_reboot_help return end client.reboot end |
#cmd_reboot_help ⇒ Object
260 261 262 263 264 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 260 def cmd_reboot_help print_line("Reboots the device. This command typically only works on independent devices that") print_line("are not attached to a laptop or other system") print_line end |
#cmd_reset(*args) ⇒ Object
Performs a device reset or factory reset
252 253 254 255 256 257 258 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 252 def cmd_reset(*args) if args.length > 0 cmd_reset_help return end client.reset end |
#cmd_reset_help ⇒ Object
244 245 246 247 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 244 def cmd_reset_help print_line("Resets the device. In some cases this can be used to perform a factory reset") print_line end |
#cmd_run(*args) ⇒ Object
Executes a script in the context of the hwbridge session.
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 398 399 400 401 402 403 404 405 406 407 408 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 370 def cmd_run(*args) if args.length.zero? 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? && 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 => e print_error("Error in script: #{script_name}") elog("Error in script: #{script_name}", error: e) end end |
#cmd_run_help ⇒ Object
358 359 360 361 362 363 364 365 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 358 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 "hardware bridge 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
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 410 def cmd_run_tabs(str, words) tabs = [] if !words[1] || !words[1].match(/^\//) begin if msf_loaded? tabs = tab_complete_postmods end [ # We can just use Meterpreters script path ::Msf::Sessions::HWBridge.script_base, ::Msf::Sessions::HWBridge.user_script_base ].each do |dir| next unless ::File.exist? dir tabs += ::Dir.new(dir).find_all { |e| path = dir + ::File::SEPARATOR + e ::File.file?(path) && ::File.readable?(path) } end rescue Exception end end return tabs.map { |e| e.sub(/\.rb$/, '') } end |
#cmd_sessions(*args) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 85 def cmd_sessions(*args) if args.length.zero? || args[0].to_i.zero? cmd_sessions_help elsif args[0].to_s == client.name.to_s print_status("Session #{client.name} is already interactive.") else print_status("Backgrounding session #{client.name}...") # store the next session id so that it can be referenced as soon # as this session is no longer interacting client.next_session = args[0] client.interacting = false end end |
#cmd_sessions_help ⇒ Object
77 78 79 80 81 82 83 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 77 def cmd_sessions_help print_line('Usage: sessions <id>') print_line print_line('Interact with a different session Id.') print_line('This works the same as calling this from the MSF shell: sessions -i <session id>') print_line end |
#cmd_specialty(*args) ⇒ Object
Get the Hardware specialty
236 237 238 239 240 241 242 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 236 def cmd_specialty(*args) if args.length > 0 cmd_specialty_help return true end print_line client.exploit.hw_specialty.to_s end |
#cmd_specialty_help ⇒ Object
227 228 229 230 231 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 227 def cmd_specialty_help print_line("Usage: specialty") print_line print_line "Simple helper function to see what the devices specialty is" end |
#cmd_status(*args) ⇒ Object
Get the HW bridge devices status
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 205 def cmd_status(*args) if args.length > 0 cmd_status_help return true end status = client.get_status stats = client.get_statistics if status.has_key? 'operational' op = 'Unknown' op = 'Yes' if status['operational'] == 1 op = 'No' if status['operational'] == 2 print_status("Operational: #{op}") end print_status("Device: #{status['device_name']}") if status.key? 'device_name' print_status("FW Version: #{status['fw_version']}") if status.key? 'fw_version' print_status("HW Version: #{status['hw_version']}") if status.key? 'hw_version' print_status("Uptime: #{stats['uptime']} seconds") if stats.key? 'uptime' print_status("Packets Sent: #{stats['packet_stats']}") if stats.key? 'packet_stats' print_status("Last packet Sent: #{::Time.at(stats['last_request'])}") if stats.key? 'last_request' print_status("Voltage: #{stats['voltage']}") if stats.key? 'voltage' and not stats['voltage'] == 'not supported' end |
#cmd_status_help ⇒ Object
196 197 198 199 200 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 196 def cmd_status_help print_line("Usage: status") print_line print_line "Retrieves the devices current status and statistics" end |
#commands ⇒ Object
List of supported commands.
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 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 46 def commands c = { "?" => "Help menu", "background" => "Backgrounds the current session", "exit" => "Terminate the hardware bridge session", "help" => "Help menu", "irb" => "Drop into irb scripting mode", "load" => "Load one or more meterpreter extensions", "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", "sessions" => "Quickly switch to another session", "status" => "Fetch bridge status information", "specialty" => "Hardware devices specialty", "reset" => "Resets the device (NOTE: on some devices this is a FULL FACTORY RESET)", "reboot" => "Reboots the device (usually only supported by stand-alone devices)", "load_custom_methods" => "Loads custom HW commands if any" } if msf_loaded? c["info"] = "Displays information about a Post module" end c end |
#name ⇒ Object
73 74 75 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 73 def name "Core" end |
#tab_complete_postmods ⇒ Object (protected)
574 575 576 577 578 579 580 581 582 583 584 585 586 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 574 def tab_complete_postmods tabs = client.framework.modules.post.module_refnames.each { | name | mod = client.framework.modules.post.create(name) if mod && mod.session_compatible?(client) mod.fullname.dup else nil end } # nils confuse readline tabs.compact end |