Notch is a network steganography tool. It hides arbitrary payloads inside ordinary-looking traffic, with optional authentication so only a holder of the shared secret can recover the data.
Prebuilt binaries, when available, are published on GitHub Releases.
Intended for learning and authorized testing only. Notch demonstrates network steganography and can be used offensively. Use it only on systems and networks you own or are explicitly authorized to test. You are responsible for complying with all applicable laws; use it at your own risk.
| Method | Status | Details |
|---|---|---|
| TCP SYN ISN injection | Available | Encodes payload data in the Initial Sequence Number (ISN) of TCP SYN packets. |
| ICMP | Planned | Planned transport method. |
Authenticated mode uses a SECRET (via HMAC) so that encoded data can be
verified by the receiver and is not trivially recoverable by an observer.
The quickest option is to download a prebuilt binary for your platform from the Releases page and make it executable:
chmod +x notchTo build from source instead, install a recent stable Rust toolchain (via rustup) and compile with Cargo:
cargo build --releaseThe resulting binary is at target/release/notch.
The payload is read from standard input by default. Each authenticated packet
encodes two payload bytes; --no-auth encodes four bytes per packet.
Authenticated mode requires the SECRET environment variable.
printf '\x12\x34' | sudo -E target/release/notch inject \
--dest 192.0.2.10 --interface eth0To read the payload from a file instead, pass its path with --payload:
sudo -E SECRET='shared secret' target/release/notch inject \
--dest 192.0.2.10 --interface eth0 --payload payload.bin --rate 10The sender prints the injection details and asks for confirmation before
sending. Raw TCP transmission requires CAP_NET_RAW, which running under sudo
typically provides. Run notch inject --help for the full list of options.
To recover a payload live, start extract on the receiving interface before
running the sender. The receiver requires the same shared secret and writes
recovered bytes to standard output; it stops when it receives the final packet.
sudo target/release/notch extract --interface eth0 --port 6769 --secret 'shared secret' > payload.binTo extract from an existing capture, pass --pcap instead of --interface:
target/release/notch extract --pcap capture.pcap --port 6769 --secret 'shared secret' > payload.binThe lab/ directory is a Buildroot BR2_EXTERNAL
tree that boots Notch inside QEMU virtual machines on an isolated layer-2
network, so the covert channel can be exercised and analyzed safely. Three
scripts in lab/qemu/ drive it:
A typical session, from lab/:
sudo ./qemu/bridge-up.sh sender # once per boot session; creates tap-sender
./qemu/run.sh sender # as your user; do not sudo (it builds with your Rust toolchain)
sudo ./qemu/bridge-down.sh sender # tear down when donelab/orchestrator.py runs a full experiment end to end: it captures SYNs on the
host, drives the VM to run notch inject, and then analyzes the captured
traffic. The lab/isn/ package performs the steganalysis, testing whether the
TCP ISNs look random (a real OS) or carry a hidden payload, and writing a
verdict plus a scorecard image to lab/results/.
cd lab
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/python orchestrator.py --mode no-auth # capture, inject, and analyze
.venv/bin/python -m isn.analyze captures/some.pcap # analyze an existing captureContributions, issues, and feature ideas are welcome. See CONTRIBUTING.md for the full guide; in short:
-
Build and test with
cargo buildandcargo test. -
Run
cargo fmtandcargo clippybefore committing. A pre-commit hook under.githooks/can do the formatting for you, enabled with:git config core.hooksPath .githooks
-
Keep pull requests focused, match the existing style, and update tests for any behavior you change.
All participants are expected to follow the Code of Conduct.
Notch is licensed under the GNU GPL-3.0.


