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 favorite module feature and show favorites command for msfconsole #14201

Merged
merged 8 commits into from
Mar 8, 2021
Merged

Add favorite module feature and show favorites command for msfconsole #14201

merged 8 commits into from
Mar 8, 2021

Conversation

ErikWynter
Copy link
Contributor

@ErikWynter ErikWynter commented Sep 30, 2020

About

This change adds a new feature to msfconsole that allows users to create, view, edit and delete a list of favorite modules. The list is by default stored in the .msf4 folder in a file called fav_modules. The feature adds two new module commands:

  • A command called favorite, which can be used to add modules to fav_modules, to delete modules from it, and to delete the fav_modules file altogether.
  • A specific show command called show favorites, which can be used to view all favorited modules in the same output format as other show commands.

Demo

I've made a short demo video of the feature in action. Check it out here

The favorite module command

Usage: favorite [mod1 mod2 ...]

Add one or multiple modules to the list of favorite modules stored in the fav_modules file
If no module name is specified, the command will add the active module if there is one

OPTIONS:
  -d               Delete the provided module(s) from the fav_modules file
  -D               Delete the fav_modules file

Adding modules

  • To add one or multiple modules to fav_modules, run favorite followed by the module name(s). It is not always necessary to add the module type at the beginning, eg:
msf6 > favorite multi/handler post/multi/manage/autoroute
[*] Added exploit/multi/handler to /root/.msf4/fav_modules
[*] Added post/multi/manage/autoroute to /root/.msf4/fav_modules
  • To add the active module, just run favorite without arguments, eg:
msf6 exploit(windows/smb/ms17_010_eternalblue) > favorite 
[*] Added exploit/windows/smb/ms17_010_eternalblue to /root/.msf4/fav_modules

Deleting modules

  • To delete one or multiple modules, run favorite with the -d flag, eg:
msf6 exploit(windows/smb/ms17_010_eternalblue) > favorite -d
[*] Removed exploit/windows/smb/ms17_010_eternalblue from /root/.msf4/fav_modules
msf6 > favorite -d multi/handler post/multi/manage/autoroute
[*] Removed exploit/multi/handler from /root/.msf4/fav_modules
[*] Removed post/multi/manage/autoroute from /root/.msf4/fav_modules
  • To delete the fav_modules file altogether, run favorite with the -D flag, eg:
msf6 > favorite -D
[*] Removing /root/.msf4/fav_modules if it exists

Errors and warnings

  • If favorite is run without arguments but there is not active module, an error message is printed
msf6 > favorite 
[-] No module active
  • If a user provides an invalid module to add or delete, an error message is printed
msf6 > favorite this/is/not/a/module
[-] Invalid module: this/is/not/a/module
msf6 > favorite -d this/is/not/a/module/either
[-] Invalid module: this/is/not/a/module/either

  • If a user tries to add a module that is already present in fav_modules, the module will not be added and a warning will be printed
msf6 > favorite multi/handler
[!] Module exploit/multi/handler has already been favorited and will not be added to /root/.msf4/fav_modules
  • If a user tries to delete a module that is not present in fav_modules, or if fav_modules does not exist, favorite will do nothing
msf6 > favorite -d post/multi/manage/autoroute
msf6 > 
  • If a user tries to delete fav_modules even though it doesn't exist, favorite will do nothing
msf6 > favorite -D
[*] Removing /root/.msf4/fav_modules if it exists
  • If the -D and -d flags are used together, or if the -D flag is used together with a module name,favorite will delete the fav_modules file and return
msf6 > favorite -D multi/handler
[*] Removing /root/.msf4/fav_modules if it exists
msf6 > favorite -D -d
[*] Removing /root/.msf4/fav_modules if it exists
msf6 > favorite -D -d multi/handler
[*] Removing /root/.msf4/fav_modules if it exists

The show favorites command

  • show favorites can be used to view the list of favorited modules stored in the fav_modules file, eg:
msf6 > show favorites 

Favorites
=========

   #  Name                                 Disclosure Date  Rank    Check  Description
   -  ----                                 ---------------  ----    -----  -----------
   0  auxiliary/scanner/smb/smb_login                       manual  No     SMB Login Check Scanner
   1  exploit/multi/handler                                 manual  No     Generic Payload Handler
   2  exploit/windows/http/zentao_pro_rce  2020-06-01       manual  Yes    ZenTao Pro 8.8.2 Remote Code Execution
   3  post/multi/manage/autoroute                           manual  No     Multi Manage Network Route via Meterpreter Session
  • If the fav_modules file is empty or does not exist, show favorites will print an error message
