intrigue-ident 0.1 → 0.2
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 +1 -0
- data/Gemfile.lock +6 -0
- data/ident.rb +92 -42
- data/lib/checks/amazon.rb +1 -1
- data/lib/checks/aruba.rb +0 -1
- data/lib/checks/asp_net.rb +2 -0
- data/lib/checks/oracle.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d05d96fbb44b3e9ea2ed428a0c63873fcfe5679a74882faa3534051ffe51338
|
4
|
+
data.tar.gz: 56e52215528ae59c96cdeb9a832ea2e9a7655a607da986499dc714b9a90fa74d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17b3fe532217c204bd8ac15f42e395268ea010f409f9b37d623d115f4fa24b5a245b77a0b79e9fd5d1a76fd9558443ad13280245d15e012e3f0180f23e6f4b47
|
7
|
+
data.tar.gz: 664d65996160c1ce2ab55569e76b9342f4574a34a6e2aec92f20810590f31056ec568191b14828a35f6745892f6820e24ab863fff50a62b44aae3ad1e8e794ae
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
GEM
|
2
2
|
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
|
+
coderay (1.1.2)
|
4
5
|
diff-lcs (1.3)
|
6
|
+
method_source (0.9.0)
|
7
|
+
pry (0.11.3)
|
8
|
+
coderay (~> 1.1.0)
|
9
|
+
method_source (~> 0.9.0)
|
5
10
|
rspec (3.7.0)
|
6
11
|
rspec-core (~> 3.7.0)
|
7
12
|
rspec-expectations (~> 3.7.0)
|
@@ -20,6 +25,7 @@ PLATFORMS
|
|
20
25
|
ruby
|
21
26
|
|
22
27
|
DEPENDENCIES
|
28
|
+
pry
|
23
29
|
rspec
|
24
30
|
|
25
31
|
RUBY VERSION
|
data/ident.rb
CHANGED
@@ -11,7 +11,7 @@ Dir["#{check_folder}/*.rb"].each { |file| require_relative file }
|
|
11
11
|
module Intrigue
|
12
12
|
module Ident
|
13
13
|
|
14
|
-
VERSION=0.
|
14
|
+
VERSION=0.2
|
15
15
|
|
16
16
|
def generate_requests_and_check(url)
|
17
17
|
|
@@ -42,7 +42,7 @@ module Intrigue
|
|
42
42
|
if response
|
43
43
|
# call each check, collecting the product if it's a match
|
44
44
|
ggc.last.each do |check|
|
45
|
-
results <<
|
45
|
+
results << _match_http_response(check, response)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -53,54 +53,107 @@ module Intrigue
|
|
53
53
|
|
54
54
|
private
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
:match => check[:type],
|
66
|
-
:hide => check[:hide]
|
67
|
-
} if "#{response.body}" =~ check[:content]
|
56
|
+
def _construct_match_response(check, data)
|
57
|
+
{
|
58
|
+
:version => (check[:dynamic_version].call(data) if check[:dynamic_version]) || check[:version],
|
59
|
+
:name => check[:name],
|
60
|
+
:tags => check[:tags],
|
61
|
+
:match => check[:type],
|
62
|
+
:hide => check[:hide]
|
63
|
+
}
|
64
|
+
end
|
68
65
|
|
69
|
-
|
66
|
+
def _match_uri(check,data)
|
70
67
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
68
|
+
# data[:body] => page body
|
69
|
+
# data[:headers] => block of text with headers, one per line
|
70
|
+
# data[:cookies] => set_cookie header
|
71
|
+
# data[:body_md5] => md5 hash of the body
|
72
|
+
# if type "content", do the content check
|
76
73
|
|
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
74
|
|
75
|
+
if check[:type] == :content_body
|
76
|
+
match = _construct_match_response(check,data) if data["details"]["hidden_response_data"] =~ check[:content]
|
77
|
+
elsif check[:type] == :content_headers
|
78
|
+
match = _construct_match_response(check,data) if data["details"]["headers"].join("\n") =~ check[:content]
|
84
79
|
elsif check[:type] == :content_cookies
|
85
80
|
# 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
|
-
|
81
|
+
match = _construct_match_response(check,data) if data["details"]["cookies"] =~ check[:content]
|
93
82
|
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]
|
83
|
+
match = _construct_match_response(check,data) if Digest::MD5.hexdigest(data["details"]["response_data_hash"]) == check[:checksum]
|
100
84
|
end
|
85
|
+
|
101
86
|
match
|
102
87
|
end
|
103
88
|
|
89
|
+
# this method takes a check and a net/http response object and
|
90
|
+
# constructs it into a format that's matchable. it then attempts
|
91
|
+
# to match, and returns a match object if it matches, otherwise
|
92
|
+
# returns nil.
|
93
|
+
def _match_http_response(check, response)
|
94
|
+
|
95
|
+
# Construct an Intrigue Entity of type Uri so we can match it
|
96
|
+
data = []
|
97
|
+
=begin
|
98
|
+
json = '{
|
99
|
+
"id": 1572,
|
100
|
+
"type": "Intrigue::Entity::Uri",
|
101
|
+
"name": "http://69.162.37.69:80",
|
102
|
+
"deleted": false,
|
103
|
+
"hidden": false,
|
104
|
+
"detail_string": "Server: | App: | Title: Index page",
|
105
|
+
"details": {
|
106
|
+
"uri": "http://69.162.37.69:80",
|
107
|
+
"code": "200",
|
108
|
+
"port": 80,
|
109
|
+
"forms": false,
|
110
|
+
"title": "Index page",
|
111
|
+
"verbs": null,
|
112
|
+
"headers": ["content-length: 701", "last-modified: Tue, 03 Jul 2018 16:55:36 GMT", "cache-control: no-cache", "content-type: text/html"],
|
113
|
+
"host_id": 1571,
|
114
|
+
"scripts": [],
|
115
|
+
"products": [],
|
116
|
+
"protocol": "tcp",
|
117
|
+
"ip_address": "69.162.37.69",
|
118
|
+
"javascript": [],
|
119
|
+
"fingerprint": [],
|
120
|
+
"api_endpoint": false,
|
121
|
+
"masscan_string": "sudo masscan -p80,443,2004,3389,7001,8000,8080,8081,8443,U:161,U:500 --max-rate 10000 -oL /tmp/masscan20180703-9816-18n0ri --range 69.162.0.0/18",
|
122
|
+
"app_fingerprint": [],
|
123
|
+
"hidden_original": "http://69.162.37.69:80",
|
124
|
+
"response_data_hash": "7o0r6ie5DOrJJnz1sS7RGO4XWsNn3hWykbwGkGnySWU=",
|
125
|
+
"server_fingerprint": [],
|
126
|
+
"enrichment_complete": ["enrich/uri"],
|
127
|
+
"include_fingerprint": [],
|
128
|
+
"enrichment_scheduled": ["enrich/uri"],
|
129
|
+
"hidden_response_data": "",
|
130
|
+
"hidden_screenshot_contents": """
|
131
|
+
},
|
132
|
+
"task_results": [{
|
133
|
+
"id": 32,
|
134
|
+
"name": "masscan_scan_on_69.162.0.0/18",
|
135
|
+
"base_entity_name": "69.162.0.0/18",
|
136
|
+
"base_entity_type": "Intrigue::Entity::NetBlock"
|
137
|
+
}],
|
138
|
+
"generated_at": "2018-07-04T03:43:11+00:00"
|
139
|
+
}'
|
140
|
+
=end
|
141
|
+
data = {}
|
142
|
+
data["details"] = {}
|
143
|
+
data["details"]["hidden_response_data"] = "#{response.body}"
|
144
|
+
# construct the headers into a big string block
|
145
|
+
headers = []
|
146
|
+
response.each_header do |h,v|
|
147
|
+
headers << "#{h}: #{v}"
|
148
|
+
end
|
149
|
+
data["details"]["headers"] = headers
|
150
|
+
data["details"]["cookies"] = response.header['set-cookie']
|
151
|
+
data["details"]["response_data_hash"] = Digest::SHA256.base64digest("#{response.body}")
|
152
|
+
|
153
|
+
# call the actual matcher & return
|
154
|
+
_match_uri check, data
|
155
|
+
end
|
156
|
+
|
104
157
|
def _http_request(method, uri_string, credentials=nil, headers={}, data=nil, limit = 10, open_timeout=15, read_timeout=15)
|
105
158
|
|
106
159
|
response = nil
|
@@ -121,7 +174,6 @@ module Intrigue
|
|
121
174
|
end
|
122
175
|
|
123
176
|
until( found || attempts >= max_attempts)
|
124
|
-
#puts "Getting #{uri}, attempt #{attempts}"
|
125
177
|
attempts+=1
|
126
178
|
|
127
179
|
# proxy configuration, disabled for now
|
@@ -134,8 +186,6 @@ module Intrigue
|
|
134
186
|
proxy_addr = nil
|
135
187
|
proxy_port = nil
|
136
188
|
|
137
|
-
|
138
|
-
|
139
189
|
# set options
|
140
190
|
opts = {}
|
141
191
|
if uri.instance_of? URI::HTTPS
|
data/lib/checks/amazon.rb
CHANGED
@@ -14,7 +14,7 @@ class Amazon < Intrigue::Ident::Check::Base
|
|
14
14
|
:type => :content_headers,
|
15
15
|
:content => /awselb\/\d.\d/,
|
16
16
|
:hide => true,
|
17
|
-
:dynamic_version => lambda { |x| x[
|
17
|
+
:dynamic_version => lambda { |x| x[:headers].match(/awselb\/(\d.\d)/).captures[0] },
|
18
18
|
:verify_sites => ["http://52.4.103.22:80"],
|
19
19
|
:paths => ["#{uri}"]
|
20
20
|
}
|
data/lib/checks/aruba.rb
CHANGED
data/lib/checks/asp_net.rb
CHANGED
@@ -6,6 +6,7 @@ class AspNet < Intrigue::Ident::Check::Base
|
|
6
6
|
def generate_checks(uri)
|
7
7
|
[
|
8
8
|
{
|
9
|
+
:accept => "Intrigue::Entity::Uri",
|
9
10
|
:name => "ASP.NET",
|
10
11
|
:description => "ASP.Net Error Message",
|
11
12
|
:version => nil,
|
@@ -16,6 +17,7 @@ class AspNet < Intrigue::Ident::Check::Base
|
|
16
17
|
:paths => ["#{uri}"]
|
17
18
|
},
|
18
19
|
{
|
20
|
+
:accept => "Intrigue::Entity::Uri",
|
19
21
|
:name => "ASP.NET",
|
20
22
|
:description => "X-AspNet Header",
|
21
23
|
:version => nil,
|
data/lib/checks/oracle.rb
CHANGED
@@ -13,7 +13,7 @@ module Check
|
|
13
13
|
:type => :content_headers,
|
14
14
|
:content => /Sun GlassFish Enterprise Server/,
|
15
15
|
:hide => true,
|
16
|
-
:dynamic_version => lambda { |x| x["
|
16
|
+
:dynamic_version => lambda { |x| x["details"]["headers"].join("\n").match(/Sun GlassFish Enterprise Server v([\d\.])/).captures[0] },
|
17
17
|
:examples => ["http://52.4.12.185/"],
|
18
18
|
:paths => ["#{uri}"]
|
19
19
|
},
|
@@ -25,7 +25,7 @@ module Check
|
|
25
25
|
:type => :content_headers,
|
26
26
|
:content => /GlassFish Server Open Source Edition/,
|
27
27
|
:hide => true,
|
28
|
-
:dynamic_version => lambda { |x| x["
|
28
|
+
:dynamic_version => lambda { |x| x["details"]["headers"].join("\n").match(/GlassFish Server Open Source Edition\s+([\d\.]+)$/).captures[0] },
|
29
29
|
:examples => ["http://52.2.97.57:80"],
|
30
30
|
:paths => ["#{uri}"]
|
31
31
|
}
|