Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Network Keylogger C2 — Network Security Project

Keystroke Interception, Encrypted C2 Channel & Port-Based Detection


Project Overview

This project demonstrates a full attack-and-defense cycle around keystroke interception over a network channel. It runs entirely on a single machine using localhost (127.0.0.1) sockets — no VMs, no second machine needed.

┌─────────────────────┐   TCP/9999 (localhost)   ┌──────────────────────┐
│   agent.py          │ ────────────────────────▶ │  c2_listener.py      │
│                     │                           │                      │
│  • Hooks keyboard   │   Payload structure:      │  • Receives packets  │
│  • Buffers keys     │   [4-byte len][JSON body] │  • Decrypts AES-CBC  │
│  • AES-256 encrypt  │                           │  • Displays + logs   │
│  • Sends every 2s   │                           │  • Multi-session     │
│  • Auto-reconnects  │                           │                      │
└─────────────────────┘                           └──────────────────────┘
                                │
                         detector.py
                  (polls port 9999 every 3s,
                   reports WATCHING / SAFE)

Files

File Module Description
agent.py 1 & 3 Keystroke capture + AES-256-CBC encrypted C2 sender
c2_listener.py 2 & 3 C2 server — receive, decrypt, display, and log keystrokes
detector.py 4 Port-based detector — polls C2 port and reports listener status
requirements.txt Python dependencies

Setup

1. Install dependencies

pip install -r requirements.txt

Note on Scapy: scapy is listed in requirements.txt for potential future packet-sniffing extensions. The current detector.py uses standard sockets only and does not require administrator/root privileges.

2. Run order (open 3 separate terminals)

Terminal 1 — Start the C2 Listener:

python c2_listener.py

Terminal 2 — Start the Agent:

# Encrypted mode (default — recommended)
python agent.py

# Plaintext mode — for Wireshark demo to show readable traffic
python agent.py --plain

Terminal 3 — Start the Detector:

python detector.py

Now type anything. Keystrokes appear in the C2 listener terminal in real time, and the detector reports the active interception channel every 3 seconds.


Module Details

agent.py — Keystroke Capture & C2 Sender (Modules 1 & 3)

  • Hooks the keyboard globally via pynput
  • Buffers captured keystrokes and flushes every 2 seconds
  • Encrypts each payload with AES-256-CBC before sending
  • Resilient connection: if the listener is not running, the agent retries every 3 seconds without crashing — and reconnects automatically when available
  • Supports two modes:
    • Default: AES-256-CBC encrypted (binary, unreadable in transit)
    • --plain: raw JSON (readable in Wireshark — demonstrates risk)
  • Press ESC to stop the agent gracefully
Payload structure per flush:
{
  "timestamp": "<ISO-8601>",
  "keystrokes": ["h", "e", "l", "l", "o", "[ENTER]"],
  "count": 6
}

Special keys (Enter, Shift, Tab, etc.) are recorded as [KEYNAME].


c2_listener.py — C2 Receive & Decrypt Server (Modules 2 & 3)

  • Binds to 0.0.0.0:9999, accepts multiple simultaneous agent connections
  • Each connection is handled in its own daemon thread
  • Reads a 4-byte length prefix then receives the exact payload bytes
  • Decrypts AES-256-CBC payloads using the pre-shared key
  • Supports both encrypted and plaintext payloads (plaintext flagged with ⚠️)
  • Logs all received keystrokes to captured_keystrokes.log (JSON, one entry per line)
  • Displays per-session running totals and color-coded output in the terminal

detector.py — Port-Based Listener Detector (Module 4)

  • Polls port 9999 on localhost every 3 seconds via a TCP connect probe
  • Classifies and reports one of two states:
State Meaning
👁️ WATCHING Port 9999 is open — a C2 listener is actively running
❌ SAFE Port 9999 is closed — no active interception channel
  • No admin/root required — uses only standard socket connections
  • Timestamped output on every check cycle
  • Stop with Ctrl+C

How the Encryption Works

