virustotal_api 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ef4844e6f5a7e7be0cf7ed1aa7c7f25027bc5522
4
+ data.tar.gz: 34c4dcb450256151376eb1486ca2b9fed3a9a3be
5
+ SHA512:
6
+ metadata.gz: 2bb1845d91af6c8ed7fef6055ec3514aa86427d6e751877b5c3ac4630430b17beb1dc9138c8a5d3d71c33ef503a0da056f558fbe97605f0fd621cb09d585ab0d
7
+ data.tar.gz: 2b73096b9aefc1aee739fb1bfb243f508a9e5b79118352dc34800c959ce1bb4ada3db7cfa2a8adccc834f65676c042ea4dfb1e5245adf480016d7212819e935c
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rubocop.yml ADDED
@@ -0,0 +1,27 @@
1
+ # This is the configuration used to check the rubocop source code.
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - 'test/fixtures/*'
6
+
7
+ Style/StringLiterals:
8
+ Enabled: true
9
+
10
+ Style/UnneededPercentQ:
11
+ Enabled: true
12
+
13
+ Style/HashSyntax:
14
+ EnforcedStyle: hash_rockets
15
+
16
+ # Disabled Checks
17
+ Style/Documentation:
18
+ Enabled: false
19
+
20
+ Style/PercentLiteralDelimiters:
21
+ Enabled: false
22
+
23
+ Style/RegexpLiteral:
24
+ Enabled: false
25
+
26
+ Style/BracesAroundHashParameters:
27
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ sudo: false
2
+ cache: bundler
3
+ language: ruby
4
+ rvm:
5
+ - 2.1
6
+ before_install: gem update --remote bundler
7
+ install:
8
+ - bundle install --retry=3
9
+ script:
10
+ - bundle exec rake test
11
+ - bundle exec rake rubocop
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 pwelch
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # VirustotalAPI
2
+
3
+ Ruby Gem for [VirusTotal](https://www.virustotal.com) [V2 API](https://www.virustotal.com/en/documentation/public-api/)
4
+
5
+ [![Build Status](https://secure.travis-ci.org/pwelch/virustotal_api.svg)](http://travis-ci.org/pwelch/virustotal_api)
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'virustotal_api'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install virustotal_api
22
+
23
+ ## Usage
24
+
25
+ ### File Report
26
+
27
+ ```ruby
28
+ require 'virustotal_api'
29
+
30
+ sha256 = '01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b'
31
+ api_key = 'MY_API_KEY'
32
+
33
+ vtreport = VirustotalAPI::FileReport.find(sha256, api_key)
34
+
35
+ # Does the resource have any results?
36
+ vtreport.exists?
37
+ # => true
38
+
39
+ # URL for File Report (if it exists)
40
+ vtreport.report_url
41
+ # => "https://www.virustotal.com/file/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b/analysis/1418032127/"
42
+
43
+ # Report results (if they exist) are available via #report
44
+ vtreport.report["scans"]["ClamAV"]
45
+ # => {"detected"=>false, "version"=>"0.98.5.0", "result"=>nil, "update"=>"20141208"}
46
+ ```
47
+
48
+ ### File Scan
49
+
50
+ ```ruby
51
+ require 'virustotal_api'
52
+
53
+ file = '/path/to/file'
54
+ api_key = 'MY_API_KEY'
55
+
56
+ vtscan = VirustotalAPI::FileScan.scan(file, api_key)
57
+
58
+ # Scan ID of file
59
+ vtscan.scan_id
60
+ # => "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b-1419454668"
61
+
62
+ # Response results are available via #response
63
+ vtreport.response
64
+ # =>
65
+ {
66
+ "scan_id"=>"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b-1419454668",
67
+ "sha1"=>"adc83b19e793491b1c6ea0fd8b46cd9f32e592fc",
68
+ "resource"=>"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b",
69
+ "response_code"=>1,
70
+ "sha256"=>"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b",
71
+ "permalink"=>"https://www.virustotal.com/file/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b/analysis/1419454668/",
72
+ "md5"=>"68b329da9893e34099c7d8ad5cb9c940",
73
+ "verbose_msg"=>"Scan request successfully queued, come back later for the report"
74
+ }
75
+ ```
76
+
77
+ ### URL Report
78
+
79
+ ```ruby
80
+ require 'virustotal_api'
81
+
82
+ url = 'http://www.google.com'
83
+ api_key = 'MY_API_KEY'
84
+
85
+ vturl_report = VirustotalAPI::URLReport.find(url, api_key)
86
+
87
+ # Does the resource have any results?
88
+ vturl_report.exists?
89
+ # => true
90
+
91
+ # URL for Report (if it exists)
92
+ vturl_report.report_url
93
+ # => "https://www.virustotal.com/url/dd014af5ed6b38d9130e3f466f850e46d21b951199d53a18ef29ee9341614eaf/analysis/1419457210/"
94
+
95
+ # Report results (if they exist) are available via #report
96
+ vturl_report.report["scans"]["Opera"]
97
+ # => {"detected"=>false, "result"=>"clean site"}
98
+ ```
99
+
100
+ ### IP Report
101
+
102
+ ```ruby
103
+ require 'virustotal_api'
104
+
105
+ ip = '8.8.8.8'
106
+ api_key = 'MY_API_KEY'
107
+
108
+ vtip_report = VirustotalAPI::IPReport.find(ip, api_key)
109
+
110
+ # Does the resource have any results?
111
+ vtip_report.exists?
112
+ # => true
113
+
114
+ # Report results (if they exist) are available via #report
115
+ vtip_report.report
116
+ # => Hash of report results
117
+ ```
118
+
119
+ ### Domain Report
120
+
121
+ ```ruby
122
+ require 'virustotal_api'
123
+
124
+ domain = 'virustotal.com'
125
+ api_key = 'MY_API_KEY'
126
+
127
+ vtdomain_report = VirustotalAPI::DomainReport.find(domain, api_key)
128
+
129
+ # Does the resource have any results?
130
+ vtdomain_report.exists?
131
+ # => true
132
+
133
+ # Report results (if they exist) are available via #report
134
+ vtdomain_report.report
135
+ # => Hash of report results
136
+ ```
137
+
138
+ ## Contributing
139
+
140
+ 1. Fork it ( https://github.com/pwelch/virustotal_api/fork )
141
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
142
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
143
+ 4. Push to the branch (`git push origin my-new-feature`)
144
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require 'bundler/gem_tasks'
3
+ require 'rake/testtask'
4
+ require 'rubocop/rake_task'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs = ['lib']
8
+ t.warning = true
9
+ t.verbose = true
10
+ t.test_files = FileList['test/*_test.rb']
11
+ end
12
+
13
+ RuboCop::RakeTask.new
14
+
15
+ require 'yard'
16
+ YARD::Rake::YardocTask.new
17
+ namespace :yard do
18
+ desc 'Run the YARD server'
19
+ task :start do
20
+ sh 'bundle exec yard server --reload'
21
+ end
22
+ end
23
+
24
+ task :default => :test
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require 'virustotal_api/domain_report'
3
+ require 'virustotal_api/file_report'
4
+ require 'virustotal_api/file_scan'
5
+ require 'virustotal_api/ip_report'
6
+ require 'virustotal_api/url_report'
7
+ require 'virustotal_api/uri'
8
+ require 'virustotal_api/version'
@@ -0,0 +1,24 @@
1
+ require 'rest-client'
2
+ require 'json'
3
+
4
+ module VirustotalAPI
5
+ class Base
6
+ # @return [String] string of API URI class method
7
+ def self.api_uri
8
+ VirustotalAPI::URI
9
+ end
10
+
11
+ # @return [String] string of API URI instance method
12
+ def api_uri
13
+ self.class.api_uri
14
+ end
15
+
16
+ # @return [Boolean] if report for resource exists
17
+ # 0 => not_present, 1 => exists, -1 => invalid_ip_address
18
+ def exists?
19
+ response_code = report.fetch('response_code') { nil }
20
+
21
+ response_code == 1 ? true : false
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ require_relative 'base'
3
+
4
+ module VirustotalAPI
5
+ class DomainReport < Base
6
+ attr_reader :report
7
+
8
+ def initialize(report)
9
+ @report = report
10
+ end
11
+
12
+ # @param [String] domain
13
+ # @param [String] api_key for virustotal
14
+ # @return [VirustotalAPI::IPReport] Report Search Result
15
+ def self.find(domain, api_key)
16
+ response = RestClient.get(
17
+ api_uri + '/domain/report',
18
+ { :params => params(domain, api_key) }
19
+ )
20
+ report = JSON.parse(response.body)
21
+
22
+ new(report)
23
+ end
24
+
25
+ # @param [String] domain
26
+ # @param [String] api_key virustotal
27
+ # @return [Hash] params for GET Request
28
+ def self.params(domain, api_key)
29
+ {
30
+ :domain => domain,
31
+ :apikey => api_key
32
+ }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ require_relative 'base'
3
+
4
+ module VirustotalAPI
5
+ class FileReport < Base
6
+ attr_reader :report, :report_url
7
+
8
+ def initialize(report)
9
+ @report = report
10
+ @report_url = report.fetch('permalink') { nil }
11
+ end
12
+
13
+ # @param [String] resource file as a md5/sha1/sha256 hash
14
+ # @param [String] api_key for virustotal
15
+ # @return [VirustotalAPI::FileReport] Report Search Result
16
+ def self.find(resource, api_key)
17
+ response = RestClient.post(
18
+ api_uri + '/file/report',
19
+ params(resource, api_key)
20
+ )
21
+ report = JSON.parse(response.body)
22
+
23
+ new(report)
24
+ end
25
+
26
+ # @param [String] resource file as a md5/sha1/sha256 hash
27
+ # @param [String] api_key for virustotal
28
+ # @return [Hash] params for POST Request
29
+ def self.params(resource, api_key)
30
+ {
31
+ :resource => resource,
32
+ :apikey => api_key
33
+ }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ require_relative 'base'
3
+
4
+ module VirustotalAPI
5
+ class FileScan < Base
6
+ attr_reader :response, :scan_id
7
+
8
+ def initialize(response)
9
+ @response = JSON.parse(response)
10
+ @scan_id = @response.fetch('scan_id') { nil }
11
+ end
12
+
13
+ # @param [String] file_path for file to be sent for scan
14
+ # @param [String] api_key for virustotal
15
+ # @param [Hash] opts hash for additional options
16
+ # @return [VirusotalAPIFileScan] Reponse
17
+ def self.scan(file_path, api_key, opts = {})
18
+ response = RestClient.post(
19
+ api_uri + '/file/scan',
20
+ :apikey => api_key,
21
+ :filename => opts.fetch('filename') { File.basename(file_path) },
22
+ :file => File.open(file_path, 'r')
23
+ )
24
+
25
+ new(response)
26
+ end
27
+
28
+ # @return [Boolean] if file was queued
29
+ # 0 => not_present, 1 => exists, -2 => queued_for_analysis
30
+ def queued_for_analysis?
31
+ response_code = report.fetch('response_code') { nil }
32
+
33
+ response_code == -2 ? true : false
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ require_relative 'base'
3
+
4
+ module VirustotalAPI
5
+ class IPReport < Base
6
+ attr_reader :report
7
+
8
+ def initialize(report)
9
+ @report = report
10
+ end
11
+
12
+ # @param [String] ip address IPv4 format
13
+ # @param [String] api_key for virustotal
14
+ # @return [VirustotalAPI::IPReport] Report Search Result
15
+ def self.find(ip, api_key)
16
+ response = RestClient.get(
17
+ api_uri + '/ip-address/report',
18
+ { :params => params(ip, api_key) }
19
+ )
20
+ report = JSON.parse(response.body)
21
+
22
+ new(report)
23
+ end
24
+
25
+ # @param [String] ip address IPv4 format
26
+ # @param [String] api_key for virustotal
27
+ # @return [Hash] params for GET Request
28
+ def self.params(ip, api_key)
29
+ {
30
+ :ip => ip,
31
+ :apikey => api_key
32
+ }
33
+ end
34
+ end
35
+ end