msf6 > show favorites 
[-] /root/.msf4/fav_modules does not exist or is empty

Potential future addition: access via use <index>

While msfconsole allows users to access modules listed in search results via the index number, eg use 5, this feature is not available for the results of any of the show commands. However, if this feature is ever added, it will be immediately available for show favorites as well, since this command supports the same output format as other show commands like show post

@ErikWynter
Copy link
Contributor Author

Notes

  • I wasn't fully sure about the best names for the commands and file, so I'm definitely open to suggestions
  • Pretty sure some of the code for the favorite command in particular could be less convoluted, but this seemed like the best spaghetti I could throw together on my first try.
  • I tried my best to prevent it from crashing due to unexpected usage and edge cases, but I would not be surprised if I have added too many checks in some places and too few in others...
  • Working on this thing made my brain segfault, so that's my excuse in case it's total garbage.

@adfoster-r7
Copy link
Contributor

Thanks for the PR @kalba-security 👍

I'm still a bit new to the workflow side of things on Metasploit, but it would be great to know how often this command might be used by an average user. From my own personal experience I've mostly been reaching for previous modules within linux's ctrl+r reverse search capabilities, or after using the metasploit's search command with some of the keywords that I remember from the module name/description. Is this a command that you'd see yourself and other users wanting to reach for often?

For context - adding an additional core command to Metasploit requires a bit more effort than normal to get it shipped - both in terms of documentation considerations, educating the community about the additional functionality, future maintenance effort, manual/automated testing, edge case handling etc, so from my perspective I just want to be sure that this is something that will benefit most users if it's provided as an out of the box command with metasploit-framework ! :)

@ErikWynter
Copy link
Contributor Author

Thanks for the question @adfoster-r7 ! I actually came up with the idea for this feature as a way to improve my workflow during penetration tests. I would personally be using this feature all the time for at least the following reasons:

  • During assessments I keep coming back to the same 20-30 modules or so. Some of these I use almost every assessment, but others only come up every now and again, so I haven't memorized the full path. Having all of these modules in a neat little overview would be great because searching for modules can be annoying. I mean if you don't remember exactly what to look for, a search can easily return dozens of results. Moreover, many modules have generic descriptions that overlap with those of other modules, requiring you to load several modules and read the info to figure out which one you want to use.
  • Proper use of this feature can provide students and (junior) pentesters with some guidance as they go through the various stages of an assessment or a lab assignment. By this I mean that instead of constantly consulting their notes to see what to do next, they can use their favorites list as a reference for what they should be testing for and in what order. Similarly, it can help them make sure they don't forget to run certain tests / attacks.
  • Because the show favorites command simply reads from the fav_modules file, pentesters can easily to automate the generation of a custom favorites list per assessment via a simple script that writes certain modules to fav_modules based on port scan results.
  • This feature makes it possible to 'bookmark' interesting modules for future reference, which can be useful for example if an interesting new attack is added that you haven't seen in the wild yet, but are likely to come across at some point in the future.

While not everyone may find this feature as useful as I do, I think many users would benefit from it, which I imagine is also the reason that the PR has received likes from several people at Rapid 7 :) Please let me know what you think about all of this!
Btw, I'd be happy to help with the documentation and some of the other stuff that needs to be done before this could get added.

Copy link
Contributor

@space-r7 space-r7 left a comment

Choose a reason for hiding this comment

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

I think this is a useful addition, and from the small bit of testing I've done so far, this is working as well. I do have some suggestions, where the main one is related to the addition / deletion logic.

The logic for adding and deleting a favorite module seems to be interweaved both within cmd_favorite() and cmd_favorite_process(). It might be helpful to separate those two features of the command into their own separate methods, especially if further additions to this command are being considered. This is untested and is just an example of what I mean:

def cmd_favorite(*args)
  if args.empty?
    unless active_module
      print_error('No module has been chosen to favorite')
      return
    end

    cmd_favorite_add(active_module)
    return
  end

  if args.include?('-D')
    args.delete('-D')
    cmd_favorite_del(args, true)
    return
  end

  if args.include?('-d')
    args.delete('-d')
    cmd_favorite_del(args)
    return
  end

  cmd_favorite_add(args)
end

def cmd_favorite_del(module, delete_all = false)
  if delete_all
    # check if fav_module file exists and delete it
    return
  end

  # handle deleting individual favorite module(s)
  ...
