Skip to content

TRextabat/net_sec

Repository files navigation

Secure UDP Chat Application — Problem Sets 2 & 3

Course: Network Security Students: Amir Tabat (05220000102) · Selanay Akbaba (05210000248) Repository: https://github.com/TRextabat/net_sec Branches: week2 (HW2) · week3 (HW3)

Branch Contents How to run
week2 Birthday Attack + Secure UDP Chat (baseline) git checkout week2 && docker compose up --build
week3 HW3 additions: password hardening, lockout, logout/TTL git checkout week3 && docker compose up --build

Submission Documents

Problem Report (LaTeX source) PDF
HW2 — Birthday Attack + Secure Chat submission_docs/problem2_report.tex submission_docs/problem2_report.pdf
HW3 — Password Hardening + Session Management submission_docs/problem3_report.tex submission_docs/problem3_report.pdf

Regenerate any PDF:

python3 submission_docs/convert_to_pdf.py   # compiles the .tex → .pdf

HW3 — What's New (week3 branch)

Built on top of HW2. Three improvement areas:

Area Implementation
Password hardening Policy: min 8 chars, upper+lower+digit+symbol required; Argon2id parameters increased; zxcvbn strength check
Brute-force / lockout Exponential back-off + account lockout after N consecutive failures; per-IP rate limiting in Redis
Logout + session expiry LOGOUT command; server-side TTL on session tokens; client-side idle timeout; SESSION_EXPIRED notification
Demo (dave) 4th Mininet client tests all 3 features: policy rejection, lockout after 5 bad logins, logout with server-side token revocation

HW3 Quick Start

git checkout week3
docker compose up --build

How to create a user (password policy)

