Skip to content

Commit 32f07f4

Browse files
committed
Initial commit
0 parents  commit 32f07f4

22 files changed

Lines changed: 4606 additions & 0 deletions

.github/CODEOWNERS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Code owners for sparkplugFuzzer.
2+
# These owners are requested for review on every pull request and must
3+
# approve changes to satisfy the "require code owner review" branch rule.
4+
* @BishopFox/bf-consultants

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
output.txt
2+
sparkplug_fuzz.json
3+
sparkplug_fuzz.jsonl
4+
fuzzer.7z
5+
blog-post-outline.md
6+
CLAUDE.md
7+
SIDEQUESTS.md
8+
PLAN.md
9+
__pycache__/
10+
.claude/
11+
.pytest_cache/
12+
tahu/
13+
sparkplug_b.py
14+
array_packer.py
15+
sparkplug_b_pb2.py
16+
sparkplug_b.proto

CHANGELOG.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Changelog
2+
3+
All notable changes to this project are documented here. The format follows
4+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project
5+
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
## [Unreleased]
8+
9+
### Added
10+
11+
- `--extra-string-payloads <FILE>` flag: append a user-supplied corpus of string-injection payloads (one per line, UTF-8) to the built-in `STRING_FUZZ_VALUES`. Use case: second-order injection corpora aimed at downstream consumers — Shellshock, Log4j JNDI, custom SSTI, regex-bypass strings, engagement-specific lists. Built-ins are preserved; the file extends them. Hard caps: 10 MB / 10,000 payloads.
12+
- 9 pytest cases for the new loader (`tests/test_extra_string_payloads.py`): blank-line drop, whitespace preservation, missing-file / invalid-UTF-8 errors, file-size and payload-count caps, `~` expansion, and a Shellshock + Log4j sanity check.
13+
- README "Custom string corpora" section with a worked Shellshock / Log4j JNDI example.
14+
- `LICENSE` (MIT)
15+
- `NOTICE` file attributing Eclipse Tahu (Apache-2.0) per §4(d)
16+
- `SECURITY.md` with disclosure contact and scope
17+
- "Responsible Use" callout in `README.md`
18+
- README "License" and "Third-Party" sections
19+
20+
### Changed
21+
22+
- README air-gapped setup example uses `~/tahu` instead of an OS-specific path
23+
- `STRING_FUZZ_VALUES` now has an explanatory header comment clarifying these payloads are transmitted over MQTT (not exec'd locally)
24+
25+
### Removed
26+
27+
- Internal-project attribution comment from `FuzzLogger` docstring
28+
29+
## [0.2] — 2026-05-06
30+
31+
### Added
32+
33+
- `--setup` flag automating `pip install`, Tahu clone, and protobuf compile
34+
- `--tahu-path` for air-gapped installs from a pre-staged Tahu directory
35+
- `--output-dir` with per-run directory layout (`./sparkplug-runs/<UTC-ts>_<host>/`)
36+
- `--tls`, `--cafile`, `--insecure` TLS options (default port becomes 8883 with `--tls`)
37+
- `MQTT_USERNAME` / `MQTT_PASSWORD` env vars; `-P -` reads password from stdin without echo
38+
- `--probe-anon-write` to confirm whether the broker accepts unauthenticated PUBLISH
39+
- pytest harness with 23 tests covering `FuzzLogger`, topic helpers, output paths, and `--tahu-path` validation
40+
- README options table, version flag, flower-box header
41+
42+
### Changed
43+
44+
- `FuzzLogger` timestamps now UTC with `Z` suffix at second resolution (was microsecond, local TZ)
45+
- `paho.mqtt` transport logger throttled to WARNING by default; scales with `-v` / `-vv`
46+
- Deprecated `datetime.utcnow()` calls replaced with timezone-aware UTC
47+
48+
### Fixed
49+
50+
- Handler guard prevents duplicate logging when `setupLogging` is re-invoked
51+
- Several review findings from internal code review: log bloat, deprecation warnings, TLS hardening
52+
53+
## [0.1] — 2026-04-16
54+
55+
### Added
56+
57+
- Initial public-prep version: 12 fuzz categories (~635 test cases)
58+
- Network discovery (`DeviceTracker`)
59+
- Spoofed birth/death and NCMD/DCMD targeting against discovered devices
60+
- JSON-lines output (`sparkplug_fuzz.jsonl`) with TX / RX / EVENT records
61+
- Auto-reconnect with NBIRTH/DBIRTH re-establishment
62+
- Self-echo filtering, publish-error counter, STATE topic decode fix
63+
64+
[Unreleased]: https://github.com/BishopFox/sparkplugFuzzer/compare/v0.2...HEAD
65+
[0.2]: https://github.com/BishopFox/sparkplugFuzzer/releases/tag/v0.2
66+
[0.1]: https://github.com/BishopFox/sparkplugFuzzer/releases/tag/v0.1

CONTRIBUTING.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Contributing
2+
3+
Thanks for your interest in improving the Sparkplug B MQTT Security Fuzzer. This document
4+
explains how to report issues, propose changes, and set up a development environment.
5+
6+
## Reporting a security issue
7+
8+
**Do not open a public issue for security problems in the tool itself.** Follow the
9+
private disclosure process in [SECURITY.md](SECURITY.md) instead.
10+
11+
## Reporting bugs and requesting features
12+
13+
Use [GitHub Issues](https://github.com/BishopFox/sparkplugFuzzer/issues) for bug reports
14+
and feature requests. A good bug report includes:
15+
16+
- What you ran (target broker, full command line, relevant environment variables)
17+
- What you expected to happen and what actually happened
18+
- Affected version (`python3 sparkplug-fuzzer.py --version` or the commit SHA)
19+
- Sample output or log excerpts where applicable
20+
21+
## Development setup
22+
23+
The fuzzer is a single Python script with a small test suite. To work on it:
24+
25+
```bash
26+
git clone https://github.com/BishopFox/sparkplugFuzzer.git
27+
cd sparkplugFuzzer
28+
29+
python3 -m venv .venv && source .venv/bin/activate
30+
pip install -r requirements.txt -r requirements-dev.txt
31+
```
32+
33+
Run the test suite before submitting changes:
34+
35+
```bash
36+
pytest
37+
```
38+
39+
## Pull requests
40+
41+
1. Fork the repository and create a topic branch off `main`.
42+
2. Keep changes focused; unrelated fixes belong in separate PRs.
43+
3. Add or update tests under `tests/` for any behavior change.
44+
4. Ensure `pytest` passes locally.
45+
5. Write a clear PR description explaining the motivation and the change.
46+
47+
By submitting a pull request, you agree that your contribution is licensed under the
48+
[MIT License](LICENSE) that covers this project.
49+
50+
## Responsible use
51+
52+
This tool sends malformed and protocol-violating traffic to MQTT brokers, which commonly
53+
sit in OT/ICS environments. Only test systems you own or have explicit written
54+
authorization to test. See the **Responsible Use** section of the [README](README.md).

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Bishop Fox
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.

NOTICE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
sparkplugFuzzer
2+
Copyright (c) 2026 Bishop Fox
3+
4+
This product depends on Eclipse Tahu at runtime. When the user runs
5+
`python3 sparkplug-fuzzer.py --setup`, the following files are fetched
6+
from the Eclipse Tahu project and copied into the working directory:
7+
8+
- sparkplug_b.py
9+
- array_packer.py
10+
11+
Eclipse Tahu
12+
Copyright (c) 2012, 2018 Cirrus Link Solutions and others
13+
Licensed under the Apache License, Version 2.0 (the "License");
14+
https://www.apache.org/licenses/LICENSE-2.0
15+
https://github.com/eclipse/tahu
16+
17+
The compiled Protocol Buffers bindings (`sparkplug_b_pb2.py`) are
18+
generated locally from `sparkplug_b.proto`, also distributed by Eclipse
19+
Tahu under the Apache License, Version 2.0.
20+
21+
Neither the Eclipse Tahu source files nor the compiled bindings are
22+
redistributed in this repository.

0 commit comments

Comments
 (0)