« Groovy 1.6.3 Released | Main | On SSL Warnings and Text Link Ads »

05/24/2009

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.

#!/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

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a01156fbc6fe6970c011572288407970b

Listed below are links to weblogs that reference Ruby: IIS WebDAV Checker:

Comments