My VSCode Workflow For Ruby Programming On Metasploit

Grant WillcoxGrant Willcox
11 min read

Plugins

Essential

Ruby

The basis for literally everything else here. Provides the Ruby language support and debugging support for Ruby programs, code folding support, semantic highlighting support, basic IntelliSense support, and automatic Ruby environment support which is essential if you're a developer with multiple Ruby versions like me.

The one downside is the syntax highlighting here is kinda meh. This is where VSCode Ruby comes in.

VSCode Ruby

Improved syntax highlighting for Ruby code. You're going to appreciate this, trust me :) Relies on having the Ruby plugin I mentioned above installed.

Ruby Solargraph from Castwide

Need this to allow VS Code to understand what you are writing and provide code completion, IntelliSense, and inline documentation. Also allows hover-over panes that can provide useful info about certain methods.

Installing Solargraph requires a bit more work than other plugins but not majorly so. First, run gem install solargraph and then run navigate to the root of your Metasploit Framework directory and run solargraph bundle to document all the gems that Metasploit Framework uses.

Next, run solargraph config in the Metasploit root to generate your .solargraph.yml file. You can use the following snippet as a baseline, however, this is what I use for my settings:

---
include:
  - "**/*.rb"
exclude:
  - spec/**/*
  - test/**/*
  - vendor/**/*
  - ".bundle/**/*"
  - data/**/*
  - db/**/*
  - external/**/*
  - plugins/**/*
  - scripts/**/* # Old stuff, no need to index this.
require: []
domains: []
reporters:
  - rubocop
  - require_not_found
formatter:
  rubocop:
    cops: safe
    except: []
    only: []
    extra_args: []
require_paths: []
plugins: []
max_files: 0

If you'd also like to enable type-checking you can add - typecheck:typed to enable Typed level type checking by Solargraph. Note this is an experimental feature and relies on YARD documentation.

Next, ensure that yard is configured such that it will always generate new documentation for Gems as you install them with yard config --gem-install-yri. Note that you may want to disable this if it's getting very long to install things, but this may help ensure Solargraph is always running with the latest YARD documentation possible and therefore all types and function info is kept up to date.

Next, run solargraph scan -v to make sure that there are no issues with your workspace and that Solargraph can run correctly. Be aware this may take a few minutes to run.

Finally, you'll want to enable the settings that are useful within the extension's settings. To do this go to View->Extensions and then search for Solargraph. Once that is done, right-click on the Solargraph entry and click Extension Settings. From here I used the following settings:

- Solargraph: Autoformat -> False
- Solargraph: Check Gem Version -> True
- Solargraph: Command Path -> Should be able to leave this on `solargraph` but update this if `solargraph` isn't in your PATH.
- Solargraph: Completion -> Enables code completion suggestions of constants and known functions etc. If you find this helpful, set it to `True`, otherwise leave it on `False` if this distracts or isn't helpful for you.
- Solargraph: Definitions -> Enables "Go To Definition". Definetely set this to `True` to enable it, its super helpful.
- Solargraph: Diagnostics -> Needed for diagnostic tools such as `Rubocop`, `require_not_found`, and type checking. See https://github.com/castwide/solargraph/tree/3254dec22a55bdb7b66382c7ebe08283a4cc1168/lib/solargraph/diagnostics for a list of current diagnostic tools that require this setting. I set this to `True`.
- Solargraph: Formatting -> This is optional but allows for Rubocop formatting using Solargraph. I set this to `True`.
- Solargraph: Hover -> Allows hover support on text to show tool tips and stuff like info about functions. Turned this to `True`.
- Solargraph: Log Level -> Left this at `warn`. No need to make the logs more severe.
- Solargraph: References -> Set this to `True`. Enables finding references. Super helpful.
- Solargraph: Rename -> Set this to `True`. Enables symbol renaming.
- Solargraph: Symbols -> Set this to `True`. Enables symbol support.
- Solargraph: Transport -> Set this to `stdio`. No need to use networking but you can if you want.
- Solargraph: Use Bundler -> Uncheck this box unless you installed `Solargraph` via bundler. Since Metasploit doesn't presently include Solargraph in its Bundler file I unchecked this.

Finally, to keep things up to date I use the following script to ensure Solargraph is looking at the latest code updates:

bundle install # Update all the Gems
yard gems # Create documentation files for all the gems
yard doc -c # Create documentation files for all files, and use the cache so that we don't do extra work regenerating docs we already have generated documentation for.
solargraph bundle # Update SolarGraph documentation for bundled gems
echo 'Scanning workspace for code that Solargraph cannot parse and that will cause errors.'
echo 'This may take a few minutes, please be patient...'
solargraph scan -v  # Scan workspace for code that Solargraph can’t parse or map and report them. In some cases, these problems can stop the language server from working properly.
echo "Now run Bust-A-Gem: Rebuild Tags"

Bust a Gem

This is an essential plugin for allowing you to use "Go to Definition" within VSCode to look for definitions within Gems. Without this you will often try to use "Go to Definition" and VSCode will not find any definitions. Also pops up a handy drop-down menu if it's not sure which definition you want to use if there are multiple potential options.

To use this tool you will need to first install the ripper-tags gem using gem install ripper-tags. Once this is done the first time you do Go to Definition, the plugin will use ripper-tags to generate a TAGS file for your project.

Personally, since this plugin doesn't rebuild the TAGS file automatically I prefer to hit CTRL+SHIFT+P to open the command palette and then run the Bust-A-Gem: Rebuild Tags command manually to ensure it is getting the latest tags available.

Note that this plugin does rely on Bundler and only works on Ruby projects that have a Gemfile but Metasploit Framework has this already set up so you should be fine :) If you do encounter issues the project recommends running bundler show --paths from the root of your Metasploit Framework install (aka where you cloned the Git repository) to make sure it includes the path to the Gem you are after.

GitLens - Git SuperCharged

A super useful plugin for showing commit history on a file over time, heatmaps of where code has been most often changed, and also helping to show who last changed a line of code as inline annotations and how long ago that change was made.

I use this a lot when I need to go ahead and figure out who made a code change so that I can go and ask the respective person questions when a more significant design change needs to be made. Also useful for finding who to ask questions to better understand the components of Metasploit.

Very Helpful But Still a Little Broken

VSCode Rdbg Ruby Debugger

To set this up you will first need rdbg. On Ruby 3.1 and later this comes standard. Otherwise, you may need to install it using gem install debug, though the Gemfile of Metasploit should now have it listed already so you can also run bundler install and then check the output to make sure debug was installed.

Once this is done, you can install this plugin and then create a new folder called .vscode and create a new file called launch.json with the following settings:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "rdbg",
            "name": "Debug current file with rdbg",
            "request": "launch",
            "script": "${cwd}/msfconsole",
            "args": [],
            "useTerminal": true,
            "askParameters": false,
            "localfs": true,
            "waitLaunchTime": 8000
        },
        {
            "type": "rdbg",
            "name": "Attach with rdbg",
            "request": "attach",
            "localfs": true
        }
    ]
}

I haven't gotten the attach operation to work so well but the other settings should work fine. From here you can then restart VSCode, and then click on Run->Start Debugging and you should now have a running instance of msfconsole that you can also pause, set breakpoints in, and use for debugging with no performance overhead.

Note that when connecting the bar at the bottom of VSCode should turn colored and should remain that way for the duration of your debugging session. If it turns back to an uncolored color (usually the same color as the tabs) then your debugging session ended or something went wrong.

Note this tool is experimental and I have encountered some issues where it did suddenly terminate in the middle of a debugging session. Support has been getting better over time and it is getting to be more and more stable with the passing months, but please keep this in mind when using this.

Helpful

Error Lens

This provides inline annotations for errors you may have made within your code. Useful for debugging errors.

Code Spell Checker

A nice offline spell checker that helps with catching spelling mistakes in code.

EndWise

A nice tool to automatically add end statements when you type something like if or def, etc. Not essential but I've found it quite helpful to save a lot of extra typing.

indent-rainbow

A great plugin that allows you to have multiple different colors to indicate how far tabbed in something is. This can be used to make sure you have indented items to the correct level at a glance.

ToDo-Tree

Uses the ripgrep gem, the same one that the Bust-A-Gem plugin uses, to search for comments like TODO and FIXME, and then shows this in a neat tree view. Very useful for finding areas of the code that need work and you can even filter to only show TODO items or only FIXME items, etc.

You can also use the customHighlight setting to set different colored highlights for different tags making it easier to differentiate them from one another, use icon to change the icon associated with a tag, and type to control how much is highlighted in the editor (just the tag, the tag and the comment, the tag and its subtag, etc).

You can even hide certain tags with the hideFromTree and hideFromStatusBar options.

ruby-symbols

Allows you to search for classes, methods, and modules using the Go to Symbol search method in VSCode. To do this type CTRL+SHIFT+O to search symbols in the current file, or CTRL+T to search symbols across files. By typing : the symbols will be grouped by category, can place this anywhere before the search.

Prepending @ will search for symbols, # will search for methods.

I don't personally use this feature at all, but I thought I'd mention it here since it might come in handy for some people.

CodeTogether

A nice plugin that allows for cross-IDE pairing sessions, whilst also allowing people to follow a leader, or go off and code on their own whilst also seeing what code their partner is looking at and on what line it's on. Also supports screen sharing and video calls.

Important to note that whilst most of this is E2E encrypted, the video and audio part is currently not due to their support for WebRTC to allow browsers to join and WebRTC's lack of support for this. See https://www.codetogether.com/docs/faq/ for more info on this. I'd therefore recommend using Zoom or something else to do the video and audio if E2E encryption is a concern.

Personal Preference

Material Theme Icons

Just makes the file view look neater and personally I find the file icons make it quicker to find what I'm after, but this is just mostly cosmetic stuff.

YARD Documentation Helpers (Aka making Solargraph better with help from some plugins)

Since Solargraph relies on YARD documentation to help perform a lot of its features, I thought it would be good to mention some plugins that can help ease the process of writing YARD documentation.

YARD Documenter

Allows you to generate a template for a given function by clicking on the name of the function and then hitting CTRL+ALT+ENTER to generate the YARD template for that given function. You can then use the TAB and SHIFT+TAB keys to shuffle through the various placeholders within the generated template so you start filling them out with the necessary detail.

Note that presently this only supports generating templates with the following tags in addition to the <Description> placeholder for describing the method itself:

  • @author

  • @option

  • @param

  • @return

Simple YARD Snippets

This allows you to autocomplete templates for simple YARD tags should you type in the tag name without the @ sign. You can also see all supported tags that it can autocomplete by typing YARD. It has a much wider range of tag support than YARD Documenter does and serves to nicely round out things via this additional support, so should you need to do things like @deprecated then it can help you fill out a template for those more advanced tags.

References

The following is a list of references I used when I was creating my workflow. Feel free to reference them if they help you at all.

0
Subscribe to my newsletter

Read articles from Grant Willcox directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Grant Willcox
Grant Willcox