rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
34.06k stars 13.95k forks source link

Is it possible to use truffleruby to run msf? #15019

Closed acodervic closed 3 years ago

bcoles commented 3 years ago

I doubt anyone knows the answer for sure.

Only one way to find out ...

acodervic commented 3 years ago

我怀疑有人肯定知道答案。

只有一种方法可以找出...

what?

bcoles commented 3 years ago

我怀疑有人肯定知道答案。 只有一种方法可以找出...

what?

没人知道

adfoster-r7 commented 3 years ago

It is not currently possible to use truffleruby with metasploit. The console does not load successfully even after a few tweaks to get it working:

bundle exec ruby ./msfconsole
<internal:core> core/string.rb:456:in `encode!': "\xE2\x80\xA8" to ASCII-8BIT in conversion from UTF-8 to ASCII-8BIT (Encoding::UndefinedConversionError)
    from /Users/user/.rvm/gems/truffleruby-20.3.0/gems/actionview-5.2.5/lib/action_view/helpers/javascript_helper.rb:20:in `<module:JavaScriptHelper>'
...
    from /Users/user/.rvm/gems/truffleruby-20.3.0/gems/railties-5.2.5/lib/rails/application.rb:361:in `initialize!'
    from /Users/user/.rvm/gems/truffleruby-20.3.0/gems/railties-5.2.5/lib/rails/railtie.rb:190:in `method_missing'
    from /Users/user/Documents/code/metasploit-framework/config/environment.rb:4:in `<top (required)>'
    from <internal:core> core/kernel.rb:234:in `gem_original_require'
    from /Users/user/Documents/code/metasploit-framework/lib/msfenv.rb:17:in `<top (required)>'
    from <internal:core> core/kernel.rb:234:in `gem_original_require'
    from ./msfconsole:18:in `<main>'

I didn't look further into this as TruffleRuby doesn't support Ruby fully yet:

TruffleRuby is not 100% compatible with MRI 2.7 yet. Please report any compatibility issues you might find. TruffleRuby passes around 97% of ruby/spec


To test this locally I had to:

rvm install truffleruby

Additionally unpin concurrent ruby to a newer version:

  # Pinned as a dependency of i18n to the last working version
  spec.add_runtime_dependency 'concurrent-ruby','1.0.5'
  spec.add_runtime_dependency 'concurrent-ruby'

Run bundle update concurrent-ruby

Start msfconsole and see the error:

<internal:core> core/string.rb:456:in `encode!': "\xE2\x80\xA8" to ASCII-8BIT in conversion from UTF-8 to ASCII-8BIT (Encoding::UndefinedConversionError)
adfoster-r7 commented 3 years ago

After manually commenting out the two lines that break within the Rails 5 dependency actionview-5.2.5/lib/action_view/helpers/javascript_helper.rb:20:

19 #JS_ESCAPE_MAP["\342\200\250".dup.force_encoding(Encoding::UTF_8).encode!] = "
" 20 #JS_ESCAPE_MAP["\342\200\251".dup.force_encoding(Encoding::UTF_8).encode!] = "
"

Then msfconsole is able to boot with truffle ruby and run a simple module:

msf6 auxiliary(scanner/smb/smb_client) > use scan http title

Matching Modules
================

   #  Name                          Disclosure Date  Rank    Check  Description
   -  ----                          ---------------  ----    -----  -----------
   0  auxiliary/scanner/http/title                   normal  No     HTTP HTML Title Tag Content Grabber

Interact with a module by name or index. For example info 0, use 0 or use auxiliary/scanner/http/title

[*] Using auxiliary/scanner/http/title
msf6 auxiliary(scanner/http/title) > set rhosts example.com
rhosts => example.com
msf6 auxiliary(scanner/http/title) > run

[+] [2606:2800:220:1:248:1893:25c8:1946:80] [C:200] [R:] [S:ECS (nyb/1D07)] Example Domain
[*] Scanned 1 of 2 hosts (50% complete)
[+] [93.184.216.34:80] [C:200] [R:] [S:ECS (nyb/1D2F)] Example Domain
[*] Scanned 2 of 2 hosts (100% complete)
[*] Auxiliary module execution completed

