Fix namespaces on Server
parent
9b7bbc220b
commit
2c842ee6d7
|
@ -1,154 +1,149 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Msf
|
||||
module Exploit::Remote::SMB
|
||||
# This mixin provides a minimal SMB server
|
||||
module Server
|
||||
include Msf::Exploit::Remote::TcpServer
|
||||
include Msf::Exploit::NTLM
|
||||
CONST = ::Rex::Proto::SMB::Constants
|
||||
CRYPT = ::Rex::Proto::SMB::Crypt
|
||||
UTILS = ::Rex::Proto::SMB::Utils
|
||||
XCEPT = ::Rex::Proto::SMB::Exceptions
|
||||
EVADE = ::Rex::Proto::SMB::Evasions
|
||||
|
||||
###
|
||||
#
|
||||
# This mixin provides a minimal SMB server
|
||||
#
|
||||
###
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
||||
module Exploit::Remote::SMB::Server
|
||||
include Exploit::Remote::TcpServer
|
||||
include Exploit::NTLM
|
||||
CONST = ::Rex::Proto::SMB::Constants
|
||||
CRYPT = ::Rex::Proto::SMB::Crypt
|
||||
UTILS = ::Rex::Proto::SMB::Utils
|
||||
XCEPT = ::Rex::Proto::SMB::Exceptions
|
||||
EVADE = ::Rex::Proto::SMB::Evasions
|
||||
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
||||
deregister_options('SSL', 'SSLCert')
|
||||
register_options(
|
||||
[
|
||||
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 445 ])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def setup
|
||||
super
|
||||
@state = {}
|
||||
end
|
||||
|
||||
def on_client_connect(client)
|
||||
# print_status("New SMB connection from #{client.peerhost}:#{client.peerport}")
|
||||
smb_conn(client)
|
||||
end
|
||||
|
||||
def on_client_data(client)
|
||||
# print_status("New data from #{client.peerhost}:#{client.peerport}")
|
||||
smb_recv(client)
|
||||
true
|
||||
end
|
||||
|
||||
def on_client_close(client)
|
||||
smb_stop(client)
|
||||
end
|
||||
|
||||
def smb_conn(c)
|
||||
@state[c] = {:name => "#{c.peerhost}:#{c.peerport}", :ip => c.peerhost, :port => c.peerport}
|
||||
end
|
||||
|
||||
def smb_stop(c)
|
||||
@state.delete(c)
|
||||
end
|
||||
|
||||
def smb_recv(c)
|
||||
smb = @state[c]
|
||||
smb[:data] ||= ''
|
||||
smb[:data] << c.get_once
|
||||
|
||||
while(smb[:data].length > 0)
|
||||
|
||||
return if smb[:data].length < 4
|
||||
|
||||
plen = smb[:data][2,2].unpack('n')[0]
|
||||
|
||||
return if smb[:data].length < plen+4
|
||||
|
||||
buff = smb[:data].slice!(0, plen+4)
|
||||
|
||||
pkt_nbs = CONST::NBRAW_PKT.make_struct
|
||||
pkt_nbs.from_s(buff)
|
||||
|
||||
# print_status("NetBIOS request from #{smb[:name]} #{pkt_nbs.v['Type']} #{pkt_nbs.v['Flags']} #{buff.inspect}")
|
||||
|
||||
# Check for a NetBIOS name request
|
||||
if (pkt_nbs.v['Type'] == 0x81)
|
||||
# Accept any name they happen to send
|
||||
|
||||
host_dst = UTILS.nbname_decode(pkt_nbs.v['Payload'][1,32]).gsub(/[\x00\x20]+$/n, '')
|
||||
host_src = UTILS.nbname_decode(pkt_nbs.v['Payload'][35,32]).gsub(/[\x00\x20]+$/n, '')
|
||||
|
||||
smb[:nbdst] = host_dst
|
||||
smb[:nbsrc] = host_src
|
||||
|
||||
# print_status("NetBIOS session request from #{smb[:name]} (asking for #{host_dst} from #{host_src})")
|
||||
c.write("\x82\x00\x00\x00")
|
||||
next
|
||||
deregister_options('SSL', 'SSLCert')
|
||||
register_options(
|
||||
[
|
||||
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 445 ])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# TODO: Support AndX parameters
|
||||
#
|
||||
|
||||
|
||||
# Cast this to a generic SMB structure
|
||||
pkt = CONST::SMB_BASE_PKT.make_struct
|
||||
pkt.from_s(buff)
|
||||
|
||||
# Only response to requests, ignore server replies
|
||||
if (pkt['Payload']['SMB'].v['Flags1'] & 128 != 0)
|
||||
print_status("Ignoring server response from #{smb[:name]}")
|
||||
next
|
||||
def setup
|
||||
super
|
||||
@state = {}
|
||||
end
|
||||
|
||||
cmd = pkt['Payload']['SMB'].v['Command']
|
||||
begin
|
||||
smb_cmd_dispatch(cmd, c, buff)
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Exception => e
|
||||
print_status("Error processing request from #{smb[:name]} (#{cmd}): #{e.class} #{e} #{e.backtrace}")
|
||||
next
|
||||
def on_client_connect(client)
|
||||
# print_status("New SMB connection from #{client.peerhost}:#{client.peerport}")
|
||||
smb_conn(client)
|
||||
end
|
||||
|
||||
def on_client_data(client)
|
||||
# print_status("New data from #{client.peerhost}:#{client.peerport}")
|
||||
smb_recv(client)
|
||||
true
|
||||
end
|
||||
|
||||
def on_client_close(client)
|
||||
smb_stop(client)
|
||||
end
|
||||
|
||||
def smb_conn(c)
|
||||
@state[c] = {:name => "#{c.peerhost}:#{c.peerport}", :ip => c.peerhost, :port => c.peerport}
|
||||
end
|
||||
|
||||
def smb_stop(c)
|
||||
@state.delete(c)
|
||||
end
|
||||
|
||||
def smb_recv(c)
|
||||
smb = @state[c]
|
||||
smb[:data] ||= ''
|
||||
smb[:data] << c.get_once
|
||||
|
||||
while(smb[:data].length > 0)
|
||||
|
||||
return if smb[:data].length < 4
|
||||
|
||||
plen = smb[:data][2,2].unpack('n')[0]
|
||||
|
||||
return if smb[:data].length < plen+4
|
||||
|
||||
buff = smb[:data].slice!(0, plen+4)
|
||||
|
||||
pkt_nbs = CONST::NBRAW_PKT.make_struct
|
||||
pkt_nbs.from_s(buff)
|
||||
|
||||
# print_status("NetBIOS request from #{smb[:name]} #{pkt_nbs.v['Type']} #{pkt_nbs.v['Flags']} #{buff.inspect}")
|
||||
|
||||
# Check for a NetBIOS name request
|
||||
if (pkt_nbs.v['Type'] == 0x81)
|
||||
# Accept any name they happen to send
|
||||
|
||||
host_dst = UTILS.nbname_decode(pkt_nbs.v['Payload'][1,32]).gsub(/[\x00\x20]+$/n, '')
|
||||
host_src = UTILS.nbname_decode(pkt_nbs.v['Payload'][35,32]).gsub(/[\x00\x20]+$/n, '')
|
||||
|
||||
smb[:nbdst] = host_dst
|
||||
smb[:nbsrc] = host_src
|
||||
|
||||
# print_status("NetBIOS session request from #{smb[:name]} (asking for #{host_dst} from #{host_src})")
|
||||
c.write("\x82\x00\x00\x00")
|
||||
next
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# TODO: Support AndX parameters
|
||||
#
|
||||
|
||||
|
||||
# Cast this to a generic SMB structure
|
||||
pkt = CONST::SMB_BASE_PKT.make_struct
|
||||
pkt.from_s(buff)
|
||||
|
||||
# Only response to requests, ignore server replies
|
||||
if (pkt['Payload']['SMB'].v['Flags1'] & 128 != 0)
|
||||
print_status("Ignoring server response from #{smb[:name]}")
|
||||
next
|
||||
end
|
||||
|
||||
cmd = pkt['Payload']['SMB'].v['Command']
|
||||
begin
|
||||
smb_cmd_dispatch(cmd, c, buff)
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Exception => e
|
||||
print_status("Error processing request from #{smb[:name]} (#{cmd}): #{e.class} #{e} #{e.backtrace}")
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def smb_cmd_dispatch(cmd, c, buff)
|
||||
smb = @state[c]
|
||||
print_status("Received command #{cmd} from #{smb[:name]}")
|
||||
end
|
||||
|
||||
def smb_set_defaults(c, pkt)
|
||||
smb = @state[c]
|
||||
pkt['Payload']['SMB'].v['ProcessID'] = smb[:process_id].to_i
|
||||
pkt['Payload']['SMB'].v['UserID'] = smb[:user_id].to_i
|
||||
pkt['Payload']['SMB'].v['TreeID'] = smb[:tree_id].to_i
|
||||
pkt['Payload']['SMB'].v['MultiplexID'] = smb[:multiplex_id].to_i
|
||||
end
|
||||
|
||||
def smb_error(cmd, c, errorclass, esn = false)
|
||||
# 0xc0000022 = Deny
|
||||
# 0xc000006D = Logon_Failure
|
||||
# 0x00000000 = Ignore
|
||||
pkt = CONST::SMB_BASE_PKT.make_struct
|
||||
smb_set_defaults(c, pkt)
|
||||
pkt['Payload']['SMB'].v['Command'] = cmd
|
||||
pkt['Payload']['SMB'].v['Flags1'] = 0x88
|
||||
if esn
|
||||
pkt['Payload']['SMB'].v['Flags2'] = 0xc801
|
||||
else
|
||||
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
|
||||
end
|
||||
pkt['Payload']['SMB'].v['ErrorClass'] = errorclass
|
||||
c.put(pkt.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def smb_cmd_dispatch(cmd, c, buff)
|
||||
smb = @state[c]
|
||||
print_status("Received command #{cmd} from #{smb[:name]}")
|
||||
end
|
||||
|
||||
def smb_set_defaults(c, pkt)
|
||||
smb = @state[c]
|
||||
pkt['Payload']['SMB'].v['ProcessID'] = smb[:process_id].to_i
|
||||
pkt['Payload']['SMB'].v['UserID'] = smb[:user_id].to_i
|
||||
pkt['Payload']['SMB'].v['TreeID'] = smb[:tree_id].to_i
|
||||
pkt['Payload']['SMB'].v['MultiplexID'] = smb[:multiplex_id].to_i
|
||||
end
|
||||
|
||||
def smb_error(cmd, c, errorclass, esn = false)
|
||||
# 0xc0000022 = Deny
|
||||
# 0xc000006D = Logon_Failure
|
||||
# 0x00000000 = Ignore
|
||||
pkt = CONST::SMB_BASE_PKT.make_struct
|
||||
smb_set_defaults(c, pkt)
|
||||
pkt['Payload']['SMB'].v['Command'] = cmd
|
||||
pkt['Payload']['SMB'].v['Flags1'] = 0x88
|
||||
if esn
|
||||
pkt['Payload']['SMB'].v['Flags2'] = 0xc801
|
||||
else
|
||||
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
|
||||
end
|
||||
pkt['Payload']['SMB'].v['ErrorClass'] = errorclass
|
||||
c.put(pkt.to_s)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue