malwagon 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- malwagon-0.1.0/.gitignore +4 -0
- malwagon-0.1.0/LICENSE +21 -0
- malwagon-0.1.0/PKG-INFO +165 -0
- malwagon-0.1.0/README.md +133 -0
- malwagon-0.1.0/pyproject.toml +56 -0
- malwagon-0.1.0/src/malwagon/__init__.py +13 -0
- malwagon-0.1.0/src/malwagon/cli.py +407 -0
- malwagon-0.1.0/src/malwagon/client.py +237 -0
- malwagon-0.1.0/src/malwagon/config.py +210 -0
- malwagon-0.1.0/src/malwagon/errors.py +17 -0
- malwagon-0.1.0/src/malwagon/localfile.py +145 -0
- malwagon-0.1.0/src/malwagon/render.py +165 -0
malwagon-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Malwagon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
malwagon-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: malwagon
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Submit a file to the Malwagon malware analysis sandbox and print the verdict.
|
|
5
|
+
Project-URL: Homepage, https://malwagon.com
|
|
6
|
+
Project-URL: Documentation, https://malwagon.com/docs/api
|
|
7
|
+
Author-email: Malwagon <info@malwagon.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: cli,dfir,malware,malware-analysis,sandbox,security,threat-intelligence
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Information Technology
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
27
|
+
Classifier: Topic :: Security
|
|
28
|
+
Classifier: Topic :: System :: Systems Administration
|
|
29
|
+
Classifier: Topic :: Utilities
|
|
30
|
+
Requires-Python: >=3.8
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# malwagon
|
|
34
|
+
|
|
35
|
+
Submit a file to the [Malwagon](https://malwagon.com) malware analysis sandbox
|
|
36
|
+
from the command line, wait for the detonation to finish, and print the verdict.
|
|
37
|
+
|
|
38
|
+
```console
|
|
39
|
+
$ malwagon suspicious.exe
|
|
40
|
+
uploading suspicious.exe (412.0 KB) to malwagon.com
|
|
41
|
+
scan 48213 queued
|
|
42
|
+
waiting for the sandbox, usually 90 to 300 seconds
|
|
43
|
+
queued 0s elapsed
|
|
44
|
+
running 12s elapsed
|
|
45
|
+
analyzing 2m 18s elapsed
|
|
46
|
+
|
|
47
|
+
MALICIOUS score 88/100
|
|
48
|
+
sha256 354fd5f5e4afc2280a19c8541fd4abe38bf8fb73efbeb3c2b0a4f2b1d9e0c7a1
|
|
49
|
+
report https://malwagon.com/s/48213
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
```console
|
|
55
|
+
pip install malwagon
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Works on Linux, macOS and Windows, on Python 3.8 and newer. It has **no
|
|
59
|
+
dependencies** - the standard library makes the request.
|
|
60
|
+
|
|
61
|
+
## An API key
|
|
62
|
+
|
|
63
|
+
Every scan needs one. Mint it in the console under **Settings -> API tokens**,
|
|
64
|
+
give it the submit permission, then store it once:
|
|
65
|
+
|
|
66
|
+
```console
|
|
67
|
+
$ malwagon login
|
|
68
|
+
Malwagon API key for malwagon.com:
|
|
69
|
+
key accepted and saved to ~/.config/malwagon/config.json
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Or keep it in the environment instead, which is what CI usually wants:
|
|
73
|
+
|
|
74
|
+
```console
|
|
75
|
+
export MALWAGON_API_KEY=mwg_...
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
There is deliberately **no `--api-key` flag**. A key on the command line is
|
|
79
|
+
visible to every process on the machine and is written verbatim into your shell
|
|
80
|
+
history.
|
|
81
|
+
|
|
82
|
+
## Usage
|
|
83
|
+
|
|
84
|
+
```console
|
|
85
|
+
malwagon FILE [options]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
| | |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `--json` | print one JSON object and nothing else |
|
|
91
|
+
| `--no-wait` | submit and exit with the scan id |
|
|
92
|
+
| `--private` | keep the report private (needs a plan that includes it) |
|
|
93
|
+
| `--internet` | detonate with internet access (paid plans only) |
|
|
94
|
+
| `--os KEY` | force a sandbox image |
|
|
95
|
+
| `--timeout-run N` | how long to let the sample run |
|
|
96
|
+
| `--quiet` | drop the progress lines, keep the result |
|
|
97
|
+
|
|
98
|
+
`malwagon --help` lists all of them.
|
|
99
|
+
|
|
100
|
+
**The sandbox is chosen from the file, not from a flag.** A Windows binary
|
|
101
|
+
detonates on Windows, an ELF or a Python package on the Linux sandbox, a driver
|
|
102
|
+
reaches the kernel analyzer. Pass `--os` only when you want to override that.
|
|
103
|
+
|
|
104
|
+
## Exit codes
|
|
105
|
+
|
|
106
|
+
| code | meaning |
|
|
107
|
+
|---|---|
|
|
108
|
+
| 0 | clean |
|
|
109
|
+
| 1 | malicious |
|
|
110
|
+
| 2 | error |
|
|
111
|
+
| 3 | suspicious |
|
|
112
|
+
|
|
113
|
+
So a pipeline can gate on it:
|
|
114
|
+
|
|
115
|
+
```console
|
|
116
|
+
malwagon build/output.exe --quiet || echo "do not ship this"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Machine-readable output
|
|
120
|
+
|
|
121
|
+
```console
|
|
122
|
+
$ malwagon sample.dll --json
|
|
123
|
+
{
|
|
124
|
+
"limitations": [],
|
|
125
|
+
"report_url": "https://malwagon.com/s/48213",
|
|
126
|
+
"scan_id": 48213,
|
|
127
|
+
"score": 88,
|
|
128
|
+
"sha256": "354fd5f5e4afc2280a19c8541fd4abe38bf8fb73efbeb3c2b0a4f2b1d9e0c7a1",
|
|
129
|
+
"size": 421888,
|
|
130
|
+
"status": "completed",
|
|
131
|
+
"verdict": "malicious",
|
|
132
|
+
"verdict_raw": null
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Progress goes to stderr and the result to stdout, so `| jq` works while you
|
|
137
|
+
still see the wait.
|
|
138
|
+
|
|
139
|
+
## Plans
|
|
140
|
+
|
|
141
|
+
A Community key works and runs a **network isolated** scan: no internet egress
|
|
142
|
+
from the sandbox, and no threat intelligence or AI layer on the report. The tool
|
|
143
|
+
says so under the verdict when a layer did not run, rather than leaving an empty
|
|
144
|
+
section to be read as "the sample did nothing". A paid plan adds egress,
|
|
145
|
+
reputation lookups and the AI narrative.
|
|
146
|
+
|
|
147
|
+
## What this client will not do
|
|
148
|
+
|
|
149
|
+
- It will not send your key over plain HTTP, or to a host other than the one the
|
|
150
|
+
key was stored for.
|
|
151
|
+
- It has no `--insecure`. TLS is verified, always. `--ca-bundle` exists for a
|
|
152
|
+
private deployment.
|
|
153
|
+
- It does not follow redirects, because that is how a bearer token walks onto
|
|
154
|
+
somebody else's host.
|
|
155
|
+
- It refuses a symlink, a device, a pipe and anything that looks like a private
|
|
156
|
+
key or a credential file, unless you insist.
|
|
157
|
+
- It treats everything the server sends as untrusted text: terminal escapes,
|
|
158
|
+
overwrite characters and bidirectional overrides are removed before anything
|
|
159
|
+
is printed, and the verdict is looked up in a fixed table rather than printed
|
|
160
|
+
as the server spelled it.
|
|
161
|
+
|
|
162
|
+
## Links
|
|
163
|
+
|
|
164
|
+
- Platform: <https://malwagon.com>
|
|
165
|
+
- API reference: <https://malwagon.com/docs/api>
|
malwagon-0.1.0/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# malwagon
|
|
2
|
+
|
|
3
|
+
Submit a file to the [Malwagon](https://malwagon.com) malware analysis sandbox
|
|
4
|
+
from the command line, wait for the detonation to finish, and print the verdict.
|
|
5
|
+
|
|
6
|
+
```console
|
|
7
|
+
$ malwagon suspicious.exe
|
|
8
|
+
uploading suspicious.exe (412.0 KB) to malwagon.com
|
|
9
|
+
scan 48213 queued
|
|
10
|
+
waiting for the sandbox, usually 90 to 300 seconds
|
|
11
|
+
queued 0s elapsed
|
|
12
|
+
running 12s elapsed
|
|
13
|
+
analyzing 2m 18s elapsed
|
|
14
|
+
|
|
15
|
+
MALICIOUS score 88/100
|
|
16
|
+
sha256 354fd5f5e4afc2280a19c8541fd4abe38bf8fb73efbeb3c2b0a4f2b1d9e0c7a1
|
|
17
|
+
report https://malwagon.com/s/48213
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```console
|
|
23
|
+
pip install malwagon
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Works on Linux, macOS and Windows, on Python 3.8 and newer. It has **no
|
|
27
|
+
dependencies** - the standard library makes the request.
|
|
28
|
+
|
|
29
|
+
## An API key
|
|
30
|
+
|
|
31
|
+
Every scan needs one. Mint it in the console under **Settings -> API tokens**,
|
|
32
|
+
give it the submit permission, then store it once:
|
|
33
|
+
|
|
34
|
+
```console
|
|
35
|
+
$ malwagon login
|
|
36
|
+
Malwagon API key for malwagon.com:
|
|
37
|
+
key accepted and saved to ~/.config/malwagon/config.json
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Or keep it in the environment instead, which is what CI usually wants:
|
|
41
|
+
|
|
42
|
+
```console
|
|
43
|
+
export MALWAGON_API_KEY=mwg_...
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
There is deliberately **no `--api-key` flag**. A key on the command line is
|
|
47
|
+
visible to every process on the machine and is written verbatim into your shell
|
|
48
|
+
history.
|
|
49
|
+
|
|
50
|
+
## Usage
|
|
51
|
+
|
|
52
|
+
```console
|
|
53
|
+
malwagon FILE [options]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
| | |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `--json` | print one JSON object and nothing else |
|
|
59
|
+
| `--no-wait` | submit and exit with the scan id |
|
|
60
|
+
| `--private` | keep the report private (needs a plan that includes it) |
|
|
61
|
+
| `--internet` | detonate with internet access (paid plans only) |
|
|
62
|
+
| `--os KEY` | force a sandbox image |
|
|
63
|
+
| `--timeout-run N` | how long to let the sample run |
|
|
64
|
+
| `--quiet` | drop the progress lines, keep the result |
|
|
65
|
+
|
|
66
|
+
`malwagon --help` lists all of them.
|
|
67
|
+
|
|
68
|
+
**The sandbox is chosen from the file, not from a flag.** A Windows binary
|
|
69
|
+
detonates on Windows, an ELF or a Python package on the Linux sandbox, a driver
|
|
70
|
+
reaches the kernel analyzer. Pass `--os` only when you want to override that.
|
|
71
|
+
|
|
72
|
+
## Exit codes
|
|
73
|
+
|
|
74
|
+
| code | meaning |
|
|
75
|
+
|---|---|
|
|
76
|
+
| 0 | clean |
|
|
77
|
+
| 1 | malicious |
|
|
78
|
+
| 2 | error |
|
|
79
|
+
| 3 | suspicious |
|
|
80
|
+
|
|
81
|
+
So a pipeline can gate on it:
|
|
82
|
+
|
|
83
|
+
```console
|
|
84
|
+
malwagon build/output.exe --quiet || echo "do not ship this"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Machine-readable output
|
|
88
|
+
|
|
89
|
+
```console
|
|
90
|
+
$ malwagon sample.dll --json
|
|
91
|
+
{
|
|
92
|
+
"limitations": [],
|
|
93
|
+
"report_url": "https://malwagon.com/s/48213",
|
|
94
|
+
"scan_id": 48213,
|
|
95
|
+
"score": 88,
|
|
96
|
+
"sha256": "354fd5f5e4afc2280a19c8541fd4abe38bf8fb73efbeb3c2b0a4f2b1d9e0c7a1",
|
|
97
|
+
"size": 421888,
|
|
98
|
+
"status": "completed",
|
|
99
|
+
"verdict": "malicious",
|
|
100
|
+
"verdict_raw": null
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Progress goes to stderr and the result to stdout, so `| jq` works while you
|
|
105
|
+
still see the wait.
|
|
106
|
+
|
|
107
|
+
## Plans
|
|
108
|
+
|
|
109
|
+
A Community key works and runs a **network isolated** scan: no internet egress
|
|
110
|
+
from the sandbox, and no threat intelligence or AI layer on the report. The tool
|
|
111
|
+
says so under the verdict when a layer did not run, rather than leaving an empty
|
|
112
|
+
section to be read as "the sample did nothing". A paid plan adds egress,
|
|
113
|
+
reputation lookups and the AI narrative.
|
|
114
|
+
|
|
115
|
+
## What this client will not do
|
|
116
|
+
|
|
117
|
+
- It will not send your key over plain HTTP, or to a host other than the one the
|
|
118
|
+
key was stored for.
|
|
119
|
+
- It has no `--insecure`. TLS is verified, always. `--ca-bundle` exists for a
|
|
120
|
+
private deployment.
|
|
121
|
+
- It does not follow redirects, because that is how a bearer token walks onto
|
|
122
|
+
somebody else's host.
|
|
123
|
+
- It refuses a symlink, a device, a pipe and anything that looks like a private
|
|
124
|
+
key or a credential file, unless you insist.
|
|
125
|
+
- It treats everything the server sends as untrusted text: terminal escapes,
|
|
126
|
+
overwrite characters and bidirectional overrides are removed before anything
|
|
127
|
+
is printed, and the verdict is looked up in a fixed table rather than printed
|
|
128
|
+
as the server spelled it.
|
|
129
|
+
|
|
130
|
+
## Links
|
|
131
|
+
|
|
132
|
+
- Platform: <https://malwagon.com>
|
|
133
|
+
- API reference: <https://malwagon.com/docs/api>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "malwagon"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Submit a file to the Malwagon malware analysis sandbox and print the verdict."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Malwagon", email = "info@malwagon.com" }]
|
|
14
|
+
keywords = ["malware", "malware-analysis", "sandbox", "security", "threat-intelligence", "cli", "dfir"]
|
|
15
|
+
dependencies = []
|
|
16
|
+
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 4 - Beta",
|
|
19
|
+
"Environment :: Console",
|
|
20
|
+
"Intended Audience :: Information Technology",
|
|
21
|
+
"Intended Audience :: System Administrators",
|
|
22
|
+
"Intended Audience :: Developers",
|
|
23
|
+
"Topic :: Security",
|
|
24
|
+
"Topic :: System :: Systems Administration",
|
|
25
|
+
"Topic :: Utilities",
|
|
26
|
+
"Operating System :: OS Independent",
|
|
27
|
+
"Operating System :: POSIX :: Linux",
|
|
28
|
+
"Operating System :: Microsoft :: Windows",
|
|
29
|
+
"Operating System :: MacOS :: MacOS X",
|
|
30
|
+
"Programming Language :: Python :: 3",
|
|
31
|
+
"Programming Language :: Python :: 3.8",
|
|
32
|
+
"Programming Language :: Python :: 3.9",
|
|
33
|
+
"Programming Language :: Python :: 3.10",
|
|
34
|
+
"Programming Language :: Python :: 3.11",
|
|
35
|
+
"Programming Language :: Python :: 3.12",
|
|
36
|
+
"Programming Language :: Python :: 3.13",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://malwagon.com"
|
|
41
|
+
Documentation = "https://malwagon.com/docs/api"
|
|
42
|
+
|
|
43
|
+
[project.scripts]
|
|
44
|
+
malwagon = "malwagon.cli:main"
|
|
45
|
+
|
|
46
|
+
[tool.hatch.version]
|
|
47
|
+
path = "src/malwagon/__init__.py"
|
|
48
|
+
|
|
49
|
+
[tool.hatch.build.targets.wheel]
|
|
50
|
+
packages = ["src/malwagon"]
|
|
51
|
+
|
|
52
|
+
# An ALLOWLIST, never an exclude list. An sdist built by exclusion ships
|
|
53
|
+
# whatever happened to be sitting in the directory, and this package must be
|
|
54
|
+
# provably free of anything that is not these five things.
|
|
55
|
+
[tool.hatch.build.targets.sdist]
|
|
56
|
+
include = ["src", "README.md", "LICENSE", "pyproject.toml"]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Malwagon command line client.
|
|
2
|
+
|
|
3
|
+
Submits a file to the Malwagon malware analysis sandbox, waits for the
|
|
4
|
+
detonation to finish, and prints the verdict.
|
|
5
|
+
|
|
6
|
+
Standard library only, on purpose. A security tool that pulls four transitive
|
|
7
|
+
dependencies to make one HTTPS request has widened its own supply chain for a
|
|
8
|
+
convenience, and every one of those maintainer keys becomes a way into the
|
|
9
|
+
machines this runs on.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
__version__ = "0.1.0"
|
|
13
|
+
__all__ = ["__version__"]
|