Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/multi/gather/check_malware.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'net/http'6require 'uri'78class MetasploitModule < Msf::Post9include Msf::Post::File1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'Multi Gather Malware Verifier',16'Description' => %q{17This module will check a file for malware on VirusTotal based on the checksum.18},19'License' => MSF_LICENSE,20'Author' => [ 'sinn3r'],21'Platform' => [ 'osx', 'win', 'linux' ],22'SessionTypes' => [ 'shell', 'meterpreter' ]23)24)2526register_options(27[28OptString.new('APIKEY', [true, 'VirusTotal API key', '501caf66349cc7357eb4398ac3298fdd03dec01a3e2f3ad576525aa7b57a1987']),29OptString.new('REMOTEFILE', [true, 'A file to check from the remote machine'])3031]32)33end3435def rhost36session.session_host37end3839def get_report(api_key, checksum)40#41# We have to use Net::HTTP instead of HttpClient because of the following error:42# The supplied module name is ambiguous: undefined method `register_autofilter_ports'43#44url = URI.parse('https://www.virustotal.com/vtapi/v2/file/report')45req = Net::HTTP::Post.new(url.path, initheader = { 'Host' => 'www.virustotal.com' })46req.set_form_data({ 'apikey' => api_key, 'resource' => checksum })47http = Net::HTTP.new(url.host, url.port)48http.use_ssl = true49res = http.start { |http| http.request(req) }5051unless res52print_error("#{rhost} - Connection timed out")53return ''54end5556case res.code57when 20458print_error("#{rhost} - You have reached the request limit, please wait for one minute to try again")59return ''60when 40361print_error("#{rhost} - No privilege to execute this request probably due to an invalye API key")62return ''63end6465body = ''66begin67body = JSON.parse(res.body)68rescue JSON::ParserError69print_error("#{rhost} - Unable to parse the response")70return body71end7273body74end7576def show_report(res, filename)77md5 = res['md5'] || ''78sha1 = res['sha1'] || ''79sha256 = res['sha256'] || ''8081print_status("#{rhost} - MD5: #{md5}") unless md5.blank?82print_status("#{rhost} - SHA1: #{sha1}") unless sha1.blank?83print_status("#{rhost} - SHA256: #{sha256}") unless sha256.blank?8485tbl = Rex::Text::Table.new(86'Header' => "Analysis Report: #{filename} (#{res['positives']} / #{res['total']}): #{res['sha256']}",87'Indent' => 1,88'Columns' => ['Antivirus', 'Detected', 'Version', 'Result', 'Update']89)9091res['scans'].each do |result|92product = result[0]93detected = result[1]['detected'].to_s94version = result[1]['version'] || ''95sig_name = result[1]['result'] || ''96timestamp = result[1]['update'] || ''9798tbl << [product, detected, version, sig_name, timestamp]99end100101report_note({102host: session,103type: 'malware.sample',104data: tbl.to_csv105})106print_status tbl.to_s107end108109def run110filename = datastore['REMOTEFILE']111api_key = datastore['APIKEY']112113unless file?(filename)114print_error("#{rhost} - File not found: #{filename}")115return116end117118checksum = file_remote_digestsha1(filename)119print_status("#{rhost} - Checking: #{filename}...")120report = get_report(api_key, checksum)121122return if report.blank?123124print_status("#{rhost} - VirusTotal message: #{report['verbose_msg']}")125if report['response_code'] == 1126show_report(report, File.basename(filename))127end128end129end130131132