Skip to main content

VirusTotal IOC Enrichment Tool for SOC/DFIR workflows

Project description

vex logo

vex

VirusTotal IOC enrichment for SOC triage and DFIR investigations, straight from your terminal.

 ██╗   ██╗███████╗██╗  ██╗
 ██║   ██║██╔════╝╚██╗██╔╝
 ██║   ██║█████╗   ╚███╔╝
 ╚██╗ ██╔╝██╔══╝   ██╔██╗
  ╚████╔╝ ███████╗██╔╝ ██╗
   ╚═══╝  ╚══════╝╚═╝  ╚═╝

Features

  • Auto-detection of IOC types: MD5, SHA1, SHA256, IPv4, IPv6, Domain, URL
  • Two modes: triage (fast, 1 API call) and investigate (deep, multiple calls)
  • Output formats: JSON (default), Rich tables, plain console, CSV, STIX 2.1
  • MITRE ATT&CK mapping from sandbox behaviors and VT tags
  • IOC defanging/refanging for safe sharing (hxxps[://]evil[.]com)
  • Automation-ready: exit codes, --alert filtering, --summary on stderr
  • Timeline enrichment: chronological event reconstruction for DFIR
  • Local knowledge base: tag, annotate, and watchlist IOCs in SQLite
  • Plugin architecture: extensible enrichment sources via Protocol interface
  • Parallel batch processing with progress bar for large IOC lists
  • STIX 2.1 export for threat intelligence sharing
  • SQLite cache with configurable TTL (default 24h)
  • Rate limiting: token-bucket, free tier (4 req/min) and premium configurable

Setup

Prerequisites

Installation

From PyPI (recommended):

pip install vex-ioc

From source:

git clone https://github.com/duathron/vex.git
cd vex

python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate

pip install -r requirements.txt
pip install -e .

Upgrade

# If installed from PyPI
pip install --upgrade vex-ioc

# If installed from git clone (editable)
cd vex
git pull
pip install -r requirements.txt
pip install -e .

API Key

Set your API key using one of these methods (priority order):

# Option 1: Per-command flag (highest priority)
vex triage 8.8.8.8 --api-key YOUR_KEY
vex investigate evil.com -k YOUR_KEY

# Option 2: Environment variable
export VT_API_KEY="your-virustotal-api-key"

# Option 3: Save permanently to ~/.vex/config.yaml
vex config --set-api-key YOUR_KEY

# Option 4: Manual config.yaml or .env
# api:
#   key: "your-key"

Quickstart

# Fast triage
vex triage 44d88612fea8a8f36de82e1278abb02f

# Rich terminal output
vex investigate evil-domain.com -o rich

# Batch from file, CSV export
vex triage -f iocs.txt --csv

# Pipe from another tool
echo "8.8.8.8" | vex triage -o rich

# Defanged IOC support
vex triage "hxxps[://]evil[.]com"

# STIX 2.1 export
vex investigate evil.com --stix > bundle.json

# Timeline reconstruction
vex investigate evil.com -o rich --timeline

# Automation: exit code + alert filter + summary
vex triage -f iocs.txt --alert SUSPICIOUS --summary
echo $?  # 0=clean, 1=suspicious, 2=malicious

Documentation

Subcommands

Command Description
vex triage <ioc> Fast SOC triage (1 API call)
vex investigate <ioc> Deep DFIR investigation (multiple calls)
vex config Manage configuration (save API key, etc.)
vex cache-clear Clear the SQLite result cache
vex version Show version
vex tag <ioc> Manage IOC tags in local knowledge base
vex note <ioc> Manage IOC notes in local knowledge base
vex watchlist <name> Manage IOC watchlists

Triage / Investigate Options

Flag Description
-k / --api-key VirusTotal API key (overrides env var & config)
-q / --quiet Suppress the ASCII banner
-o / --output Output format: json | rich | console (default: console)
-f / --file File with one IOC per line
-c / --config Custom config.yaml path
--no-cache Bypass cache, force fresh lookup
--csv CSV output (triage only)
--defang Defang IOCs in output
--stix Export as STIX 2.1 JSON bundle
--alert <LEVEL> Only show results >= verdict level
--summary Print verdict summary to stderr
--timeline Show chronological timeline (investigate only)

Configuration Command

Manage vex configuration:

# Save API key permanently
vex config --set-api-key YOUR_KEY

# Show usage
vex config

Saved config is stored at ~/.vex/config.yaml with restricted permissions (0o600).

IOC Types

Type Example
MD5 44d88612fea8a8f36de82e1278abb02f
SHA1 3395856ce81f2b7382dee72602f798b642f14140
SHA256 275a021bbfb6489e54d471899f7db9d1663fc695...
IPv4 8.8.8.8
IPv6 2001:4860:4860::8888
Domain example.com
URL https://example.com/malware.exe

Defanged IOCs are automatically refanged before lookup: hxxps[://]evil[.]com becomes https://evil.com.

Verdict System

Verdict Condition Exit Code
MALICIOUS >= 3 malicious detections 2
SUSPICIOUS >= 1 malicious detection 1
UNKNOWN Zero detections OR too few engines 0
CLEAN Zero detections AND enough engines 0

Zero detections does not mean CLEAN. If too few engines reported, the verdict is UNKNOWN.

MITRE ATT&CK Mapping

In investigate mode, vex maps sandbox behaviors and VT tags to MITRE ATT&CK techniques. Mappings cover 80+ keywords across all major tactics (Execution, Persistence, Defense Evasion, etc.) and appear in Rich output and STIX exports.

Knowledge Base

Manage local IOC metadata that persists across sessions:

# Tag IOCs
vex tag 8.8.8.8 --add dns --add google
vex tag 8.8.8.8  # list tags

# Add notes
vex note evil.com --add "Seen in phishing campaign Q4"
vex note evil.com  # list notes

# Watchlists
vex watchlist priority --add 8.8.8.8 --add evil.com
vex watchlist priority --list

Plugin Architecture

vex uses a Protocol-based plugin system. The built-in VirusTotal plugin implements EnricherProtocol. Third-party sources (OTX, AbuseIPDB, etc.) can be added by implementing the same protocol.


Config Reference

api:
  # key: "your-key"        # or set VT_API_KEY env var
  tier: free                # free | premium
  rate_limit:
    free:
      requests_per_minute: 4
      requests_per_day: 500
    premium:
      requests_per_minute: 1000
      requests_per_day: 50000

thresholds:
  malicious_min_detections: 3
  suspicious_min_detections: 1
  min_engines_for_clean: 10

cache:
  enabled: true
  ttl_hours: 24
  # db_path: "/custom/path/cache.db"  # default: ~/.vex/cache.db

output:
  default_format: json
  quiet: false  # suppress banner (-q)

Project Structure

vex/
├── __init__.py          # Package version (1.1.0)
├── main.py              # Typer CLI app with all subcommands
├── banner.py            # ASCII art banner (ffuf-style)
├── client.py            # Sync VT API v3 client + rate limiter
├── async_client.py      # Async VT API client for parallel ops
├── config.py            # Pydantic config from config.yaml
├── cache.py             # SQLite result cache with TTL
├── ioc_detector.py      # Regex auto-detection of IOC types
├── defang.py            # IOC defanging/refanging
├── models.py            # Pydantic v2 models + Verdict enum
├── batch.py             # Parallel batch processing
├── timeline.py          # Timeline event reconstruction
├── vex.png              # Logo
├── enrichers/
│   ├── base.py          # Shared enricher utilities
│   ├── protocol.py      # EnricherProtocol interface
│   ├── hash.py          # MD5/SHA1/SHA256 enrichment
│   ├── ip.py            # IPv4/IPv6 enrichment
│   ├── domain.py        # Domain enrichment
│   └── url.py           # URL enrichment
├── plugins/
│   ├── registry.py      # Plugin discovery & registration
│   ├── loader.py        # Plugin loading
│   └── virustotal.py    # Built-in VT plugin
├── mitre/
│   ├── mapping.py       # VT behavior → ATT&CK technique dict
│   └── mapper.py        # Result → ATT&CK mapping engine
├── knowledge/
│   ├── db.py            # SQLite knowledge base (tags/notes/watchlists)
│   └── api.py           # High-level knowledge base API
└── output/
    ├── formatter.py     # Rich + console + timeline formatters
    ├── export.py        # JSON + CSV export
    └── stix.py          # STIX 2.1 bundle generation

Built by Christian Huhngithub.com/duathron/vex

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vex_ioc-1.1.0.tar.gz (42.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vex_ioc-1.1.0-py3-none-any.whl (50.3 kB view details)

Uploaded Python 3

File details

Details for the file vex_ioc-1.1.0.tar.gz.

File metadata

  • Download URL: vex_ioc-1.1.0.tar.gz
  • Upload date:
  • Size: 42.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for vex_ioc-1.1.0.tar.gz
Algorithm Hash digest
SHA256 a8cf21a6942afb1f566c0f42813aaa5ed40b0d28dfefca6076683eb3f7f14571
MD5 54f5715471050e2aac3306a85994b697
BLAKE2b-256 565a925b97fee43464fc00f457d359f3a7c7bd3a0485327f1aa062822fc2855a

See more details on using hashes here.

File details

Details for the file vex_ioc-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: vex_ioc-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 50.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for vex_ioc-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f378d8081c60107e5eb9c299fdd134288f576a6d3e156200a3ee51cea4d46daf
MD5 54e048d45c77913b7d5b69981096765e
BLAKE2b-256 28f5c2fd81fc813790c90e995faff667fa12d08bdd49e2b2bd9031f071f5e9a2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page