Creating a Malware Analyzer Tool

  • Analyze the reputation of an IP address or domain.
  • Fetch file hash information.
  • Check IP geo-location.
  • Check API usage stats.
  • Process a batch of inputs from a file.

import os
import requests
import json
import re
from colorama import Fore, Back, Style, init
from dotenv import load_dotenv
ascii_art = f"""
{Fore.CYAN}{Style.BRIGHT}



    __  ___      __                            ___                __                     
   /  |/  /___ _/ /      ______ _________     /   |  ____  ____ _/ /_  ______  ___  _____
  / /|_/ / __ `/ / | /| / / __ `/ ___/ _ \   / /| | / __ \/ __ `/ / / / /_  / / _ \/ ___/
 / /  / / /_/ / /| |/ |/ / /_/ / /  /  __/  / ___ |/ / / / /_/ / / /_/ / / /_/  __/ /    
/_/  /_/\__,_/_/ |__/|__/\__,_/_/   \___/  /_/  |_/_/ /_/\__,_/_/\__, / /___/\___/_/     
                                                                /____/                   
             

{Fore.CYAN}Welcome to the VirusTotal Investigation Script
"""

def setup_api_key():
    print(f"{Fore.YELLOW}It looks like this is your first time running the script.")
    
    # Prompt the user for the API key
    api_key = input(f"{Fore.CYAN}Enter your VirusTotal API key: ")
    
    # Ask for directory to save the .env file
    env_dir = input(f"{Fore.CYAN}Enter the directory to save the .env file (default is current directory): ")

    if not env_dir:  # Use current directory if no input is provided
        env_dir = os.getcwd()

    # Ensure the directory exists
    if not os.path.exists(env_dir):
        print(f"{Fore.RED}Error: The specified directory does not exist.")
        return False

    # Define the path to the .env file
    env_file_path = os.path.join(env_dir, ".env")

    # Create .env file and write the API key to it
    with open(env_file_path, "w") as file:
        file.write(f"VIRUSTOTAL_API_KEY={api_key}\n")

    print(f"{Fore.GREEN}API key saved successfully in {env_file_path}")
    return True
def load_api_key_from_env():
    load_dotenv()
    api_key = os.getenv("VIRUSTOTAL_API_KEY")
    if api_key:
        print(f"{Fore.GREEN}API Key loaded successfully.")
        return api_key
    else:
        print(f"{Fore.RED}Error: The VIRUSTOTAL_API_KEY environment variable is not set.")
        return None
def check_env_file():
    env_file_path = ".env"
    return os.path.exists(env_file_path)

def is_ip(address):
# Regular expression for validating IPv4 addresses
ip_regex = r"^(?:[0-9]{1,3}.){3}[0-9]{1,3}$"
return re.match(ip_regex, address) is not None

BASE_URL = "https://www.virustotal.com/api/v3"
def check_ip(ip_address, api_key):
    url = f"{BASE_URL}/ip_addresses/{ip_address}"
    headers = {"x-apikey": api_key}
    response = requests.get(url, headers=headers)
    
    if response.status_code == 200:
        data = response.json()
        last_analysis_stats = data.get("data", {}).get("attributes", {}).get("last_analysis_stats", {})
        print(f"{Fore.YELLOW}IP Address Analysis Stats:")
        print(json.dumps(last_analysis_stats, indent=4))
    else:
        print(f"{Fore.RED}Error: {response.status_code}")
        try:
            print(json.dumps(response.json(), indent=4))
        except json.JSONDecodeError:
            print(response.text)

def check_domain(domain, api_key):
    url = f"{BASE_URL}/domains/{domain}"
    headers = {"x-apikey": api_key}
    response = requests.get(url, headers=headers)

    if response.status_code == 200:
        data = response.json()
        last_analysis_stats = data.get("data", {}).get("attributes", {}).get("last_analysis_stats", {})
        print(f"{Fore.YELLOW}Domain Analysis Stats:")
        print(json.dumps(last_analysis_stats, indent=4))
    else:
        print(f"{Fore.RED}Error: {response.status_code}")
        try:
            print(json.dumps(response.json(), indent=4))
        except json.JSONDecodeError:
            print(response.text)

def check_ip_geolocation(ip_address, api_key):
    url = f"{BASE_URL}/ip_addresses/{ip_address}"
    headers = {"x-apikey": api_key}
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        data = response.json()
        geolocation_info = data.get("data", {}).get("attributes", {}).get("geolocation", {})
        print(f"{Fore.CYAN}Geolocation Info:")
        print(json.dumps(geolocation_info, indent=4))
    else:
        print(f"{Fore.RED}Error: {response.status_code}")

def check_reputation(ip_or_domain, api_key):
    entity_type = "ip_addresses" if is_ip(ip_or_domain) else "domains"
    url = f"{BASE_URL}/{entity_type}/{ip_or_domain}"
    headers = {"x-apikey": api_key}
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        data = response.json()
        reputation = data.get("data", {}).get("attributes", {}).get("reputation", "Unknown")
        print(f"{Fore.MAGENTA}Reputation Score: {reputation}")
    else:
        print(f"{Fore.RED}Error: {response.status_code}")

def check_api_usage(api_key):
    url = f"{BASE_URL}/usage_stats"
    headers = {"x-apikey": api_key}
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        stats = response.json()
        print(f"{Fore.BLUE}API Usage Stats:")
        print(json.dumps(stats, indent=4))
    else:
        print(f"{Fore.RED}Error: {response.status_code}")
def check_batch(file_path, api_key, entity_type):
    if not os.path.exists(file_path):
        print(f"{Fore.RED}Error: File not found.")
        return
    with open(file_path, "r") as file:
        entities = file.read().splitlines()
    for entity in entities:
        if entity_type == "ip_addresses":
            check_ip(entity, api_key)
        elif entity_type == "domains":
            check_domain(entity, api_key)

Finally, if the setup fails or the user enters a invalid choice, the script exits and avoids further processing.

Here is the code snippet to finally finish our Malware Analyzer Script!

# Main function to run the script
if __name__ == "__main__":
    # Check if .env file exists
    if not check_env_file():
        if not setup_api_key():
            exit(1)  # Exit if there is an error during setup

    # Load the API key from the .env file
    API_KEY = load_api_key_from_env()

    # Proceed if the API key is loaded correctly
    if API_KEY:
        # Display a greeting
        print("Select the type of query:")
        print(f"{Fore.RED}1. IP Address")
        print(f"{Fore.GREEN}2. Domain")
        print(f"{Fore.YELLOW}3. File Hash (MD5, SHA1, SHA256)")
        print(f"{Fore.CYAN}4. Check IP Geolocation")
        print(f"{Fore.MAGENTA}5. Check Reputation Score")
        print(f"{Fore.BLUE}6. View API Usage Stats")
        print(f"{Fore.WHITE}7. Batch File Processing")
        choice = input("Enter choice (1-7): ")

        if choice == "1":
            ip_address = input("Enter the IP address to investigate: ")
            check_ip(ip_address, API_KEY)
        elif choice == "2":
            domain = input("Enter the domain to investigate: ")
            check_domain(domain, API_KEY)
        elif choice == "3":
            file_hash = input("Enter the file hash (MD5, SHA1, SHA256): ")
            # Add a function to handle file hash if needed
        elif choice == "4":
            ip_address = input("Enter the IP address to investigate for geolocation: ")
            check_ip_geolocation(ip_address, API_KEY)
        elif choice == "5":
            ip_or_domain = input("Enter the IP or domain to check reputation: ")
            check_reputation(ip_or_domain, API_KEY)
        elif choice == "6":
            check_api_usage(API_KEY)
        elif choice == "7":
            file_path = input("Enter the path to the file containing IPs/domains: ")
            entity_type = input("Enter type (domains/ip_addresses): ")
            check_batch(file_path, API_KEY, entity_type)
        else:
            print(f"{Fore.RED}Invalid choice. Please restart the script and enter a valid option.")