Ruby: IIS WebDAV Checker
Sometimes, the frustrating thing about being a systems administrator is that often one's attention gets distracted easily by current events. The IIS WebDAV vulnerability and exploit making the rounds recently made me wonder just how many sites that I am responsible for supporting are utilizing WebDAV. So, the latest batch of Tomcat Management articles will have to wait a little bit longer.
Administering a large number of sites, it actually isn't all that unusual to come across a site built by someone else that might not have the required controls in place that Disables WebDAV on an IIS server, so a discovery tool like this I thought might be useful to more folks than just myself.
So, during this long, rainy, first unofficial start of Summer weekend, I've written the following script that will scan a site and report back whether or not WebDAV is enabled on it. I've tested it on all platforms except for SharePoint Portal, and I'd appreciate it if anyone out there with access to a SharePoint portal server could run it and report back whether the script reports correctly. I'd also appreciate any feedback from readers who are more experienced with Ruby as to whether this script could be fixed or made better.
The script uses the logic from a recent Technet blog article regarding the most recent WebDAV vulnerability. It doesn't work with SSL encrypted sites yet.
Administering a large number of sites, it actually isn't all that unusual to come across a site built by someone else that might not have the required controls in place that Disables WebDAV on an IIS server, so a discovery tool like this I thought might be useful to more folks than just myself.
So, during this long, rainy, first unofficial start of Summer weekend, I've written the following script that will scan a site and report back whether or not WebDAV is enabled on it. I've tested it on all platforms except for SharePoint Portal, and I'd appreciate it if anyone out there with access to a SharePoint portal server could run it and report back whether the script reports correctly. I'd also appreciate any feedback from readers who are more experienced with Ruby as to whether this script could be fixed or made better.
The script uses the logic from a recent Technet blog article regarding the most recent WebDAV vulnerability. It doesn't work with SSL encrypted sites yet.
#!/usr/bin/env ruby
# Original Written by Chris @ Blogging Techstacks
# Updates by $Your_Name_Could_Go_Here!
# This script tests for the existence of an IIS server running WebDAV. It
# is based upon the following article:
# http://blogs.technet.com/srd/archive/2009/05/20/answers-to-the-iis-webdav-authentication-bypass-questions.aspx
#
# This script DOES NOT attempt any kind of exploit against WebDAV servers.
# All it does is test for the existence of WebDAV.
#
# Usage: ./iisWebDAVTest.rb <site> where <site> must use
# the following syntax: http://fully-qualifed-hostname/
# Trailing slash is required.
# Works with https as well!
require 'net/http'
# Text Colorization Class--not needed but looks fancy
class String
def red; colorize(self, "\e[1m\e[31m"); end
def green; colorize(self, "\e[1m\e[32m"); end
def dark_green; colorize(self, "\e[32m"); end
def yellow; colorize(self, "\e[1m\e[33m"); end
def blue; colorize(self, "\e[1m\e[34m"); end
def dark_blue; colorize(self, "\e[34m"); end
def purple; colorize(self, "\e[1m\e[35m"); end
def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
end
puts "\nEnter the URL for the site (example: http://www.some-site.com/)"
name = gets
url = URI.parse(name)
begin
req = Net::HTTP::Options.new(url.path)
resp = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
rescue Errno::ECONNRESET, Errno::ECONNABORTED
puts "Connection Dropped! - Site could be dropping OPTIONS requests."
exit
end
# Case statement - delivers response based on status code returned from site
statuscode = resp.code
result = case statuscode
when "200"
then
if resp.header['DAV'] == '1, 2' && resp.header['MS-Author-Via'] == 'DAV'
then
puts "Site has WebDAV enabled. Could be at risk. Get current on patches.".yellow
puts "Allowable Methods: " + resp.header['Allow']
elsif resp.header['DAV'] == '1,2' && resp.header['MS-Author-Via'] == 'DAV' && resp.header['X-MSDAVEXT'].exists
then
puts "Site uses Sharepoint's DAV".dark_green
puts "Allowable Methods: " + resp.header['Allow']
else
puts "Server is not running WebDAV"
puts "Allowable Methods: " + resp.header['Allow']
end
when "301"
then
puts "\nSite responded with a 301 - Permanent Redirect".yellow
puts "\nAn OPTIONS request to redirect target: "
puts resp.header['Location'].dark_green
puts "may not work and RFC 2616 states that an OPTIONS"
puts "request MUST NOT automatically follow a redirect."
puts
puts "Retry the request to: " + resp.header['Location'].dark_green
puts "but you might get no response or an error."
puts
when "302"
then
puts "\nSite responded with a 302 - Found".yellow
puts "\nAn OPTIONS request to redirect target: "
puts resp.header['Location'].dark_green
puts "may not work and RFC 2616 states that an OPTIONS"
puts "request MUST NOT automatically follow a redirect."
puts
puts "Retry the request to: " + resp.header['Location'].dark_green
puts "but you might get no response or an error."
puts
when "403"
then
puts "OPTIONS is disabled. 403 Forbidden".red
when "404"
then
puts "OPTIONS is probably disabled. 404 Not Found".red
when "405"
then
puts "OPTIONS is disabled. 405 Method Not Allowed Response".red
when "501"
then
puts "OPTIONS is disabled. 501 Not Implemented Response.".red
else
puts "Unexpected Response."
end