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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0e967b3178e27809a9bb0c71c48fef2e6ff1e450f560b43a76ba3fc4caebef0
4
- data.tar.gz: 05a4e019d926775d4c305bac4fc714156e5b1eaf68ca14a3edb83b7155256895
3
+ metadata.gz: e76c6d1b9897e0c01e5a9dbfe8e717f1220b9e24e77fcde3efa4578dd51c1a94
4
+ data.tar.gz: 8ba5eaf7e216f0c9010775382debfd11667d0415bfc7ee97d296f0d33ad1d67b
5
5
  SHA512:
6
- metadata.gz: 2df07a457057f0a29d43e16d6fe3399014652862bf976d6fab3de337c010a634b571c44e27f4bafa282159ee7e4a98ee7d16143eb20522a1bb8a97114eb2c98a
7
- data.tar.gz: e1f11b5808000e438b3cc1e403e12bee9fba06c122ce4cd66d22969a15c72cb1bc640d8d8937256c0fb477a0638224dcbed9638536a5e8f49f796ba37fed42c4
6
+ metadata.gz: afcc9ffd3d7378575bef4ae4e01d61681e15f5744285a8183f8ad13ac2360549b5150c4d0ee7de5fb9e29392f91ce92ed486cad4fe7e01982a357a2a2727d78e
7
+ data.tar.gz: e96d2a429e161a6b0b37292a9f18e0f07016fa25d9059c612e0187ac05b9292b688325dfb2058abecdc137ff2fff8e67a3c1005abf18e665a4a8e8b73e1a86ef
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- falconz (1.0.1)
4
+ falconz (1.0.2)
5
5
  httparty (~> 0.16.2)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -13,12 +13,12 @@
13
13
 
14
14
  ## Usage
15
15
 
16
- Currently requires the `HYBRID_ANALYSIS_API_KEY` environment variable set to communicate with the API.
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
- # md5
45
- client.search_hash("4d86e66537ac0130cce541890e1d9c4b")
46
-
47
- # sha1
48
- client.search_hash("62f585da3fea334b83cb8b4cee9b605d901c825c")
49
-
50
- # sha256
51
- client.search_hash("82d14e45e6a0586e66f359c6854bd90b6180b92d66d3db03e5e85234edfdcc04")
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.
@@ -1,6 +1,6 @@
1
1
  module Falconz
2
2
  module APIs
3
- # A module consisting of the method associted with the
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 ammount of data found in the feed.
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 [void]
51
+ # @return [Integer]
37
52
  # @see #latest_feed
38
53
  def latest_feed_count
39
54
  # capture response
@@ -1,23 +1,67 @@
1
1
  module Falconz
2
2
  module APIs
3
3
  module Search
4
- # summary for given hash
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, **options)
7
- raise "Requires a MD5, SHA1 or SHA256 hash" if string.nil?
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
- # summary for given hashes
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, **options)
15
- raise "Requires at least one MD5, SHA1 or SHA256 hash" if strings.nil? or strings.empty?
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
- # search the database using search terms
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
- # submit a local file for analysis
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
- # submit a file by url for analysis
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
- # submit a url for analysis
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)
@@ -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 queue_size
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
@@ -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
- def initialize
22
- @url = "https://www.hybrid-analysis.com/api/v2"
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" => ENV["HYBRID_ANALYSIS_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
@@ -8,7 +8,7 @@ module Falconz
8
8
  def get_request(path)
9
9
  response = HTTParty.get(url + path, headers: header)
10
10
  return response if response.success?
11
- raise response
11
+ raise RuntimeError, response
12
12
  end
13
13
  end
14
14
  end
@@ -9,8 +9,7 @@ module Falconz
9
9
  return response.body if json
10
10
  return response
11
11
  else
12
- binding.pry
13
- raise response.to_h
12
+ raise RuntimeError, response.to_h
14
13
  end
15
14
  end
16
15
  end
@@ -1,3 +1,3 @@
1
1
  module Falconz
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.2"
3
3
  end
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.1
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-29 00:00:00.000000000 Z
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
@@ -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