end

def cmd_favorite_add(module)
  # logic for adding favorites
  ...
end

lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
… functions; improve syntax and error handling
@ErikWynter
Copy link
Contributor Author

Thanks for the suggestions, @space-r7! Great to hear that you also think this could be a nice feature. I was starting to think this PR had been forgotten.
In any case, after looking at the code again I completely agree about separating the addition and deletion logic, so I have fixed that in the latest PR. The separation allows for some more specific error handling, which I have added. Also, if the favorite command is run with -d, it will now automatically delete the fav_modules file if that ends up empty after all provided modules have been deleted. Please let me know if you'd like me to make additional changes. :)

@space-r7 space-r7 self-assigned this Jan 5, 2021
Copy link
Contributor

@space-r7 space-r7 left a comment

Choose a reason for hiding this comment

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

I've a few more suggestions, mostly centered around utilizing the Rex::Parser::Arguments class. Let me know if you have any questions!

lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
…-D' delete file to '-c' for clearing the contents, change helper method names, add helper method 'favorite_check_fav_modules'
@ErikWynter
Copy link
Contributor Author

Thanks for the great suggestions @space-r7 ! I have implemented all of them, and made the following additional improvements:

  • Providing the full path to the fav_modules file in the help banner
  • Adding some extra error handling for incorrect usage of options
  • Instead of option -D for deleting the fav_modules file, you can now use -c to clear the contents, so once created, the file will not be deleted unless the user manually does this.
  • Cleaning up the cmd_favorite method by adding a new helper method to check the existence of the fav_modules file as well as the file permissions and potentially the contents, as this info is required for several options.

I tried to test all different scenarios and didn't run into any errors. Please let me know if you'd like me to make any final changes. Looking forward to seeing this get landed!

Copy link
Contributor

@space-r7 space-r7 left a comment

Choose a reason for hiding this comment

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

The bulk of the remaining suggestions are really just re-ordering / moving around some logic and changing up some wording. This pr might be hanging around a little longer, as I'll be on research rotation, but I think this is almost done. Please let me know if you have any questions!

lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
lib/msf/ui/console/command_dispatcher/modules.rb Outdated Show resolved Hide resolved
…help banner when user input is invalid, do not use parse
@ErikWynter
Copy link
Contributor Author

Hi @space-r7, thanks for the additional suggestions! I did struggle quite a bit with parse() last time because it doesn't work as might expect, so I say good riddance. I also agree that moving the permissions checks to favorite_cmd and favorite_del is a good idea. The template you provided is very neat and worked well. In addition to your suggestions, the only thing I added is a little customized error message for the file permissions checks in favorite_del based on whether or not delete_all is true. Let me know what you think!

@space-r7
Copy link
Contributor

Just wanted to give an update on this. I've done some testing on this this week although it's unlikely that I'll get done with it / land it today. I'll resume work on it next rotation. The changes look good to me. Thanks!

@ErikWynter
Copy link
Contributor Author

Thanks for the update @space-r7 ! Can you say anything more about the expected timeline for landing this? If not, that's fine, I'm just curious. :)

@space-r7
Copy link
Contributor

Thanks for the update @space-r7 ! Can you say anything more about the expected timeline for landing this? If not, that's fine, I'm just curious. :)

Will try and get back to this on the 1st.

@space-r7
Copy link
Contributor

space-r7 commented Mar 2, 2021

Submitted https://github.com/kalba-security/metasploit-framework/pull/3 to your branch. Please let me know if that looks good to you, thanks!

@ErikWynter
Copy link
Contributor Author

Thanks! I'll test this on Saturday. Probably won't have time before.

@ErikWynter
Copy link
Contributor Author

@space-r7 I tested the changes locally and everything looks and works great, so I just merged it. So feel free to land this :)

@space-r7 space-r7 merged commit d114641 into rapid7:master Mar 8, 2021
@space-r7
Copy link
Contributor

space-r7 commented Mar 8, 2021

Release Notes

Added a new msfconsole command, favorite, which allows users to easily save favorite / commonly-used modules for quick retrieval later.

@space-r7
Copy link
Contributor

space-r7 commented Mar 8, 2021

For future reference, I added a small wiki page that details the usage of this command: https://github.com/rapid7/metasploit-framework/wiki/How-to-use-the-Favorite-command.

@ErikWynter
Copy link
Contributor Author

Thanks for working with me on this @space-r7 and for adding the wiki!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants