Using virustotal
The virustotal package provides access to the VirusTotal API v3, allowing you to scan files and URLs for malware, get domain and IP intelligence, and retrieve comprehensive threat analysis reports.
Installation
From CRAN:
install.packages("virustotal")Or the development version from GitHub, with pak:
pak::pak("themains/virustotal")Authentication
- Get your free API key from VirusTotal
- Set it once per session:
set_key("your_api_key_here")Or set the VIRUSTOTAL_API_KEY environment variable (for
example in ~/.Renviron) and skip set_key()
entirely. The historical VirustotalToken variable is still
honored.
Core Functions
File Analysis
Scan a file for malware:
result <- scan_file("path/to/suspicious_file.exe")
analysis_id <- result$data$idGet file analysis report:
report <- file_report("99017f6eebbac24f351415dd410d522d")
report## VirusTotal API Response
## ======================
##
## Type: File Report
## ID: 99017f6eebbac24f351415dd410d522d
## Resource Type: file
##
## Detection Summary:
## Malicious: 61
## Suspicious: 0
## Undetected: 4
## Harmless: 0
The raw response stays a list underneath:
scan_results <- report$data$attributes$last_analysis_results
detections <- sum(sapply(scan_results, function(x) x$category == "malicious"))Request file rescan:
rescan_result <- rescan_file("99017f6eebbac24f351415dd410d522d")
new_analysis_id <- rescan_result$data$idURL Analysis
Scan a URL:
url_result <- scan_url("http://www.example.com")
analysis_id <- url_result$data$idGet URL analysis report:
report <- url_report("http://www.google.com")
scan_results <- report$data$attributes$last_analysis_resultsDomain Intelligence
domain_info <- domain_report("google.com")
categories <- domain_info$data$attributes$categories
whois_data <- domain_info$data$attributes$whois
dns_records <- domain_info$data$attributes$last_dns_recordsIP Address Intelligence
ip_info <- ip_report("8.8.8.8")
country <- ip_info$data$attributes$country
asn <- ip_info$data$attributes$asn
network <- ip_info$data$attributes$networkRate Limiting, Retries and Timeouts
The package paces itself to the public API’s allowance (4 requests
per minute) and retries transient failures (HTTP 429 and 503), honoring
the server’s Retry-After header. Four options control
this:
options(
virustotal.requests_per_minute = 1000, # premium keys can go faster
virustotal.max_tries = 3, # attempts per request
virustotal.timeout = 60, # seconds
virustotal.throttle = TRUE # FALSE disables client-side pacing
)Error Handling
API failures are typed conditions, so specific failures can be handled without string-matching messages:
tryCatch(
file_report("0000000000000000000000000000000000000000"),
virustotal_rate_limit_error = function(e) {
message("Out of quota; retry after ", e$retry_after, "s")
},
virustotal_auth_error = function(e) message("Check the API key"),
virustotal_error = function(e) message("VT error: ", conditionMessage(e))
)The classes are virustotal_auth_error,
virustotal_rate_limit_error (with a
retry_after field),
virustotal_validation_error (bad input, thrown before any
network traffic), and their parent virustotal_error.