nessus-export 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.
- nessus_export-0.1.0/LICENSE +21 -0
- nessus_export-0.1.0/PKG-INFO +254 -0
- nessus_export-0.1.0/README.md +234 -0
- nessus_export-0.1.0/nessus_export/__init__.py +4 -0
- nessus_export-0.1.0/nessus_export/__main__.py +6 -0
- nessus_export-0.1.0/nessus_export/cli.py +242 -0
- nessus_export-0.1.0/nessus_export/client.py +178 -0
- nessus_export-0.1.0/nessus_export/exporter.py +110 -0
- nessus_export-0.1.0/nessus_export/reconstruct.py +218 -0
- nessus_export-0.1.0/nessus_export.egg-info/PKG-INFO +254 -0
- nessus_export-0.1.0/nessus_export.egg-info/SOURCES.txt +15 -0
- nessus_export-0.1.0/nessus_export.egg-info/dependency_links.txt +1 -0
- nessus_export-0.1.0/nessus_export.egg-info/entry_points.txt +2 -0
- nessus_export-0.1.0/nessus_export.egg-info/top_level.txt +1 -0
- nessus_export-0.1.0/pyproject.toml +32 -0
- nessus_export-0.1.0/setup.cfg +4 -0
- nessus_export-0.1.0/tests/test_reconstruct.py +94 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 setuidloot
|
|
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.
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nessus-export
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Export Nessus scan results via the API, with a reconstruction fallback for trial-mode servers.
|
|
5
|
+
Author-email: setuidloot <michael@mccord.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/setuidloot/nessus-export
|
|
8
|
+
Project-URL: Issues, https://github.com/setuidloot/nessus-export/issues
|
|
9
|
+
Keywords: nessus,tenable,security,vulnerability,export,scanner
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Information Technology
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Security
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# nessus-export
|
|
22
|
+
|
|
23
|
+
[](https://github.com/setuidloot/nessus-export/actions/workflows/ci.yml)
|
|
24
|
+
[](https://pypi.org/project/nessus-export/)
|
|
25
|
+
[](https://pypi.org/project/nessus-export/)
|
|
26
|
+
[](LICENSE)
|
|
27
|
+
|
|
28
|
+
Export [Nessus](https://www.tenable.com/products/nessus) scan results from the
|
|
29
|
+
command line via the REST API — **with an automatic fallback that reconstructs a
|
|
30
|
+
valid `.nessus` file even when the server's native export is locked** (as it is
|
|
31
|
+
on Nessus Essentials / trial installations).
|
|
32
|
+
|
|
33
|
+
Zero dependencies. Pure Python standard library.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Why this exists
|
|
38
|
+
|
|
39
|
+
Nessus has a perfectly good export API (`POST /scans/{id}/export`). But on
|
|
40
|
+
**Nessus Essentials** and **trial** installations, every export format is
|
|
41
|
+
license-gated. Ask for one and the server refuses:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{ "error": "Export is not allowed in trial mode. Please purchase a full Nessus license to enable exports." }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
That's frustrating, because **the scan data itself is not restricted** — the
|
|
48
|
+
per-scan, per-host, and per-plugin *read* endpoints (`GET /scans/{id}`,
|
|
49
|
+
`GET /scans/{id}/hosts/{host}`, `GET /scans/{id}/hosts/{host}/plugins/{plugin}`)
|
|
50
|
+
return everything: findings, ports/services, severities, CVSS scores, CVEs,
|
|
51
|
+
plugin output, remediation text. The export endpoint is gated; the data is not.
|
|
52
|
+
|
|
53
|
+
**nessus-export** does the obvious thing:
|
|
54
|
+
|
|
55
|
+
1. **Try the native export API first.** If your server is licensed, you get the
|
|
56
|
+
real, byte-for-byte Nessus export (`.nessus`, CSV, PDF, HTML, DB) — no
|
|
57
|
+
reconstruction, nothing lost.
|
|
58
|
+
2. **If the server is in trial mode**, it transparently reads the scan data and
|
|
59
|
+
**reconstructs** a spec-compliant `NessusClientData_v2` (`.nessus`) or CSV
|
|
60
|
+
file itself.
|
|
61
|
+
|
|
62
|
+
The reconstructed `.nessus` imports cleanly back into Nessus and into anything
|
|
63
|
+
else that consumes the format (parsers, dashboards, DefectDojo, etc.).
|
|
64
|
+
|
|
65
|
+
## Install
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install nessus-export
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Or from source:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
git clone https://github.com/setuidloot/nessus-export
|
|
75
|
+
cd nessus-export
|
|
76
|
+
pip install .
|
|
77
|
+
# or run without installing:
|
|
78
|
+
python -m nessus_export --help
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Requires Python 3.8+. No third-party packages.
|
|
82
|
+
|
|
83
|
+
## Authentication
|
|
84
|
+
|
|
85
|
+
Generate API keys in Nessus: **Settings → My Account → API Keys → Generate**.
|
|
86
|
+
|
|
87
|
+
Provide them any of these ways (checked in order):
|
|
88
|
+
|
|
89
|
+
- CLI flags: `--access-key` / `--secret-key`
|
|
90
|
+
- Environment: `ACCESS_KEY` / `SECRET_KEY` (or `NESSUS_ACCESS_KEY` / `NESSUS_SECRET_KEY`)
|
|
91
|
+
- A `.env` file in the working directory (auto-loaded), or `--env-file PATH`
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
cp .env.example .env # then edit in your keys
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Nessus ships a self-signed TLS certificate, so certificate verification is
|
|
98
|
+
**off by default**. Turn it on with `--verify-ssl` (optionally `--ca-bundle`).
|
|
99
|
+
|
|
100
|
+
## Usage
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# List scans on the server
|
|
104
|
+
nessus-export list
|
|
105
|
+
nessus-export list --status completed
|
|
106
|
+
nessus-export list --json
|
|
107
|
+
|
|
108
|
+
# Export one scan by name or id (defaults to .nessus, into the current dir)
|
|
109
|
+
nessus-export export myscan
|
|
110
|
+
nessus-export export 5 -o results.nessus
|
|
111
|
+
|
|
112
|
+
# Pick a format
|
|
113
|
+
nessus-export export myscan -f csv
|
|
114
|
+
nessus-export export myscan -f pdf --chapters vuln_by_host,remediations
|
|
115
|
+
|
|
116
|
+
# Export several scans into a directory
|
|
117
|
+
nessus-export export web-scan db-scan -d ./exports
|
|
118
|
+
nessus-export export --all --status completed -d ./exports
|
|
119
|
+
|
|
120
|
+
# Force behavior
|
|
121
|
+
nessus-export export myscan -m native # native API only (fails under trial)
|
|
122
|
+
nessus-export export myscan -m reconstruct # skip the API, rebuild locally
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Commands
|
|
126
|
+
|
|
127
|
+
| Command | Purpose |
|
|
128
|
+
|----------|-----------------------------------------------------|
|
|
129
|
+
| `list` | List scans (`--status`, `--json`) |
|
|
130
|
+
| `export` | Export one/several/all scans |
|
|
131
|
+
| `status` | Show server status |
|
|
132
|
+
|
|
133
|
+
### Key `export` options
|
|
134
|
+
|
|
135
|
+
| Option | Description |
|
|
136
|
+
|---------------------|-------------------------------------------------------------------|
|
|
137
|
+
| `SCAN…` | One or more scan names or ids |
|
|
138
|
+
| `--all` | Export every scan (combine with `--status`) |
|
|
139
|
+
| `-f, --format` | `nessus` (default), `csv`, `pdf`, `html`, `db` |
|
|
140
|
+
| `-m, --mode` | `auto` (default), `native`, `reconstruct` |
|
|
141
|
+
| `-o, --output` | Output file (single scan) |
|
|
142
|
+
| `-d, --out-dir` | Output directory (multiple scans; filenames from scan names) |
|
|
143
|
+
| `--chapters` | `pdf`/`html` sections, comma-separated |
|
|
144
|
+
| `--db-password` | Required for `-f db` |
|
|
145
|
+
| `-q, --quiet` | Suppress per-step progress |
|
|
146
|
+
|
|
147
|
+
### Export modes
|
|
148
|
+
|
|
149
|
+
- **`auto`** *(default)* — try the native API; if the server reports a
|
|
150
|
+
trial-mode restriction, fall back to reconstruction (for `nessus`/`csv`).
|
|
151
|
+
- **`native`** — only use the API. Exits non-zero under trial mode. Use this
|
|
152
|
+
when you specifically want the licensed, byte-exact export or nothing.
|
|
153
|
+
- **`reconstruct`** — skip the API export entirely and rebuild locally. Handy
|
|
154
|
+
for consistent output across mixed licensed/trial servers.
|
|
155
|
+
|
|
156
|
+
### Formats and modes at a glance
|
|
157
|
+
|
|
158
|
+
| Format | Native (licensed) | Reconstruction fallback (trial) |
|
|
159
|
+
|----------|:-----------------:|:-------------------------------:|
|
|
160
|
+
| `nessus` | ✅ | ✅ |
|
|
161
|
+
| `csv` | ✅ | ✅ |
|
|
162
|
+
| `pdf` | ✅ | ❌ (needs a licensed server) |
|
|
163
|
+
| `html` | ✅ | ❌ (needs a licensed server) |
|
|
164
|
+
| `db` | ✅ | ❌ (needs a licensed server) |
|
|
165
|
+
|
|
166
|
+
`pdf`, `html`, and `db` are report renderings Nessus builds server-side; there's
|
|
167
|
+
no faithful way to reproduce them from the read API, so they require a licensed
|
|
168
|
+
server. In `auto` mode, requesting one on a trial server yields a clear error
|
|
169
|
+
rather than a degraded file.
|
|
170
|
+
|
|
171
|
+
## Caveats when reconstructing (trial mode)
|
|
172
|
+
|
|
173
|
+
When the tool falls back to reconstruction, the **findings are complete and
|
|
174
|
+
faithful** — hosts, ports/services, severities, CVSS v2/v3 scores and vectors,
|
|
175
|
+
CVEs/BIDs/xrefs, synopsis, description, solution, see-also, and plugin output
|
|
176
|
+
are all carried through. But a reconstructed file is **not byte-identical** to a
|
|
177
|
+
licensed export, in these specific ways:
|
|
178
|
+
|
|
179
|
+
1. **The `<Policy>` block is a stub.** A licensed export embeds the full scan
|
|
180
|
+
policy — every server/plugin preference and the plugin-family selection.
|
|
181
|
+
Trial mode does not expose that data through the API, so the policy elements
|
|
182
|
+
are emitted empty. Your *findings* are intact; the scan *configuration*
|
|
183
|
+
metadata is not.
|
|
184
|
+
2. **`HostProperties` is a subset.** It contains what the host-info endpoint
|
|
185
|
+
returns (IP, FQDN, OS, MAC, start/end time, …) — generally fewer tags than a
|
|
186
|
+
native export writes.
|
|
187
|
+
3. **Plugin output honors the API's truncation.** Very large outputs flagged
|
|
188
|
+
`max_attachments_exceeded` by the API are carried through exactly as the API
|
|
189
|
+
returned them (i.e. possibly truncated).
|
|
190
|
+
4. **No attachments.** Binary attachments some plugins produce are not
|
|
191
|
+
reassembled.
|
|
192
|
+
5. **CSV columns approximate** the native Nessus CSV layout; exact column
|
|
193
|
+
ordering/quoting may differ slightly.
|
|
194
|
+
|
|
195
|
+
If any of that matters for your use case, use a licensed server with
|
|
196
|
+
`-m native`. For the common need — "get my findings out in a portable,
|
|
197
|
+
importable format" — the reconstructed `.nessus` does the job.
|
|
198
|
+
|
|
199
|
+
## Supported Nessus versions
|
|
200
|
+
|
|
201
|
+
Developed and verified against **Nessus 10.12.1** (latest at time of writing);
|
|
202
|
+
expected to work on the Nessus 10.x API generally. It uses only long-standing,
|
|
203
|
+
stable REST endpoints, so older 8.x/9.x servers will likely work too but are
|
|
204
|
+
untested. If you run it against another version, a PR updating this section is
|
|
205
|
+
welcome.
|
|
206
|
+
|
|
207
|
+
| Nessus version | Status |
|
|
208
|
+
|----------------|---------------------|
|
|
209
|
+
| 10.12.1 | ✅ Verified |
|
|
210
|
+
| 10.x (other) | 🟡 Expected to work |
|
|
211
|
+
| 8.x – 9.x | 🟡 Likely, untested |
|
|
212
|
+
|
|
213
|
+
## How it works
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
export ──► native API export ──► ready? ──► download (licensed servers)
|
|
217
|
+
│
|
|
218
|
+
└─ trial-mode 403 ──► read scan + hosts + plugins
|
|
219
|
+
└─► serialize NessusClientData_v2 / CSV
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The reconstruction walks every host and every plugin finding, so it makes more
|
|
223
|
+
API calls than a native export — expect it to take longer on large scans.
|
|
224
|
+
|
|
225
|
+
## Library use
|
|
226
|
+
|
|
227
|
+
```python
|
|
228
|
+
from nessus_export.client import NessusClient
|
|
229
|
+
from nessus_export.exporter import export_scan
|
|
230
|
+
|
|
231
|
+
client = NessusClient(url="https://localhost:8834",
|
|
232
|
+
access_key="…", secret_key="…")
|
|
233
|
+
result = export_scan(client, scan_id=5, fmt="nessus", mode="auto")
|
|
234
|
+
open("myscan.nessus", "wb").write(result.content)
|
|
235
|
+
print(result.mode) # "native" or "reconstruct"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Security notes
|
|
239
|
+
|
|
240
|
+
- Never commit your `.env` / API keys. `.gitignore` already excludes `.env` and
|
|
241
|
+
common export artifacts (`*.nessus`, `*.pdf`, `*.db`).
|
|
242
|
+
- Exported scan results contain sensitive vulnerability data — handle and store
|
|
243
|
+
them accordingly.
|
|
244
|
+
|
|
245
|
+
## License
|
|
246
|
+
|
|
247
|
+
MIT — see [LICENSE](LICENSE).
|
|
248
|
+
|
|
249
|
+
## Disclaimer
|
|
250
|
+
|
|
251
|
+
Not affiliated with or endorsed by Tenable, Inc. "Nessus" is a trademark of
|
|
252
|
+
Tenable, Inc. This tool uses only documented REST endpoints and does not
|
|
253
|
+
circumvent licensing: it reads data the API already exposes and formats it
|
|
254
|
+
locally.
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# nessus-export
|
|
2
|
+
|
|
3
|
+
[](https://github.com/setuidloot/nessus-export/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/nessus-export/)
|
|
5
|
+
[](https://pypi.org/project/nessus-export/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
Export [Nessus](https://www.tenable.com/products/nessus) scan results from the
|
|
9
|
+
command line via the REST API — **with an automatic fallback that reconstructs a
|
|
10
|
+
valid `.nessus` file even when the server's native export is locked** (as it is
|
|
11
|
+
on Nessus Essentials / trial installations).
|
|
12
|
+
|
|
13
|
+
Zero dependencies. Pure Python standard library.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Why this exists
|
|
18
|
+
|
|
19
|
+
Nessus has a perfectly good export API (`POST /scans/{id}/export`). But on
|
|
20
|
+
**Nessus Essentials** and **trial** installations, every export format is
|
|
21
|
+
license-gated. Ask for one and the server refuses:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{ "error": "Export is not allowed in trial mode. Please purchase a full Nessus license to enable exports." }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
That's frustrating, because **the scan data itself is not restricted** — the
|
|
28
|
+
per-scan, per-host, and per-plugin *read* endpoints (`GET /scans/{id}`,
|
|
29
|
+
`GET /scans/{id}/hosts/{host}`, `GET /scans/{id}/hosts/{host}/plugins/{plugin}`)
|
|
30
|
+
return everything: findings, ports/services, severities, CVSS scores, CVEs,
|
|
31
|
+
plugin output, remediation text. The export endpoint is gated; the data is not.
|
|
32
|
+
|
|
33
|
+
**nessus-export** does the obvious thing:
|
|
34
|
+
|
|
35
|
+
1. **Try the native export API first.** If your server is licensed, you get the
|
|
36
|
+
real, byte-for-byte Nessus export (`.nessus`, CSV, PDF, HTML, DB) — no
|
|
37
|
+
reconstruction, nothing lost.
|
|
38
|
+
2. **If the server is in trial mode**, it transparently reads the scan data and
|
|
39
|
+
**reconstructs** a spec-compliant `NessusClientData_v2` (`.nessus`) or CSV
|
|
40
|
+
file itself.
|
|
41
|
+
|
|
42
|
+
The reconstructed `.nessus` imports cleanly back into Nessus and into anything
|
|
43
|
+
else that consumes the format (parsers, dashboards, DefectDojo, etc.).
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install nessus-export
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or from source:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/setuidloot/nessus-export
|
|
55
|
+
cd nessus-export
|
|
56
|
+
pip install .
|
|
57
|
+
# or run without installing:
|
|
58
|
+
python -m nessus_export --help
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Requires Python 3.8+. No third-party packages.
|
|
62
|
+
|
|
63
|
+
## Authentication
|
|
64
|
+
|
|
65
|
+
Generate API keys in Nessus: **Settings → My Account → API Keys → Generate**.
|
|
66
|
+
|
|
67
|
+
Provide them any of these ways (checked in order):
|
|
68
|
+
|
|
69
|
+
- CLI flags: `--access-key` / `--secret-key`
|
|
70
|
+
- Environment: `ACCESS_KEY` / `SECRET_KEY` (or `NESSUS_ACCESS_KEY` / `NESSUS_SECRET_KEY`)
|
|
71
|
+
- A `.env` file in the working directory (auto-loaded), or `--env-file PATH`
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
cp .env.example .env # then edit in your keys
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Nessus ships a self-signed TLS certificate, so certificate verification is
|
|
78
|
+
**off by default**. Turn it on with `--verify-ssl` (optionally `--ca-bundle`).
|
|
79
|
+
|
|
80
|
+
## Usage
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# List scans on the server
|
|
84
|
+
nessus-export list
|
|
85
|
+
nessus-export list --status completed
|
|
86
|
+
nessus-export list --json
|
|
87
|
+
|
|
88
|
+
# Export one scan by name or id (defaults to .nessus, into the current dir)
|
|
89
|
+
nessus-export export myscan
|
|
90
|
+
nessus-export export 5 -o results.nessus
|
|
91
|
+
|
|
92
|
+
# Pick a format
|
|
93
|
+
nessus-export export myscan -f csv
|
|
94
|
+
nessus-export export myscan -f pdf --chapters vuln_by_host,remediations
|
|
95
|
+
|
|
96
|
+
# Export several scans into a directory
|
|
97
|
+
nessus-export export web-scan db-scan -d ./exports
|
|
98
|
+
nessus-export export --all --status completed -d ./exports
|
|
99
|
+
|
|
100
|
+
# Force behavior
|
|
101
|
+
nessus-export export myscan -m native # native API only (fails under trial)
|
|
102
|
+
nessus-export export myscan -m reconstruct # skip the API, rebuild locally
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Commands
|
|
106
|
+
|
|
107
|
+
| Command | Purpose |
|
|
108
|
+
|----------|-----------------------------------------------------|
|
|
109
|
+
| `list` | List scans (`--status`, `--json`) |
|
|
110
|
+
| `export` | Export one/several/all scans |
|
|
111
|
+
| `status` | Show server status |
|
|
112
|
+
|
|
113
|
+
### Key `export` options
|
|
114
|
+
|
|
115
|
+
| Option | Description |
|
|
116
|
+
|---------------------|-------------------------------------------------------------------|
|
|
117
|
+
| `SCAN…` | One or more scan names or ids |
|
|
118
|
+
| `--all` | Export every scan (combine with `--status`) |
|
|
119
|
+
| `-f, --format` | `nessus` (default), `csv`, `pdf`, `html`, `db` |
|
|
120
|
+
| `-m, --mode` | `auto` (default), `native`, `reconstruct` |
|
|
121
|
+
| `-o, --output` | Output file (single scan) |
|
|
122
|
+
| `-d, --out-dir` | Output directory (multiple scans; filenames from scan names) |
|
|
123
|
+
| `--chapters` | `pdf`/`html` sections, comma-separated |
|
|
124
|
+
| `--db-password` | Required for `-f db` |
|
|
125
|
+
| `-q, --quiet` | Suppress per-step progress |
|
|
126
|
+
|
|
127
|
+
### Export modes
|
|
128
|
+
|
|
129
|
+
- **`auto`** *(default)* — try the native API; if the server reports a
|
|
130
|
+
trial-mode restriction, fall back to reconstruction (for `nessus`/`csv`).
|
|
131
|
+
- **`native`** — only use the API. Exits non-zero under trial mode. Use this
|
|
132
|
+
when you specifically want the licensed, byte-exact export or nothing.
|
|
133
|
+
- **`reconstruct`** — skip the API export entirely and rebuild locally. Handy
|
|
134
|
+
for consistent output across mixed licensed/trial servers.
|
|
135
|
+
|
|
136
|
+
### Formats and modes at a glance
|
|
137
|
+
|
|
138
|
+
| Format | Native (licensed) | Reconstruction fallback (trial) |
|
|
139
|
+
|----------|:-----------------:|:-------------------------------:|
|
|
140
|
+
| `nessus` | ✅ | ✅ |
|
|
141
|
+
| `csv` | ✅ | ✅ |
|
|
142
|
+
| `pdf` | ✅ | ❌ (needs a licensed server) |
|
|
143
|
+
| `html` | ✅ | ❌ (needs a licensed server) |
|
|
144
|
+
| `db` | ✅ | ❌ (needs a licensed server) |
|
|
145
|
+
|
|
146
|
+
`pdf`, `html`, and `db` are report renderings Nessus builds server-side; there's
|
|
147
|
+
no faithful way to reproduce them from the read API, so they require a licensed
|
|
148
|
+
server. In `auto` mode, requesting one on a trial server yields a clear error
|
|
149
|
+
rather than a degraded file.
|
|
150
|
+
|
|
151
|
+
## Caveats when reconstructing (trial mode)
|
|
152
|
+
|
|
153
|
+
When the tool falls back to reconstruction, the **findings are complete and
|
|
154
|
+
faithful** — hosts, ports/services, severities, CVSS v2/v3 scores and vectors,
|
|
155
|
+
CVEs/BIDs/xrefs, synopsis, description, solution, see-also, and plugin output
|
|
156
|
+
are all carried through. But a reconstructed file is **not byte-identical** to a
|
|
157
|
+
licensed export, in these specific ways:
|
|
158
|
+
|
|
159
|
+
1. **The `<Policy>` block is a stub.** A licensed export embeds the full scan
|
|
160
|
+
policy — every server/plugin preference and the plugin-family selection.
|
|
161
|
+
Trial mode does not expose that data through the API, so the policy elements
|
|
162
|
+
are emitted empty. Your *findings* are intact; the scan *configuration*
|
|
163
|
+
metadata is not.
|
|
164
|
+
2. **`HostProperties` is a subset.** It contains what the host-info endpoint
|
|
165
|
+
returns (IP, FQDN, OS, MAC, start/end time, …) — generally fewer tags than a
|
|
166
|
+
native export writes.
|
|
167
|
+
3. **Plugin output honors the API's truncation.** Very large outputs flagged
|
|
168
|
+
`max_attachments_exceeded` by the API are carried through exactly as the API
|
|
169
|
+
returned them (i.e. possibly truncated).
|
|
170
|
+
4. **No attachments.** Binary attachments some plugins produce are not
|
|
171
|
+
reassembled.
|
|
172
|
+
5. **CSV columns approximate** the native Nessus CSV layout; exact column
|
|
173
|
+
ordering/quoting may differ slightly.
|
|
174
|
+
|
|
175
|
+
If any of that matters for your use case, use a licensed server with
|
|
176
|
+
`-m native`. For the common need — "get my findings out in a portable,
|
|
177
|
+
importable format" — the reconstructed `.nessus` does the job.
|
|
178
|
+
|
|
179
|
+
## Supported Nessus versions
|
|
180
|
+
|
|
181
|
+
Developed and verified against **Nessus 10.12.1** (latest at time of writing);
|
|
182
|
+
expected to work on the Nessus 10.x API generally. It uses only long-standing,
|
|
183
|
+
stable REST endpoints, so older 8.x/9.x servers will likely work too but are
|
|
184
|
+
untested. If you run it against another version, a PR updating this section is
|
|
185
|
+
welcome.
|
|
186
|
+
|
|
187
|
+
| Nessus version | Status |
|
|
188
|
+
|----------------|---------------------|
|
|
189
|
+
| 10.12.1 | ✅ Verified |
|
|
190
|
+
| 10.x (other) | 🟡 Expected to work |
|
|
191
|
+
| 8.x – 9.x | 🟡 Likely, untested |
|
|
192
|
+
|
|
193
|
+
## How it works
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
export ──► native API export ──► ready? ──► download (licensed servers)
|
|
197
|
+
│
|
|
198
|
+
└─ trial-mode 403 ──► read scan + hosts + plugins
|
|
199
|
+
└─► serialize NessusClientData_v2 / CSV
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The reconstruction walks every host and every plugin finding, so it makes more
|
|
203
|
+
API calls than a native export — expect it to take longer on large scans.
|
|
204
|
+
|
|
205
|
+
## Library use
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
from nessus_export.client import NessusClient
|
|
209
|
+
from nessus_export.exporter import export_scan
|
|
210
|
+
|
|
211
|
+
client = NessusClient(url="https://localhost:8834",
|
|
212
|
+
access_key="…", secret_key="…")
|
|
213
|
+
result = export_scan(client, scan_id=5, fmt="nessus", mode="auto")
|
|
214
|
+
open("myscan.nessus", "wb").write(result.content)
|
|
215
|
+
print(result.mode) # "native" or "reconstruct"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Security notes
|
|
219
|
+
|
|
220
|
+
- Never commit your `.env` / API keys. `.gitignore` already excludes `.env` and
|
|
221
|
+
common export artifacts (`*.nessus`, `*.pdf`, `*.db`).
|
|
222
|
+
- Exported scan results contain sensitive vulnerability data — handle and store
|
|
223
|
+
them accordingly.
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
MIT — see [LICENSE](LICENSE).
|
|
228
|
+
|
|
229
|
+
## Disclaimer
|
|
230
|
+
|
|
231
|
+
Not affiliated with or endorsed by Tenable, Inc. "Nessus" is a trademark of
|
|
232
|
+
Tenable, Inc. This tool uses only documented REST endpoints and does not
|
|
233
|
+
circumvent licensing: it reads data the API already exposes and formats it
|
|
234
|
+
locally.
|