virustotal_api 0.1.0

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