intrigue-ident 0.4 → 0.6
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 +4 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -6
- data/data/logos/apache.png +0 -0
- data/data/logos/generic.png +0 -0
- data/data/logos/oracle_java.png +0 -0
- data/data/logos/php.png +0 -0
- data/data/logos/varnish.png +0 -0
- data/intrigue-ident.gemspec +2 -2
- data/lib/checks/acquia.rb +26 -0
- data/lib/checks/adobe.rb +38 -0
- data/lib/checks/akamai.rb +6 -4
- data/lib/checks/amazon.rb +54 -8
- data/lib/checks/apache.rb +113 -0
- data/lib/checks/aruba.rb +6 -3
- data/lib/checks/atlassian.rb +46 -28
- data/lib/checks/automattic.rb +189 -0
- data/lib/checks/axis.rb +24 -0
- data/lib/checks/banu.rb +28 -0
- data/lib/checks/base.rb +58 -0
- data/lib/checks/checkpoint.rb +55 -0
- data/lib/checks/chef.rb +16 -12
- data/lib/checks/cisco.rb +85 -12
- data/lib/checks/citrix.rb +81 -6
- data/lib/checks/cloudflare.rb +40 -30
- data/lib/checks/cpanel.rb +8 -6
- data/lib/checks/craft.rb +25 -0
- data/lib/checks/django.rb +8 -6
- data/lib/checks/docuwiki.rb +25 -0
- data/lib/checks/drupal.rb +25 -8
- data/lib/checks/f5.rb +35 -7
- data/lib/checks/fastly.rb +22 -7
- data/lib/checks/generic.rb +34 -6
- data/lib/checks/gitlab.rb +12 -6
- data/lib/checks/google.rb +19 -6
- data/lib/checks/grafana.rb +8 -6
- data/lib/checks/groovy.rb +24 -0
- data/lib/checks/heroku.rb +27 -0
- data/lib/checks/hp.rb +25 -0
- data/lib/checks/ibm.rb +77 -0
- data/lib/checks/ivanti.rb +27 -0
- data/lib/checks/jamf.rb +26 -0
- data/lib/checks/jekyll.rb +28 -0
- data/lib/checks/jenkins.rb +24 -18
- data/lib/checks/jive.rb +25 -0
- data/lib/checks/jobvite.rb +25 -0
- data/lib/checks/joomla.rb +9 -6
- data/lib/checks/jupyter.rb +26 -0
- data/lib/checks/lighttpd.rb +28 -0
- data/lib/checks/limesuvey.rb +8 -6
- data/lib/checks/lithium.rb +15 -11
- data/lib/checks/lotus.rb +27 -0
- data/lib/checks/magento.rb +8 -6
- data/lib/checks/mailchimp.rb +25 -0
- data/lib/checks/mcafee.rb +8 -6
- data/lib/checks/mediawiki.rb +31 -32
- data/lib/checks/microsoft.rb +240 -34
- data/lib/checks/microtik.rb +27 -0
- data/lib/checks/nagios.rb +8 -6
- data/lib/checks/new_relic.rb +25 -0
- data/lib/checks/nginx.rb +40 -0
- data/lib/checks/okta.rb +25 -0
- data/lib/checks/ookla.rb +27 -0
- data/lib/checks/openresty.rb +25 -0
- data/lib/checks/oracle.rb +208 -17
- data/lib/checks/palo_alto.rb +6 -4
- data/lib/checks/pantheon.rb +26 -0
- data/lib/checks/pardot.rb +8 -6
- data/lib/checks/perfectsense.rb +27 -0
- data/lib/checks/pfsense.rb +8 -9
- data/lib/checks/php.rb +41 -0
- data/lib/checks/phpmyadmin.rb +8 -6
- data/lib/checks/ping_identity.rb +27 -0
- data/lib/checks/pivotal.rb +24 -0
- data/lib/checks/plesk.rb +41 -0
- data/lib/checks/pulse_secure.rb +27 -0
- data/lib/checks/rabbitmq.rb +15 -11
- data/lib/checks/restlet.rb +28 -0
- data/lib/checks/ruckus_wireless.rb +24 -0
- data/lib/checks/sailpoint.rb +27 -0
- data/lib/checks/sap.rb +43 -0
- data/lib/checks/tableau.rb +26 -0
- data/lib/checks/team_city.rb +8 -6
- data/lib/checks/telerik.rb +23 -8
- data/lib/checks/varnish.rb +8 -11
- data/lib/checks/vmware.rb +38 -0
- data/lib/checks/webmin.rb +41 -0
- data/lib/checks/wp_engine.rb +10 -6
- data/lib/checks/yaws.rb +29 -0
- data/lib/checks/zeit.rb +28 -0
- data/lib/checks/zendesk.rb +39 -0
- data/lib/checks/zimbra.rb +24 -0
- data/lib/checks/zscaler.rb +28 -0
- data/{ident.rb → lib/intrigue-ident.rb} +66 -32
- data/lib/traverse_exceptions.rb +196 -0
- data/util/check.rb +20 -0
- data/util/list.rb +9 -0
- metadata +58 -9
- data/lib/checks/asp_net.rb +0 -70
- data/lib/checks/cloudfront.rb +0 -41
- data/lib/checks/spring.rb +0 -31
- data/lib/checks/tomcat.rb +0 -22
- data/lib/checks/wordpress.rb +0 -120
@@ -0,0 +1,26 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Tableau < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:type => "application",
|
10
|
+
:vendor => "Tableau",
|
11
|
+
:product => "Tableau",
|
12
|
+
:match_details => "Tableau Server",
|
13
|
+
:version => nil,
|
14
|
+
:references => ["https://community.tableau.com/thread/165653"],
|
15
|
+
:match_type => :content_body,
|
16
|
+
:match_content => /<meta name="vizportal-config" data-buildId=/i,
|
17
|
+
:examples => ["http://137.154.26.56:80"],
|
18
|
+
:paths => ["#{url}"]
|
19
|
+
}
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/checks/team_city.rb
CHANGED
@@ -3,15 +3,17 @@ module Ident
|
|
3
3
|
module Check
|
4
4
|
class TeamCity < Intrigue::Ident::Check::Base
|
5
5
|
|
6
|
-
def generate_checks(
|
6
|
+
def generate_checks(url)
|
7
7
|
[
|
8
8
|
{
|
9
|
-
:
|
10
|
-
:
|
9
|
+
:type => "application",
|
10
|
+
:vendor => "TeamCity",
|
11
|
+
:product => "TeamCity",
|
12
|
+
:match_details => "TeamCity Continuous Integration",
|
11
13
|
:version => nil,
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:paths => ["#{
|
14
|
+
:match_type => :content_body,
|
15
|
+
:match_content => /icons\/teamcity.black.svg/i,
|
16
|
+
:paths => ["#{url}"]
|
15
17
|
}
|
16
18
|
]
|
17
19
|
end
|
data/lib/checks/telerik.rb
CHANGED
@@ -3,18 +3,33 @@ module Ident
|
|
3
3
|
module Check
|
4
4
|
class Telerik < Intrigue::Ident::Check::Base
|
5
5
|
|
6
|
-
def generate_checks(
|
6
|
+
def generate_checks(url)
|
7
7
|
[
|
8
8
|
{
|
9
|
-
:
|
10
|
-
:
|
9
|
+
:type => "application",
|
10
|
+
:vendor => "Telerik",
|
11
|
+
:product => "Sitefinity",
|
12
|
+
:match_details => "Telerik Sitefinity is an ASP.NET 2.0-based Content Management System (CMS)",
|
11
13
|
:url => "https://www.sitefinity.com/",
|
12
14
|
:version => nil,
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:dynamic_version => lambda { |x| x
|
16
|
-
:
|
17
|
-
:paths => ["#{
|
15
|
+
:match_type => :content_body,
|
16
|
+
:match_content => /Telerik.Sitefinity.Resources/,
|
17
|
+
:dynamic_version => lambda { |x| _first_body_capture x, /Version=([\d\.]+),/ },
|
18
|
+
:examples => [],
|
19
|
+
:paths => ["#{url}"]
|
20
|
+
},
|
21
|
+
{
|
22
|
+
:type => "application",
|
23
|
+
:vendor => "Telerik",
|
24
|
+
:product => "Sitefinity",
|
25
|
+
:match_details => "Detect Telerik via a meta generator tag",
|
26
|
+
:url => "https://www.sitefinity.com/",
|
27
|
+
:version => nil,
|
28
|
+
:match_type => :content_body,
|
29
|
+
:match_content => /<meta\ name=\"Generator\"\ content=\"Sitefinity/,
|
30
|
+
:dynamic_version => lambda { |x| _first_body_capture x, /<meta name=\"Generator\" content=\"Sitefinity (.*)\ \/><link/ },
|
31
|
+
:examples => [],
|
32
|
+
:paths => ["#{url}"]
|
18
33
|
}
|
19
34
|
]
|
20
35
|
end
|
data/lib/checks/varnish.rb
CHANGED
@@ -3,20 +3,17 @@ module Ident
|
|
3
3
|
module Check
|
4
4
|
class Varnish < Intrigue::Ident::Check::Base
|
5
5
|
|
6
|
-
def generate_checks(
|
6
|
+
def generate_checks(url)
|
7
7
|
[
|
8
8
|
{
|
9
|
-
:
|
10
|
-
:
|
9
|
+
:type => "application",
|
10
|
+
:vendor =>"Varnish",
|
11
|
+
:product =>"Varnish",
|
12
|
+
:match_details =>"Varnish Proxy",
|
11
13
|
:version => nil,
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
m = nil
|
16
|
-
x.each_header{|h,v| m = v if (h == "via" && v =~ /varnish/) }
|
17
|
-
m.gsub("varnish ","") if m
|
18
|
-
},
|
19
|
-
:paths => ["#{uri}"]
|
14
|
+
:match_type => :content_headers,
|
15
|
+
:match_content => /via: [0-9]\.[0-9] varnish/i,
|
16
|
+
:paths => ["#{url}"]
|
20
17
|
}
|
21
18
|
]
|
22
19
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Vmware < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:type => "application",
|
10
|
+
:vendor => "VMWare",
|
11
|
+
:tags => ["tech:hypervisor"],
|
12
|
+
:product =>"ESXi",
|
13
|
+
:match_details =>"unique page string",
|
14
|
+
:version => nil,
|
15
|
+
:match_type => :content_body,
|
16
|
+
:match_content => /document.write\(\"<title>\"\ \+\ ID_EESX_Welcome/,
|
17
|
+
:paths => ["#{url}"],
|
18
|
+
:verify => ["aWJtI0ludHJpZ3VlOjpFbnRpdHk6OlVyaSNodHRwOi8vMTIuNDIuMjA1LjEyNzo4MA=="],
|
19
|
+
:examples => ["http://12.42.205.127:80"]
|
20
|
+
},
|
21
|
+
{
|
22
|
+
:type => "application",
|
23
|
+
:vendor => "VMWare",
|
24
|
+
:tags => ["tech:hypervisor"],
|
25
|
+
:product =>"Horizon",
|
26
|
+
:match_details =>"page title",
|
27
|
+
:version => nil,
|
28
|
+
:match_type => :content_body,
|
29
|
+
:match_content => /<title>VMware Horizon/,
|
30
|
+
:paths => ["#{url}"]
|
31
|
+
}
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Webmin < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:type => "application",
|
10
|
+
:vendor =>"Webmin",
|
11
|
+
:product =>"MiniServ",
|
12
|
+
:match_details => "server header",
|
13
|
+
:match_type => :content_headers,
|
14
|
+
:references => [],
|
15
|
+
:match_content => /server: MiniServ/,
|
16
|
+
:version => nil,
|
17
|
+
:dynamic_version => lambda {|x| _first_header_capture(x,/server: MiniServ\/(.*)/)},
|
18
|
+
:examples => ["http://158.85.208.126:8080"],
|
19
|
+
:verify => ["aWJtI0ludHJpZ3VlOjpFbnRpdHk6OlVyaSNodHRwOi8vMTU4Ljg1LjIwOC4xMjY6ODA4MA=="],
|
20
|
+
:paths => ["#{url}"]
|
21
|
+
},
|
22
|
+
{
|
23
|
+
:type => "application",
|
24
|
+
:vendor =>"Webmin",
|
25
|
+
:product =>"Webmin",
|
26
|
+
:match_details => "page title",
|
27
|
+
:match_type => :content_body,
|
28
|
+
:references => [],
|
29
|
+
:match_content => /<title>Login to Webmin/,
|
30
|
+
:version => nil,
|
31
|
+
:examples => ["http://158.85.208.126:8080"],
|
32
|
+
:verify => ["aWJtI0ludHJpZ3VlOjpFbnRpdHk6OlVyaSNodHRwOi8vMTU4Ljg1LjIwOC4xMjY6ODA4MA=="],
|
33
|
+
:paths => ["#{url}"]
|
34
|
+
}
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/checks/wp_engine.rb
CHANGED
@@ -3,15 +3,19 @@ module Ident
|
|
3
3
|
module Check
|
4
4
|
class WpEngine < Intrigue::Ident::Check::Base
|
5
5
|
|
6
|
-
def generate_checks(
|
6
|
+
def generate_checks(url)
|
7
7
|
[
|
8
8
|
{
|
9
|
-
:
|
10
|
-
:
|
9
|
+
:type => "service",
|
10
|
+
:vendor =>"WPEngine",
|
11
|
+
:tags => ["hosting_provider"],
|
12
|
+
:product =>"WPEngine",
|
13
|
+
:match_details =>"WPEngine - Access site by IP",
|
11
14
|
:version => nil,
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
+
:match_type => :content_body,
|
16
|
+
:match_content => /This domain is successfully pointed at WP Engine, but is not configured for an account on our platform./,
|
17
|
+
:hide => true,
|
18
|
+
:paths => ["#{url}"]
|
15
19
|
}
|
16
20
|
]
|
17
21
|
end
|
data/lib/checks/yaws.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Yaws < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:type => "application",
|
10
|
+
:vendor =>"Yaws",
|
11
|
+
:product =>"Yaws",
|
12
|
+
:match_details =>"server header",
|
13
|
+
:references => ["https://en.wikipedia.org/wiki/Yaws_(web_server)"],
|
14
|
+
:match_type => :content_headers,
|
15
|
+
:match_content => /server: Yaws/i,
|
16
|
+
:dynamic_version => lambda { |x|
|
17
|
+
_first_header_capture(x,/server: Yaws (.*)/i)
|
18
|
+
},
|
19
|
+
:examples => ["https://158.85.224.176:443"],
|
20
|
+
:verify => ["aWJtI0ludHJpZ3VlOjpFbnRpdHk6OlVyaSNodHRwczovLzE1OC44NS4yMjQuMTc2OjQ0Mw=="],
|
21
|
+
:paths => ["#{url}"]
|
22
|
+
}
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/checks/zeit.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Zeit < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:type => "application",
|
10
|
+
:vendor =>"Zeit",
|
11
|
+
:product =>"Next.js",
|
12
|
+
:match_details =>"x-powered-by header",
|
13
|
+
:references => ["https://zeit.co/blog/next"],
|
14
|
+
:match_type => :content_headers,
|
15
|
+
:match_content => /x-powered-by: Next.js/i,
|
16
|
+
:dynamic_version => lambda { |x|
|
17
|
+
_first_header_capture(x,/sx-powered-by: Next.js\ (.*)/i)
|
18
|
+
},
|
19
|
+
:examples => ["http://static.invisionapp.com:80"],
|
20
|
+
:paths => ["#{url}"]
|
21
|
+
}
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Zendesk < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:type => "service",
|
10
|
+
:vendor =>"Zendesk",
|
11
|
+
:product =>"Zendesk",
|
12
|
+
:match_details =>"unique header",
|
13
|
+
:references => [],
|
14
|
+
:match_type => :content_headers,
|
15
|
+
:match_content => /^x-zendesk-origin-server:.*$/i,
|
16
|
+
:examples => ["http://help.etsy.com:80"],
|
17
|
+
:verify => ["ZXRzeSNJbnRyaWd1ZTo6RW50aXR5OjpVcmkjaHR0cDovL2hlbHAuZXRzeS5jb206ODA="],
|
18
|
+
:paths => ["#{url}"]
|
19
|
+
},
|
20
|
+
{ # TODO - this might catch valid (closed) helpdesk uris too.
|
21
|
+
:type => "service",
|
22
|
+
:vendor =>"Zendesk",
|
23
|
+
:product =>"Zendesk",
|
24
|
+
:match_details =>"zendesk access by IP / invalid hostname",
|
25
|
+
:references => [],
|
26
|
+
:hide => true,
|
27
|
+
:match_type => :content_body,
|
28
|
+
:match_content => /<title>Help Center Closed \| Zendesk/i,
|
29
|
+
:examples => ["http://192.161.147.1:80"],
|
30
|
+
:verify => ["a2VubmFzZWN1cml0eSNJbnRyaWd1ZTo6RW50aXR5OjpVcmkjaHR0cDovLzE5Mi4xNjEuMTQ3LjE6ODA="],
|
31
|
+
:paths => ["#{url}"]
|
32
|
+
}
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Zimbra < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:type => "service",
|
10
|
+
:vendor =>"Zimbra",
|
11
|
+
:product =>"Server",
|
12
|
+
:match_details =>"login page for zimbra",
|
13
|
+
:match_type => :content_body,
|
14
|
+
:match_content => /<title>Zimbra Web Client Sign In/i,
|
15
|
+
:examples => ["https://219.84.198.177:443"],
|
16
|
+
:paths => ["#{url}"]
|
17
|
+
}
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Intrigue
|
2
|
+
module Ident
|
3
|
+
module Check
|
4
|
+
class Zscaler < Intrigue::Ident::Check::Base
|
5
|
+
|
6
|
+
def generate_checks(url)
|
7
|
+
[
|
8
|
+
{
|
9
|
+
:type => "service",
|
10
|
+
:vendor =>"Zscaler",
|
11
|
+
:product =>"Zscaler",
|
12
|
+
:match_details =>"server header for Zscaler",
|
13
|
+
:references => ["https://help.zscaler.com/zia/about-private-zens"],
|
14
|
+
:match_type => :content_headers,
|
15
|
+
:match_content => /server: Zscaler/i,
|
16
|
+
:dynamic_version => lambda { |x|
|
17
|
+
_first_header_capture(x,/server: Zscaler\/(.*)/i)
|
18
|
+
},
|
19
|
+
:examples => ["http://152.26.176.12:80"],
|
20
|
+
:paths => ["#{url}"]
|
21
|
+
}
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -3,15 +3,18 @@ require 'net/http'
|
|
3
3
|
require 'openssl'
|
4
4
|
require 'zlib'
|
5
5
|
|
6
|
-
require_relative '
|
7
|
-
require_relative '
|
8
|
-
check_folder = File.expand_path('
|
6
|
+
require_relative 'check_factory'
|
7
|
+
require_relative 'checks/base'
|
8
|
+
check_folder = File.expand_path('checks', File.dirname(__FILE__)) # get absolute directory
|
9
9
|
Dir["#{check_folder}/*.rb"].each { |file| require_relative file }
|
10
10
|
|
11
|
+
require_relative 'traverse_exceptions'
|
12
|
+
include Intrigue::Ident::TraverseExceptions
|
13
|
+
|
11
14
|
module Intrigue
|
12
15
|
module Ident
|
13
16
|
|
14
|
-
VERSION=0.
|
17
|
+
VERSION=0.60
|
15
18
|
|
16
19
|
def generate_requests_and_check(url)
|
17
20
|
|
@@ -51,7 +54,7 @@ module Intrigue
|
|
51
54
|
results.compact
|
52
55
|
end
|
53
56
|
|
54
|
-
def
|
57
|
+
def check_intrigue_uri_hash(intrigue_uri_data)
|
55
58
|
|
56
59
|
results = []
|
57
60
|
|
@@ -70,7 +73,7 @@ module Intrigue
|
|
70
73
|
|
71
74
|
# call each check, collecting the product if it's a match
|
72
75
|
ggc.last.each do |check|
|
73
|
-
results <<
|
76
|
+
results << _match_uri_hash(check, intrigue_uri_data)
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
@@ -78,19 +81,48 @@ module Intrigue
|
|
78
81
|
results.compact
|
79
82
|
end
|
80
83
|
|
84
|
+
# remove bad checks we need to roll back
|
85
|
+
def remove_bad_ident_matches(matches)
|
86
|
+
passed_matches = []
|
87
|
+
matches.each do |m|
|
88
|
+
next if (m["match_type"] == "content_body" &&
|
89
|
+
m["matched_content"] == "(?-mix:Drupal)")
|
90
|
+
passed_matches << m
|
91
|
+
end
|
92
|
+
passed_matches
|
93
|
+
end
|
94
|
+
|
81
95
|
private
|
82
96
|
|
83
97
|
def _construct_match_response(check, data)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
98
|
+
calculated_version = (check[:dynamic_version].call(data) if check[:dynamic_version]) || check[:version]
|
99
|
+
|
100
|
+
calculated_type = "a" if check[:type] == "application"
|
101
|
+
calculated_type = "h" if check[:type] == "hardware"
|
102
|
+
calculated_type = "o" if check[:type] == "operating_system"
|
103
|
+
calculated_type = "s" if check[:type] == "service" # literally made up
|
104
|
+
|
105
|
+
cpe_string = "cpe:/#{calculated_type}:#{check[:vendor]}:#{check[:product]}".downcase
|
106
|
+
cpe_string << ":#{calculated_version}".downcase if calculated_version
|
107
|
+
|
108
|
+
{
|
109
|
+
"type" => check[:type],
|
110
|
+
"vendor" => check[:vendor],
|
111
|
+
"product" => check[:product],
|
112
|
+
"version" => calculated_version,
|
113
|
+
"tags" => check[:tags],
|
114
|
+
"matched_content" => check[:match_content],
|
115
|
+
"match_type" => check[:match_type],
|
116
|
+
"match_details" => check[:match_details],
|
117
|
+
"hide" => check[:hide],
|
118
|
+
"cpe" => cpe_string
|
119
|
+
}
|
91
120
|
end
|
92
121
|
|
93
|
-
def
|
122
|
+
def _match_uri_hash(check,data)
|
123
|
+
return nil unless check && data
|
124
|
+
|
125
|
+
#puts "Trying to match #{check[:vendor]} #{check[:product]}: #{data["details"]["cookies"][0..10]}"
|
94
126
|
|
95
127
|
# data[:body] => page body
|
96
128
|
# data[:headers] => block of text with headers, one per line
|
@@ -98,16 +130,23 @@ module Intrigue
|
|
98
130
|
# data[:body_md5] => md5 hash of the body
|
99
131
|
# if type "content", do the content check
|
100
132
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
133
|
+
if check[:match_type] == :content_body
|
134
|
+
if data["details"] && data["details"]["hidden_response_data"]
|
135
|
+
match = _construct_match_response(check,data) if data["details"]["hidden_response_data"] =~ check[:match_content]
|
136
|
+
end
|
137
|
+
elsif check[:match_type] == :content_headers
|
138
|
+
if data["details"] && data["details"]["headers"]
|
139
|
+
match = _construct_match_response(check,data) if data["details"]["headers"].join("\n") =~ check[:match_content]
|
140
|
+
end
|
141
|
+
elsif check[:match_type] == :content_cookies
|
107
142
|
# Check only the set-cookie header
|
108
|
-
|
109
|
-
|
110
|
-
|
143
|
+
if data["details"] && data["details"]["cookies"]
|
144
|
+
match = _construct_match_response(check,data) if data["details"]["cookies"] =~ check[:match_content]
|
145
|
+
end
|
146
|
+
elsif check[:match_type] == :checksum_body
|
147
|
+
if data["details"] && data["details"]["response_data_hash"]
|
148
|
+
match = _construct_match_response(check,data) if Digest::MD5.hexdigest(data["details"]["response_data_hash"]) == check[:checksum]
|
149
|
+
end
|
111
150
|
end
|
112
151
|
|
113
152
|
match
|
@@ -130,7 +169,7 @@ module Intrigue
|
|
130
169
|
"hidden": false,
|
131
170
|
"detail_string": "Server: | App: | Title: Index page",
|
132
171
|
"details": {
|
133
|
-
"uri": "http://69.
|
172
|
+
"uri": "http://69.112.37.69:80",
|
134
173
|
"code": "200",
|
135
174
|
"port": 80,
|
136
175
|
"forms": false,
|
@@ -140,8 +179,9 @@ module Intrigue
|
|
140
179
|
"host_id": 1571,
|
141
180
|
"scripts": [],
|
142
181
|
"products": [],
|
182
|
+
"cookies": "",
|
143
183
|
"protocol": "tcp",
|
144
|
-
"ip_address": "69.
|
184
|
+
"ip_address": "69.112.37.69",
|
145
185
|
"javascript": [],
|
146
186
|
"fingerprint": [],
|
147
187
|
"api_endpoint": false,
|
@@ -156,12 +196,6 @@ module Intrigue
|
|
156
196
|
"hidden_response_data": "",
|
157
197
|
"hidden_screenshot_contents": """
|
158
198
|
},
|
159
|
-
"task_results": [{
|
160
|
-
"id": 32,
|
161
|
-
"name": "masscan_scan_on_69.162.0.0/18",
|
162
|
-
"base_entity_name": "69.162.0.0/18",
|
163
|
-
"base_entity_type": "Intrigue::Entity::NetBlock"
|
164
|
-
}],
|
165
199
|
"generated_at": "2018-07-04T03:43:11+00:00"
|
166
200
|
}'
|
167
201
|
=end
|
@@ -178,7 +212,7 @@ module Intrigue
|
|
178
212
|
data["details"]["response_data_hash"] = Digest::SHA256.base64digest("#{response.body}")
|
179
213
|
|
180
214
|
# call the actual matcher & return
|
181
|
-
|
215
|
+
_match_uri_hash check, data
|
182
216
|
end
|
183
217
|
|
184
218
|
def _http_request(method, uri_string, credentials=nil, headers={}, data=nil, limit = 10, open_timeout=15, read_timeout=15)
|