Skip to main content
Malwagon logo

malwagon

Scan a file for malware from your terminal, and get a scored verdict back

Automated malware analysis sandbox in one command. Upload a file and it detonates in an isolated virtual machine, observed agentless at the hypervisor layer, so there is no in-guest agent for a sample to find, unhook or disable. Windows kernel drivers get a dedicated BYOVD analysis module, and an AI layer explains the run in words. You get back a scored verdict, the indicators behind it, and an exit code your pipeline can gate on.

PyPI Python License Dependencies Platforms

Install · Quick start · Why it is different · Screenshots · CI/CD · FAQ


malwagon CLI scanning a suspicious executable and printing a malicious verdict with a score of 100 out of 100 and a link to the full sandbox report

📦 Install

pip install malwagon

That is the whole dependency list: none. The standard library makes the HTTPS request, so installing a malware analysis client does not widen your supply chain by four packages.

Works on Linux, macOS and Windows, Python 3.8+.

⚡ Quick start

# 1. get a free API key at https://malwagon.com  (Settings -> API tokens)
export MALWAGON_API_KEY=mwg_...

# 2. scan anything
malwagon suspicious.exe
malwagon driver.sys
malwagon payload.elf
malwagon dropper.ps1
malwagon invoice.docm
$ malwagon suspicious.exe
uploading suspicious.exe (412.0 KB) to malwagon.com
scan 48213 queued
waiting for the sandbox, usually 90 to 300 seconds
  queued       0s elapsed
  running      12s elapsed
  analyzing    2m 18s elapsed

  MALICIOUS  score 88/100
  sha256 354fd5f5e4afc2280a19c8541fd4abe38bf8fb73efbeb3c2b0a4f2b1d9e0c7a1
  report https://malwagon.com/s/48213

The sandbox is chosen from the file. A Windows binary detonates on Windows, an ELF or a pip package on the Linux sandbox, a kernel driver reaches the BYOVD analyzer. There is no flag to get wrong.

💻 Three ways to run it

Installed command malwagon suspicious.exe
Python module python -m malwagon suspicious.exe
From a clone, no install git clone https://github.com/Malwagon/malwagon-cli && cd malwagon-cli
PYTHONPATH=src python -m malwagon suspicious.exe

As a Python library

The client is importable, so a script can submit and poll without shelling out:

import os, time
from malwagon.client import Client

client = Client("https://malwagon.com", os.environ["MALWAGON_API_KEY"])

with open("suspicious.exe", "rb") as handle:
    status, body, _ = client.submit_file(handle, "suspicious.exe", {"private": "true"})

scan_id = body["scan"]["scan_id"]
print("report:", client.report_url(scan_id))

while True:
    status, body, _ = client.scan_status(scan_id)
    scan = body["scan"]
    if scan["terminal"]:
        break
    time.sleep(10)

print(scan["verdict"], scan["score"])     # -> malicious 88

Every response is bounded before it is parsed, TLS is verified, and redirects are never followed. See What this client will not do.


🔮 Why this sandbox is different

🧭 Hypervisor-level, agentless observation

Behaviour is recorded from outside the guest. The analysis is logged at the hypervisor layer rather than by a driver or a hooking DLL installed inside the virtual machine, so there is no in-guest agent for a sample to find, unhook or disable. Malware that checks for analysis tooling in its own process space finds an ordinary Windows desktop.

Real virtual machines on real hardware the operator runs. Not an emulator, not a container.

🛡 BYOVD and kernel driver analysis

A dedicated module for Windows kernel-mode PE images. Bring Your Own Vulnerable Driver is how modern ransomware turns off endpoint protection, and a driver is not an ordinary executable: the questions are which primitive it hands to user mode, which control codes reach it, and whether the world already knows it is abusable.

The kernel module returns the IOCTL dispatch surface, the privileged hardware access in the code (physical memory mapping, MSR access, arbitrary process termination), the signing and mitigation state, an ATT&CK mapping in kill-chain order, and generated Sigma rules as a downloadable bundle.

Every import, rule and hardware primitive is weighed against how common it is across a corpus of real signed drivers, so an ordinary call is not reported as a finding.

🧠 AI analysis on derived data only

The narrative layer explains the run in words, and never sees the sample. It receives a behaviour summary, the API call sequence, the indicator list and non-sensitive extracted strings, assembled locally by one module that copies named fields and drops everything else.

The raw sample is never sent to any model, and never leaves the analysis host. The AI layer reads what the platform already worked out; it does not do the working out.

📈 Four layers, one score