Passwords must satisfy all of:

  • Minimum 8 characters
  • At least one uppercase letter (A–Z)
  • At least one lowercase letter (a–z)
  • At least one digit (0–9)
  • At least one symbol (!@#$%^&* etc.)
  • zxcvbn strength score ≥ 2 (rejects common passwords / dictionary words)
# Valid:  "Secure#42"   "P@ssw0rd!"
# Invalid: "password", "12345678", "aaaaaaaa"

How to log in

python3 -c "
import sys, time; sys.path.insert(0, '.')
from client.client import SecureUDPChatClient
c = SecureUDPChatClient('127.0.0.1', 9090)
c.connect()
c.login('alice', 'Secure#42')
print('Session token:', c._token[:8], '...')
time.sleep(2)
c.disconnect()
"

How logout works

The client sends a LOGOUT message with its session token. The server immediately invalidates the token in Redis. Any subsequent message using that token receives SESSION_EXPIRED.

python3 -c "
import sys, time; sys.path.insert(0, '.')
from client.client import SecureUDPChatClient
c = SecureUDPChatClient('127.0.0.1', 9090)
c.connect()
c.login('alice', 'Secure#42')
c.logout()          # sends LOGOUT, token revoked server-side
time.sleep(1)
c.disconnect()
"

How to test session expiration

Set a short TTL via environment variable and observe SESSION_EXPIRED:

SESSION_TTL_SECONDS=10 docker compose up --build
# After 10 s of inactivity the server evicts the token
# Client receives SESSION_EXPIRED on next send

How to test brute-force protection

python3 -c "
import sys; sys.path.insert(0, '.')
from client.client import SecureUDPChatClient
c = SecureUDPChatClient('127.0.0.1', 9090)
c.connect()
for i in range(10):
    ok = c.login('alice', 'wrongpassword')
    print(f'attempt {i+1}:', ok)
# After 5 consecutive failures: account locked for LOCKOUT_SECONDS
# Subsequent attempts return AUTH_LOCKED immediately
"

HW2 Overview

A complete secure chat system over UDP, running inside a Mininet network topology within a single Docker container.

Security stack:

  • Passwords: Argon2id (PHC format)
  • Session keys: X25519 ECDH + HKDF-SHA256 → AES-256 key
  • Confidentiality + Integrity: AES-256-GCM (authenticated encryption)
  • Non-repudiation: ECDSA P-256 signatures stored in server audit log
  • Replay protection: sequence counter + msg_id deduplication + 30-second timestamp window
  • Group keys: per-group random AES-256 key, distributed encrypted per member

Prerequisites

  • Docker ≥ 24.0 and Docker Compose v2
  • Linux host with OVS kernel module:
    sudo modprobe openvswitch
  • Privileged containers (required for Mininet network namespaces)

Quick Start (HW2)

git checkout week2
docker compose up --build

The demo automatically:

  1. Starts the secure chat server on h_server (10.0.0.1:9090)
  2. alice registers, logs in, creates group #team, sends a DM to bob and a group message
  3. bob registers, logs in, sends a DM to alice
  4. carol registers, logs in, joins #team, receives the group message
  5. Verifies ECDSA signatures, replay rejection, and delivery statuses

Manual Usage

Run the server

python3 server/server.py 9090

Environment variables:

Variable Default Purpose
REDIS_HOST localhost Redis hostname
REDIS_PORT 6379 Redis port
SESSION_TTL_SECONDS 3600 Session token lifetime (HW3)
LOCKOUT_THRESHOLD 5 Failed logins before lockout (HW3)
LOCKOUT_SECONDS 300 Lockout duration in seconds (HW3)

Create a user account

python3 -c "
import sys; sys.path.insert(0, '.')
from client.client import SecureUDPChatClient
c = SecureUDPChatClient('127.0.0.1', 9090)
c.connect()
ok = c.register('alice', 'Secure#42')
print('Registered:', ok)
c.disconnect()
"

Create and use a group

# alice creates the group
python3 -c "
import sys, time; sys.path.insert(0, '.')
from client.client import SecureUDPChatClient
c = SecureUDPChatClient('127.0.0.1', 9090)
c.connect(); c.login('alice', 'Secure#42')
c.create_group('team'); c.send_group('team', 'Hello team!')
time.sleep(2); c.disconnect()
"

# carol joins the group
python3 -c "
import sys, time; sys.path.insert(0, '.')
from client.client import SecureUDPChatClient
c = SecureUDPChatClient('127.0.0.1', 9090)
c.connect(); c.login('carol', 'C@rol123!')
c.join_group('team'); time.sleep(3); c.disconnect()
"

Running Tests

python3 client/crypto_utils.py       # crypto primitives self-test
python3 shared/protocol.py           # protocol pack/unpack self-test
python3 birthday_attack/birthday_attack.py  # BD attack + plot
docker compose up --build            # full Mininet integration test

Project Structure

net_sec/
├── server/
│   ├── server.py          # ChatServer + SecureChatServer
│   ├── auth.py            # AccountManager (register, login, session, lockout, logout)
│   ├── group.py           # GroupManager (create/join/leave + group keys)
│   ├── store.py           # Redis-backed UserStore + MessageLog
│   └── crypto_server.py   # Server-side crypto primitives
├── client/
│   ├── client.py          # UDPChatClient + SecureUDPChatClient
│   ├── demo_client.py     # DemoClient + SecureDemoClient
│   └── crypto_utils.py    # Client-side crypto primitives (+ password policy)
├── shared/
│   └── protocol.py        # Message constants + pack/unpack helpers
├── birthday_attack/
│   └── birthday_attack.py # BD attack derivation + plot
├── mininet/
│   ├── run_demo.py        # Demo orchestration (week2 + week3 scenarios)
│   └── Dockerfile
├── docker-compose.yml
├── submission_docs/
│   ├── problem2_report.tex / .pdf   # HW2 report
│   ├── problem3_report.tex / .pdf   # HW3 report
│   ├── convert_to_pdf.py
│   └── figures/
└── problem_sets/
    ├── problem1.txt
    ├── problem2.txt
    └── problem3.txt

Security Design Summary (HW2 baseline)

Session establishment

Client                                    Server
  │── REGISTER {user, argon2_hash(pw), pub} ─►│  store user:username hash
  │── LOGIN {user, pw_plaintext, ecdh_pub} ──►│  verify Argon2, run ECDH
  │◄── SESSION {token, server_ecdh_pub} ──── │
  │  Both sides: HKDF(X25519(priv,pub)) → session_key (AES-256)

HW3 additions

  │── LOGOUT {token} ─────────────────────►│  revoke token in Redis
  │                                         │  (TTL-based expiry also running)
  │◄── SESSION_EXPIRED ─────────────────── │  sent on any use of expired token

Dependencies

Package Version Purpose
cryptography 46.0.3 X25519, AES-GCM, ECDSA P-256
argon2-cffi 23.1.0 Argon2id password hashing
redis 5.x Redis client + session TTL
zxcvbn 4.4.28 Password strength estimation (HW3)

Run Notes & Possible Issues

Issue Cause Fix
user_exists error on second run Redis persists data between container restarts docker compose down -v && docker compose up --build
DEMO_PASSWORD rejected by policy Password lacks uppercase/lowercase/digit/symbol or is too weak Use a strong password: DEMO_PASSWORD=Secure#42 in .env
ModuleNotFoundError: zxcvbn Package not installed in local dev pip install zxcvbn or use Docker (docker compose up --build)
OVS kernel module missing Host kernel module not loaded sudo modprobe openvswitch on the host before running Docker
Dave's lockout test shows "locked" warning with wrong count LOCKOUT_THRESHOLD env var set differently Default is 5; override in .env or docker-compose.yml
Session expired mid-conversation SESSION_TTL_SECONDS too short Increase in .env, default is 3600 (1 hour)

Known Limitations

  • UDP MTU: messages > ~1300 bytes may exceed payload; fragmentation not implemented
  • Group key rotation only on leave; not on periodic schedule
  • No forward secrecy for stored messages (server log holds ciphertext)

About

Network Security coursework — UDP Chat, Birthday Attack, Mininet-in-Docker

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors