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

Enable using modules when deferred loading is turned on #18171

Merged
merged 3 commits into from Oct 6, 2023

Conversation

dwelch-r7
Copy link
Contributor

@dwelch-r7 dwelch-r7 commented Jul 6, 2023

Resolves #18198

Following on from #17901 which allowed for lazy loading of payloads, this PR will now allow users to use a payload when framework is started with the --defer-module-loads flag is set, previously this just wouldn't work at all giving this error

$ ./msfconsole -q --defer-module-loads                                                                        ‹ruby-3.0.5@metasploit-framework›
msf6 > use payload/windows/x64/meterpreter/reverse_tcp
[-] The supplied module name is ambiguous: undefined method `dependencies' for nil:NilClass.
msf6 >

This also adds a new feature flag option defer_module_loads which when enabled will defer module loads by default without need to specify the --defer-module-loads every time you boot framework

This also comes with a sizeable improvement on frameworks boot up time
Before: hyperfine --export-json /dev/stdout --warmup 3 "bundle exec ruby ./msfconsole --no-defer-module-loads -qx 'exit'"

Benchmark 2: bundle exec ruby ./msfconsole --no-defer-module-loads -qx 'exit'
  Time (mean ± σ):      9.001 s ±  0.467 s    [User: 7.219 s, System: 2.169 s]
  Range (min … max):    8.624 s … 10.271 s    10 runs

After: hyperfine --export-json /dev/stdout --warmup 3 "bundle exec ruby ./msfconsole --defer-module-loads -qx 'exit'"

Benchmark 1: bundle exec ruby ./msfconsole --defer-module-loads -qx 'exit'
  Time (mean ± σ):      3.462 s ±  0.144 s    [User: 2.209 s, System: 1.344 s]
  Range (min … max):    3.301 s …  3.633 s    10 runs

from ~9s to ~3.5s on my machine

Known Issues

  • Time taken to use an exploit can be increased if no payload is configured see example
msf6 > time use exploit/windows/smb/psexec
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
[+] Command "use exploit/windows/smb/psexec" completed in 1.263082000077702 seconds
msf6 > time use exploit/windows/smb/psexec
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
[+] Command "use exploit/windows/smb/psexec" completed in 4.395296000060625 seconds
  • show payloads takes noticeably longer on some modules, especially exploit/multi/handler as all payloads are compatible with it
msf6 exploit(multi/handler) > time show payloads
...
[+] Command "show payloads" completed in 5.081300999969244 seconds
msf6 exploit(multi/handler) > time show payloads
...
[+] Command "show payloads" completed in 4.849963999935426 seconds
msf6 exploit(multi/handler) > time show payloads
...
[+] Command "show payloads" completed in 12.359868000028655 seconds
msf6 exploit(multi/handler) > time show payloads
...
[+] Command "show payloads" completed in 4.319238999974914 seconds

Note that the increased delay only occurs the first time and this was the worst case scenario

Verification Steps

  • CI passes
  • Manually boot into msfconsole
  • Use and generate a variety of payloads
    • Singles payloads (e.g. payload/windows/x64/meterpreter/reverse_tcp)
    • Staged payloads (e.g. payload/windows/x64/meterpreter_reverse_tcp)
    • Adapted single payloads (e.g. payload/cmd/windows/http/x64/meterpreter_reverse_tcp`)
    • Adapted staged payloads (e.g. payload/cmd/windows/http/x64/meterpreter/reverse_tcp)
  • use exploit/multi/handler and then show payloads this will force all payloads to be created
  • Check that generating the same payloads via msfvenom also works
  • loadpath test/modules or any other path with modules, check all modules are available and working as intended
  • check any payloads added to ~/.msf4/modules/ work as expected
  • run time unknown_command and check it's roughy in line with master [+] Command "unknown_command" completed in 0.006908999988809228 seconds was my result on master your mileage may vary
  • Run through manual and automated testing for Metasploit Pro

@dwelch-r7 dwelch-r7 added the rn-enhancement release notes enhancement label Jul 6, 2023
Comment on lines -70 to -83
def num_payload_stages
framework.payloads.stages.length
end

#
# Returns the number of stagers in the framework.
#
def num_payload_stagers
framework.payloads.stagers.length
end

#
# Returns the number of singles in the framework.
#
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've removed these as they weren't being referenced anywhere and when I checked the values they had on master they were incorrect anyway

@dwelch-r7 dwelch-r7 force-pushed the defer-module-loads-by-default branch from 6b67ecd to ef87168 Compare October 6, 2023 15:05
@adfoster-r7 adfoster-r7 marked this pull request as ready for review October 6, 2023 16:37
@adfoster-r7 adfoster-r7 merged commit 93fb0dd into rapid7:master Oct 6, 2023
57 checks passed
@cdelafuente-r7
Copy link
Contributor

Release Notes

This fixes an issue when users use a payload when framework is started with the --defer-module-loads flag set. This also adds a new feature flag option defer_module_loads which, when enabled, will defer module loads by default without the need to specify--defer-module-loads every time the framework boot. Finally, this comes with a sizeable improvement on frameworks boot up time.

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

Successfully merging this pull request may close these issues.

Cannot start msfconsole after upgrade
3 participants