Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 177 lines (136 sloc) 4.26 KB
#!/usr/bin/ruby
# Dropzone Destination Info
# Name: VirusTotal
# Description: Sends the dropped files to virustotal.com and shows the corresponding antivirus reports on your web browser.
# Handles: NSFilenamesPboardType
# Events: Clicked, Dragged
# Creator: Victor M. Alvarez
# URL: http://www.hispasec.com
# IconURL: http://dl.dropbox.com/u/174999/virustotal.png
require 'digest/md5'
require 'net/http'
require 'net/https'
require 'pathname'
class Multipart
def initialize( file_names )
@file_names = file_names
end
def post( to_url )
boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ'
parts = []
streams = []
@file_names.each do |param_name, filepath|
pos = filepath.rindex('/')
filename = filepath[pos + 1, filepath.length - pos]
parts << StringPart.new ( "--" + boundary + "\r\n" +
"Content-Disposition: form-data; name=\"" + param_name.to_s + "\"; filename=\"" + filename + "\"\r\n" +
"Content-Type: video/x-msvideo\r\n\r\n")
stream = File.open(filepath, "rb")
streams << stream
parts << StreamPart.new (stream, File.size(filepath))
end
parts << StringPart.new ( "\r\n--" + boundary + "--\r\n" )
post_stream = MultipartStream.new( parts )
url = URI.parse( to_url )
req = Net::HTTP::Post.new(url.path)
req.content_length = post_stream.size
req.content_type = 'multipart/form-data; boundary=' + boundary
req.body_stream = post_stream
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
streams.each do |stream|
stream.close();
end
res
end
end
class StreamPart
def initialize( stream, size )
@stream, @size = stream, size
end
def size
@size
end
def read ( offset, how_much )
@stream.read ( how_much )
end
end
class StringPart
def initialize ( str )
@str = str
end
def size
@str.length
end
def read ( offset, how_much )
@str[offset, how_much]
end
end
class MultipartStream
def initialize( parts )
@parts = parts
@part_no = 0;
@part_offset = 0;
end
def size
total = 0
@parts.each do |part|
total += part.size
end
total
end
def read ( how_much )
if @part_no >= @parts.size
return nil;
end
how_much_current_part = @parts[@part_no].size - @part_offset
how_much_current_part = if how_much_current_part > how_much
how_much
else
how_much_current_part
end
how_much_next_part = how_much - how_much_current_part
current_part = @parts[@part_no].read(@part_offset, how_much_current_part )
if how_much_next_part > 0
@part_no += 1
@part_offset = 0
next_part = read ( how_much_next_part )
current_part + if next_part
next_part
else
''
end
else
@part_offset += how_much_current_part
current_part
end
end
end
def dragged
$dz.determinate(false)
$dz.begin("Talking to VirusTotal.com...")
for path in $items
if not File.directory?(path)
file_name = Pathname.new(path).basename
md5 = Digest::MD5.hexdigest(File.read(path))
http = Net::HTTP.new("www.virustotal.com", 80)
data = "hash=#{md5}"
response, data = http.post("/vt/en/consultamd5", data)
answer = 0
if not response["Location"].include?("notfound")
answer = `./CocoaDialog yesno-msgbox --string-output --no-newline --title "VirusTotal" --no-cancel --informative-text "This file was uploaded to VirusTotal before. Do you want to re-analyse it again?" --text "#{file_name}"`
end
if response["Location"].include?("notfound") or answer == "Yes"
$dz.begin("Uploading...")
multi = Multipart.new({:archivo => path})
response = multi.post('http://www.virustotal.com/vt/en/recepcionf')
url = response["Location"]
else
location = response["Location"]
url = "http://www.virustotal.com#{location}"
end
system("open #{url}")
end
end
$dz.finish("Completed")
$dz.url(url)
end