falconz 1.0.1 → 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.lock +1 -1
- data/README.md +37 -10
- data/lib/falconz/apis/feed.rb +18 -3
- data/lib/falconz/apis/search.rb +53 -9
- data/lib/falconz/apis/submission.rb +48 -7
- data/lib/falconz/apis/system.rb +58 -3
- data/lib/falconz/client.rb +17 -19
- data/lib/falconz/rest/get.rb +1 -1
- data/lib/falconz/rest/post.rb +1 -2
- data/lib/falconz/version.rb +1 -1
- metadata +2 -3
- data/lib/falconz/apis/apis.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e76c6d1b9897e0c01e5a9dbfe8e717f1220b9e24e77fcde3efa4578dd51c1a94
|
4
|
+
data.tar.gz: 8ba5eaf7e216f0c9010775382debfd11667d0415bfc7ee97d296f0d33ad1d67b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afcc9ffd3d7378575bef4ae4e01d61681e15f5744285a8183f8ad13ac2360549b5150c4d0ee7de5fb9e29392f91ce92ed486cad4fe7e01982a357a2a2727d78e
|
7
|
+
data.tar.gz: e96d2a429e161a6b0b37292a9f18e0f07016fa25d9059c612e0187ac05b9292b688325dfb2058abecdc137ff2fff8e67a3c1005abf18e665a4a8e8b73e1a86ef
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -13,12 +13,12 @@
|
|
13
13
|
|
14
14
|
## Usage
|
15
15
|
|
16
|
-
|
16
|
+
To create a client, we can specify our API key or set the `HYBRID_ANALYSIS_API_KEY` environment variable to communicate with the API.
|
17
17
|
|
18
18
|
```ruby
|
19
19
|
require "falconz"
|
20
20
|
|
21
|
-
client = Falconz.client.new
|
21
|
+
client = Falconz.client.new(key: "your_api_key")
|
22
22
|
```
|
23
23
|
|
24
24
|
Get the current file hashes that are being processed along with their environment IDs.
|
@@ -41,14 +41,41 @@ client.submit_file(file: "malware.exe", environment_id: 100)
|
|
41
41
|
|
42
42
|
Search for results related to a given hash (MD5/SHA1/SHA256).
|
43
43
|
```ruby
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
#
|
48
|
-
|
49
|
-
|
50
|
-
#
|
51
|
-
|
44
|
+
client.search_hash("cc311a06612f1b420cf788bd8883fa9dbd34d33ba8fa2443b86b7f88c7a75c2c")
|
45
|
+
# => [{"job_id"=>"5ae641ad7ca3e175d57a6013",
|
46
|
+
# "environment_id"=>"100",
|
47
|
+
# "environment_description"=>"Windows 7 32 bit",
|
48
|
+
# "size"=>3127633,
|
49
|
+
# "type"=>"PE32 executable (GUI) Intel 80386, for MS Windows",
|
50
|
+
# "type_short"=>["peexe"],
|
51
|
+
# "target_url"=>nil,
|
52
|
+
# "state"=>"SUCCESS",
|
53
|
+
# "submit_name"=>"sospecha.exe",
|
54
|
+
# "md5"=>"7421fed9ae4b6643913b080718b919cc",
|
55
|
+
# "sha1"=>"4f86bc7a578b6ac9d1e5f1fc325917e436f60520",
|
56
|
+
# "sha256"=>"cc311a06612f1b420cf788bd8883fa9dbd34d33ba8fa2443b86b7f88c7a75c2c",
|
57
|
+
# "sha512"=>"684558a218f6039ba718bfeac763f529222474498a41fdfa6994c8a3955b2686c07fd053d1afab73b2403b9f98fd3cf7112faec220c1b12b574c6a7fea828a8b",
|
58
|
+
# "ssdeep"=>"49152:32uJI9LH1MuvxlFl7Z0pnZASuwSpW/vnjC91R8rsiX8L1ViGiJJLQRRtaU:muwLH6oF0pZAS6W/vWzRo8iGi2RtaU",
|
59
|
+
# "imphash"=>"884310b1928934402ea6fec1dbd3cf5e",
|
60
|
+
# "av_detect"=>1,
|
61
|
+
# "vx_family"=>"TSGeneric",
|
62
|
+
# "url_analysis"=>false,
|
63
|
+
# "analysis_start_time"=>"2018-04-30T00:06:01-05:00",
|
64
|
+
# "threat_score"=>85,
|
65
|
+
# "interesting"=>false,
|
66
|
+
# "threat_level"=>2,
|
67
|
+
# "verdict"=>"malicious",
|
68
|
+
# "certificates"=>[],
|
69
|
+
# "domains"=>[],
|
70
|
+
# "classification_tags"=>[],
|
71
|
+
# "compromised_hosts"=>[],
|
72
|
+
# "hosts"=>[],
|
73
|
+
# "total_network_connections"=>0,
|
74
|
+
# "total_processes"=>5,
|
75
|
+
# "total_signatures"=>56,
|
76
|
+
# "extracted_files"=>[],
|
77
|
+
# "processes"=>[],
|
78
|
+
# "file_metadata"=>nil}]
|
52
79
|
```
|
53
80
|
|
54
81
|
Check the number of environments available to use.
|
data/lib/falconz/apis/feed.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Falconz
|
2
2
|
module APIs
|
3
|
-
# A module consisting of the method
|
3
|
+
# A module consisting of the method associated with the
|
4
4
|
# Feed section of the API.
|
5
5
|
#
|
6
6
|
# @author Kent 'picat' Gruber
|
@@ -8,6 +8,7 @@ module Falconz
|
|
8
8
|
# access a feed of last 250 reports over 24h
|
9
9
|
#
|
10
10
|
# == Example
|
11
|
+
# # create a new client
|
11
12
|
# client = Falconz.client.new
|
12
13
|
#
|
13
14
|
# client.latest_feed do |data|
|
@@ -15,6 +16,13 @@ module Falconz
|
|
15
16
|
# puts data.to_json
|
16
17
|
# end
|
17
18
|
#
|
19
|
+
# # or, if you'd like, you can be a fancy shamncy pants
|
20
|
+
#
|
21
|
+
# client.latest_feed { |data| puts data.to_json }
|
22
|
+
#
|
23
|
+
# feed = client.latest_feed
|
24
|
+
#
|
25
|
+
# @return
|
18
26
|
# https://www.hybrid-analysis.com/docs/api/v2#/Feed/get_feed_latest
|
19
27
|
def latest_feed
|
20
28
|
# return response unless block was given ( like the in-line example )
|
@@ -31,9 +39,16 @@ module Falconz
|
|
31
39
|
end
|
32
40
|
|
33
41
|
# A little wrapper method to #latest_feed that returns the count
|
34
|
-
# of the
|
42
|
+
# of the amount of data found in the feed.
|
43
|
+
#
|
44
|
+
# == Example
|
45
|
+
# # create a new client
|
46
|
+
# client = Falconz.client.new
|
47
|
+
#
|
48
|
+
# # print latest feed found to the screen
|
49
|
+
# puts client.latest_feed_count
|
35
50
|
#
|
36
|
-
# @return [
|
51
|
+
# @return [Integer]
|
37
52
|
# @see #latest_feed
|
38
53
|
def latest_feed_count
|
39
54
|
# capture response
|
data/lib/falconz/apis/search.rb
CHANGED
@@ -1,23 +1,67 @@
|
|
1
1
|
module Falconz
|
2
2
|
module APIs
|
3
3
|
module Search
|
4
|
-
#
|
4
|
+
# Get summaries for a given hash.
|
5
|
+
#
|
6
|
+
# == Example
|
7
|
+
# search_results = client.search_hash("e2442c82f3af5c6c72694ad670d385571418f64b998e2c470c3a5fcd18181932")
|
8
|
+
#
|
9
|
+
# search_results.first["total_signatures"]
|
10
|
+
# # => 15
|
11
|
+
#
|
12
|
+
# @param string [String] the hash to search for.
|
13
|
+
# @return [Array<Hash>] the result(s) from the search.
|
14
|
+
#
|
5
15
|
# https://www.hybrid-analysis.com/docs/api/v2#/Search/post_search_hash
|
6
|
-
def search_hash(string
|
7
|
-
|
8
|
-
options[:hash] = string
|
16
|
+
def search_hash(string)
|
17
|
+
options = {}
|
18
|
+
options[:hash] = string unless string.nil?
|
19
|
+
raise "Requires a MD5, SHA1 or SHA256 hash" if options[:hash].nil?
|
9
20
|
post_request("/search/hash", options)
|
10
21
|
end
|
11
22
|
|
12
|
-
#
|
23
|
+
# Get a summaries for any amount of given hashes.
|
24
|
+
#
|
25
|
+
# == Example
|
26
|
+
# search_results = client.search_hashes("e2442c82f3af5c6c72694ad670d385571418f64b998e2c470c3a5fcd18181932", "1cc406f6bf071bf5d96634cf9ab4ee94c2103e9b96207fdb37234536bb12bd50")
|
27
|
+
#
|
28
|
+
# search_results.count
|
29
|
+
# # => 2
|
30
|
+
#
|
31
|
+
# search_results.first["total_signatures"]
|
32
|
+
# # => 15
|
33
|
+
#
|
34
|
+
# # print all search results to screen, as json
|
35
|
+
# puts search.to_json
|
36
|
+
#
|
37
|
+
# @param strings [Array<String>] the hashes to search for.
|
38
|
+
# @return [Array<Hash>] the results from the search.
|
39
|
+
#
|
13
40
|
# https://www.hybrid-analysis.com/docs/api/v2#/Search/post_search_hashes
|
14
|
-
def search_hashes(*strings
|
15
|
-
|
16
|
-
options[:hashes] = strings
|
41
|
+
def search_hashes(*strings)
|
42
|
+
options = {}
|
43
|
+
options[:hashes] = strings unless strings.nil? or strings.empty?
|
44
|
+
raise "Requires MD5, SHA1 or SHA256 hashes" if options[:hashes].nil?
|
17
45
|
post_request("/search/hashes", options)
|
18
46
|
end
|
19
47
|
|
20
|
-
#
|
48
|
+
# Search the database using search terms.
|
49
|
+
#
|
50
|
+
# == Example
|
51
|
+
# pdf_results = client.search_terms(filetype: "pdf")
|
52
|
+
#
|
53
|
+
# # count malicious pdfs from results
|
54
|
+
# pdf_results["result"].select { |r| r["verdict"] == "malicious" }.count
|
55
|
+
#
|
56
|
+
# == Example
|
57
|
+
# ransomware_results = client.search_terms(tag: "ransomware")
|
58
|
+
#
|
59
|
+
# ransomware_results["count"]
|
60
|
+
# # => 196
|
61
|
+
#
|
62
|
+
# @param options [Hash] the hashes to search for.
|
63
|
+
# @return [Array<Hash>] the results from the search.
|
64
|
+
#
|
21
65
|
# https://www.hybrid-analysis.com/docs/api/v2#/Search/post_search_terms
|
22
66
|
def search_terms(**options)
|
23
67
|
post_request("/search/terms", options)
|
@@ -1,7 +1,18 @@
|
|
1
1
|
module Falconz
|
2
2
|
module APIs
|
3
3
|
module Submission
|
4
|
-
#
|
4
|
+
# Submit a local file for analysis.
|
5
|
+
#
|
6
|
+
# == Example
|
7
|
+
#
|
8
|
+
# response = client.submit_file(file: "/path/to/local/file", environment_id: 300)
|
9
|
+
#
|
10
|
+
# # print job ID from response
|
11
|
+
# puts response["job_id"]
|
12
|
+
#
|
13
|
+
# @param options [Hash] the hashes to search for.
|
14
|
+
# @return [Hash]
|
15
|
+
#
|
5
16
|
# https://www.hybrid-analysis.com/docs/api/v2#/Submission/post_submit_file
|
6
17
|
def submit_file(**options)
|
7
18
|
options[:file] = File.open(options[:file], "r")
|
@@ -9,27 +20,57 @@ module Falconz
|
|
9
20
|
options[:file].close
|
10
21
|
return response
|
11
22
|
end
|
12
|
-
|
13
|
-
#
|
23
|
+
|
24
|
+
# Submit a file by URL for analysis.
|
25
|
+
#
|
26
|
+
# == Example
|
27
|
+
#
|
28
|
+
# response = client.submit_url(url: "www.malicious-google.com/malware.exe", environment_id: 100, no_share_third_party: true)
|
29
|
+
#
|
30
|
+
# # print job ID from response
|
31
|
+
# puts response["job_id"]
|
32
|
+
#
|
33
|
+
# @param options [Hash]
|
34
|
+
# @return [Hash]
|
35
|
+
#
|
14
36
|
# https://www.hybrid-analysis.com/docs/api/v2#/Submission/post_submit_url_to_file
|
15
37
|
def submit_file_by_url(**options)
|
16
38
|
post_request("/submit/url-to-file", options)
|
17
39
|
end
|
18
|
-
|
19
|
-
#
|
40
|
+
|
41
|
+
# Submit a url for analysis.
|
42
|
+
#
|
43
|
+
# == Example
|
44
|
+
#
|
45
|
+
# response = client.submit_url(url: "www.malicious-google.com", environment_id: 100, experimental_anti_evasion: true)
|
46
|
+
#
|
47
|
+
# # print job ID from response
|
48
|
+
# puts response["job_id"]
|
49
|
+
#
|
50
|
+
# @param options [Hash]
|
51
|
+
# @return [Hash]
|
52
|
+
#
|
20
53
|
# https://www.hybrid-analysis.com/docs/api/v2#/Submission/post_submit_url_for_analysis
|
21
54
|
def submit_url(**options)
|
22
55
|
post_request("/submit/url-for-analysis", options)
|
23
56
|
end
|
24
|
-
|
57
|
+
|
25
58
|
# determine a SHA256 that an online file or URL submission will
|
26
59
|
# have when being processed by the system. Note: this is useful when looking up URL analysis
|
60
|
+
#
|
61
|
+
# @param options [Hash]
|
62
|
+
# @return [Hash]
|
63
|
+
#
|
27
64
|
# https://www.hybrid-analysis.com/docs/api/v2#/Submission/post_submit_hash_for_url
|
28
65
|
def hash_for_url(url)
|
29
66
|
post_request("/submit/hash-for-url", url: url)
|
30
67
|
end
|
31
|
-
|
68
|
+
|
32
69
|
# submit dropped file for analysis
|
70
|
+
#
|
71
|
+
# @param options [Hash]
|
72
|
+
# @return [Hash]
|
73
|
+
#
|
33
74
|
# https://www.hybrid-analysis.com/docs/api/v2#/Submission/post_submit_dropped_file
|
34
75
|
def submit_dropped_file(**options)
|
35
76
|
post_request("/submit/dropped-file", options)
|
data/lib/falconz/apis/system.rb
CHANGED
@@ -58,6 +58,28 @@ module Falconz
|
|
58
58
|
end
|
59
59
|
|
60
60
|
# return information about configured backend nodes
|
61
|
+
#
|
62
|
+
# == Example
|
63
|
+
#
|
64
|
+
# client = Falconz.client.new
|
65
|
+
#
|
66
|
+
# backend_information = client.backend
|
67
|
+
#
|
68
|
+
# # example of accessing specific information from hash
|
69
|
+
# puts backend_information["version"]
|
70
|
+
#
|
71
|
+
# # all the keys in the hash
|
72
|
+
# puts backend_information.keys
|
73
|
+
#
|
74
|
+
# # count the number of backend nodes
|
75
|
+
# puts backend_information["nodes"].count
|
76
|
+
#
|
77
|
+
# # you can get hell'a fancy
|
78
|
+
# client.backend["nodes"].map { |node| node["environments"].map { |e| [e["architecture"], e["analysis_mode"]] } }.flatten(1).uniq.each do |arch, mode|
|
79
|
+
# puts "The " + arch + " architecture supports " + mode + " level analysis."
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# @return [Hash] all the information about the system backend
|
61
83
|
# https://www.hybrid-analysis.com/docs/api/v2#/System/get_system_backend
|
62
84
|
def backend
|
63
85
|
get_request("/system/backend")
|
@@ -134,16 +156,49 @@ module Falconz
|
|
134
156
|
end
|
135
157
|
|
136
158
|
# return information about the instance version
|
159
|
+
#
|
160
|
+
# == Example
|
161
|
+
#
|
162
|
+
# client = Falconz.client.new
|
163
|
+
#
|
164
|
+
# # get system version info, as a hash
|
165
|
+
# version_info = client.system_version
|
166
|
+
# # => {"instance"=>"8.0-5305cf9", "sandbox"=>"8.10", "api"=>"2.1.5"}
|
167
|
+
#
|
168
|
+
# # iterate over each lil'bit of information
|
169
|
+
# version_info.each do |name, value|
|
170
|
+
# puts name + " " + value
|
171
|
+
# end
|
172
|
+
#
|
173
|
+
# # you can also access the information directly
|
174
|
+
# puts "found API version " + version_info["api"]
|
175
|
+
#
|
137
176
|
# https://www.reverse.it/docs/api/v2#/System/get_system_version
|
138
177
|
def system_version
|
139
178
|
get_request("/system/version")
|
140
179
|
end
|
141
180
|
|
142
|
-
# return information about queue size
|
181
|
+
# return information about system queue size
|
182
|
+
#
|
183
|
+
# == Example
|
184
|
+
#
|
185
|
+
# client = Falconz.client.new
|
186
|
+
#
|
187
|
+
# # print the system queue size to the screen
|
188
|
+
# puts client.system_queue_size
|
189
|
+
#
|
143
190
|
# https://www.reverse.it/docs/api/v2#/System/get_system_queue_size
|
144
|
-
def
|
145
|
-
get_request("/system/queue-size")["value"]
|
191
|
+
def system_queue_size
|
192
|
+
@cached_queue_size = get_request("/system/queue-size")["value"]
|
193
|
+
rescue => error
|
194
|
+
if JSON.parse(error.message)["code"] == 429 && @cached_queue_size
|
195
|
+
return @cached_queue_size
|
196
|
+
end
|
197
|
+
raise error
|
146
198
|
end
|
199
|
+
|
200
|
+
# For backwards compatibility with the old method API.
|
201
|
+
alias queue_size system_queue_size
|
147
202
|
end
|
148
203
|
end
|
149
204
|
end
|
data/lib/falconz/client.rb
CHANGED
@@ -9,8 +9,12 @@ require_relative "apis/report.rb"
|
|
9
9
|
|
10
10
|
module Falconz
|
11
11
|
class Client
|
12
|
+
# Need some special REST API powers.
|
12
13
|
include REST::GET
|
13
14
|
include REST::POST
|
15
|
+
|
16
|
+
# All of the magic API methods, nestled away
|
17
|
+
# into their own modules.
|
14
18
|
include APIs::Key
|
15
19
|
include APIs::Search
|
16
20
|
include APIs::System
|
@@ -18,12 +22,22 @@ module Falconz
|
|
18
22
|
include APIs::Feed
|
19
23
|
include APIs::Report
|
20
24
|
|
21
|
-
|
22
|
-
|
25
|
+
# Client HTTP header information.
|
26
|
+
attr_accessor :header
|
27
|
+
|
28
|
+
# Client HTTP base URL.
|
29
|
+
attr_accessor :url
|
30
|
+
|
31
|
+
# When initializing a Client, you can optionally specify the base API (v2) URL
|
32
|
+
# and the API key to be used for communication. These can both be changed later on.
|
33
|
+
#
|
34
|
+
# Note: If not specified, the HYBRID_ANALYSIS_API_KEY environment variable is used.
|
35
|
+
def initialize(url: "https://www.hybrid-analysis.com/api/v2", key: ENV["HYBRID_ANALYSIS_API_KEY"])
|
36
|
+
@url = url
|
23
37
|
|
24
38
|
@header = {
|
25
39
|
"User-Agent" => "Falcon Sandbox",
|
26
|
-
"api-key" =>
|
40
|
+
"api-key" => key
|
27
41
|
}
|
28
42
|
end
|
29
43
|
|
@@ -44,21 +58,5 @@ module Falconz
|
|
44
58
|
def api_key=(k)
|
45
59
|
@header["api-key"] = k
|
46
60
|
end
|
47
|
-
|
48
|
-
def url
|
49
|
-
@url
|
50
|
-
end
|
51
|
-
|
52
|
-
def url=(u)
|
53
|
-
@url = u
|
54
|
-
end
|
55
|
-
|
56
|
-
def header
|
57
|
-
@header
|
58
|
-
end
|
59
|
-
|
60
|
-
def header=(h)
|
61
|
-
@header
|
62
|
-
end
|
63
61
|
end
|
64
62
|
end
|
data/lib/falconz/rest/get.rb
CHANGED
data/lib/falconz/rest/post.rb
CHANGED
data/lib/falconz/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: falconz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kent 'picat' Gruber
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04
|
11
|
+
date: 2018-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -102,7 +102,6 @@ files:
|
|
102
102
|
- falcon.jpg
|
103
103
|
- falconz.gemspec
|
104
104
|
- lib/falconz.rb
|
105
|
-
- lib/falconz/apis/apis.rb
|
106
105
|
- lib/falconz/apis/feed.rb
|
107
106
|
- lib/falconz/apis/key.rb
|
108
107
|
- lib/falconz/apis/report.rb
|
data/lib/falconz/apis/apis.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module Falconz
|
2
|
-
module APIs
|
3
|
-
module Search
|
4
|
-
# summary for given hash
|
5
|
-
# https://www.hybrid-analysis.com/docs/api/v2#/Search/post_search_hash
|
6
|
-
def hash(string, **options)
|
7
|
-
options[:hash] = string unless string.nil?
|
8
|
-
raise "Requires a MD5, SHA1 or SHA256 hash" if options[:hash].nil?
|
9
|
-
get_request("/key/current", options)
|
10
|
-
end
|
11
|
-
|
12
|
-
# summary for given hashes
|
13
|
-
# https://www.hybrid-analysis.com/docs/api/v2#/Search/post_search_hashes
|
14
|
-
def hashes(*strings, **options)
|
15
|
-
options[:hashes] = strings unless strings.nil? or strings.empty?
|
16
|
-
raise "Requires MD5, SHA1 or SHA256 hashes" if options[:hashes].nil?
|
17
|
-
get_request("/search/hashes", options)
|
18
|
-
end
|
19
|
-
|
20
|
-
# search the database using search terms
|
21
|
-
# https://www.hybrid-analysis.com/docs/api/v2#/Search/post_search_terms
|
22
|
-
def terms(**options)
|
23
|
-
get_request("/search/terms", options)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|