Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add repeat command for repeating other commands #10625

Merged
merged 8 commits into from
Sep 20, 2018

Conversation

acammack-r7
Copy link
Contributor

@acammack-r7 acammack-r7 commented Sep 11, 2018

Recently watching an assessment I came across a need to dump lots of memory from a heartbleed-vulnerable host (manually running the module lots of times was technically an option, but there wasn't a lot of time). I hacked something up with irb and driver.run_single, but it didn't feel very satisfying or user-friendly. I imagine there are other classes of auxiliary module that could use this, so instead of adding module specific options for repetition I added a new command that can be used with any module/command.

The repeat command will continue starting commands until a certain amount of time elapses with -t, for a fixed number of iterations with -n, or indefinitely (the default). It supports running a list of commands separated by ;, since the sleep command (and probably others) might come in handy. Any exception running a command will cause the loop to stop.

Verification

  • start msfconsole

Happy path

  • repeat grep grep grep; sleep 1 should print two lines every second until you CTRL-C
  • repeat -n 5 grep grep grep; sleep 1 should print the same 5 times
  • repeat -t 6 grep grep grep; sleep 1 should do the same
  • repeat -h and help repeat should be identical and informative
  • Options to repeat should tab-complete

Sad path

  • repeat -t 5 grep -A should print an error and not loop
  • repeat -t asdf grep grep grep should print an error and not loop
  • repeat -n asdf grep grep grep should print an error and not loop
  • repeat (with and without options) should print help when run with no commands

@h00die
Copy link
Contributor

h00die commented Sep 11, 2018

Interesting idea. If you didn't tell me it was heartbleed driven originally, I'd only be able to point to that module as one that would have a strong use case. However who knows what the future may hold!

To me, having a command list, a ;, then sleep, then understanding the sleep runs between each iteration doesn't seem intuitive. What about adding a -p or -s that would do it. repeat -n 5 -p 1 action action action seems more intuitive to me.

@acammack-r7
Copy link
Contributor Author

acammack-r7 commented Sep 12, 2018

; is the standard unconditional pipeline delimiter in most shells and the statement/expression separator in Ruby and other languages, so I borrowed it here. I suppose it could take a list of actions, but any that took arguments would have to be quoted and omitting quotes would likely lead to interesting errors. A pause option does feel more Metasploit-y, but also much more cumbersome, which is why I initially passed on it.

Ideally I would have made this behave more like a bourne-style shell, since there are lots of great one-liners and tutorials available and other reasons for learning, but that's not really feasible in the current code base.

@wvu
Copy link
Contributor

wvu commented Sep 12, 2018

Great use case picking Heartbleed. I think this will be a superior approach for simple cases where writing a resource script is overkill. Thank you!

@@ -432,7 +432,7 @@ def tab_complete_helper(dispatcher, str, words)
#
# Run a single command line.
#
def run_single(line)
def run_single(line, propogate_errors: false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you mean "propagate."

@@ -109,7 +109,10 @@ def initialize
STARTTLS may also be vulnerable.

The module supports several actions, allowing for scanning, dumping of
memory contents, and private key recovery.
memory contents, and private key recovery. The `repeat` command can be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I should have added a dump count to this module years ago. I will probably do this when I update Shellshock. In the absence of a true pipeline, I think we should keep this note regardless.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was considering an advanced option for all modules for number of times to loop, but this felt more flexible and possibly less obscure. I think the MS15-034 scanner could also benefit.

Copy link
Contributor

@wvu wvu Sep 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm a fan of this command over another top-level option. A pipeline would be a fantastic next evolution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, I had found it annoying to use the Heartbleed module because you had to check the loot file(s) manually for anything interesting. I would have liked a way to tee in a sense, but that was well outside design parameters.

@@ -109,7 +109,10 @@ def initialize
STARTTLS may also be vulnerable.

The module supports several actions, allowing for scanning, dumping of
memory contents, and private key recovery.
memory contents, and private key recovery. The `repeat` command can be
used to make running the `DUMP` many times more convient. As in:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean "convenient" here.

opts.separator ''

opts.on '-t SECONDS', '--time SECONDS', 'Number of seconds to repeat COMMAND...', Integer do |n|
looper = ->(&block) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the shorter lambda syntax with a block.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a block that takes a block in a block for a block!

@acammack-r7
Copy link
Contributor Author

Typos fixed, @wvu-r7.

Also, it now prints help when run without any commands instead of going into a loop with now output (similar to the grep msf command).

@wvu wvu self-assigned this Sep 13, 2018
@wvu wvu merged commit 175dec7 into rapid7:master Sep 20, 2018
wvu added a commit that referenced this pull request Sep 20, 2018
@wvu
Copy link
Contributor

wvu commented Sep 20, 2018

msf5 > repeat --crash-me
[-] repeat: invalid option: --crash-me
Traceback (most recent call last):
	7: from ./msfconsole:49:in `<main>'
	6: from /Users/wvu/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
	5: from /Users/wvu/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
	4: from /Users/wvu/metasploit-framework/lib/rex/ui/text/shell.rb:208:in `run'
	3: from /Users/wvu/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:447:in `run_single'
	2: from /Users/wvu/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:447:in `each'
	1: from /Users/wvu/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:450:in `block in run_single'
/Users/wvu/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:461:in `rescue in block in run_single': undefined local variable or method `propogate_errors' for #<Msf::Ui::Console::Driver:0x00007fced92af468> (NameError)
Did you mean?  propagate_errors
wvu@kharak:~/metasploit-framework:pr/10625$

6f72a05

@wvu
Copy link
Contributor

wvu commented Sep 20, 2018

Release Notes

This adds a repeat command to msfconsole, allowing a user to repeat a ;-separated list of commands for -n number of times and for -t seconds.

@wvu wvu mentioned this pull request Sep 20, 2018
2 tasks
@gdavidson-r7 gdavidson-r7 added the rn-enhancement release notes enhancement label Oct 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants