Files
metasploit-gs/modules/post/multi/gather/check_malware.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

131 lines
3.6 KiB
Ruby
Raw Normal View History

##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'net/http'
require 'uri'
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Post
include Msf::Post::File
2023-02-08 13:47:34 +00:00
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Multi Gather Malware Verifier',
'Description' => %q{
This module will check a file for malware on VirusTotal based on the checksum.
},
'License' => MSF_LICENSE,
'Author' => [ 'sinn3r'],
'Platform' => [ 'osx', 'win', 'linux' ],
'SessionTypes' => [ 'shell', 'meterpreter' ]
)
)
register_options(
[
2023-02-08 13:47:34 +00:00
OptString.new('APIKEY', [true, 'VirusTotal API key', '501caf66349cc7357eb4398ac3298fdd03dec01a3e2f3ad576525aa7b57a1987']),
OptString.new('REMOTEFILE', [true, 'A file to check from the remote machine'])
2023-02-08 13:47:34 +00:00
]
)
end
2014-01-08 18:41:22 -06:00
def rhost
2014-01-10 18:27:03 -06:00
session.session_host
2014-01-08 18:41:22 -06:00
end
def get_report(api_key, checksum)
2014-01-08 18:41:22 -06:00
#
# We have to use Net::HTTP instead of HttpClient because of the following error:
# The supplied module name is ambiguous: undefined method `register_autofilter_ports'
#
2023-02-08 13:47:34 +00:00
url = URI.parse('https://www.virustotal.com/vtapi/v2/file/report')
req = Net::HTTP::Post.new(url.path, initheader = { 'Host' => 'www.virustotal.com' })
req.set_form_data({ 'apikey' => api_key, 'resource' => checksum })
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
2023-02-08 13:47:34 +00:00
res = http.start { |http| http.request(req) }
unless res
2014-01-08 18:41:22 -06:00
print_error("#{rhost} - Connection timed out")
return ''
end
case res.code
when 204
2014-01-08 18:41:22 -06:00
print_error("#{rhost} - You have reached the request limit, please wait for one minute to try again")
return ''
when 403
2014-01-08 18:41:22 -06:00
print_error("#{rhost} - No privilege to execute this request probably due to an invalye API key")
return ''
end
body = ''
begin
body = JSON.parse(res.body)
2014-01-08 18:41:22 -06:00
rescue JSON::ParserError
print_error("#{rhost} - Unable to parse the response")
return body
end
body
end
def show_report(res, filename)
2023-02-08 13:47:34 +00:00
md5 = res['md5'] || ''
sha1 = res['sha1'] || ''
sha256 = res['sha256'] || ''
2023-02-08 13:47:34 +00:00
print_status("#{rhost} - MD5: #{md5}") unless md5.blank?
print_status("#{rhost} - SHA1: #{sha1}") unless sha1.blank?
2014-01-08 18:41:22 -06:00
print_status("#{rhost} - SHA256: #{sha256}") unless sha256.blank?
2016-08-10 13:30:09 -05:00
tbl = Rex::Text::Table.new(
2023-02-08 13:47:34 +00:00
'Header' => "Analysis Report: #{filename} (#{res['positives']} / #{res['total']}): #{res['sha256']}",
'Indent' => 1,
'Columns' => ['Antivirus', 'Detected', 'Version', 'Result', 'Update']
)
res['scans'].each do |result|
2023-02-08 13:47:34 +00:00
product = result[0]
detected = result[1]['detected'].to_s
2023-02-08 13:47:34 +00:00
version = result[1]['version'] || ''
sig_name = result[1]['result'] || ''
timestamp = result[1]['update'] || ''
tbl << [product, detected, version, sig_name, timestamp]
end
2014-01-10 01:49:07 -06:00
report_note({
2023-02-08 13:47:34 +00:00
host: session,
type: 'malware.sample',
data: tbl.to_csv
2014-01-10 01:49:07 -06:00
})
print_status tbl.to_s
end
def run
filename = datastore['REMOTEFILE']
2023-02-08 13:47:34 +00:00
api_key = datastore['APIKEY']
unless file?(filename)
2014-01-08 18:41:22 -06:00
print_error("#{rhost} - File not found: #{filename}")
return
end
checksum = file_remote_digestsha1(filename)
2014-01-08 18:41:22 -06:00
print_status("#{rhost} - Checking: #{filename}...")
2023-02-08 13:47:34 +00:00
report = get_report(api_key, checksum)
2014-01-08 18:41:22 -06:00
return if report.blank?
print_status("#{rhost} - VirusTotal message: #{report['verbose_msg']}")
if report['response_code'] == 1
show_report(report, File.basename(filename))
end
end
end