uirusu 0.0.0 → 0.0.1

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.
data/NEWS.markdown CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  # 0.0.1 (??)
4
4
  - Rename ruby-virustotal/virustotal gem to uirusu, to prevent being sued.
5
- - Complete rewrite of those gems
5
+ - Complete rewrite of the gem
data/README.markdown CHANGED
@@ -1,2 +1,44 @@
1
1
  # uirusu
2
2
 
3
+ uirusu is [virustotal](http://www.virustotal.com) automation and convenience tool for hash, file and URL submission.
4
+
5
+ The current version is 0.0.1
6
+
7
+ ## Requirements
8
+
9
+ * ruby
10
+ * rubygems
11
+ * json
12
+ * rest-client
13
+
14
+ * **public api key from [virustotal.com](http://www.virustotal.com)**
15
+
16
+ ## Installation
17
+
18
+ % gem install uirusu
19
+ % uirusu [options]
20
+
21
+ ## Usage
22
+
23
+ ### Searching a file of hashes
24
+
25
+ % uirusu -f <file_with_hashes_one_per_line>
26
+
27
+ ### Searching a single hash
28
+
29
+ % uirusu -h FD287794107630FA3116800E617466A9
30
+
31
+ ### Searching a file of hashes and outputting to XML
32
+ % uirusu -f <file_with_hashes_one_per_line> -x
33
+
34
+ ### Upload a file to Virustotal and wait for analysis
35
+ % uirusu -u </path/to/file>
36
+
37
+ ### Search for a single URL
38
+ % uirusu -s "http://www.google.com"
39
+
40
+ ### Saving results to a file
41
+ % uirusu -s "http://www.google.com" --yaml-output > file.yaml
42
+
43
+ ## Contact
44
+ You can reach me at Jacob[dot]Hammack[at]hammackj[dot]com or http://www.hammackj.com
data/Rakefile CHANGED
@@ -19,10 +19,10 @@ task :clean do
19
19
  system "rm -rf coverage"
20
20
  end
21
21
 
22
- task :default => [:test_unit]
22
+ task :default => [:test]
23
23
 
24
- Rake::TestTask.new("test_unit") { |t|
24
+ Rake::TestTask.new("test") do |t|
25
25
  t.libs << "test"
26
26
  t.pattern = 'test/*/*_test.rb'
27
27
  t.verbose = true
28
- }
28
+ end
data/bin/uirusu CHANGED
@@ -1,3 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- puts "Not implemented yet."
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '/../lib'))
4
+
5
+ require 'rubygems'
6
+ require 'uirusu'
7
+
8
+ app = Uirusu::CLI::Application.new
9
+ app.main(ARGV)
data/lib/uirusu.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Uirusu
2
2
  APP_NAME = "uirusu"
3
- VERSION = "0.0.0"
3
+ VERSION = "0.0.1"
4
4
  CONFIG_FILE = "~/.uirusu"
5
5
  end
6
6
 
@@ -8,3 +8,9 @@ require 'json'
8
8
  require 'rest_client'
9
9
  require 'optparse'
10
10
  require 'yaml'
