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, #print, #print_error, #print_good, #print_line, #print_status, #print_warning, #tab_complete_directory, #tab_complete_filenames, #tab_complete_generic, #tab_complete_source_address, #update_prompt
Constructor Details
#initialize(shell) ⇒ Core
Initializes an instance of the core command set using the supplied shell for interactivity.
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 25 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:
525 526 527 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 525 def bgjob_id @bgjob_id end |
#bgjobs ⇒ Object (protected)
:nodoc:
525 526 527 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 525 def bgjobs @bgjobs end |
#extensions ⇒ Object (protected)
:nodoc:
524 525 526 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 524 def extensions @extensions end |
Class Method Details
.add_client_extension_search_path(path) ⇒ Object
515 516 517 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 515 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
518 519 520 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 518 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
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 573 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 532 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
107 108 109 110 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 107 def cmd_background print_status "Backgrounding session #{client.name}..." client.interacting = false end |
#cmd_background_help ⇒ Object
100 101 102 103 104 105 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 100 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
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 476 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
497 498 499 500 501 502 503 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 497 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
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 464 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 437 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
469 470 471 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 469 def cmd_bgrun_tabs(*args) cmd_run_tabs(*args) end |
#cmd_exit(*args) ⇒ Object Also known as: cmd_quit
Terminates the hwbridge
115 116 117 118 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 115 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
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 170 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
158 159 160 161 162 163 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 158 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
192 193 194 195 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 192 def cmd_info_tabs(*args) return unless msf_loaded? tab_complete_postmods end |
#cmd_irb(*args) ⇒ Object
Runs the IRB scripting shell
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 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 132 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
122 123 124 125 126 127 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 122 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.
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 357 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 317 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
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 288 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
278 279 280 281 282 283 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 278 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
307 308 309 310 311 312 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 307 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
270 271 272 273 274 275 276 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 270 def cmd_reboot(*args) if args.length > 0 cmd_reboot_help return end client.reboot end |
#cmd_reboot_help ⇒ Object
261 262 263 264 265 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 261 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
253 254 255 256 257 258 259 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 253 def cmd_reset(*args) if args.length > 0 cmd_reset_help return end client.reset end |
#cmd_reset_help ⇒ Object
245 246 247 248 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 245 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.
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 409 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 371 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
359 360 361 362 363 364 365 366 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 359 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
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 411 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
86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 86 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
78 79 80 81 82 83 84 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 78 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
237 238 239 240 241 242 243 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 237 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
228 229 230 231 232 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 228 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
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 206 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
197 198 199 200 201 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 197 def cmd_status_help print_line("Usage: status") print_line print_line "Retrives the devices current status and statistics" end |
#commands ⇒ Object
List of supported commands.
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 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 47 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
74 75 76 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 74 def name "Core" end |
#tab_complete_postmods ⇒ Object (protected)
575 576 577 578 579 580 581 582 583 584 585 586 587 |
# File 'lib/rex/post/hwbridge/ui/console/command_dispatcher/core.rb', line 575 def tab_complete_postmods tabs = client.framework.modules.post.map { |name, klass| 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 |