intrigue-ident 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +29 -0
- data/ident.rb +269 -0
- data/intrigue-ident.gemspec +22 -0
- data/lib/check_factory.rb +22 -0
- data/lib/checks/akamai.rb +22 -0
- data/lib/checks/amazon.rb +26 -0
- data/lib/checks/aruba.rb +21 -0
- data/lib/checks/asp_net.rb +68 -0
- data/lib/checks/atlassian.rb +55 -0
- data/lib/checks/base.rb +13 -0
- data/lib/checks/chef.rb +31 -0
- data/lib/checks/cisco.rb +33 -0
- data/lib/checks/citrix.rb +24 -0
- data/lib/checks/cloudflare.rb +59 -0
- data/lib/checks/cloudfront.rb +41 -0
- data/lib/checks/cpanel.rb +23 -0
- data/lib/checks/django.rb +22 -0
- data/lib/checks/drupal.rb +26 -0
- data/lib/checks/f5.rb +24 -0
- data/lib/checks/fastly.rb +22 -0
- data/lib/checks/generic.rb +23 -0
- data/lib/checks/gitlab.rb +22 -0
- data/lib/checks/google.rb +23 -0
- data/lib/checks/grafana.rb +22 -0
- data/lib/checks/jenkins.rb +40 -0
- data/lib/checks/joomla.rb +23 -0
- data/lib/checks/limesuvey.rb +22 -0
- data/lib/checks/lithium.rb +30 -0
- data/lib/checks/magento.rb +22 -0
- data/lib/checks/mcafee.rb +22 -0
- data/lib/checks/mediawiki.rb +38 -0
- data/lib/checks/microsoft.rb +69 -0
- data/lib/checks/nagios.rb +22 -0
- data/lib/checks/oracle.rb +38 -0
- data/lib/checks/palo_alto.rb +23 -0
- data/lib/checks/pardot.rb +22 -0
- data/lib/checks/pfsense.rb +25 -0
- data/lib/checks/phpmyadmin.rb +22 -0
- data/lib/checks/rabbitmq.rb +29 -0
- data/lib/checks/spring.rb +31 -0
- data/lib/checks/team_city.rb +22 -0
- data/lib/checks/telerik.rb +25 -0
- data/lib/checks/tomcat.rb +22 -0
- data/lib/checks/varnish.rb +27 -0
- data/lib/checks/wordpress.rb +120 -0
- data/lib/checks/wp_engine.rb +22 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b379c724034923eb05671859aaaaa17ad8ee2be348bdf4c272c428c16121d3fb
|
4
|
+
data.tar.gz: 138245f1078a14b88fa1651fbd61fa8be202c7bc92fe13a9cae90abf91934415
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e7330591c145a0357ca6ded382d1407bff366fab69146f1cf73b8f1cb9aab1e8fca6c3798c7d462753405870def4d115f524f11a0cf022b4ee57eb82898d7c3a
|
7
|
+
data.tar.gz: 55d7000e202d10a0fb7ce64d34f12163ef73d4caf244ddab04c5d1add173e1db3caba6b5e3ada16bc9b875e74dfc096c0485e53bf60184ca11574f0f75bcf9f5
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.3)
|
5
|
+
rspec (3.7.0)
|
6
|
+
rspec-core (~> 3.7.0)
|
7
|
+
rspec-expectations (~> 3.7.0)
|
8
|
+
rspec-mocks (~> 3.7.0)
|
9
|
+
rspec-core (3.7.1)
|
10
|
+
rspec-support (~> 3.7.0)
|
11
|
+
rspec-expectations (3.7.0)
|
12
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
13
|
+
rspec-support (~> 3.7.0)
|
14
|
+
rspec-mocks (3.7.0)
|
15
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
16
|
+
rspec-support (~> 3.7.0)
|
17
|
+
rspec-support (3.7.1)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
rspec
|
24
|
+
|
25
|
+
RUBY VERSION
|
26
|
+
ruby 2.5.1p57
|
27
|
+
|
28
|
+
BUNDLED WITH
|
29
|
+
1.16.1
|
data/ident.rb
ADDED
@@ -0,0 +1,269 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'net/http'
|
3
|
+
require 'openssl'
|
4
|
+
require 'zlib'
|
5
|
+
|
6
|
+
require_relative 'lib/check_factory'
|
7
|
+
require_relative 'lib/checks/base'
|
8
|
+
check_folder = File.expand_path('lib/checks', File.dirname(__FILE__)) # get absolute directory
|
9
|
+
Dir["#{check_folder}/*.rb"].each { |file| require_relative file }
|
10
|
+
|
11
|
+
module Intrigue
|
12
|
+
module Ident
|
13
|
+
|
14
|
+
VERSION=0.1
|
15
|
+
|
16
|
+
def generate_requests_and_check(url)
|
17
|
+
|
18
|
+
results = []
|
19
|
+
|
20
|
+
# gather all fingeprints for each product
|
21
|
+
# this will look like an array of checks, each with a uri and a SET of checks
|
22
|
+
generated_checks = Intrigue::Ident::CheckFactory.all.map{|x| x.new.generate_checks(url) }.flatten
|
23
|
+
|
24
|
+
# group by the uris, with the associated checks
|
25
|
+
# TODO - this only currently supports the first path of the group!!!!
|
26
|
+
grouped_generated_checks = generated_checks.group_by{|x| x[:paths].first }
|
27
|
+
|
28
|
+
# call the check on each uri
|
29
|
+
grouped_generated_checks.each do |ggc|
|
30
|
+
|
31
|
+
target_url = ggc.first
|
32
|
+
|
33
|
+
# get the response
|
34
|
+
response = _http_request :get, "#{target_url}"
|
35
|
+
|
36
|
+
unless response
|
37
|
+
puts "Unable to get a response at: #{target_url}, failing"
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# Go ahead and match it up if we got a response!
|
42
|
+
if response
|
43
|
+
# call each check, collecting the product if it's a match
|
44
|
+
ggc.last.each do |check|
|
45
|
+
results << _check_response(check, response)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Return all matches, minus the nils (non-matches)
|
51
|
+
results.compact
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# this method takes a check and returns a ~match object if it matches, otherwise
|
57
|
+
# returns nil.
|
58
|
+
def _check_response(check, response)
|
59
|
+
|
60
|
+
# if type "content", do the content check
|
61
|
+
if check[:type] == :content_body
|
62
|
+
match = {
|
63
|
+
:version => (check[:dynamic_version].call(response) if check[:dynamic_version]) || check[:version],
|
64
|
+
:name => check[:name],
|
65
|
+
:match => check[:type],
|
66
|
+
:hide => check[:hide]
|
67
|
+
} if "#{response.body}" =~ check[:content]
|
68
|
+
|
69
|
+
elsif check[:type] == :content_headers
|
70
|
+
|
71
|
+
# construct the headers into a big string block
|
72
|
+
header_string = ""
|
73
|
+
response.each_header do |h,v|
|
74
|
+
header_string << "#{h}: #{v}\n"
|
75
|
+
end
|
76
|
+
|
77
|
+
match = {
|
78
|
+
:version => (check[:dynamic_version].call(response) if check[:dynamic_version]) || check[:version],
|
79
|
+
:name => check[:name],
|
80
|
+
:match => check[:type],
|
81
|
+
:hide => check[:hide]
|
82
|
+
} if header_string =~ check[:content]
|
83
|
+
|
84
|
+
elsif check[:type] == :content_cookies
|
85
|
+
# Check only the set-cookie header
|
86
|
+
match = {
|
87
|
+
:version => (check[:dynamic_version].call(response) if check[:dynamic_version]) || check[:version],
|
88
|
+
:name => check[:name],
|
89
|
+
:match => check[:type],
|
90
|
+
:hide => check[:hide]
|
91
|
+
} if response.header['set-cookie'] =~ check[:content]
|
92
|
+
|
93
|
+
elsif check[:type] == :checksum_body
|
94
|
+
match = {
|
95
|
+
:version => (check[:dynamic_version].call(response) if check[:dynamic_version]) || check[:version],
|
96
|
+
:name => check[:name],
|
97
|
+
:match => check[:type],
|
98
|
+
:hide => check[:hide]
|
99
|
+
} if Digest::MD5.hexdigest("#{response.body}") == check[:checksum]
|
100
|
+
end
|
101
|
+
match
|
102
|
+
end
|
103
|
+
|
104
|
+
def _http_request(method, uri_string, credentials=nil, headers={}, data=nil, limit = 10, open_timeout=15, read_timeout=15)
|
105
|
+
|
106
|
+
response = nil
|
107
|
+
begin
|
108
|
+
|
109
|
+
# set user agent
|
110
|
+
headers["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"
|
111
|
+
|
112
|
+
attempts=0
|
113
|
+
max_attempts=10
|
114
|
+
found = false
|
115
|
+
|
116
|
+
uri = URI.parse uri_string
|
117
|
+
|
118
|
+
unless uri
|
119
|
+
_log error "Unable to parse URI from: #{uri_string}"
|
120
|
+
return
|
121
|
+
end
|
122
|
+
|
123
|
+
until( found || attempts >= max_attempts)
|
124
|
+
#puts "Getting #{uri}, attempt #{attempts}"
|
125
|
+
attempts+=1
|
126
|
+
|
127
|
+
# proxy configuration, disabled for now
|
128
|
+
#if $config["http_proxy"]
|
129
|
+
# proxy_addr = $config["http_proxy"]["host"]
|
130
|
+
# proxy_port = $config["http_proxy"]["port"]
|
131
|
+
# proxy_user = $config["http_proxy"]["user"]
|
132
|
+
# proxy_pass = $config["http_proxy"]["pass"]
|
133
|
+
#end
|
134
|
+
proxy_addr = nil
|
135
|
+
proxy_port = nil
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
# set options
|
140
|
+
opts = {}
|
141
|
+
if uri.instance_of? URI::HTTPS
|
142
|
+
opts[:use_ssl] = true
|
143
|
+
opts[:verify_mode] = OpenSSL::SSL::VERIFY_NONE
|
144
|
+
end
|
145
|
+
|
146
|
+
http = Net::HTTP.start(uri.host, uri.port, proxy_addr, proxy_port, opts)
|
147
|
+
#http.set_debug_output($stdout) if _get_system_config "debug"
|
148
|
+
http.read_timeout = 20
|
149
|
+
http.open_timeout = 20
|
150
|
+
|
151
|
+
path = "#{uri.path}"
|
152
|
+
path = "/" if path==""
|
153
|
+
|
154
|
+
# add in the query parameters
|
155
|
+
if uri.query
|
156
|
+
path += "?#{uri.query}"
|
157
|
+
end
|
158
|
+
|
159
|
+
### ALLOW DIFFERENT VERBS HERE
|
160
|
+
if method == :get
|
161
|
+
request = Net::HTTP::Get.new(uri)
|
162
|
+
elsif method == :post
|
163
|
+
# see: https://coderwall.com/p/c-mu-a/http-posts-in-ruby
|
164
|
+
request = Net::HTTP::Post.new(uri)
|
165
|
+
request.body = data
|
166
|
+
elsif method == :head
|
167
|
+
request = Net::HTTP::Head.new(uri)
|
168
|
+
elsif method == :propfind
|
169
|
+
request = Net::HTTP::Propfind.new(uri.request_uri)
|
170
|
+
request.body = "Here's the body." # Set your body (data)
|
171
|
+
request["Depth"] = "1" # Set your headers: one header per line.
|
172
|
+
elsif method == :options
|
173
|
+
request = Net::HTTP::Options.new(uri.request_uri)
|
174
|
+
elsif method == :trace
|
175
|
+
request = Net::HTTP::Trace.new(uri.request_uri)
|
176
|
+
request.body = "intrigue"
|
177
|
+
end
|
178
|
+
### END VERBS
|
179
|
+
|
180
|
+
# set the headers
|
181
|
+
headers.each do |k,v|
|
182
|
+
request[k] = v
|
183
|
+
end
|
184
|
+
|
185
|
+
# handle credentials
|
186
|
+
#if credentials
|
187
|
+
# request.basic_auth(credentials[:username],credentials[:password])
|
188
|
+
#end
|
189
|
+
|
190
|
+
# get the response
|
191
|
+
response = http.request(request)
|
192
|
+
|
193
|
+
if response.code=="200"
|
194
|
+
break
|
195
|
+
end
|
196
|
+
|
197
|
+
if (response.header['location']!=nil)
|
198
|
+
newuri=URI.parse(response.header['location'])
|
199
|
+
if(newuri.relative?)
|
200
|
+
newuri=uri+response.header['location']
|
201
|
+
end
|
202
|
+
uri=newuri
|
203
|
+
|
204
|
+
else
|
205
|
+
found=true #resp was 404, etc
|
206
|
+
end #end if location
|
207
|
+
end #until
|
208
|
+
|
209
|
+
### TODO - this code may be be called outside the context of a task,
|
210
|
+
### meaning @task_result is not available to it. Below, we check to
|
211
|
+
### make sure that it exists before attempting to log anything,
|
212
|
+
### but there may be a cleaner way to do this (hopefully?). Maybe a
|
213
|
+
### global logger or logging queue?
|
214
|
+
###
|
215
|
+
#rescue TypeError
|
216
|
+
# # https://github.com/jaimeiniesta/metainspector/issues/125
|
217
|
+
# puts "TypeError - unknown failure"
|
218
|
+
rescue ArgumentError => e
|
219
|
+
puts "Unable to open connection: #{e}"
|
220
|
+
rescue Net::OpenTimeout => e
|
221
|
+
puts "Timeout : #{e}"
|
222
|
+
rescue Net::ReadTimeout => e
|
223
|
+
puts "Timeout : #{e}"
|
224
|
+
rescue Errno::ETIMEDOUT => e
|
225
|
+
puts "Timeout : #{e}"
|
226
|
+
rescue Errno::EINVAL => e
|
227
|
+
puts "Unable to connect: #{e}"
|
228
|
+
rescue Errno::ENETUNREACH => e
|
229
|
+
puts "Unable to connect: #{e}"
|
230
|
+
rescue Errno::EHOSTUNREACH => e
|
231
|
+
puts "Unable to connect: #{e}"
|
232
|
+
rescue URI::InvalidURIError => e
|
233
|
+
#
|
234
|
+
# XXX - This is an issue. We should catch this and ensure it's not
|
235
|
+
# due to an underscore / other acceptable character in the URI
|
236
|
+
# http://stackoverflow.com/questions/5208851/is-there-a-workaround-to-open-urls-containing-underscores-in-ruby
|
237
|
+
#
|
238
|
+
puts "Unable to request URI: #{uri} #{e}"
|
239
|
+
rescue OpenSSL::SSL::SSLError => e
|
240
|
+
puts "SSL connect error : #{e}"
|
241
|
+
rescue Errno::ECONNREFUSED => e
|
242
|
+
puts "Unable to connect: #{e}"
|
243
|
+
rescue Errno::ECONNRESET => e
|
244
|
+
puts "Unable to connect: #{e}"
|
245
|
+
rescue Net::HTTPBadResponse => e
|
246
|
+
puts "Unable to connect: #{e}"
|
247
|
+
rescue Zlib::BufError => e
|
248
|
+
puts "Unable to connect: #{e}"
|
249
|
+
rescue Zlib::DataError => e # "incorrect header check - may be specific to ruby 2.0"
|
250
|
+
puts "Unable to connect: #{e}"
|
251
|
+
rescue EOFError => e
|
252
|
+
puts "Unable to connect: #{e}"
|
253
|
+
rescue SocketError => e
|
254
|
+
puts "Unable to connect: #{e}"
|
255
|
+
#rescue SystemCallError => e
|
256
|
+
# puts "Unable to connect: #{e}"
|
257
|
+
#rescue ArgumentError => e
|
258
|
+
# puts "Argument Error: #{e}"
|
259
|
+
rescue Encoding::InvalidByteSequenceError => e
|
260
|
+
puts "Encoding error: #{e}"
|
261
|
+
rescue Encoding::UndefinedConversionError => e
|
262
|
+
puts "Encoding error: #{e}"
|
263
|
+
end
|
264
|
+
|
265
|
+
response
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require './ident'
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "intrigue-ident"
|
6
|
+
spec.version = Intrigue::Ident::VERSION
|
7
|
+
spec.authors = ["jcran"]
|
8
|
+
spec.email = ["jcran@intrigue.io"]
|
9
|
+
|
10
|
+
spec.summary = %q{Fingerprinter for Intrigue Data}
|
11
|
+
spec.description = %q{Fingerprinter for Intrigue Data}
|
12
|
+
spec.homepage = "https://intrigue.io"
|
13
|
+
spec.license = "BSD"
|
14
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
15
|
+
spec.bindir = "exe"
|
16
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
20
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
21
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
class CheckFactory
|
4
|
+
|
5
|
+
#
|
6
|
+
# Register a new handler
|
7
|
+
#
|
8
|
+
def self.register(klass)
|
9
|
+
@checks = [] unless @checks
|
10
|
+
@checks << klass if klass
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Provide the full list of checks
|
15
|
+
#
|
16
|
+
def self.all
|
17
|
+
@checks
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Akamai < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:name => "Akamai",
|
10
|
+
:description => "Akamai Missing Uri",
|
11
|
+
:version => nil,
|
12
|
+
:type => :content_body,
|
13
|
+
:content => /The requested URL "[no URL]", is invalid.<p>/,
|
14
|
+
:hide => true,
|
15
|
+
:paths => ["#{url}"]
|
16
|
+
}
|
17
|
+
]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Amazon < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(uri)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:name => "Amazon ELB",
|
10
|
+
:description => "Amazon Elastic Load Balancer",
|
11
|
+
:url => "https://aws.amazon.com/elasticloadbalancing/",
|
12
|
+
:version => nil,
|
13
|
+
:tags => ["error_page"],
|
14
|
+
:type => :content_headers,
|
15
|
+
:content => /awselb\/\d.\d/,
|
16
|
+
:hide => true,
|
17
|
+
:dynamic_version => lambda { |x| x["server"].match(/awselb\/(\d.\d)/).captures[0] },
|
18
|
+
:verify_sites => ["http://52.4.103.22:80"],
|
19
|
+
:paths => ["#{uri}"]
|
20
|
+
}
|
21
|
+
]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/checks/aruba.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Aruba < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:name => "Aruba Wireless Controller",
|
10
|
+
:description => "Aruba Wireless Controller",
|
11
|
+
:version => nil,
|
12
|
+
:type => :content_body,
|
13
|
+
:content => /arubalp=/,
|
14
|
+
:paths => ["#{url}"]
|
15
|
+
}
|
16
|
+
]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class AspNet < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(uri)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:name => "ASP.NET",
|
10
|
+
:description => "ASP.Net Error Message",
|
11
|
+
:version => nil,
|
12
|
+
:tags => ["error_page"],
|
13
|
+
:type => :content_body,
|
14
|
+
:content => /^.*ASP.NET is configured.*$/i,
|
15
|
+
:dynamic_version => lambda{|x| x.body.scan(/ASP.NET Version:(.*)$/)[0].first.chomp },
|
16
|
+
:paths => ["#{uri}"]
|
17
|
+
},
|
18
|
+
{
|
19
|
+
:name => "ASP.NET",
|
20
|
+
:description => "X-AspNet Header",
|
21
|
+
:version => nil,
|
22
|
+
:type => :content_headers,
|
23
|
+
:content => /^x-aspnet-version:.*$/i,
|
24
|
+
:dynamic_version => lambda{|x| x.body.scan(/ASP.NET Version:(.*)$/i)[0].first.chomp if x.body.scan(/ASP.NET Version:(.*)$/i)[0] },
|
25
|
+
:paths => ["#{uri}"]
|
26
|
+
},
|
27
|
+
{
|
28
|
+
:name => "ASP.NET",
|
29
|
+
:description => "Asp.Net Default Cookie",
|
30
|
+
:version => nil,
|
31
|
+
:type => :content_cookies,
|
32
|
+
:content => /ASPSESSIONID.*$/i,
|
33
|
+
:paths => ["#{uri}"]
|
34
|
+
#:dynamic_version => lambda{|x| x.each_header{|k,v| return v if k =~ /x-aspnet-version/ } }
|
35
|
+
},
|
36
|
+
{
|
37
|
+
:name => "ASP.NET",
|
38
|
+
:description => "Asp.Net Default Cookie",
|
39
|
+
:version => nil,
|
40
|
+
:type => :content_cookies,
|
41
|
+
:content => /ASP.NET_SessionId.*$/i,
|
42
|
+
:paths => ["#{uri}"]
|
43
|
+
#:dynamic_version => lambda{|x| x.each_header{|k,v| return v if k =~ /x-aspnet-version/ } }
|
44
|
+
},
|
45
|
+
{
|
46
|
+
:name => "ASP.NET MVC",
|
47
|
+
:description => "Asp.Net MVC Header",
|
48
|
+
:version => nil,
|
49
|
+
:type => :content_headers,
|
50
|
+
:content => /x-aspnetmvc-version/i,
|
51
|
+
:paths => ["#{uri}"]
|
52
|
+
#:dynamic_version => lambda{|x| x.each_header{|k,v| return v if k =~ /x-aspnetmvc-version/ } }
|
53
|
+
},
|
54
|
+
{
|
55
|
+
:name => "ASP.NET",
|
56
|
+
:description => "WebResource.axd link in the page",
|
57
|
+
:version => nil,
|
58
|
+
:type => :content_body,
|
59
|
+
:content => /WebResource.axd?d=/i,
|
60
|
+
:paths => ["#{uri}"]
|
61
|
+
#:dynamic_version => lambda{|x| x.each_header{|k,v| return v if k =~ /WebResource.axd?d=/ } }
|
62
|
+
}
|
63
|
+
]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|