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.
Install · Quick start · Why it is different · Screenshots · CI/CD · FAQ
pip install malwagonThat 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+.
# 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/48213The 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.
| 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-cliPYTHONPATH=src python -m malwagon suspicious.exe |
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 88Every response is bounded before it is parsed, TLS is verified, and redirects are never followed. See What this client will not do.
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.
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.
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.
| 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.
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.
Score, the reasoning behind it, which layers ran and what each one moved.
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.
$ 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.
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.jsonGitLab CI
malware-scan:
script:
- pip install malwagon
- malwagon dist/installer.exe --quietUseful for scanning build artifacts before release, third-party binaries before they reach a fleet, and attachments pulled out of a phishing report.
The key comes from one of these, highest first:
--api-key-file PATH--api-key-stdinMALWAGON_API_KEYin the environment- the config file written by
malwagon login - an interactive prompt when stdin is a terminal
$ malwagon login
Malwagon API key for malwagon.com:
key accepted and saved to ~/.config/malwagon/config.jsonThe file is created mode 0600, and the client refuses to read it if the rest of the machine can.
There is deliberately no
--api-keyflag. 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.
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-bundleexists 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
Locationinstead 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.examplecannot 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.
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 |
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".
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.
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.
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.
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.
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.
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.
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.
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.
| 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/ |
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


