falconz 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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