Pages

Thursday, March 17, 2011

Ruby 'O Virustotal

# START OF CODE
#!/usr/bin/ruby
#
# 17 February 2011 by Alip Undead
#
# WHAT THE CODE DO #
# This is a ruby code that will receive one argument (ARGV[0]) of "MD5" and do a search on virus total URL.
# If the search return a result, there is a redirection on the URL, which will be called on the specific function.
# It will then write the result to the output file name out.htm and save it to database
# if the search return no result, it will also output the file to out.html but wont save the result to database.
# END

# usage $ ruby main.rb

require 'rubygems'
require 'net/http'
require 'uri'
require 'mysql'
require 'parseconfig'
require 'optparse'

def no_redirection(url,search)
params = {'chain' => search
}
x = Net::HTTP.post_form(URI.parse(url), params)
# get the url and write to output out.htm
File.open('out.htm', 'w') { |f| f.write x.body }
end


def redirection(url)
url = URI.parse(url)
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url.request_uri)
response = http.request(request)
File.open('out.htm', 'w') do |f|
f.write response.body
end
end

def search_virus_total(url,search)
url2 = URI.parse(url)
req = Net::HTTP::Post.new(url2.path)
req.set_form_data({'chain'=>search}, ';')
http = Net::HTTP.new(url2.host, url2.port)
res = http.start {|http| http.request(req) }
case res
when Net::HTTPRedirection
puts "redirect found, headed to #{res['location']}"
new_url = res['location']
redirection(new_url)
return res['location']
when Net::HTTPSuccess
puts "no redirection found"
no_redirection(url,search)
return "empty"
else
res.error!
end
end

def check(dbh,md5)
statement = "select * from binaries where md5_hash ='#{md5}'"
result = dbh.query(statement)

puts "Checking for previous search for #{md5} ... #{result.num_rows} number of rows found in database"

#if found md5 already in the database, exit the program =)
exit if result.num_rows > 0
end


@search = ARGV[0]
url = 'http://www.virustotal.com/search.html'

begin
# connect to the MySQL server
dbh = Mysql.real_connect("127.0.0.1", "username", "password", "sample")

#check if binary already exist in database
check(dbh,@search)

#if binary does not exist, run the search by calling search_virus_total function
virus_total = search_virus_total(url,@search)

puts "keyword to search: #{@search}"
puts "url to search is #{url}"
statement = "INSERT INTO binaries (md5_hash,vt_link) VALUES ('#{@search}','#{virus_total}')"

#output some information of the database and query
dbh.query(statement)
puts "Connected to #{dbh.get_host_info}"
puts "Number of rows affected: #{dbh.affected_rows}"
puts "Statement: #{statement}"

# if ERRRRRR... puts error code
rescue Mysql::Error => e
puts "Error code: #{e.errno}"
puts "Error message: #{e.error}"
puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate")
ensure
# disconnect from server
dbh.close if dbh
end

# END OF CODE


SQL Dump for Sample

-- Table structure for table `binaries`
--

DROP TABLE IF EXISTS `binaries`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `binaries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`md5_hash` varchar(255) NOT NULL,
`vt_link` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

No comments:

Post a Comment