11
+
12
+ require 'uirusu/vtfile'
13
+ require 'uirusu/vturl'
14
+ require 'uirusu/vtcomment'
15
+ require 'uirusu/vtresult'
16
+ require 'uirusu/cli/application'
@@ -0,0 +1,243 @@
1
+ module Uirusu
2
+ module CLI
3
+ class Application
4
+
5
+ # Creates a new instance of the [Application] class
6
+ #
7
+ def initialize
8
+ @options = {}
9
+ @config = {}
10
+ @hashes = Array.new
11
+ @files_of_hashes = Array.new
12
+ @sites = Array.new
13
+ @uploads = Array.new
14
+ end
15
+
16
+ # Parses the command the line options and returns the parsed options hash
17
+ #
18
+ # @return [Hash] of the parsed options
19
+ def parse_options(args)
20
+ begin
21
+ @options['output'] = :stdout
22
+ @options['verbose'] = false
23
+
24
+ opt = OptionParser.new do |opt|
25
+ opt.banner = "#{APP_NAME} v#{VERSION}\nJacob Hammack\nhttp://www.hammackj.com\n\n"
26
+ opt.banner << "Usage: #{APP_NAME} <options>"
27
+ opt.separator('')
28
+ opt.separator("File Options")
29
+
30
+ opt.on('-h HASH', '--search-hash HASH', 'Searches a single hash on virustotal.com') do |hash|
31
+ @hashes.push(hash)
32
+ end
33
+
34
+ opt.on('-f FILE', '--search-hash-file FILE', 'Searches a each hash in a file of hashes on virustotal.com') do |file|
35
+ if File.exists?(file)
36
+ puts "[+] Adding file #{file}" if @options["verbose"]
37
+ @files_of_hashes.push(file)
38
+ else
39
+ puts "[!] #{file} does not exist, please check your input!\n"
40
+ end
41
+ end
42
+
43
+ opt.on('-u FILE', '--upload-file FILE', 'Uploads a file to virustotal.com for analysis') do |file|
44
+ if File.exists?(file)
45
+ puts "[+] Adding file #{file}" if @options["verbose"]
46
+ @uploads.push(file)
47
+ else
48
+ puts "[!] #{file} does not exist, please check your input!\n"
49
+ end
50
+ end
51
+
52
+ opt.separator('')
53
+ opt.separator("Url Options")
54
+
55
+ opt.on('-s SITE', '--search-site SITE', 'Searches for a single url on virustotal.com') { |site|
56
+ @sites.push(site)
57
+ }
58
+
59
+ opt.separator('')
60
+ opt.separator('Output Options')
61
+
62
+ opt.on('-x', '--xml-output', 'Print results as xml to stdout') do
63
+ @options["output"] = :xml
64
+ end
65
+
66
+ opt.on('-y', '--yaml-output', 'Print results as yaml to stdout') do
67
+ @options['output'] = :yaml
68
+ end
69
+
70
+ opt.on('--stdout-output', 'Print results as normal text line to stdout, this is default') do
71
+ @options['output'] = :stdout
72
+ end
73
+
74
+ opt.separator ''
75
+ opt.separator 'Advanced Options'
76
+
77
+ opt.on('-c', '--create-config', 'Creates a skeleton config file to use') do
78
+ if File.exists?(File.expand_path(CONFIG_FILE)) == false
79
+ File.open(File.expand_path(CONFIG_FILE), 'w+') do |f|
80
+ f.write("virustotal: \n api-key: \n timeout: 25\n\n")
81
+ end
82
+
83
+ puts "[*] An empty #{File.expand_path(CONFIG_FILE)} has been created. Please edit and fill in the correct values."
84
+ exit
85
+ else
86
+ puts "[!] #{File.expand_path(CONFIG_FILE)} already exists. Please delete it if you wish to re-create it."
87
+ exit
88
+ end
89
+ end
90
+
91
+ opt.on('--[no-]verbose', 'Print verbose information') do |v|
92
+ @options["verbose"] = v
93
+ end
94
+
95
+ opt.separator ''
96
+ opt.separator 'Other Options'
97
+
98
+ opt.on('-v', '--version', "Shows application version information") do
99
+ puts "#{APP_NAME} - #{VERSION}"
100
+ exit
101
+ end
102
+
103
+ opt.on_tail("-?", "--help", "Show this message") { |help|
104
+ puts opt.to_s + "\n"
105
+ exit
106
+ }
107
+ end
108
+
109
+ if ARGV.length != 0
110
+ opt.parse!
111
+ else
112
+ puts opt.to_s + "\n"
113
+ exit
114
+ end
115
+ rescue OptionParser::MissingArgument => m
116
+ puts opt.to_s + "\n"
117
+ exit
118
+ end
119
+ end
120
+
121
+ # Loads the .uirusu config file for the api key
122
+ #
123
+ def load_config
124
+ if File.exists?(File.expand_path(CONFIG_FILE))
125
+ @config = YAML.load_file File.expand_path(CONFIG_FILE)
126
+ else
127
+ STDERR.puts "[!] #{CONFIG_FILE} does not exist. Please run #{APP_NAME} --create-config, to create it."
128
+ exit
129
+ end
130
+ end
131
+
132
+ # Submits a file/url and waits for analysis to be complete and returns the results.
133
+ #
134
+ # @param mod
135
+ # @param resource
136
+ # @param attempts
137
+ #
138
+ def scan_and_wait(mod, resource, attempts)
139
+ method = nil
140
+ retries = attempts
141
+
142
+ if mod.name == "Uirusu::VTFile"
143
+ method = mod.method :scan_file
144
+ else
145
+ method = mod.method :scan_url
146
+ end
147
+
148
+ begin
149
+ STDERR.puts "[*] Attempting to upload file #{resource}" if @options["verbose"]
150
+ result = method.call(@config["virustotal"]["api-key"], resource)
151
+ rescue => e
152
+ STDERR.puts "[!] An error has occured uploading the file. Retrying 60 seconds up #{retries} retries.\n" if @options["verbose"]
153
+ if retries >= 0
154
+ sleep 60
155
+ retry
156
+ retries = retries - 1
157
+ end
158
+ end
159
+
160
+ begin
161
+ if result['response_code'] == 1
162
+ results = mod.query_report(@config["virustotal"]["api-key"], result['resource'])
163
+
164
+ while results["response_code"] != 1
165
+ STDERR.puts "[*] File has not been analyized yet, waiting 60 seconds to try again" if @options["verbose"]
166
+ sleep 60
167
+ results = mod.query_report(@config["virustotal"]["api-key"], result['resource'])
168
+ end
169
+
170
+ return [result['resource'], results]
171
+ elsif result['response_code'] == -2
172
+ STDERR.puts "[!] Virustotal limits exceeded, ***do not edit the timeout values.***"
173
+ exit(1)
174
+ else
175
+ nil
176
+ end
177
+ rescue => e
178
+ STDERR.puts "[!] An error has occured retrieving the report. Retrying 60 seconds up #{retries} retries.\n" if @options["verbose"]
179
+ if retries >= 0
180
+ sleep 60
181
+ retry
182
+ retries = retries - 1
183
+ end
184
+ end
185
+ end
186
+
187
+ #
188
+ #
189
+ def main(args)
190
+ parse_options(args)
191
+ load_config
192
+
193
+ if @options['output'] == :stdout
194
+ output_method = :to_stdout
195
+ elsif @options['output'] == :yaml
196
+ output_method = :to_yaml
197
+ elsif @options['output'] == :xml
198
+ output_method = :to_xml
199
+ print "<results>\n"
200
+ end
201
+
202
+ if @files_of_hashes != nil
203
+ @files_of_hashes.each do |file|
204
+ f = File.open(file, 'r')
205
+
206
+ f.each do |hash|
207
+ hash.chomp!
208
+ @hashes.push hash
209
+ end
210
+ end
211
+ end
212
+
213
+ if @hashes != nil
214
+ @hashes.each do |hash|
215
+ results = Uirusu::VTFile.query_report(@config["virustotal"]["api-key"], hash)
216
+ result = Uirusu::VTResult.new(hash, results)
217
+ print result.send output_method if result != nil
218
+ end
219
+ end
220
+
221
+ if @sites != nil
222
+ @sites.each do |url|
223
+ results = scan_and_wait(Uirusu::VTUrl, url, 5)
224
+ result = Uirusu::VTResult.new(results[0], results[1])
225
+ print result.send output_method if result != nil
226
+ end
227
+ end
228
+
229
+ if @uploads != nil
230
+ @uploads.each do |upload|
231
+ results = scan_and_wait(Uirusu::VTFile, upload, 5)
232
+ result = Uirusu::VTResult.new(results[0], results[1])
233
+ print result.send output_method if result != nil
234
+ end
235
+ end
236
+
237
+ if @options['output'] == :xml
238
+ print "</results>\n"
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end
@@ -0,0 +1,41 @@
1
+ module Uirusu
2
+ # Module for submiting comments to Virustotal.com resources using the
3
+ # Virustotal.com public API
4
+ module VTComment
5
+ POST_URL = "https://www.virustotal.com/vtapi/v2/comments/put"
6
+
7
+ # Submits a comment to Virustotal.com for a specific resource
8
+ #
9
+ # @param [String] api_key Virustotal.com API key
10
+ # @param [String] resource MD5/sha1/sha256/scan_id to search for
11
+ # @param [String] comment Comment to post to the resource
12
+ #
13
+ # @return [JSON] Parsed response
14
+ def self.post_comment(api_key, resource, comment)
15
+ if api_key == nil
16
+ raise "Invalid API Key"
17
+ end
18
+
19
+ if resource == nil
20
+ raise "Invalid resource, must be a valid url"
21
+ end
22
+
23
+ if comment == nil
24
+ raise "You must provide a comment to submit."
25
+ end
26
+
27
+ response = RestClient.post POST_URL, :apikey => api_key, :resource => resource, :comment => comment
28
+
29
+ case response.code
30
+ when 429
31
+ raise "Virustotal limit reached. Try again later."
32
+ when 403
33
+ raise "Invalid privileges, please check your API key."
34
+ when 200
35
+ JSON.parse(response)
36
+ else
37
+ raise "Unknown Server error."
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,66 @@
1
+ module Uirusu
2
+ # Module for Accessing the File scan and report functionalities of the
3
+ # Virustotal.com public API
4
+ module VTFile
5
+ SCAN_URL = "http://www.virustotal.com/vtapi/v2/file/scan"
6
+ REPORT_URL = "https://www.virustotal.com/vtapi/v2/file/report"
7
+
8
+ # Queries a report from Virustotal.com
9
+ #
10
+ # @param api_key Virustotal.com API key
11
+ # @param resource MD5/sha1/sha256/scan_id to search for
12
+ #
13
+ # @return [JSON] Parsed response
14
+ def VTFile.query_report(api_key, resource)
15
+ if api_key == nil
16
+ raise "Invalid API Key"
17
+ end
18
+
19
+ if resource == nil
20
+ raise "Invalid resource, must be MD5/sha1/sha256/scan_id"
21
+ end
22
+
23
+ response = RestClient.post REPORT_URL, :apikey => api_key, :resource => resource
24
+
25
+ case response.code
26
+ when 429
27
+ raise "Virustotal limit reached. Try again later."
28
+ when 403
29
+ raise "Invalid privileges, please check your API key."
30
+ when 200
31
+ JSON.parse(response)
32
+ when 500
33
+ nil
34
+ end
35
+ end
36
+
37
+ # Submits a file to Virustotal.com for analysis
38
+ #
39
+ # @param api_key Virustotal.com API key
40
+ # @param path_to_file Path to file on disk to upload
41
+ #
42
+ # @return [JSON] Parsed response
43
+ def self.scan_file(api_key, path_to_file)
44
+ if !File.exists?(path_to_file)
45
+ raise Errno::ENOENT
46
+ end
47
+
48
+ if api_key == nil
49
+ raise "Invalid API Key"
50
+ end
51
+
52
+ response = RestClient.post SCAN_URL, :apikey => api_key, :filename=> path_to_file, :file => File.new(path_to_file, 'rb')
53
+
54
+ case response.code
55
+ when 429
56
+ raise "Virustotal limit reached. Try again later."
57
+ when 403
58
+ raise "Invalid privileges, please check your API key."
59
+ when 200
60
+ JSON.parse(response)
61
+ else
62
+ raise "Unknown Server error."
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,132 @@
1
+ module Uirusu
2
+ #
3
+ #
4
+ class VTResult
5
+ def initialize hash, result
6
+ if result == nil
7
+ return
8
+ end
9
+
10
+ @results = Array.new
11
+
12
+ if result["response_code"] == 0
13
+ res = Hash.new
14
+ res['hash'] = hash
15
+ res['scanner'] = '-'
16
+ res['md5'] = '-'
17
+ res['sha1'] = '-'
18
+ res['sha256'] = '-'
19
+ res['detected'] = '-'
20
+ res['version'] = '-'
21
+ res['result'] = '-'
22
+ res['update'] = '-'
23
+ res['permalink'] = '-'
24
+ res['result'] = result["verbose_msg"]
25
+
26
+ @results.push res
27
+ elsif result["response_code"] == 0
28
+ puts "[!] Invalid API KEY! Please correct this! Check ~/.uirusu"
29
+ exit
30
+ else
31
+ permalink = result["permalink"]
32
+ date = result["scan_date"]
33
+ md5 = result["md5"]
34
+ sha1 = result["sha1"]
35
+ sha256 = result["sha256"]
36
+
37
+ result["scans"].each do |scanner, value|
38
+ if value != ''
39
+ res = Hash.new
40
+ res['hash'] = hash
41
+ res['md5'] = md5
42
+ res['sha1'] = sha1
43
+ res['sha256'] = sha256
44
+ res['scanner'] = scanner
45
+ res['detected'] = value["detected"]
46
+ res['version'] = value["version"]
47
+
48
+ if value["result"] == nil
49
+ res['result'] = "Nothing detected"
50
+ else
51
+ res['result'] = value["result"]
52
+ end
53
+
54
+ res['update'] = value['update']
55
+ res['permalink'] = permalink unless permalink == nil
56
+
57
+ @results.push res
58
+ end
59
+ end
60
+ end
61
+
62
+ #if we didn't have any results let create a fake not found
63
+ if @results.size == 0
64
+ res = Hash.new
65
+ res['hash'] = hash
66
+ res['scanner'] = '-'
67
+ res['md5'] = '-'
68
+ res['sha1'] = '-'
69
+ res['sha256'] = '-'
70
+ res['permalink'] = '-'
71
+ res['detected'] = '-'
72
+ res['version'] = '-'
73
+ res['result'] = '-'
74
+ res['update'] = '-'
75
+ res['result'] = result["verbose_msg"]
76
+ @results.push res
77
+ end
78
+ end
79
+
80
+ #
81
+ #
82
+ def to_stdout
83
+ result_string = String.new
84
+ @results.each do |result|
85
+ result_string << "#{result['hash']}: Scanner: #{result['scanner']} Result: #{result['result']}\n"
86
+ end
87
+
88
+ print result_string
89
+ end
90
+
91
+ #
92
+ #
93
+ def to_yaml
94
+ result_string = String.new
95
+ @results.each do |result|
96
+ result_string << "vtresult:\n"
97
+ result_string << " hash: #{result['hash']}\n"
98
+ result_string << " md5: #{result['md5']}\n"
99
+ result_string << " sha1: #{result['sha1']}\n"
100
+ result_string << " sha256: #{result['sha256']}\n"
101
+ result_string << " scanner: #{result['scanner']}\n"
102
+ result_string << " detected: #{result['detected']}\n"
103
+ result_string << " date: #{result['date']}\n"
104
+ result_string << " permalink: #{result['permalink']}\n" unless result['permalink'] == nil
105
+ result_string << " result: #{result['result']}\n\n"
106
+ end
107
+
108
+ print result_string
109
+ end
110
+
111
+ #
112
+ #
113
+ def to_xml
114
+ result_string = String.new
115
+ @results.each do |result|
116
+ result_string << "\t<vtresult>\n"
117
+ result_string << "\t\t<hash>#{result['hash']}</hash>\n"
118
+ result_string << "\t\t<md5>#{result['md5']}</md5>\n"
119
+ result_string << "\t\t<sha1>#{result['sha1']}</sha1>\n"
120
+ result_string << "\t\t<sha256>#{result['sha256']}</sha256>\n"
121
+ result_string << "\t\t<scanner>#{result['scanner']}</scanner>\n"
122
+ result_string << "\t\t<detected>#{result['detected']}</detected>\n"
123
+ result_string << "\t\t<date>#{result['date']}</date>\n"
124
+ result_string << "\t\t<permalink>#{result['permalink']}</permalink>\n" unless result['permalink'] == nil
125
+ result_string << "\t\t<result>#{result['result']}</result>\n"
126
+ result_string << "\t</vtresult>\n"
127
+ end
128
+
129
+ print result_string
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,66 @@
1
+ module Uirusu
2
+ #
3
+ #
4
+ module VTUrl
5
+ SCAN_URL = "https://www.virustotal.com/vtapi/v2/url/scan"
6
+ REPORT_URL = "http://www.virustotal.com/vtapi/v2/url/report"
7
+
8
+ # Submits a URL to be scanned by Virustotal.com
9
+ #
10
+ # @param api_key Virustotal.com API key
11
+ # @param resource url to submit
12
+ #
13
+ # @return [JSON] Parsed response
14
+ def self.scan_url(api_key, resource)
15
+ if api_key == nil
16
+ raise "Invalid API Key"
17
+ end
18
+
19
+ if resource == nil
20
+ raise "Invalid resource, must be a valid url"
21
+ end
22
+
23
+ response = RestClient.post SCAN_URL, :apikey => api_key, :url => resource
24
+
25
+ case response.code
26
+ when 429
27
+ raise "Virustotal limit reached. Try again later."
28
+ when 403
29
+ raise "Invalid privileges, please check your API key."
30
+ when 200
31
+ JSON.parse(response)
32
+ else
33
+ raise "Unknown Server error."
34
+ end
35
+ end
36
+
37
+ # Searchs reports by URL from Virustotal.com
38
+ #
39
+ # @param api_key Virustotal.com API key
40
+ # @param resource url to search
41
+ #
42
+ # @return [JSON] Parsed response
43
+ def self.query_report(api_key, resource)
44
+ if api_key == nil
45
+ raise "Invalid API Key"
46
+ end
47
+
48
+ if resource == nil
49
+ raise "Invalid resource, must be a valid url"
50
+ end
51
+
52
+ response = RestClient.post REPORT_URL, :apikey => api_key, :resource => resource
53
+
54
+ case response.code
55
+ when 429
56
+ raise "Virustotal limit reached. Try again later."
57
+ when 403
58
+ raise "Invalid privileges, please check your API key."
59
+ when 200
60
+ JSON.parse(response)
61
+ else
62
+ raise "Unknown Server error."
63
+ end
64
+ end
65
+ end
66
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uirusu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-25 00:00:00.000000000 Z
12
+ date: 2012-03-02 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
- requirement: &70221526495640 !ruby/object:Gem::Requirement
16
+ requirement: &70176306777160 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.5.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70221526495640
24
+ version_requirements: *70176306777160
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rest-client
27
- requirement: &70221526495100 !ruby/object:Gem::Requirement
27
+ requirement: &70176306776280 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: 1.6.1
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70221526495100
35
+ version_requirements: *70176306776280
36
36
  description: uirusu is library for interacting with Virustotal.org
37
37
  email: jacob.hammack@hammackj.com
38
38
  executables:
@@ -49,10 +49,14 @@ files:
49
49
  - Rakefile
50
50
  - README.markdown
51
51
  - TODO.markdown
52
+ - lib/uirusu/cli/application.rb
53
+ - lib/uirusu/vtcomment.rb
54
+ - lib/uirusu/vtfile.rb
55
+ - lib/uirusu/vtresult.rb
56
+ - lib/uirusu/vturl.rb
52
57
  - lib/uirusu.rb
53
58
  - uirusu.gemspec
54
- - !binary |-
55
- YmluL3VpcnVzdQ==
59
+ - bin/uirusu
56
60
  homepage: http://github.com/hammackj/uirusu/
57
61
  licenses:
58
62
  - BSD
@@ -74,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
78
  version: 1.8.16
75
79
  requirements: []
76
80
  rubyforge_project:
77
- rubygems_version: 1.8.16
81
+ rubygems_version: 1.8.6
78
82
  signing_key:
79
83
  specification_version: 3
80
84
  summary: uirusu