SHARED_SECRET ──SHA-256 KDF──▶ 32-byte AES Key
                                      │
           Keystroke JSON ────────────┤
           Random IV (16 bytes) ──────┤
                                      ▼
                               AES-256-CBC
                                      │
                                      ▼
                    { "iv": base64(IV), "ct": base64(ciphertext), "encrypted": true }
                    ──────────────── TCP/9999 ────────────────▶

The C2 listener reverses this exactly using the same SHARED_SECRET.


Demonstration Scenarios

Scenario A — Encrypted Traffic (Default Operation)

  1. Start c2_listener.py, then agent.py (no flags)
  2. Open Wireshark → capture on Loopback Adapter → filter: tcp.port == 9999
  3. Observe: payload bytes are binary and unreadable — AES encrypted
  4. C2 listener terminal shows decrypted, readable keystrokes in real time
  5. detector.py reports 👁️ WATCHING every 3 seconds

Scenario B — Plaintext Demo (Shows the Risk)

  1. Stop the agent, restart with python agent.py --plain
  2. In Wireshark, right-click a packet → Follow → TCP Stream
  3. Observe: the full JSON payload is readable — passwords and text are visible in clear
  4. C2 listener flags each batch with ⚠️ PLAIN in red
  5. This demonstrates exactly why encryption matters

Scenario C — Detector Lifecycle

  1. Start detector.py first, before the listener — observe ❌ SAFE
  2. Start c2_listener.py — within 3 seconds detector switches to 👁️ WATCHING
  3. Stop c2_listener.py — detector reverts to ❌ SAFE on the next poll cycle

Security Concepts Demonstrated

Concept Where
Keylogger / spyware mechanics agent.pypynput global keyboard hook
C2 (Command & Control) infrastructure agent.py + c2_listener.py — TCP socket channel
Resilient malware (auto-reconnect) agent.py — retry loop in connect()
AES-256-CBC symmetric encryption agent.py encrypt → c2_listener.py decrypt
Pre-shared key (PSK) + SHA-256 KDF SHARED_SECRETderive_key() in both files
Length-prefixed framing (protocol design) 4-byte big-endian header in sender and receiver
Plaintext vs. encrypted traffic contrast --plain flag in agent.py; Wireshark inspection
Packet / traffic analysis Wireshark on loopback, tcp.port == 9999
Port-based threat detection detector.py — TCP connect probe every 3s
Attack vs. defense perspective Agent = attacker, Listener = exfil server, Detector = defender
Multi-session C2 server c2_listener.py — threaded client handling

Configuration Reference

All tunable constants are at the top of each file:

Constant File(s) Default Description
C2_HOST agent.py, detector.py 127.0.0.1 Target/monitored host
C2_PORT all files 9999 C2 TCP port
SHARED_SECRET agent.py, c2_listener.py network_security_project_2024 AES key derivation secret
BUFFER_FLUSH_INTERVAL agent.py 2.0 s How often keystrokes are sent
RETRY_INTERVAL agent.py 3 s Reconnect delay if listener is down
CHECK_INTERVAL detector.py 3 s Port poll frequency
LOG_FILE c2_listener.py captured_keystrokes.log Output log path
LISTEN_HOST c2_listener.py 0.0.0.0 Bind address for the C2 server

Install with:

pip install -r requirements.txt

Ethical & Legal Notice

This project is built strictly for educational purposes in a controlled, single-machine environment. All traffic is confined to localhost (127.0.0.1) and never leaves your machine.

Deploying keyloggers, C2 infrastructure, or any form of unauthorized interception against real users or systems without explicit written consent is illegal under:

  • IT Act 2000 (India) — Sections 43, 66, 66B
  • Computer Fraud and Abuse Act (USA)
  • Computer Misuse Act 1990 (UK)
  • Equivalent laws in all other jurisdictions

Use this code only in sandboxed, consent-based lab environments.

About

This project demonstrates a full attack-and-defense cycle around keystroke interception over a network channel.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages