Skip to content

Commit 2c842ee

Browse files
committed
Fix namespaces on Server
1 parent 9b7bbc2 commit 2c842ee

File tree

1 file changed

+112
-117
lines changed

1 file changed

+112
-117
lines changed

lib/msf/core/exploit/smb/server.rb

Lines changed: 112 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,149 @@
11
# -*- coding: binary -*-
22

33
module Msf
4+
module Exploit::Remote::SMB
5+
# This mixin provides a minimal SMB server
6+
module Server
7+
include Msf::Exploit::Remote::TcpServer
8+
include Msf::Exploit::NTLM
9+
CONST = ::Rex::Proto::SMB::Constants
10+
CRYPT = ::Rex::Proto::SMB::Crypt
11+
UTILS = ::Rex::Proto::SMB::Utils
12+
XCEPT = ::Rex::Proto::SMB::Exceptions
13+
EVADE = ::Rex::Proto::SMB::Evasions
14+
15+
def initialize(info = {})
16+
super
17+
18+
deregister_options('SSL', 'SSLCert')
19+
register_options(
20+
[
21+
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 445 ])
22+
], self.class)
23+
end
424

5-
###
6-
#
7-
# This mixin provides a minimal SMB server
8-
#
9-
###
10-
11-
module Exploit::Remote::SMB::Server
12-
include Exploit::Remote::TcpServer
13-
include Exploit::NTLM
14-
CONST = ::Rex::Proto::SMB::Constants
15-
CRYPT = ::Rex::Proto::SMB::Crypt
16-
UTILS = ::Rex::Proto::SMB::Utils
17-
XCEPT = ::Rex::Proto::SMB::Exceptions
18-
EVADE = ::Rex::Proto::SMB::Evasions
19-
20-
def initialize(info = {})
21-
super
22-
23-
deregister_options('SSL', 'SSLCert')
24-
register_options(
25-
[
26-
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 445 ])
27-
], self.class)
28-
end
25+
def setup
26+
super
27+
@state = {}
28+
end
2929

30-
def setup
31-
super
32-
@state = {}
33-
end
30+
def on_client_connect(client)
31+
# print_status("New SMB connection from #{client.peerhost}:#{client.peerport}")
32+
smb_conn(client)
33+
end
3434

35-
def on_client_connect(client)
36-
# print_status("New SMB connection from #{client.peerhost}:#{client.peerport}")
37-
smb_conn(client)
38-
end
35+
def on_client_data(client)
36+
# print_status("New data from #{client.peerhost}:#{client.peerport}")
37+
smb_recv(client)
38+
true
39+
end
3940

40-
def on_client_data(client)
41-
# print_status("New data from #{client.peerhost}:#{client.peerport}")
42-
smb_recv(client)
43-
true
44-
end
41+
def on_client_close(client)
42+
smb_stop(client)
43+
end
4544

46-
def on_client_close(client)
47-
smb_stop(client)
48-
end
45+
def smb_conn(c)
46+
@state[c] = {:name => "#{c.peerhost}:#{c.peerport}", :ip => c.peerhost, :port => c.peerport}
47+
end
4948

50-
def smb_conn(c)
51-
@state[c] = {:name => "#{c.peerhost}:#{c.peerport}", :ip => c.peerhost, :port => c.peerport}
52-
end
49+
def smb_stop(c)
50+
@state.delete(c)
51+
end
5352

54-
def smb_stop(c)
55-
@state.delete(c)
56-
end
53+
def smb_recv(c)
54+
smb = @state[c]
55+
smb[:data] ||= ''
56+
smb[:data] << c.get_once
5757

58-
def smb_recv(c)
59-
smb = @state[c]
60-
smb[:data] ||= ''
61-
smb[:data] << c.get_once
58+
while(smb[:data].length > 0)
6259

63-
while(smb[:data].length > 0)
60+
return if smb[:data].length < 4
6461

65-
return if smb[:data].length < 4
62+
plen = smb[:data][2,2].unpack('n')[0]
6663

67-
plen = smb[:data][2,2].unpack('n')[0]
64+
return if smb[:data].length < plen+4
6865

69-
return if smb[:data].length < plen+4
66+
buff = smb[:data].slice!(0, plen+4)
7067

71-
buff = smb[:data].slice!(0, plen+4)
68+
pkt_nbs = CONST::NBRAW_PKT.make_struct
69+
pkt_nbs.from_s(buff)
7270

73-
pkt_nbs = CONST::NBRAW_PKT.make_struct
74-
pkt_nbs.from_s(buff)
71+
# print_status("NetBIOS request from #{smb[:name]} #{pkt_nbs.v['Type']} #{pkt_nbs.v['Flags']} #{buff.inspect}")
7572

76-
# print_status("NetBIOS request from #{smb[:name]} #{pkt_nbs.v['Type']} #{pkt_nbs.v['Flags']} #{buff.inspect}")
73+
# Check for a NetBIOS name request
74+
if (pkt_nbs.v['Type'] == 0x81)
75+
# Accept any name they happen to send
7776

78-
# Check for a NetBIOS name request
79-
if (pkt_nbs.v['Type'] == 0x81)
80-
# Accept any name they happen to send
77+
host_dst = UTILS.nbname_decode(pkt_nbs.v['Payload'][1,32]).gsub(/[\x00\x20]+$/n, '')
78+
host_src = UTILS.nbname_decode(pkt_nbs.v['Payload'][35,32]).gsub(/[\x00\x20]+$/n, '')
8179

82-
host_dst = UTILS.nbname_decode(pkt_nbs.v['Payload'][1,32]).gsub(/[\x00\x20]+$/n, '')
83-
host_src = UTILS.nbname_decode(pkt_nbs.v['Payload'][35,32]).gsub(/[\x00\x20]+$/n, '')
80+
smb[:nbdst] = host_dst
81+
smb[:nbsrc] = host_src
8482

85-
smb[:nbdst] = host_dst
86-
smb[:nbsrc] = host_src
83+
# print_status("NetBIOS session request from #{smb[:name]} (asking for #{host_dst} from #{host_src})")
84+
c.write("\x82\x00\x00\x00")
85+
next
86+
end
8787

88-
# print_status("NetBIOS session request from #{smb[:name]} (asking for #{host_dst} from #{host_src})")
89-
c.write("\x82\x00\x00\x00")
90-
next
91-
end
9288

89+
#
90+
# TODO: Support AndX parameters
91+
#
9392

94-
#
95-
# TODO: Support AndX parameters
96-
#
9793

94+
# Cast this to a generic SMB structure
95+
pkt = CONST::SMB_BASE_PKT.make_struct
96+
pkt.from_s(buff)
9897

99-
# Cast this to a generic SMB structure
100-
pkt = CONST::SMB_BASE_PKT.make_struct
101-
pkt.from_s(buff)
98+
# Only response to requests, ignore server replies
99+
if (pkt['Payload']['SMB'].v['Flags1'] & 128 != 0)
100+
print_status("Ignoring server response from #{smb[:name]}")
101+
next
102+
end
102103

103-
# Only response to requests, ignore server replies
104-
if (pkt['Payload']['SMB'].v['Flags1'] & 128 != 0)
105-
print_status("Ignoring server response from #{smb[:name]}")
106-
next
104+
cmd = pkt['Payload']['SMB'].v['Command']
105+
begin
106+
smb_cmd_dispatch(cmd, c, buff)
107+
rescue ::Interrupt
108+
raise $!
109+
rescue ::Exception => e
110+
print_status("Error processing request from #{smb[:name]} (#{cmd}): #{e.class} #{e} #{e.backtrace}")
111+
next
112+
end
113+
end
107114
end
108115

109-
cmd = pkt['Payload']['SMB'].v['Command']
110-
begin
111-
smb_cmd_dispatch(cmd, c, buff)
112-
rescue ::Interrupt
113-
raise $!
114-
rescue ::Exception => e
115-
print_status("Error processing request from #{smb[:name]} (#{cmd}): #{e.class} #{e} #{e.backtrace}")
116-
next
116+
def smb_cmd_dispatch(cmd, c, buff)
117+
smb = @state[c]
118+
print_status("Received command #{cmd} from #{smb[:name]}")
117119
end
118-
end
119-
end
120-
121-
def smb_cmd_dispatch(cmd, c, buff)
122-
smb = @state[c]
123-
print_status("Received command #{cmd} from #{smb[:name]}")
124-
end
125120

126-
def smb_set_defaults(c, pkt)
127-
smb = @state[c]
128-
pkt['Payload']['SMB'].v['ProcessID'] = smb[:process_id].to_i
129-
pkt['Payload']['SMB'].v['UserID'] = smb[:user_id].to_i
130-
pkt['Payload']['SMB'].v['TreeID'] = smb[:tree_id].to_i
131-
pkt['Payload']['SMB'].v['MultiplexID'] = smb[:multiplex_id].to_i
132-
end
121+
def smb_set_defaults(c, pkt)
122+
smb = @state[c]
123+
pkt['Payload']['SMB'].v['ProcessID'] = smb[:process_id].to_i
124+
pkt['Payload']['SMB'].v['UserID'] = smb[:user_id].to_i
125+
pkt['Payload']['SMB'].v['TreeID'] = smb[:tree_id].to_i
126+
pkt['Payload']['SMB'].v['MultiplexID'] = smb[:multiplex_id].to_i
127+
end
133128

134-
def smb_error(cmd, c, errorclass, esn = false)
135-
# 0xc0000022 = Deny
136-
# 0xc000006D = Logon_Failure
137-
# 0x00000000 = Ignore
138-
pkt = CONST::SMB_BASE_PKT.make_struct
139-
smb_set_defaults(c, pkt)
140-
pkt['Payload']['SMB'].v['Command'] = cmd
141-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
142-
if esn
143-
pkt['Payload']['SMB'].v['Flags2'] = 0xc801
144-
else
145-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
129+
def smb_error(cmd, c, errorclass, esn = false)
130+
# 0xc0000022 = Deny
131+
# 0xc000006D = Logon_Failure
132+
# 0x00000000 = Ignore
133+
pkt = CONST::SMB_BASE_PKT.make_struct
134+
smb_set_defaults(c, pkt)
135+
pkt['Payload']['SMB'].v['Command'] = cmd
136+
pkt['Payload']['SMB'].v['Flags1'] = 0x88
137+
if esn
138+
pkt['Payload']['SMB'].v['Flags2'] = 0xc801
139+
else
140+
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
141+
end
142+
pkt['Payload']['SMB'].v['ErrorClass'] = errorclass
143+
c.put(pkt.to_s)
144+
end
146145
end
147-
pkt['Payload']['SMB'].v['ErrorClass'] = errorclass
148-
c.put(pkt.to_s)
149146
end
150147

151148
end
152149

153-
end
154-

0 commit comments

Comments
 (0)