msf6 auxiliary(scanner/http/title) > db_status
[*] Connected to remote_data_service: (https://localhost:5443). Connection type: http. Connection name: local-https-data-service.

msf6 auxiliary(scanner/http/title) > irb
[*] Starting IRB shell...
[*] You are in auxiliary/scanner/http/title

>> RUBY_DESCRIPTION
=> "truffleruby 20.3.0, like ruby 2.6.6, GraalVM CE Native [x86_64-darwin]"
>> exit

There's also a considerable time difference between Ruby MRI 2.7 and truffleruby when starting msfconsole:

$ rvm use 2.7
Using /Users/user/.rvm/gems/ruby-2.7.2
$ time bundle exec ./msfconsole -qx 'exit'
bundle exec ./msfconsole -qx 'exit'  4.42s user 2.66s system 85% cpu 8.323 total

Versus truffleruby:

$ rvm use truffleruby
Using /Users/user/.rvm/gems/truffleruby-20.3.0
$ time bundle exec ./msfconsole -qx 'exit'
bundle exec ./msfconsole -qx 'exit'  377.00s user 21.13s system 404% cpu 1:38.37 total

This aligns with the notes in the readme:

TruffleRuby might not be fast yet on Rails applications and large programs. Notably, large programs currently take a long time to warmup on TruffleRuby and this is something the TruffleRuby team is currently working on. Large programs often involve more performance-critical code so there is a higher chance of hitting an area of TruffleRuby which has not been optimized yet.

I'd say until we're on Rails 6 and truffleruby has 100% test coverage and has more performance tweaks, we're not in a position to support truffleruby officially.

adfoster-r7 commented 3 years ago

I think we could revisit this question again in the future when truffle ruby is more performant, but I'll close this issue for now - thanks! 👍

acodervic commented 3 years ago

I think we could revisit this question again in the future when truffle ruby is more performant, but I'll close this issue for now - thanks!

good job! thanks for you!

adfoster-r7 commented 2 years ago

Still slow:

rvm install truffleruby-head

Unlocking concurrent ruby and running bundle update concurrent-ruby

diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec
index d34e147e6b..aeee0c1125 100644
--- a/metasploit-framework.gemspec
+++ b/metasploit-framework.gemspec
@@ -206,7 +206,7 @@ Gem::Specification.new do |spec|
   # Needed for ::Msf...CertProvider
   spec.add_runtime_dependency 'faker'
   # Pinned as a dependency of i18n to the last working version
-  spec.add_runtime_dependency 'concurrent-ruby','1.0.5'
+  spec.add_runtime_dependency 'concurrent-ruby' #,'1.0.5'
   # SSH server library with ed25519
   spec.add_runtime_dependency 'hrr_rb_ssh-ed25519'
   # Needed for irb internal command

Patching actionview - vim /Users/user/.rvm/gems/truffleruby-head/gems/actionview-6.1.6/lib/action_view/helpers/javascript_helper.rb

-        JS_ESCAPE_MAP[(+"\342\200\250").force_encoding(Encoding::UTF_8).encode!] = "&#x2028;"
-        JS_ESCAPE_MAP[(+"\342\200\251").force_encoding(Encoding::UTF_8).encode!] = "&#x2029;"
+        #JS_ESCAPE_MAP[(+"\342\200\250").force_encoding(Encoding::UTF_8).encode!] = "&#x2028;"
+        #JS_ESCAPE_MAP[(+"\342\200\251").force_encoding(Encoding::UTF_8).encode!] = "&#x2029;"

Which avoids the following exception:

/Users/user/Documents/code/metasploit-framework/lib/msf/core/payload/python/meterpreter_loader.rb:145: warning: named capture conflicts a local variable - offset_string
<internal:core> core/string.rb:368:in `encode!': "\xE2\x80\xA8" to ASCII-8BIT in conversion from UTF-8 to ASCII-8BIT (Encoding::UndefinedConversionError)
    from /Users/adfoster/.rvm/gems/truffleruby-head/gems/actionview-6.1.6/lib/action_view/helpers/javascript_helper.rb:20:in `<module:JavaScriptHelper>'
    from /Users/adfoster/.rvm/gems/truffleruby-head/gems/actionview-6.1.6/lib/action_view/helpers/javascript_helper.rb:7:in `<module:Helpers>'
    from /Users/adfoster/.rvm/gems/truffleruby-head/gems/actionview-6.1.6/lib/action_view/helpers/javascript_helper.rb:6:in `<module:ActionView>'
    from /Users/adfoster/.rvm/gems/truffleruby-head/gems/actionview-6.1.6/lib/action_view/helpers/javascript_helper.rb:5:in `<top (required)>'

Which I believe is caused by our forced ascii encoding patch: https://github.com/rapid7/metasploit-framework/blob/0b5a2ffecfc4a5b413cbf45fca9c53278e3359f2/lib/metasploit/framework/common_engine.rb#L25-L33

As encode! uses the default internal encoding


After those patches - it still takes 1 minute 40 in comparison to MRI which takes 18 on mac osx

$ time bundle exec ruby ./msfconsole -qx "irb -e 'puts RUBY_DESCRIPTION'; exit"
/Users/user/Documents/code/metasploit-framework/lib/msf/core/payload/python/meterpreter_loader.rb:145: warning: named capture conflicts a local variable - offset_string
truffleruby 22.3.0-dev-fee6dd99, like ruby 3.0.3, GraalVM CE Native [x86_64-darwin]

274.56s user 15.65s system 299% cpu 1:36.99 total