Layer What it contributes
Static PE structure, packing and signing, capability detection, YARA, extracted strings
Dynamic Process tree, file and registry activity, network, persistence, memory, screen recording
Threat intelligence Reputation on hashes and derived indicators, open indicator feeds
AI A written explanation of what the run did, from derived data only

Each layer's contribution to the score is shown, so a verdict is auditable rather than an oracle.


🖼 Screenshots

The platform this client talks to

Drop a file in the browser, or send it from your shell with the same account. Seven submission modules: file, hash, command, URL, document, package and Windows kernel driver.

Malwagon malware analysis sandbox home page showing the file, hash, command, URL, document, package and kernel driver submission tabs above a drag and drop upload area

The report a scan produces

Score, the reasoning behind it, which layers ran and what each one moved.

Malwagon scan report showing a malicious verdict scoring 100 out of 100, the runtime behaviour, persistence, threat intelligence and static analysis contributions to the score, and which analysis layers ran

⚙ Options

malwagon FILE [options]
Option Effect
--json Print one JSON object and nothing else
--no-wait Submit and exit immediately with the scan id
--private Keep the report private (needs a plan that includes it)
--internet Detonate with internet access (paid plans)
--os KEY Force a sandbox image instead of letting the file decide
--timeout-run N How long the sample runs inside the sandbox
--no-dynamic Static analysis only, no detonation
--quiet Drop the progress lines, keep the result
--api-key-file PATH Read the key from a file
--api-key-stdin Read the key from stdin
--ca-bundle PATH Verify TLS against your own CA bundle

malwagon --help lists every option.

Machine-readable output

$ malwagon sample.dll --json
{
  "limitations": [],
  "report_url": "https://malwagon.com/s/48213",
  "scan_id": 48213,
  "score": 88,
  "sha256": "354fd5f5e4afc2280a19c8541fd4abe38bf8fb73efbeb3c2b0a4f2b1d9e0c7a1",
  "size": 421888,
  "status": "completed",
  "verdict": "malicious",
  "verdict_raw": null
}

Progress goes to stderr and the result to stdout, so malwagon sample.bin --json | jq works while you still watch the wait.


🛠 Use it in CI/CD

The exit code is the verdict, so a build step can gate on it with no parsing:

Code Meaning
0 Clean
1 Malicious
2 Error
3 Suspicious
malwagon dist/installer.exe --quiet || { echo "do not ship this"; exit 1; }

GitHub Actions

- name: Detonate the release artifact
  env:
    MALWAGON_API_KEY: ${{ secrets.MALWAGON_API_KEY }}
  run: |
    pip install malwagon
    malwagon dist/installer.exe --json --quiet | tee scan.json

GitLab CI

malware-scan:
  script:
    - pip install malwagon
    - malwagon dist/installer.exe --quiet

Useful for scanning build artifacts before release, third-party binaries before they reach a fleet, and attachments pulled out of a phishing report.


🔒 Authentication

The key comes from one of these, highest first:

  1. --api-key-file PATH
  2. --api-key-stdin
  3. MALWAGON_API_KEY in the environment
  4. the config file written by malwagon login
  5. an interactive prompt when stdin is a terminal
$ malwagon login
Malwagon API key for malwagon.com:
key accepted and saved to ~/.config/malwagon/config.json

The file is created mode 0600, and the client refuses to read it if the rest of the machine can.

There is deliberately no --api-key flag. A credential on the command line is visible to every process on the machine through the process list, and is written verbatim into your shell history and into CI job logs. The absence is a feature, and there is a test that keeps it absent.


🛡 What this client will not do

Everything here is enforced in code, and each one has a test:

  • It will not disable TLS verification. There is no --insecure, and there will not be one. --ca-bundle exists for a private deployment.
  • It will not follow redirects. A redirect is the standard way a bearer token is walked onto a host it was not issued for. The client reports the Location instead of chasing it.
  • It will not send your key to a host it was not stored for. Keys are bound per host, so --api-url https://evil.example cannot harvest a credential stored for somewhere else.
  • It will not send plain HTTP anywhere but loopback.
  • It will not upload what you did not mean to upload. Symlinks, devices, pipes, directories, empty files and anything shaped like a private key or a credential file are refused unless you insist. Every check is made on the open file descriptor rather than on the path, so there is no window between the check and the read.
  • It will not trust the server's text on your terminal. ANSI escapes, carriage returns, OSC 8 hyperlinks, clipboard writes and bidirectional overrides are stripped before anything is printed, and the verdict is read from a fixed vocabulary rather than echoed as the server spelled it.
  • It will not parse an unbounded response. Bodies are capped before decoding, and the cap applies to the decompressed stream.

💰 Plans

A free Community key works and runs a network isolated scan: no internet egress from the sandbox, and no threat intelligence or AI layer on the report.

The client says which layers did not run, rather than leaving an empty section to be read as "the sample did nothing":

  CLEAN  score 10/100
  report https://malwagon.com/s/48213

  - threat intelligence lookups did not run
  - the AI narrative did not run
    a paid plan adds internet egress, threat intelligence and the
    AI narrative to this report
Community Paid
File, driver, document and script analysis Yes Yes
Hypervisor-level dynamic analysis Yes Yes
Live VNC while the sample runs Yes Yes
Internet egress from the sandbox No Yes
Threat intelligence enrichment No Yes
AI narrative No Yes
Private reports No Yes

❓ FAQ

What is a malware analysis sandbox?

A malware analysis sandbox runs a suspicious file inside an isolated virtual machine and records what it actually does: the processes it starts, the files and registry keys it touches, the network it reaches and the persistence it installs. It answers "what does this do" rather than "does a signature match".

How do I scan a file for malware from the command line?

Install the client with pip install malwagon, set MALWAGON_API_KEY, then run malwagon suspicious.exe. The command uploads the file, waits for the detonation, prints a scored verdict and a link to the full report, and exits 1 if the verdict is malicious.

Is it free?

Yes, on the Community plan. Scans run network isolated and without the threat intelligence and AI layers. Paid plans add internet egress, reputation enrichment, the AI narrative and private reports.

Does the sample leave my machine?

Yes, it is uploaded to the analysis platform, because it has to be detonated there. Use --private on a plan that includes private reports if the analysis should not be published to the public corpus.

What is agentless sandbox analysis?

Agentless means behaviour is recorded from outside the guest, at the hypervisor layer, rather than by software installed inside the virtual machine. There is no in-guest agent for a sample to detect, unhook or disable.

What is BYOVD?

Bring Your Own Vulnerable Driver: an attacker loads a legitimately signed but exploitable kernel driver to get kernel-level access, typically to disable endpoint protection. The kernel driver module analyses the driver's IOCTL dispatch surface and privileged hardware access to answer whether it hands that primitive out.

Can I use it in a CI pipeline?

Yes. The exit code is the verdict (0 clean, 1 malicious, 3 suspicious), so a build step gates on it with no parsing. --json gives a machine-readable object on stdout while progress stays on stderr.

Does it work on Windows?

Yes. Linux, macOS and Windows, Python 3.8 and newer. The client uses no POSIX-only calls without a guard, and the config file lives under %APPDATA% on Windows.

What file types can it analyse?

Windows executables and DLLs, Windows kernel drivers (.sys), Linux ELF binaries, Office documents and PDFs, scripts (PowerShell, batch, VBS, JS, Python), archives, and pip packages. The platform types the sample by its content, not by its extension.


🔗 Links

Platform https://malwagon.com
API reference https://malwagon.com/docs/api
Command line docs https://malwagon.com/docs/api#cli
Public scan corpus https://malwagon.com/samples
PyPI package https://pypi.org/project/malwagon/

📜 License

MIT. See LICENSE.


Keywords · malware analysis sandbox · automated malware analysis · dynamic analysis · static analysis · hypervisor-level monitoring · agentless sandbox · BYOVD · vulnerable driver analysis · kernel driver analysis · AI malware analysis · threat intelligence · IOC extraction · YARA · Sigma rules · MITRE ATT&CK · DFIR · malware sandbox CLI · malware scanning API · CI/CD malware scanning

Download files

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

Source Distribution

malwagon-0.1.2.tar.gz (470.7 kB view details)

Uploaded Source

Built Distribution

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

malwagon-0.1.2-py3-none-any.whl (28.5 kB view details)

Uploaded Python 3

File details

Details for the file malwagon-0.1.2.tar.gz.

File metadata

  • Download URL: malwagon-0.1.2.tar.gz
  • Upload date:
  • Size: 470.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for malwagon-0.1.2.tar.gz
Algorithm Hash digest
SHA256 f9cf7edeaa61ace6d1e089cd0eb900e5d490ea6a23233ee1500f99922cd08ca0
MD5 8b75826a790e17aa987095d2e7aadf75
BLAKE2b-256 f83351577cd52d382405dd0418fc1b277924832ced82abc6e26c836f351ba156

See more details on using hashes here.

File details

Details for the file malwagon-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: malwagon-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 28.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for malwagon-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 88dba71043b7775d64d151e06e9c85e72040230b53d4f01b6778b42f80ffe13a
MD5 aa27cc822bb816610b1661fcfdce0b6e
BLAKE2b-256 fe430223618ad9c26d47ab0e1aa20dc2c1c0fe80a2c3496fb126a253224cd92a

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.3

2 files

This release

0.1.2 This release

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page