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

don't create a new socket every time the command prompt is displayed #11392

Merged
merged 3 commits into from
Feb 20, 2019

Conversation

busterb
Copy link
Member

@busterb busterb commented Feb 13, 2019

This probably fixes #11302 though it's not clear what the real root issue is there. @conniest noted that the console prompt randomly segfaults under Kali Linux with Ruby 2.5.3 and MSF5. The crash information shows that Metasploit is creating a new socket every time the command prompt is formatted on the hopes that the user included '%L' in the prompt format string and needs the local IP address displayed.

[-] Error while running command show: failed to allocate memory
/usr/lib/ruby/2.5.0/timeout.rb:97: [BUG] rb_register_sigaltstack: th->altstack not initialized

ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux-gnu]

-- Control frame information -----------------------------------------------
c:0020 p:---- s:0133 e:000132 CFUNC  :join
c:0019 p:0015 s:0129 e:000128 RESCUE /usr/lib/ruby/2.5.0/timeout.rb:97
c:0018 p:0048 s:0125 E:0013a8 BLOCK  /usr/lib/ruby/2.5.0/timeout.rb:97
c:0017 p:0005 s:0118 e:000117 BLOCK  /usr/lib/ruby/2.5.0/timeout.rb:33 [FINISH]
c:0016 p:---- s:0115 e:000114 CFUNC  :catch
c:0015 p:0044 s:0110 e:000109 METHOD /usr/lib/ruby/2.5.0/timeout.rb:33
c:0014 p:0113 s:0104 E:0009d0 METHOD /usr/lib/ruby/2.5.0/timeout.rb:108
c:0013 p:0879 s:0092 E:000020 METHOD /usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket/comm/local.rb:266
c:0012 p:0141 s:0076 e:000075 METHOD /usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket/comm/local.rb:35
c:0011 p:0010 s:0071 e:000070 METHOD /usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket.rb:49
c:0010 p:0033 s:0066 e:000065 METHOD /usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket.rb:70
c:0009 p:0040 s:0061 e:000060 METHOD /usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket.rb:599
c:0008 p:0269 s:0053 e:000050 METHOD /usr/share/metasploit-framework/lib/rex/ui/text/shell.rb:407
c:0007 p:0066 s:0042 e:000038 METHOD /usr/share/metasploit-framework/lib/rex/ui/text/shell.rb:198
c:0006 p:0124 s:0032 e:000031 METHOD /usr/share/metasploit-framework/lib/msf/ui/console/driver.rb:443
c:0005 p:0032 s:0025 e:000024 METHOD /usr/share/metasploit-framework/lib/rex/ui/text/shell.rb:132
c:0004 p:0049 s:0018 e:000017 METHOD /usr/share/metasploit-framework/lib/metasploit/framework/command/console.rb:48
c:0003 p:0025 s:0014 e:000013 METHOD /usr/share/metasploit-framework/lib/metasploit/framework/command/base.rb:82
c:0002 p:0184 s:0009 E:000db8 EVAL   /usr/bin/msfconsole:49 [FINISH]
c:0001 p:0000 s:0003 E:0003d0 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
/usr/bin/msfconsole:49:in `<main>'
/usr/share/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
/usr/share/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
/usr/share/metasploit-framework/lib/rex/ui/text/shell.rb:132:in `run'
/usr/share/metasploit-framework/lib/msf/ui/console/driver.rb:443:in `update_prompt'
/usr/share/metasploit-framework/lib/rex/ui/text/shell.rb:198:in `update_prompt'
/usr/share/metasploit-framework/lib/rex/ui/text/shell.rb:407:in `format_prompt'
/usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket.rb:599:in `source_address'
/usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket.rb:70:in `create_udp'
/usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket.rb:49:in `create_param'
/usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket/comm/local.rb:35:in `create'
/usr/share/metasploit-framework/vendor/bundle/ruby/2.5.0/gems/rex-socket-0.1.15/lib/rex/socket/comm/local.rb:266:in `create_by_type'
/usr/lib/ruby/2.5.0/timeout.rb:108:in `timeout'
/usr/lib/ruby/2.5.0/timeout.rb:33:in `catch'
/usr/lib/ruby/2.5.0/timeout.rb:33:in `catch'
/usr/lib/ruby/2.5.0/timeout.rb:33:in `block in catch'
/usr/lib/ruby/2.5.0/timeout.rb:97:in `block in timeout'
/usr/lib/ruby/2.5.0/timeout.rb:97:in `ensure in block in timeout'
/usr/lib/ruby/2.5.0/timeout.rb:97:in `join'

This PR avoids this expensive operation by first checking if the user actually used that format string, and then uses native Ruby methods for determining the local IP address rather than creating a Rex socket.

This does prevent Metasploit from actually connecting a UDP socket on IP 50.50.50.50 every time a prompt is displayed, which is a good thing independent of the bug reported above.

Verification

List the steps needed to make sure this thing works

  • Start msfconsole
  • Add %L to your local prompt:
msf5 auxiliary(scanner/snmp/snmp_login) > setg Prompt %L
Prompt => %L
192.168.86.31 auxiliary(scanner/snmp/snmp_login) >
  • Verify the local IP displays, and especially that your console does not crash
  • Check the other prompt expansion variables to ensure they work as well.

@bcoles bcoles added the bug label Feb 13, 2019
@bcoles
Copy link
Contributor

bcoles commented Feb 13, 2019

Adding bug label because leaking sockets is silly.

lib/rex/ui/text/shell.rb Outdated Show resolved Hide resolved
@busterb
Copy link
Member Author

busterb commented Feb 13, 2019

See rapid7/rex-socket#15 and other comments addressed as well.

@busterb busterb self-assigned this Feb 20, 2019
@busterb
Copy link
Member Author

busterb commented Feb 20, 2019

All comments addressed, landing.

@busterb busterb merged commit 1b4a0e1 into rapid7:master Feb 20, 2019
@busterb
Copy link
Member Author

busterb commented Feb 20, 2019

Release Notes

This optimizes the msfconsole shell prompt to not compute every expansion character content if they are not used. Namely, it avoids computing '%L', which appears to be fairly expensive and possibly leads to crashes in some circumstances.

@gdavidson-r7 gdavidson-r7 added the rn-fix release notes fix label Mar 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants